[Mesa-dev] [PATCH 1/7] draw/tgsi: implement geom shader invocation support.
Roland Scheidegger
sroland at vmware.com
Wed May 27 04:42:14 PDT 2015
Am 27.05.2015 um 09:45 schrieb Dave Airlie:
> From: Dave Airlie <airlied at redhat.com>
>
> This is just for softpipe, llvmpipe won't work without
> some changes.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/gallium/auxiliary/draw/draw_gs.c | 47 +++++++++++++++++++++-------------
> src/gallium/auxiliary/draw/draw_gs.h | 2 ++
> src/gallium/auxiliary/tgsi/tgsi_scan.c | 2 ++
> src/gallium/auxiliary/tgsi/tgsi_scan.h | 1 +
> 4 files changed, 34 insertions(+), 18 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
> index 6375d41..755e527 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.c
> +++ b/src/gallium/auxiliary/draw/draw_gs.c
> @@ -190,9 +190,15 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
> const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
> {
> struct tgsi_exec_machine *machine = shader->machine;
> -
> + int j;
> tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
> constants, constants_size);
> +
> + if (shader->info.uses_invocationid) {
> + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
> + for (j = 0; j < TGSI_QUAD_SIZE; j++)
> + machine->SystemValue[i].i[j] = shader->invocation_id;
> + }
> }
>
> static unsigned tgsi_gs_run(struct draw_geometry_shader *shader,
> @@ -555,7 +561,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
> * overflown vertices into some area where they won't harm anyone */
> unsigned total_verts_per_buffer = shader->primitive_boundary *
> num_in_primitives;
> -
> + unsigned invocation;
> //Assume at least one primitive
> max_out_prims = MAX2(max_out_prims, 1);
>
> @@ -564,7 +570,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
> output_verts->stride = output_verts->vertex_size;
> output_verts->verts =
> (struct vertex_header *)MALLOC(output_verts->vertex_size *
> - total_verts_per_buffer);
> + total_verts_per_buffer * shader->num_invocations);
This can't get very large, right?
Otherwise,
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
> debug_assert(output_verts->verts);
>
> #if 0
> @@ -592,7 +598,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
> shader->input = input;
> shader->input_info = input_info;
> FREE(shader->primitive_lengths);
> - shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
> + shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned) * shader->num_invocations);
>
>
> #ifdef HAVE_LLVM
> @@ -622,23 +628,26 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
> }
> #endif
>
> - shader->prepare(shader, constants, constants_size);
> + for (invocation = 0; invocation < shader->num_invocations; invocation++) {
> + shader->invocation_id = invocation;
>
> - if (input_prim->linear)
> - gs_run(shader, input_prim, input_verts,
> - output_prims, output_verts);
> - else
> - gs_run_elts(shader, input_prim, input_verts,
> - output_prims, output_verts);
> + shader->prepare(shader, constants, constants_size);
>
> - /* Flush the remaining primitives. Will happen if
> - * num_input_primitives % 4 != 0
> - */
> - if (shader->fetched_prim_count > 0) {
> - gs_flush(shader);
> - }
> + if (input_prim->linear)
> + gs_run(shader, input_prim, input_verts,
> + output_prims, output_verts);
> + else
> + gs_run_elts(shader, input_prim, input_verts,
> + output_prims, output_verts);
>
> - debug_assert(shader->fetched_prim_count == 0);
> + /* Flush the remaining primitives. Will happen if
> + * num_input_primitives % 4 != 0
> + */
> + if (shader->fetched_prim_count > 0) {
> + gs_flush(shader);
> + }
> + debug_assert(shader->fetched_prim_count == 0);
> + }
>
> /* Update prim_info:
> */
> @@ -771,6 +780,8 @@ draw_create_geometry_shader(struct draw_context *draw,
> gs->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
> gs->max_output_vertices =
> gs->info.properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES];
> + gs->num_invocations =
> + gs->info.properties[TGSI_PROPERTY_GS_INVOCATIONS];
> if (!gs->max_output_vertices)
> gs->max_output_vertices = 32;
>
> diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
> index 49e93d5..663ba84 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.h
> +++ b/src/gallium/auxiliary/draw/draw_gs.h
> @@ -90,6 +90,8 @@ struct draw_geometry_shader {
> unsigned vector_length;
> unsigned max_out_prims;
>
> + unsigned num_invocations;
> + unsigned invocation_id;
> #ifdef HAVE_LLVM
> struct draw_gs_inputs *gs_input;
> struct draw_gs_jit_context *jit_context;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index d821072..e0506f4 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -230,6 +230,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
> }
> else if (semName == TGSI_SEMANTIC_PRIMID) {
> info->uses_primid = TRUE;
> + } else if (semName == TGSI_SEMANTIC_INVOCATIONID) {
> + info->uses_invocationid = TRUE;
> }
> }
> else if (file == TGSI_FILE_OUTPUT) {
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> index 0ea0e88..77c649a 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> @@ -85,6 +85,7 @@ struct tgsi_shader_info
> boolean uses_basevertex;
> boolean uses_primid;
> boolean uses_frontface;
> + boolean uses_invocationid;
> boolean writes_psize;
> boolean writes_clipvertex;
> boolean writes_viewport_index;
>
More information about the mesa-dev
mailing list