[Mesa-dev] [PATCH] st/mesa: accelerate glCopyPixels(STENCIL)

Marek Olšák maraeo at gmail.com
Tue Jun 25 00:12:28 UTC 2019


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

---
 src/mesa/state_tracker/st_cb_drawpixels.c | 58 +++++++++++++++--------
 1 file changed, 38 insertions(+), 20 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 59868d3ff1d..26d3cc33e5c 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1508,35 +1508,35 @@ static GLboolean
 blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                  GLsizei width, GLsizei height,
                  GLint dstx, GLint dsty, GLenum type)
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct gl_pixelstore_attrib pack, unpack;
    GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH;
 
-   if (type == GL_COLOR &&
-       ctx->Pixel.ZoomX == 1.0 &&
+   if (ctx->Pixel.ZoomX == 1.0 &&
        ctx->Pixel.ZoomY == 1.0 &&
-       ctx->_ImageTransferState == 0x0 &&
-       !ctx->Color.BlendEnabled &&
-       !ctx->Color.AlphaEnabled &&
-       (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
-       !ctx->Depth.Test &&
-       !ctx->Fog.Enabled &&
-       !ctx->Stencil.Enabled &&
-       !ctx->FragmentProgram.Enabled &&
-       !ctx->VertexProgram.Enabled &&
-       !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
-       !_mesa_ati_fragment_shader_enabled(ctx) &&
-       ctx->DrawBuffer->_NumColorDrawBuffers == 1 &&
+       (type != GL_COLOR ||
+        (ctx->_ImageTransferState == 0x0 &&
+         !ctx->Color.BlendEnabled &&
+         !ctx->Color.AlphaEnabled &&
+         (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
+         !ctx->Depth.Test &&
+         !ctx->Fog.Enabled &&
+         !ctx->Stencil.Enabled &&
+         !ctx->FragmentProgram.Enabled &&
+         !ctx->VertexProgram.Enabled &&
+         !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
+         !_mesa_ati_fragment_shader_enabled(ctx) &&
+         ctx->DrawBuffer->_NumColorDrawBuffers == 1)) &&
        !ctx->Query.CondRenderQuery &&
        !ctx->Query.CurrentOcclusionObject) {
       struct st_renderbuffer *rbRead, *rbDraw;
 
       /*
        * Clip the read region against the src buffer bounds.
        * We'll still allocate a temporary buffer/texture for the original
        * src region size but we'll only read the region which is on-screen.
        * This may mean that we draw garbage pixels into the dest region, but
        * that's expected.
@@ -1555,22 +1555,32 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       unpack = pack;
       if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack))
          return GL_TRUE; /* all done */
 
       readX = readX - pack.SkipPixels + unpack.SkipPixels;
       readY = readY - pack.SkipRows + unpack.SkipRows;
 
       drawW = readW;
       drawH = readH;
 
-      rbRead = st_get_color_read_renderbuffer(ctx);
-      rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+      if (type == GL_COLOR) {
+         rbRead = st_get_color_read_renderbuffer(ctx);
+         rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+      } else if (type == GL_DEPTH || type == GL_DEPTH_STENCIL) {
+         rbRead = st_renderbuffer(ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer);
+         rbDraw = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer);
+      } else if (type == GL_STENCIL) {
+         rbRead = st_renderbuffer(ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
+         rbDraw = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
+      } else {
+         return false;
+      }
 
       /* Flip src/dst position depending on the orientation of buffers. */
       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
          readY = rbRead->Base.Height - readY;
          readH = -readH;
       }
 
       if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
          /* We can't flip the destination for pipe->blit, so we only adjust
           * its position and flip the source.
@@ -1597,23 +1607,31 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
          blit.src.box.depth = 1;
          blit.dst.resource = rbDraw->texture;
          blit.dst.level = rbDraw->surface->u.tex.level;
          blit.dst.format = rbDraw->texture->format;
          blit.dst.box.x = drawX;
          blit.dst.box.y = drawY;
          blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
          blit.dst.box.width = drawW;
          blit.dst.box.height = drawH;
          blit.dst.box.depth = 1;
-         blit.mask = PIPE_MASK_RGBA;
          blit.filter = PIPE_TEX_FILTER_NEAREST;
 
+         if (type == GL_COLOR)
+            blit.mask |= PIPE_MASK_RGBA;
+         if (type == GL_DEPTH)
+            blit.mask |= PIPE_MASK_Z;
+         if (type == GL_STENCIL)
+            blit.mask |= PIPE_MASK_S;
+         if (type == GL_DEPTH_STENCIL)
+            blit.mask |= PIPE_MASK_ZS;
+
          if (ctx->DrawBuffer != ctx->WinSysDrawBuffer)
             st_window_rectangles_to_blit(ctx, &blit);
 
          if (screen->is_format_supported(screen, blit.src.format,
                                          blit.src.resource->target,
                                          blit.src.resource->nr_samples,
                                          blit.src.resource->nr_storage_samples,
                                          PIPE_BIND_SAMPLER_VIEW) &&
              screen->is_format_supported(screen, blit.dst.format,
                                          blit.dst.resource->target,
@@ -1650,36 +1668,36 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    GLint readX, readY, readW, readH;
    struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
 
    _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
 
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    st_validate_state(st, ST_PIPELINE_META);
 
+   if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
+      return;
+
    if (type == GL_DEPTH_STENCIL) {
       /* XXX make this more efficient */
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
       return;
    }
 
    if (type == GL_STENCIL) {
       /* can't use texturing to do stencil */
       copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
       return;
    }
 
-   if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
-      return;
-
    /*
     * The subsequent code implements glCopyPixels by copying the source
     * pixels into a temporary texture that's then applied to a textured quad.
     * When we draw the textured quad, all the usual per-fragment operations
     * are handled.
     */
 
    st_make_passthrough_vertex_shader(st);
 
    /*
-- 
2.17.1



More information about the mesa-dev mailing list