[Mesa-dev] [RFCv0 2/8] gallium: refactor pipe_shader_state to support multiple IR's

Rob Clark robdclark at gmail.com
Mon Oct 19 13:54:32 PDT 2015


On Mon, Oct 19, 2015 at 4:24 PM, Roland Scheidegger <sroland at vmware.com> wrote:
> Am 19.10.2015 um 21:54 schrieb Rob Clark:
>> 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).
>
> So, it is only possible to indicate one preferred IR? Would it make
> sense to to be able to say something along the lines "prefer native over
> NIR over TGSI"?
>

I hadn't thought of the use-case for that, although doesn't mean there
isn't one.  (But at that point I'm not sure it fits in very cleanly as
a shader-cap..)

I had *assumed* that drivers would only support TGSI and one
alternative.  But I may be wrong.

BR,
-R


>
>>
>> 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;
>>  };
>>
>>
>


More information about the mesa-dev mailing list