[Mesa-dev] [PATCH 10/17] st/mesa: make Z/S drawpix shaders independent of variants, don't use Mesa IR

Marek Olšák maraeo at gmail.com
Mon Oct 5 18:26:23 PDT 2015


From: Marek Olšák <marek.olsak at amd.com>

- there is no connection to user fragment shaders, so having these as
  shader variants makes no sense
- don't use Mesa IR, use TGSI
- don't create gl_fragment_program, just create the shader CSO
---
 src/mesa/state_tracker/st_cb_drawpixels.c | 185 +++++++++++-------------------
 src/mesa/state_tracker/st_cb_drawpixels.h |   6 -
 src/mesa/state_tracker/st_context.h       |   2 +-
 src/mesa/state_tracker/st_program.c       |  15 +--
 src/mesa/state_tracker/st_program.h       |   2 -
 5 files changed, 72 insertions(+), 138 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 152160e..0ef0e69 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -189,100 +189,80 @@ st_make_drawpix_fragment_program(struct st_context *st,
  * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
  * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
  * Pass fragment color through as-is.
- * \return pointer to the gl_fragment program
+ *
+ * \return CSO of the fragment shader.
  */
-struct gl_fragment_program *
-st_make_drawpix_z_stencil_program(struct st_context *st,
-                                  GLboolean write_depth,
-                                  GLboolean write_stencil)
+static void *
+get_drawpix_z_stencil_program(struct st_context *st,
+                              GLboolean write_depth,
+                              GLboolean write_stencil)
 {
-   struct gl_context *ctx = st->ctx;
-   struct gl_program *p;
-   struct gl_fragment_program *fp;
-   GLuint ic = 0;
+   struct ureg_program *ureg;
+   struct ureg_src depth_sampler, stencil_sampler;
+   struct ureg_src texcoord, color;
+   struct ureg_dst out_color, out_depth, out_stencil;
    const GLuint shaderIndex = write_depth * 2 + write_stencil;
+   void *cso;
 
-   assert(shaderIndex < ARRAY_SIZE(st->drawpix.shaders));
+   assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
 
-   if (st->drawpix.shaders[shaderIndex]) {
+   if (st->drawpix.zs_shaders[shaderIndex]) {
       /* already have the proper shader */
-      return st->drawpix.shaders[shaderIndex];
+      return st->drawpix.zs_shaders[shaderIndex];
    }
 
-   /*
-    * Create shader now
-    */
-   p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-   if (!p)
-      return NULL;
-
-   p->NumInstructions = write_depth ? 3 : 1;
-   p->NumInstructions += write_stencil ? 1 : 0;
-
-   p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
-   if (!p->Instructions) {
-      ctx->Driver.DeleteProgram(ctx, p);
+   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   if (ureg == NULL)
       return NULL;
-   }
-   _mesa_init_instructions(p->Instructions, p->NumInstructions);
 
    if (write_depth) {
-      /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */
-      p->Instructions[ic].Opcode = OPCODE_TEX;
-      p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-      p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH;
-      p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z;
-      p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-      p->Instructions[ic].SrcReg[0].Index = VARYING_SLOT_TEX0;
-      p->Instructions[ic].TexSrcUnit = 0;
-      p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
-      ic++;
-      /* MOV result.color, fragment.color; */
-      p->Instructions[ic].Opcode = OPCODE_MOV;
-      p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-      p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR;
-      p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-      p->Instructions[ic].SrcReg[0].Index = VARYING_SLOT_COL0;
-      ic++;
+      depth_sampler = ureg_DECL_sampler(ureg, 0);
+      ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT,
+                             TGSI_RETURN_TYPE_FLOAT);
+      out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
    }
 
    if (write_stencil) {
-      /* TEX result.stencil, fragment.texcoord[0], texture[0], 2D; */
-      p->Instructions[ic].Opcode = OPCODE_TEX;
-      p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-      p->Instructions[ic].DstReg.Index = FRAG_RESULT_STENCIL;
-      p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Y;
-      p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-      p->Instructions[ic].SrcReg[0].Index = VARYING_SLOT_TEX0;
-      p->Instructions[ic].TexSrcUnit = 1;
-      p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
-      ic++;
+      stencil_sampler = ureg_DECL_sampler(ureg, 1);
+      ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT,
+                             TGSI_RETURN_TYPE_UINT);
+      out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
+   } else {
+      /* Non-stencil case. Writing stencil skips the fragment operations. */
+      color = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0,
+                                 TGSI_INTERPOLATE_LINEAR);
+      out_color = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
    }
 
-   /* END; */
-   p->Instructions[ic++].Opcode = OPCODE_END;
+   texcoord = ureg_DECL_fs_input(ureg,
+                                 st->needs_texcoord_semantic ?
+                                    TGSI_SEMANTIC_TEXCOORD :
+                                    TGSI_SEMANTIC_GENERIC,
+                                 0, TGSI_INTERPOLATE_LINEAR);
 
-   assert(ic == p->NumInstructions);
+   if (!write_stencil)
+      ureg_MOV(ureg, out_color, color); /* TODO: clamp_color? */
 
-   p->InputsRead = VARYING_BIT_TEX0 | VARYING_BIT_COL0;
-   p->OutputsWritten = 0;
-   if (write_depth) {
-      p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_DEPTH);
-      p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_COLOR);
-   }
-   if (write_stencil)
-      p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_STENCIL);
+   if (write_depth)
+      ureg_TEX(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z),
+               TGSI_TEXTURE_2D, texcoord, depth_sampler);
 
-   p->SamplersUsed =  0x1;  /* sampler 0 (bit 0) is used */
    if (write_stencil)
-      p->SamplersUsed |= 1 << 1;
+      ureg_TEX(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y),
+               TGSI_TEXTURE_2D, texcoord, stencil_sampler);
 
-   fp = (struct gl_fragment_program *) p;
+   ureg_END(ureg);
+   cso = ureg_create_shader_and_destroy(ureg, st->pipe);
 
    /* save the new shader */
-   st->drawpix.shaders[shaderIndex] = fp;
-
-   return fp;
+   st->drawpix.zs_shaders[shaderIndex] = cso;
+   return cso;
 }
 
 
@@ -1048,30 +1028,6 @@ get_color_fp_variant(struct st_context *st)
 
 
 /**
- * Get fragment program variant for a glDrawPixels or glCopyPixels
- * command for depth/stencil data.
- */
-static struct st_fp_variant *
-get_depth_stencil_fp_variant(struct st_context *st, GLboolean write_depth,
-                             GLboolean write_stencil)
-{
-   struct st_fp_variant_key key;
-   struct st_fp_variant *fpv;
-
-   memset(&key, 0, sizeof(key));
-
-   key.st = st;
-   key.drawpixels = 1;
-   key.drawpixels_z = write_depth;
-   key.drawpixels_stencil = write_stencil;
-
-   fpv = st_get_fp_variant(st, st->fp, &key);
-
-   return fpv;
-}
-
-
-/**
  * Clamp glDrawPixels width and height to the maximum texture size.
  */
 static void
@@ -1109,7 +1065,6 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
    GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
    struct pipe_sampler_view *sv[2] = { NULL };
    int num_sampler_view = 1;
-   struct st_fp_variant *fpv;
    struct gl_pixelstore_attrib clippedUnpack;
 
    /* Mesa state should be up to date by now */
@@ -1144,19 +1099,15 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
     * Get vertex/fragment shaders
     */
    if (write_depth || write_stencil) {
-      fpv = get_depth_stencil_fp_variant(st, write_depth, write_stencil);
-
-      driver_fp = fpv->driver_shader;
-
+      driver_fp = get_drawpix_z_stencil_program(st, write_depth,
+                                                write_stencil);
       driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
-
       color = ctx->Current.RasterColor;
    }
    else {
-      fpv = get_color_fp_variant(st);
+      struct st_fp_variant *fpv = get_color_fp_variant(st);
 
       driver_fp = fpv->driver_shader;
-
       driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
 
       color = NULL;
@@ -1165,10 +1116,10 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
                                      st->pixel_xfer.pixelmap_sampler_view);
          num_sampler_view++;
       }
-   }
 
-   /* update fragment program constants */
-   st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+      /* update fragment program constants */
+      st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+   }
 
    /* draw with textured quad */
    {
@@ -1459,7 +1410,6 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    GLboolean invertTex = GL_FALSE;
    GLint readX, readY, readW, readH;
    struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
-   struct st_fp_variant *fpv;
 
    st_validate_state(st);
 
@@ -1491,12 +1441,12 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
     * Get vertex/fragment shaders
     */
    if (type == GL_COLOR) {
+      struct st_fp_variant *fpv = get_color_fp_variant(st);
+
       rbRead = st_get_color_read_renderbuffer(ctx);
       color = NULL;
 
-      fpv = get_color_fp_variant(st);
       driver_fp = fpv->driver_shader;
-
       driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
 
       if (st->pixel_xfer.pixelmap_enabled) {
@@ -1504,6 +1454,9 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                                      st->pixel_xfer.pixelmap_sampler_view);
          num_sampler_view++;
       }
+
+      /* update fragment program constants */
+      st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
    }
    else {
       assert(type == GL_DEPTH);
@@ -1511,15 +1464,10 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                                Attachment[BUFFER_DEPTH].Renderbuffer);
       color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
 
-      fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE);
-      driver_fp = fpv->driver_shader;
-
+      driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
       driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
    }
 
-   /* update fragment program constants */
-   st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
-
    /* Choose the format for the temporary texture. */
    srcFormat = rbRead->texture->format;
    srcBind = PIPE_BIND_SAMPLER_VIEW |
@@ -1666,9 +1614,10 @@ st_destroy_drawpix(struct st_context *st)
 {
    GLuint i;
 
-   for (i = 0; i < ARRAY_SIZE(st->drawpix.shaders); i++) {
-      if (st->drawpix.shaders[i])
-         _mesa_reference_fragprog(st->ctx, &st->drawpix.shaders[i], NULL);
+   for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
+      if (st->drawpix.zs_shaders[i])
+         cso_delete_fragment_shader(st->cso_context,
+                                    st->drawpix.zs_shaders[i]);
    }
 
    st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h
index c707ace..c6649cb 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.h
+++ b/src/mesa/state_tracker/st_cb_drawpixels.h
@@ -45,10 +45,4 @@ st_make_drawpix_fragment_program(struct st_context *st,
                                  struct gl_fragment_program *fpIn,
                                  struct gl_fragment_program **fpOut);
 
-extern struct gl_fragment_program *
-st_make_drawpix_z_stencil_program(struct st_context *st,
-                                  GLboolean write_depth,
-                                  GLboolean write_stencil);
-
-
 #endif /* ST_CB_DRAWPIXELS_H */
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index a4cda29..262581e 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -184,7 +184,7 @@ struct st_context
 
    /** for glDraw/CopyPixels */
    struct {
-      struct gl_fragment_program *shaders[4];
+      void *zs_shaders[4];
       void *vert_shaders[2];   /**< ureg shaders */
    } drawpix;
 
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index fba661b..d900ede 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -568,19 +568,12 @@ st_translate_fragment_program(struct st_context *st,
    memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr));
 
    if (key->drawpixels) {
-      /* glDrawPixels drawing */
+      /* glDrawPixels color drawing */
       struct gl_fragment_program *fp; /* we free this temp program below */
 
-      if (key->drawpixels_z || key->drawpixels_stencil) {
-         fp = st_make_drawpix_z_stencil_program(st, key->drawpixels_z,
-                                                key->drawpixels_stencil);
-      }
-      else {
-         /* RGBA */
-         st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
-         variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
-         deleteFP = GL_TRUE;
-      }
+      st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
+      variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
+      deleteFP = GL_TRUE;
       stfp = st_fragment_program(fp);
    }
 
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index c60d2d5..2927d54 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -59,8 +59,6 @@ struct st_fp_variant_key
    GLuint drawpixels:1;           /**< glDrawPixels variant */
    GLuint scaleAndBias:1;         /**< glDrawPixels w/ scale and/or bias? */
    GLuint pixelMaps:1;            /**< glDrawPixels w/ pixel lookup map? */
-   GLuint drawpixels_z:1;         /**< glDrawPixels(GL_DEPTH) */
-   GLuint drawpixels_stencil:1;   /**< glDrawPixels(GL_STENCIL) */
 
    /** for ARB_color_buffer_float */
    GLuint clamp_color:1;
-- 
2.1.4



More information about the mesa-dev mailing list