From: Dave Airlie Date: Tue, 14 Apr 2020 02:39:42 +0000 (+1000) Subject: draw/gs: reverse the polarity of the invocation/prims execution X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e455d6ad31400f4733a2f859cc5ecade7efdbe1;p=mesa.git draw/gs: reverse the polarity of the invocation/prims execution The current code runs primitives per invocation, but the spec wants invocations per primitive. However it means having to flush after each invocation to get correct XFB behaviour Fixes: GTF-GL41.gtf40.GL3Tests.transform_feedback3.transform_feedback3_geometry_instanced Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index f648a96db7b..2d11430b274 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -69,7 +69,7 @@ draw_gs_get_input_index(int semantic, int index, static inline boolean draw_gs_should_flush(struct draw_geometry_shader *shader) { - return (shader->fetched_prim_count == shader->vector_length); + return (shader->fetched_prim_count == shader->vector_length || shader->num_invocations > 1); } /*#define DEBUG_OUTPUTS 1*/ @@ -192,15 +192,8 @@ 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].xyzw[0].i[j] = shader->invocation_id; - } } static void tgsi_gs_run(struct draw_geometry_shader *shader, @@ -210,6 +203,12 @@ static void tgsi_gs_run(struct draw_geometry_shader *shader, struct tgsi_exec_machine *machine = shader->machine; int i; + if (shader->info.uses_invocationid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID]; + for (int j = 0; j < TGSI_QUAD_SIZE; j++) + machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id; + } + /* run interpreter */ tgsi_exec_machine_run(machine, 0); @@ -437,10 +436,13 @@ static void gs_flush(struct draw_geometry_shader *shader) debug_assert(input_primitives > 0 && input_primitives <= 4); - shader->run(shader, input_primitives, out_prim_count); - for (i = 0; i < shader->num_vertex_streams; i++) { - shader->fetch_outputs(shader, i, out_prim_count[i], - &shader->stream[i].tmp_output); + for (unsigned invocation = 0; invocation < shader->num_invocations; invocation++) { + shader->invocation_id = invocation; + shader->run(shader, input_primitives, out_prim_count); + for (i = 0; i < shader->num_vertex_streams; i++) { + shader->fetch_outputs(shader, i, out_prim_count[i], + &shader->stream[i].tmp_output); + } } #if 0 @@ -592,7 +594,6 @@ 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; int i; //Assume at least one primitive max_out_prims = MAX2(max_out_prims, 1); @@ -666,26 +667,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, } #endif - for (invocation = 0; invocation < shader->num_invocations; invocation++) { - shader->invocation_id = invocation; + shader->prepare(shader, constants, constants_size); - shader->prepare(shader, constants, constants_size); + 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); - 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); - - /* 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); + /* 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: */