[Mesa-dev] [RFCv0 2/8] gallium: refactor pipe_shader_state to support multiple IR's
Rob Clark
robdclark at gmail.com
Mon Oct 19 12:54:35 PDT 2015
The goal is to allow the pipe driver to request something other than
TGSI, but detect whether what is getting is TGSI vs what it requested.
The pipe drivers will always have to support TGSI (and convert that into
whatever it is that they prefer), but in some cases we should be able to
skip the TGSI intermediate step (such as glsl->nir vs glsl->tgsi->nir).
I think pipe_compute_state should get similar treatment. Currently,
afaict, it has one user and one consumer, which has allowed it to be
sloppy wrt. supporting alternative IR's.
---
src/gallium/auxiliary/hud/hud_context.c | 14 +++++++--
src/gallium/auxiliary/postprocess/pp_run.c | 4 ++-
src/gallium/auxiliary/tgsi/tgsi_ureg.c | 6 ++--
src/gallium/auxiliary/util/u_simple_shaders.c | 42 +++++++++++++++++++++++----
src/gallium/auxiliary/util/u_tests.c | 7 ++++-
src/gallium/include/pipe/p_defines.h | 12 ++++++--
src/gallium/include/pipe/p_state.h | 20 +++++++++++--
7 files changed, 89 insertions(+), 16 deletions(-)
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index 95eed26..9f39abd 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -1179,7 +1179,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
};
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(fragment_shader_text, tokens, Elements(tokens))) {
assert(0);
@@ -1226,7 +1231,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
};
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(vertex_shader_text, tokens, Elements(tokens))) {
assert(0);
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
index caa2062..6cd2b70 100644
--- a/src/gallium/auxiliary/postprocess/pp_run.c
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -272,8 +272,10 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
return NULL;
}
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
state.tokens = tokens;
- memset(&state.stream_output, 0, sizeof(state.stream_output));
if (isvs) {
ret_state = pipe->create_vs_state(pipe, &state);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 3d21319..96a51c4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1777,14 +1777,16 @@ void *ureg_create_shader( struct ureg_program *ureg,
{
struct pipe_shader_state state;
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+
state.tokens = ureg_finalize(ureg);
if(!state.tokens)
return NULL;
if (so)
state.stream_output = *so;
- else
- memset(&state.stream_output, 0, sizeof(state.stream_output));
switch (ureg->processor) {
case TGSI_PROCESSOR_VERTEX:
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 6eed337..8be0da9 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -121,7 +121,12 @@ void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe)
"MOV OUT[2], SV[0]\n"
"END\n";
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
assert(0);
@@ -149,7 +154,12 @@ void *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe)
"MOV OUT[2].x, SV[0].xxxx\n"
"END\n";
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
assert(0);
@@ -192,7 +202,12 @@ void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe)
"EMIT IMM[0].xxxx\n"
"END\n";
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
assert(0);
@@ -471,7 +486,12 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe,
char text[sizeof(shader_templ)+100];
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
sprintf(text, shader_templ,
write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "",
@@ -558,7 +578,12 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
const char *type = tgsi_texture_names[tgsi_tex];
char text[sizeof(shader_templ)+100];
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
@@ -658,7 +683,12 @@ util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe,
const char *type = tgsi_texture_names[tgsi_tex];
char text[sizeof(shader_templ)+100];
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);
diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
index a94e5cc..3790011 100644
--- a/src/gallium/auxiliary/util/u_tests.c
+++ b/src/gallium/auxiliary/util/u_tests.c
@@ -422,7 +422,12 @@ null_constant_buffer(struct pipe_context *ctx)
"MOV OUT[0], CONST[0]\n"
"END\n";
struct tgsi_token tokens[1000];
- struct pipe_shader_state state = {tokens};
+ struct pipe_shader_state state;
+
+ memset(&state, 0, sizeof(state));
+
+ state.ir = PIPE_SHADER_IR_TGSI;
+ state.tokens = tokens;
if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
puts("Can't compile a fragment shader.");
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index a494715..29b0bfb 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -701,12 +701,20 @@ enum pipe_shader_cap
/**
* Shader intermediate representation.
+ *
+ * Note that if the driver requests something other than TGSI, it must
+ * always be prepared to receive TGSI in addition to it's preferred IR.
+ * If the driver requests TGSI as it's preferred IR, it will *always*
+ * get TGSI.
+ *
+ * Note that PIPE_SHADER_IR_TGSI should be zero for backwards compat with
+ * state trackers that only understand TGSI.
*/
enum pipe_shader_ir
{
- PIPE_SHADER_IR_TGSI,
+ PIPE_SHADER_IR_TGSI = 0,
PIPE_SHADER_IR_LLVM,
- PIPE_SHADER_IR_NATIVE
+ PIPE_SHADER_IR_NATIVE,
};
/**
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 4bf8d46..50bfc4a 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -211,10 +211,26 @@ struct pipe_stream_output_info
} output[PIPE_MAX_SO_OUTPUTS];
};
-
+/**
+ * The 'ir' parameter identifies whether the shader state contains TGSI
+ * tokens, etc. If the driver returns 'PIPE_SHADER_IR_TGSI' for the
+ * 'PIPE_SHADER_CAP_PREFERRED_IR' shader param, the ir will *always* be
+ * 'PIPE_SHADER_IR_TGSI' and the tokens ptr will be valid. If the driver
+ * requests a different 'pipe_shader_ir' type, then it must check the 'ir'
+ * enum to see if it is getting TGSI tokens or it's preferred IR.
+ *
+ * TODO pipe_compute_state should probably get similar treatment to handle
+ * multiple IR's in a cleaner way..
+ */
struct pipe_shader_state
{
- const struct tgsi_token *tokens;
+ enum pipe_shader_ir ir;
+ /* TODO are anon unions allowed? */
+ union {
+ const struct tgsi_token *tokens;
+ void *llvm;
+ void *native;
+ };
struct pipe_stream_output_info stream_output;
};
--
2.5.0
More information about the mesa-dev
mailing list