st/program: add support for gs/tes/tcs nir shaders.
authorDave Airlie <airlied@redhat.com>
Mon, 23 Oct 2017 05:48:30 +0000 (06:48 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 25 Oct 2017 23:55:56 +0000 (00:55 +0100)
This probably needs more work but this just add the initial
code to convert gs/tcs/tes nir based shaders in the state tracker.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/mesa/state_tracker/st_glsl_to_nir.cpp
src/mesa/state_tracker/st_program.c
src/mesa/state_tracker/st_program.h

index 4effd8074ed79ae123a033827f7d3c410c8abed9..e9a8d6414e73dff9b8893ed1997f6259bf0ed188 100644 (file)
@@ -359,6 +359,11 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog, nir_shader *nir)
    case MESA_SHADER_VERTEX:
       shader_program = ((struct st_vertex_program *)prog)->shader_program;
       break;
+   case MESA_SHADER_GEOMETRY:
+   case MESA_SHADER_TESS_CTRL:
+   case MESA_SHADER_TESS_EVAL:
+      shader_program = ((struct st_common_program *)prog)->shader_program;
+      break;
    case MESA_SHADER_FRAGMENT:
       shader_program = ((struct st_fragment_program *)prog)->shader_program;
       break;
@@ -451,6 +456,7 @@ st_nir_get_mesa_program(struct gl_context *ctx,
    _mesa_associate_uniform_storage(ctx, shader_program, prog, true);
 
    struct st_vertex_program *stvp;
+   struct st_common_program *stp;
    struct st_fragment_program *stfp;
    struct st_compute_program *stcp;
 
@@ -459,6 +465,12 @@ st_nir_get_mesa_program(struct gl_context *ctx,
       stvp = (struct st_vertex_program *)prog;
       stvp->shader_program = shader_program;
       break;
+   case MESA_SHADER_GEOMETRY:
+   case MESA_SHADER_TESS_CTRL:
+   case MESA_SHADER_TESS_EVAL:
+      stp = (struct st_common_program *)prog;
+      stp->shader_program = shader_program;
+      break;
    case MESA_SHADER_FRAGMENT:
       stfp = (struct st_fragment_program *)prog;
       stfp->shader_program = shader_program;
index 1695f4835dbc3ac723dcfcc12e231e6f88bdbd65..335d45ba2822056c03b5236ed1e33a999b70415d 100644 (file)
@@ -1576,6 +1576,16 @@ st_translate_geometry_program(struct st_context *st,
 {
    struct ureg_program *ureg;
 
+   if (stgp->shader_program) {
+      nir_shader *nir = st_glsl_to_nir(st, &stgp->Base, stgp->shader_program,
+                                       MESA_SHADER_GEOMETRY);
+
+      stgp->tgsi.type = PIPE_SHADER_IR_NIR;
+      stgp->tgsi.ir.nir = nir;
+
+      return true;
+   }
+
    ureg = ureg_create_with_screen(PIPE_SHADER_GEOMETRY, st->pipe->screen);
    if (ureg == NULL)
       return false;
@@ -1609,7 +1619,7 @@ st_get_basic_variant(struct st_context *st,
    struct pipe_context *pipe = st->pipe;
    struct st_basic_variant *v;
    struct st_basic_variant_key key;
-
+   struct pipe_shader_state tgsi = {0};
    memset(&key, 0, sizeof(key));
    key.st = st->has_shareable_shaders ? NULL : st;
 
@@ -1624,16 +1634,23 @@ st_get_basic_variant(struct st_context *st,
       /* create new */
       v = CALLOC_STRUCT(st_basic_variant);
       if (v) {
+
+        if (prog->tgsi.type == PIPE_SHADER_IR_NIR) {
+           tgsi.type = PIPE_SHADER_IR_NIR;
+           tgsi.ir.nir = nir_shader_clone(NULL, prog->tgsi.ir.nir);
+           st_finalize_nir(st, &prog->Base, tgsi.ir.nir);
+        } else
+           tgsi = prog->tgsi;
          /* fill in new variant */
          switch (pipe_shader) {
          case PIPE_SHADER_TESS_CTRL:
-            v->driver_shader = pipe->create_tcs_state(pipe, &prog->tgsi);
+            v->driver_shader = pipe->create_tcs_state(pipe, &tgsi);
             break;
          case PIPE_SHADER_TESS_EVAL:
-            v->driver_shader = pipe->create_tes_state(pipe, &prog->tgsi);
+            v->driver_shader = pipe->create_tes_state(pipe, &tgsi);
             break;
          case PIPE_SHADER_GEOMETRY:
-            v->driver_shader = pipe->create_gs_state(pipe, &prog->tgsi);
+            v->driver_shader = pipe->create_gs_state(pipe, &tgsi);
             break;
          default:
             assert(!"unhandled shader type");
@@ -1662,6 +1679,16 @@ st_translate_tessctrl_program(struct st_context *st,
 {
    struct ureg_program *ureg;
 
+   if (sttcp->shader_program) {
+      nir_shader *nir = st_glsl_to_nir(st, &sttcp->Base, sttcp->shader_program,
+                                       MESA_SHADER_TESS_EVAL);
+
+      sttcp->tgsi.type = PIPE_SHADER_IR_NIR;
+      sttcp->tgsi.ir.nir = nir;
+
+      return true;
+   }
+
    ureg = ureg_create_with_screen(PIPE_SHADER_TESS_CTRL, st->pipe->screen);
    if (ureg == NULL)
       return false;
@@ -1687,6 +1714,16 @@ st_translate_tesseval_program(struct st_context *st,
 {
    struct ureg_program *ureg;
 
+   if (sttep->shader_program) {
+      nir_shader *nir = st_glsl_to_nir(st, &sttep->Base, sttep->shader_program,
+                                       MESA_SHADER_TESS_EVAL);
+
+      sttep->tgsi.type = PIPE_SHADER_IR_NIR;
+      sttep->tgsi.ir.nir = nir;
+
+      return true;
+   }
+
    ureg = ureg_create_with_screen(PIPE_SHADER_TESS_EVAL, st->pipe->screen);
    if (ureg == NULL)
       return false;
index 27cc9b6e92f6d2e2d54c9a44f0f4a88798007036..6049fba517b4824f9460dfda6fa5d945d745518b 100644 (file)
@@ -260,6 +260,9 @@ struct st_common_program
    struct glsl_to_tgsi_visitor* glsl_to_tgsi;
    uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
 
+  /* used when bypassing glsl_to_tgsi: */
+   struct gl_shader_program *shader_program;
+
    struct st_basic_variant *variants;
 
    /** SHA1 hash of linked tgsi shader program, used for on-disk cache */