From 7dcb1d272fa29d2003ccbae180aba5dee52921e8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Louis-Francis=20Ratt=C3=A9-Boulianne?= Date: Thu, 19 Mar 2020 04:59:27 -0400 Subject: [PATCH] st/mesa: Replace UsesStreams by ActiveStreamMask for GS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Some drivers need to know which streams are used by a geometry shader. Adding a mask of active streams makes the use of UsesStreams superfluous as it's the equivalent of: ActiveStreamMask != (1 << 0) Signed-off-by: Louis-Francis Ratté-Boulianne Reviewed-by: Gert Wollny Part-of: --- src/compiler/glsl/linker.cpp | 22 +++++++-------- src/compiler/nir/nir_gather_info.c | 3 +-- src/compiler/nir/nir_lower_gs_intrinsics.c | 31 +++++++++++++--------- src/compiler/shader_info.h | 4 +-- src/intel/compiler/brw_vec4_gs_visitor.cpp | 4 +-- src/mesa/main/mtypes.h | 2 +- src/mesa/main/shaderapi.c | 2 +- src/mesa/main/shaderobj.c | 2 +- 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 8761c16e2fe..52646752c97 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -332,7 +332,7 @@ public: invalid_stream_id(0), invalid_stream_id_from_emit_vertex(false), end_primitive_found(false), - uses_non_zero_stream(false) + used_streams(0) { /* empty */ } @@ -353,8 +353,7 @@ public: return visit_stop; } - if (stream_id != 0) - uses_non_zero_stream = true; + used_streams |= 1 << stream_id; return visit_continue; } @@ -377,8 +376,7 @@ public: return visit_stop; } - if (stream_id != 0) - uses_non_zero_stream = true; + used_streams |= 1 << stream_id; return visit_continue; } @@ -399,9 +397,9 @@ public: return invalid_stream_id; } - bool uses_streams() + unsigned active_stream_mask() { - return uses_non_zero_stream; + return used_streams; } bool uses_end_primitive() @@ -414,7 +412,7 @@ private: int invalid_stream_id; bool invalid_stream_id_from_emit_vertex; bool end_primitive_found; - bool uses_non_zero_stream; + unsigned used_streams; }; /* Class that finds array derefs and check if indexes are dynamic. */ @@ -811,7 +809,7 @@ validate_geometry_shader_emissions(struct gl_context *ctx, emit_vertex.error_stream(), ctx->Const.MaxVertexStreams - 1); } - prog->Geom.UsesStreams = emit_vertex.uses_streams(); + prog->Geom.ActiveStreamMask = emit_vertex.active_stream_mask(); prog->Geom.UsesEndPrimitive = emit_vertex.uses_end_primitive(); /* From the ARB_gpu_shader5 spec: @@ -834,11 +832,11 @@ validate_geometry_shader_emissions(struct gl_context *ctx, * Since we can call EmitVertex() and EndPrimitive() when we output * primitives other than points, calling EmitStreamVertex(0) or * EmitEndPrimitive(0) should not produce errors. This it also what Nvidia - * does. Currently we only set prog->Geom.UsesStreams to TRUE when - * EmitStreamVertex() or EmitEndPrimitive() are called with a non-zero + * does. We can use prog->Geom.ActiveStreamMask to check whether only the + * first (zero) stream is active. * stream. */ - if (prog->Geom.UsesStreams && + if (prog->Geom.ActiveStreamMask & ~(1 << 0) && sh->Program->info.gs.output_primitive != GL_POINTS) { linker_error(prog, "EmitStreamVertex(n) and EndStreamPrimitive(n) " "with n>0 requires point output\n"); diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index 0e2624c4219..5f59dd21dd0 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -390,8 +390,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, case nir_intrinsic_emit_vertex: case nir_intrinsic_emit_vertex_with_counter: - if (nir_intrinsic_stream_id(instr) > 0) - shader->info.gs.uses_streams = true; + shader->info.gs.active_stream_mask |= 1 << nir_intrinsic_stream_id(instr); break; diff --git a/src/compiler/nir/nir_lower_gs_intrinsics.c b/src/compiler/nir/nir_lower_gs_intrinsics.c index 9d7cfbee427..6e0f4da360e 100644 --- a/src/compiler/nir/nir_lower_gs_intrinsics.c +++ b/src/compiler/nir/nir_lower_gs_intrinsics.c @@ -76,6 +76,7 @@ rewrite_emit_vertex(nir_intrinsic_instr *intrin, struct state *state) /* Load the vertex count */ b->cursor = nir_before_instr(&intrin->instr); + assert(state->vertex_count_vars[stream] != NULL); nir_ssa_def *count = nir_load_var(b, state->vertex_count_vars[stream]); nir_ssa_def *max_vertices = @@ -117,6 +118,7 @@ rewrite_end_primitive(nir_intrinsic_instr *intrin, struct state *state) unsigned stream = nir_intrinsic_stream_id(intrin); b->cursor = nir_before_instr(&intrin->instr); + assert(state->vertex_count_vars[stream] != NULL); nir_ssa_def *count = nir_load_var(b, state->vertex_count_vars[stream]); nir_intrinsic_instr *lowered = @@ -197,20 +199,23 @@ nir_lower_gs_intrinsics(nir_shader *shader, bool per_stream) /* Create the counter variables */ b.cursor = nir_before_cf_list(&impl->body); - unsigned num_counters = per_stream && shader->info.gs.uses_streams ? - NIR_MAX_XFB_STREAMS : 1; - for (unsigned i = 0; i < num_counters; i++) { - state.vertex_count_vars[i] = - nir_local_variable_create(impl, glsl_uint_type(), "vertex_count"); - /* initialize to 0 */ - nir_store_var(&b, state.vertex_count_vars[i], nir_imm_int(&b, 0), 0x1); + for (unsigned i = 0; i < NIR_MAX_XFB_STREAMS; i++) { + if (per_stream && !(shader->info.gs.active_stream_mask & (1 << i))) + continue; + + if (i == 0 || per_stream) { + state.vertex_count_vars[i] = + nir_local_variable_create(impl, glsl_uint_type(), "vertex_count"); + /* initialize to 0 */ + nir_store_var(&b, state.vertex_count_vars[i], nir_imm_int(&b, 0), 0x1); + } else { + /* If per_stream is false, we only have one counter which we want to use + * for all streams. Duplicate the counter pointer so all streams use the + * same counter. + */ + state.vertex_count_vars[i] = state.vertex_count_vars[0]; + } } - /* If per_stream is false, we only have one counter which we want to use - * for all streams. Duplicate the counter pointer so all streams use the - * same counter. - */ - for (unsigned i = num_counters; i < NIR_MAX_XFB_STREAMS; i++) - state.vertex_count_vars[i] = state.vertex_count_vars[0]; nir_foreach_block_safe(block, impl) rewrite_intrinsics(block, &state); diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index c4294b3b140..8c632de5387 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -234,8 +234,8 @@ typedef struct shader_info { /** Whether or not this shader uses EndPrimitive */ bool uses_end_primitive:1; - /** Whether or not this shader uses non-zero streams */ - bool uses_streams:1; + /** The streams used in this shaders (max. 4) */ + uint8_t active_stream_mask:4; } gs; struct { diff --git a/src/intel/compiler/brw_vec4_gs_visitor.cpp b/src/intel/compiler/brw_vec4_gs_visitor.cpp index ce341806c7b..58f6f1212ac 100644 --- a/src/intel/compiler/brw_vec4_gs_visitor.cpp +++ b/src/intel/compiler/brw_vec4_gs_visitor.cpp @@ -667,8 +667,8 @@ brw_compile_gs(const struct brw_compiler *compiler, void *log_data, */ prog_data->control_data_format = GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID; - /* We only have to emit control bits if we are using streams */ - if (shader->info.gs.uses_streams) + /* We only have to emit control bits if we are using non-zero streams */ + if (shader->info.gs.active_stream_mask != (1 << 0)) c.control_data_bits_per_vertex = 2; else c.control_data_bits_per_vertex = 0; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f78d2b5d980..0feebc5f5d0 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3050,7 +3050,7 @@ struct gl_shader_program GLint VerticesIn; bool UsesEndPrimitive; - bool UsesStreams; + unsigned ActiveStreamMask; } Geom; /** diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 19d7a3ab440..86c8c8597d9 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -2610,7 +2610,7 @@ _mesa_copy_linked_program_data(const struct gl_shader_program *src, case MESA_SHADER_GEOMETRY: { dst->info.gs.vertices_in = src->Geom.VerticesIn; dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive; - dst->info.gs.uses_streams = src->Geom.UsesStreams; + dst->info.gs.active_stream_mask = src->Geom.ActiveStreamMask; break; } case MESA_SHADER_FRAGMENT: { diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index a2478d96975..9a4225d608a 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -291,7 +291,7 @@ init_shader_program(struct gl_shader_program *prog) prog->FragDataIndexBindings = string_to_uint_map_ctor(); prog->Geom.UsesEndPrimitive = false; - prog->Geom.UsesStreams = false; + prog->Geom.ActiveStreamMask = 0; prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS; -- 2.30.2