Mesa (master): st/mesa: Replace UsesStreams by ActiveStreamMask for GS
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Aug 18 11:34:08 UTC 2020
Module: Mesa
Branch: master
Commit: 7dcb1d272fa29d2003ccbae180aba5dee52921e8
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=7dcb1d272fa29d2003ccbae180aba5dee52921e8
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Mar 19 04:59:27 2020 -0400
st/mesa: Replace UsesStreams by ActiveStreamMask for GS
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 <lfrb at collabora.com>
Reviewed-by: Gert Wollny <gert.wollny at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5984>
---
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;
More information about the mesa-commit
mailing list