v3d: add initial compiler plumbing for geometry shaders

Most of the relevant work happens in the v3d_nir_lower_io. Since
geometry shaders can write any number of output vertices, this pass
injects a few variables into the shader code to keep track of things
like the number of vertices emitted or the offsets into the VPM
of the current vertex output, etc. This is also where we handle
EmitVertex() and EmitPrimitive() intrinsics.

The geometry shader VPM output layout has a specific structure
with a 32-bit general header, then another 32-bit header slot for
each output vertex, and finally the actual vertex data.

When vertex shaders are paired with geometry shaders we also need
to consider the following:
  - Only geometry shaders emit fixed function outputs.
  - The coordinate shader used for the vertex stage during binning must
    not drop varyings other than those used by transform feedback, since
    these may be read by the binning GS.

v2:
 - Use MAX3 instead of a chain of MAX2 (Alejandro).
 - Make all loop variables unsigned in ntq_setup_gs_inputs (Alejandro)
 - Update comment in IO owering so it includes the GS stage (Alejandro)

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
This commit is contained in:
Iago Toral Quiroga
2019-10-28 13:24:44 +01:00
parent f63750accf
commit 5d578c27ce
7 changed files with 778 additions and 110 deletions

View File

@@ -329,6 +329,7 @@ struct v3d_key {
bool clamp_r:1;
} tex[V3D_MAX_TEXTURE_SAMPLERS];
uint8_t ucp_enables;
bool is_last_geometry_stage;
};
struct v3d_fs_key {
@@ -371,6 +372,16 @@ struct v3d_fs_key {
struct pipe_rt_blend_state blend;
};
struct v3d_gs_key {
struct v3d_key base;
struct v3d_varying_slot used_outputs[V3D_MAX_FS_INPUTS];
uint8_t num_used_outputs;
bool is_coord;
bool per_vertex_point_size;
};
struct v3d_vs_key {
struct v3d_key base;
@@ -552,6 +563,7 @@ struct v3d_compile {
int local_invocation_index_bits;
uint8_t vattr_sizes[V3D_MAX_VS_INPUTS / 4];
uint8_t gs_input_sizes[V3D_MAX_GS_INPUTS];
uint32_t vpm_output_size;
/* Size in bytes of registers that have been spilled. This is how much
@@ -586,6 +598,7 @@ struct v3d_compile {
struct pipe_shader_state *shader_state;
struct v3d_key *key;
struct v3d_fs_key *fs_key;
struct v3d_gs_key *gs_key;
struct v3d_vs_key *vs_key;
/* Live ranges of temps. */
@@ -687,6 +700,26 @@ struct v3d_vs_prog_data {
uint8_t vcm_cache_size;
};
struct v3d_gs_prog_data {
struct v3d_prog_data base;
/* Whether the program reads gl_PrimitiveIDIn */
bool uses_pid;
/* Number of components read from each input varying. */
uint8_t input_sizes[V3D_MAX_GS_INPUTS / 4];
/* Number of inputs */
uint8_t num_inputs;
struct v3d_varying_slot input_slots[V3D_MAX_GS_INPUTS];
/* Total number of components written, for the shader state record. */
uint32_t vpm_output_size;
/* Output primitive type */
uint8_t out_prim_type;
};
struct v3d_fs_prog_data {
struct v3d_prog_data base;