On Sun, Nov 8, 2015 at 9:12 PM, Rob Clark <robdcl...@gmail.com> wrote: > 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 ffe30b8..2344a48 100644 > --- a/src/gallium/auxiliary/hud/hud_context.c > +++ b/src/gallium/auxiliary/hud/hud_context.c > @@ -1182,7 +1182,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); > @@ -1229,7 +1234,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 f2f5181..6c40bc1 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c > @@ -1778,14 +1778,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 006dfa9..97fa502 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 d6f87cc..0a9d98d 100644 > --- a/src/gallium/include/pipe/p_defines.h > +++ b/src/gallium/include/pipe/p_defines.h > @@ -704,12 +704,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 its preferred IR. > + * If the driver requests TGSI as its 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 6bdf03a..f1c4b49 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 its 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; > };
Nameless unions shouldn't be used, as you're probably aware, but if you don't want to fix all drivers, you can just put *llvm and *native into pipe_shader_state without a union. Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev