st/mesa: optimize DEPTH_STENCIL copies using fragment shader
authorIndrajit Kumar Das <indrajit-kumar.das@amd.com>
Mon, 27 Jul 2020 13:51:42 +0000 (19:21 +0530)
committerMarge Bot <eric+marge@anholt.net>
Wed, 5 Aug 2020 19:25:14 +0000 (19:25 +0000)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6088>

src/mesa/state_tracker/st_cb_drawpixels.c

index 366c324800f32608ce0d40a0596adc52e9eda587..2a1ac8f4f0269df4ab47c4e94d5720eaacb32c14 100644 (file)
@@ -1717,8 +1717,9 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
       return;
 
    if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
       return;
 
-   if (type == GL_DEPTH_STENCIL) {
-      /* XXX make this more efficient */
+   /* fallback if the driver can't do stencil exports */
+   if (type == GL_DEPTH_STENCIL &&
+      !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
       return;
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
       return;
@@ -1764,13 +1765,18 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       rbRead = st_renderbuffer(ctx->ReadBuffer->
                                Attachment[BUFFER_DEPTH].Renderbuffer);
       driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
       rbRead = st_renderbuffer(ctx->ReadBuffer->
                                Attachment[BUFFER_DEPTH].Renderbuffer);
       driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
-   } else {
-      assert(type == GL_STENCIL);
+   } else if (type == GL_STENCIL) {
       rbRead = st_renderbuffer(ctx->ReadBuffer->
                                Attachment[BUFFER_STENCIL].Renderbuffer);
       driver_fp = get_drawpix_z_stencil_program(st, GL_FALSE, GL_TRUE);
       rbRead = st_renderbuffer(ctx->ReadBuffer->
                                Attachment[BUFFER_STENCIL].Renderbuffer);
       driver_fp = get_drawpix_z_stencil_program(st, GL_FALSE, GL_TRUE);
+   } else {
+      assert(type == GL_DEPTH_STENCIL);
+      rbRead = st_renderbuffer(ctx->ReadBuffer->
+                               Attachment[BUFFER_DEPTH].Renderbuffer);
+      driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_TRUE);
    }
 
    }
 
+
    /* Choose the format for the temporary texture. */
    srcFormat = rbRead->texture->format;
    srcBind = PIPE_BIND_SAMPLER_VIEW |
    /* Choose the format for the temporary texture. */
    srcFormat = rbRead->texture->format;
    srcBind = PIPE_BIND_SAMPLER_VIEW |
@@ -1865,8 +1871,10 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    }
 
    /* Create a second sampler view to read stencil */
    }
 
    /* Create a second sampler view to read stencil */
-   if (type == GL_STENCIL) {
+   if (type == GL_STENCIL || type == GL_DEPTH_STENCIL) {
       write_stencil = GL_TRUE;
       write_stencil = GL_TRUE;
+      if (type == GL_DEPTH_STENCIL)
+         write_depth = GL_TRUE;
       enum pipe_format stencil_format =
          util_format_stencil_only(pt->format);
       /* we should not be doing pixel map/transfer (see above) */
       enum pipe_format stencil_format =
          util_format_stencil_only(pt->format);
       /* we should not be doing pixel map/transfer (see above) */
@@ -1904,10 +1912,12 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       blit.dst.box.width = readW;
       blit.dst.box.height = readH;
       blit.dst.box.depth = 1;
       blit.dst.box.width = readW;
       blit.dst.box.height = readH;
       blit.dst.box.depth = 1;
-      if (type != GL_STENCIL)
-         blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
+      if (type == GL_DEPTH)
+          blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
+      else if (type == GL_STENCIL)
+          blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_Z;
       else
       else
-         blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_Z;
+         blit.mask = util_format_get_mask(pt->format);
       blit.filter = PIPE_TEX_FILTER_NEAREST;
 
       pipe->blit(pipe, &blit);
       blit.filter = PIPE_TEX_FILTER_NEAREST;
 
       pipe->blit(pipe, &blit);