[Mesa-dev] [PATCH 10/18] gallium/u_blitter: use draw_rectangle for all blits except cubemaps

Marek Olšák maraeo at gmail.com
Thu Aug 17 18:31:31 UTC 2017


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

Add ZW coordinates to the draw_rectangle callback and use it.
---
 src/gallium/auxiliary/util/u_blitter.c        | 181 ++++++++++++++------------
 src/gallium/auxiliary/util/u_blitter.h        |   5 +-
 src/gallium/drivers/r300/r300_render.c        |   7 +-
 src/gallium/drivers/radeon/r600_pipe_common.c |   6 +-
 4 files changed, 107 insertions(+), 92 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index de2a27a..d71a238 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -740,124 +740,94 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
       for (i = 0; i < 4; i++)
          memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
    } else {
       for (i = 0; i < 4; i++)
          memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
    }
 }
 
 static void get_texcoords(struct pipe_sampler_view *src,
                           unsigned src_width0, unsigned src_height0,
-                          int x1, int y1, int x2, int y2, bool uses_txf,
-                          union blitter_attrib *out)
+                          int x1, int y1, int x2, int y2,
+                          float layer, unsigned sample,
+                          bool uses_txf, union blitter_attrib *out)
 {
    unsigned level = src->u.tex.first_level;
    boolean normalized = !uses_txf &&
                         src->target != PIPE_TEXTURE_RECT &&
                         src->texture->nr_samples <= 1;
 
    if (normalized) {
       out->texcoord.x1 = x1 / (float)u_minify(src_width0,  level);
       out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
       out->texcoord.x2 = x2 / (float)u_minify(src_width0,  level);
       out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
    } else {
       out->texcoord.x1 = x1;
       out->texcoord.y1 = y1;
       out->texcoord.x2 = x2;
       out->texcoord.y2 = y2;
    }
-}
 
-static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
-                                      float *out, unsigned stride)
-{
-   out[0] = attrib->texcoord.x1;
-   out[1] = attrib->texcoord.y1;
-   out += stride;
-   out[0] = attrib->texcoord.x2;
-   out[1] = attrib->texcoord.y1;
-   out += stride;
-   out[0] = attrib->texcoord.x2;
-   out[1] = attrib->texcoord.y2;
-   out += stride;
-   out[0] = attrib->texcoord.x1;
-   out[1] = attrib->texcoord.y2;
-}
-
-static void blitter_set_texcoords(struct blitter_context_priv *ctx,
-                                  struct pipe_sampler_view *src,
-                                  unsigned src_width0, unsigned src_height0,
-                                  float layer, unsigned sample,
-                                  int x1, int y1, int x2, int y2,
-                                  bool uses_txf)
-{
-   unsigned i;
-   union blitter_attrib coord;
-   float face_coord[4][2];
-
-   get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, uses_txf,
-                 &coord);
-
-   if (src->target == PIPE_TEXTURE_CUBE ||
-       src->target == PIPE_TEXTURE_CUBE_ARRAY) {
-      set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
-      util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
-                                        /* pointer, stride in floats */
-                                        &face_coord[0][0], 2,
-                                        &ctx->vertices[0][1][0], 8,
-                                        FALSE);
-   } else {
-      set_texcoords_in_vertices(&coord, &ctx->vertices[0][1][0], 8);
-   }
+   out->texcoord.z = 0;
+   out->texcoord.w = 0;
 
    /* Set the layer. */
    switch (src->target) {
    case PIPE_TEXTURE_3D:
       {
          float r = layer;
 
          if (!uses_txf)
             r /= u_minify(src->texture->depth0, src->u.tex.first_level);
 
-         for (i = 0; i < 4; i++)
-            ctx->vertices[i][1][2] = r; /*r*/
+         out->texcoord.z = r;
       }
       break;
 
    case PIPE_TEXTURE_1D_ARRAY:
-      for (i = 0; i < 4; i++)
-         ctx->vertices[i][1][1] = (float) layer; /*t*/
+      out->texcoord.y1 = out->texcoord.y2 = layer;
       break;
 
    case PIPE_TEXTURE_2D_ARRAY:
-      for (i = 0; i < 4; i++) {
-         ctx->vertices[i][1][2] = (float) layer;  /*r*/
-         ctx->vertices[i][1][3] = (float) sample; /*q*/
-      }
+      out->texcoord.z = layer;
+      out->texcoord.w = sample;
       break;
 
    case PIPE_TEXTURE_CUBE_ARRAY:
-      for (i = 0; i < 4; i++)
-         ctx->vertices[i][1][3] = (float) ((unsigned)layer / 6); /*w*/
+      out->texcoord.w = (unsigned)layer / 6;
       break;
 
    case PIPE_TEXTURE_2D:
-      for (i = 0; i < 4; i++) {
-         ctx->vertices[i][1][3] = (float) sample; /*r*/
-      }
+      out->texcoord.w = sample;
       break;
 
    default:;
    }
 }
 
+static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
+                                      float *out, unsigned stride)
+{
+   out[0] = attrib->texcoord.x1;
+   out[1] = attrib->texcoord.y1;
+   out += stride;
+   out[0] = attrib->texcoord.x2;
+   out[1] = attrib->texcoord.y1;
+   out += stride;
+   out[0] = attrib->texcoord.x2;
+   out[1] = attrib->texcoord.y2;
+   out += stride;
+   out[0] = attrib->texcoord.x1;
+   out[1] = attrib->texcoord.y2;
+}
+
 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
                                          enum pipe_format src_format,
                                          enum pipe_format dst_format,
                                          enum pipe_texture_target target,
                                          unsigned src_nr_samples,
                                          unsigned dst_nr_samples,
                                          unsigned filter,
                                          bool use_txf)
 {
    struct pipe_context *pipe = ctx->base.pipe;
@@ -1252,27 +1222,34 @@ static void blitter_draw(struct blitter_context_priv *ctx,
    pipe_resource_reference(&vb.buffer.resource, NULL);
 }
 
 void util_blitter_draw_rectangle(struct blitter_context *blitter,
                                  int x1, int y1, int x2, int y2,
                                  float depth, unsigned num_instances,
                                  enum blitter_attrib_type type,
                                  const union blitter_attrib *attrib)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   unsigned i;
 
    switch (type) {
       case UTIL_BLITTER_ATTRIB_COLOR:
          blitter_set_clear_color(ctx, (uint32_t*)attrib->color);
          break;
 
-      case UTIL_BLITTER_ATTRIB_TEXCOORD:
+      case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
+         for (i = 0; i < 4; i++) {
+            ctx->vertices[i][1][2] = attrib->texcoord.z;
+            ctx->vertices[i][1][3] = attrib->texcoord.w;
+         }
+         /* fall through */
+      case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
          set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
          break;
 
       default:;
    }
 
    blitter_draw(ctx, x1, y1, x2, y2, depth, num_instances);
 }
 
 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
@@ -1573,20 +1550,56 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
    /* Copy. */
    util_blitter_blit_generic(blitter, dst_view, &dstbox,
                              src_view, srcbox, src->width0, src->height0,
                              PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
                              FALSE);
 
    pipe_surface_reference(&dst_view, NULL);
    pipe_sampler_view_reference(&src_view, NULL);
 }
 
+static void
+blitter_draw_tex(struct blitter_context_priv *ctx,
+                 int dst_x1, int dst_y1, int dst_x2, int dst_y2,
+                 struct pipe_sampler_view *src,
+                 unsigned src_width0, unsigned src_height0,
+                 int src_x1, int src_y1, int src_x2, int src_y2,
+                 float layer, unsigned sample,
+                 bool uses_txf, enum blitter_attrib_type type)
+{
+   union blitter_attrib coord;
+
+   get_texcoords(src, src_width0, src_height0,
+                 src_x1, src_y1, src_x2, src_y2, layer, sample,
+                 uses_txf, &coord);
+
+   if (src->target == PIPE_TEXTURE_CUBE ||
+       src->target == PIPE_TEXTURE_CUBE_ARRAY) {
+      float face_coord[4][2];
+
+      set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
+      util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
+                                        /* pointer, stride in floats */
+                                        &face_coord[0][0], 2,
+                                        &ctx->vertices[0][1][0], 8,
+                                        FALSE);
+      for (unsigned i = 0; i < 4; i++)
+         ctx->vertices[i][1][3] = coord.texcoord.w;
+
+      /* Cubemaps don't use draw_rectangle. */
+      blitter_draw(ctx, dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
+   } else {
+      ctx->base.draw_rectangle(&ctx->base, dst_x1, dst_y1, dst_x2, dst_y2, 0,
+                               1, type, &coord);
+   }
+}
+
 static void do_blits(struct blitter_context_priv *ctx,
                      struct pipe_surface *dst,
                      const struct pipe_box *dstbox,
                      struct pipe_sampler_view *src,
                      unsigned src_width0,
                      unsigned src_height0,
                      const struct pipe_box *srcbox,
                      bool is_zsbuf,
                      bool uses_txf)
 {
@@ -1598,42 +1611,36 @@ static void do_blits(struct blitter_context_priv *ctx,
 
    /* Initialize framebuffer state. */
    fb_state.width = dst->width;
    fb_state.height = dst->height;
    fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
 
    if ((src_target == PIPE_TEXTURE_1D ||
         src_target == PIPE_TEXTURE_2D ||
         src_target == PIPE_TEXTURE_RECT) &&
        src_samples <= 1) {
-      /* Draw the quad with the draw_rectangle callback. */
-
-      /* Set texture coordinates. */
-      union blitter_attrib coord;
-      get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
-                    srcbox->x+srcbox->width, srcbox->y+srcbox->height,
-                    uses_txf, &coord);
-
       /* Set framebuffer state. */
       if (is_zsbuf) {
          fb_state.zsbuf = dst;
       } else {
          fb_state.cbufs[0] = dst;
       }
       pipe->set_framebuffer_state(pipe, &fb_state);
 
       /* Draw. */
       pipe->set_sample_mask(pipe, ~0);
-      ctx->base.draw_rectangle(&ctx->base, dstbox->x, dstbox->y,
-                               dstbox->x + dstbox->width,
-                               dstbox->y + dstbox->height, 0, 1,
-                               UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
+      blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+                       dstbox->x + dstbox->width,
+                       dstbox->y + dstbox->height,
+                       src, src_width0, src_height0, srcbox->x, srcbox->y,
+                       srcbox->x + srcbox->width, srcbox->y + srcbox->height,
+                       0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
    } else {
       /* Draw the quad with the generic codepath. */
       int dst_z;
       for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
          struct pipe_surface *old;
          float dst2src_scale = srcbox->depth / (float)dstbox->depth;
 
          /* Scale Z properly if the blit is scaled.
           *
           * When downscaling, we want the coordinates centered, so that
@@ -1663,40 +1670,42 @@ static void do_blits(struct blitter_context_priv *ctx,
          }
          pipe->set_framebuffer_state(pipe, &fb_state);
 
          /* See if we need to blit a multisample or singlesample buffer. */
          if (src_samples == dst_samples && dst_samples > 1) {
             /* MSAA copy. */
             unsigned i, max_sample = dst_samples - 1;
 
             for (i = 0; i <= max_sample; i++) {
                pipe->set_sample_mask(pipe, 1 << i);
-               blitter_set_texcoords(ctx, src, src_width0, src_height0,
-                                     srcbox->z + src_z,
-                                     i, srcbox->x, srcbox->y,
-                                     srcbox->x + srcbox->width,
-                                     srcbox->y + srcbox->height, uses_txf);
-               blitter_draw(ctx, dstbox->x, dstbox->y,
-                            dstbox->x + dstbox->width,
-                            dstbox->y + dstbox->height, 0, 1);
+               blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+                                dstbox->x + dstbox->width,
+                                dstbox->y + dstbox->height,
+                                src, src_width0, src_height0,
+                                srcbox->x, srcbox->y,
+                                srcbox->x + srcbox->width,
+                                srcbox->y + srcbox->height,
+                                srcbox->z + src_z, i, uses_txf,
+                                UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
             }
          } else {
             /* Normal copy, MSAA upsampling, or MSAA resolve. */
             pipe->set_sample_mask(pipe, ~0);
-            blitter_set_texcoords(ctx, src, src_width0, src_height0,
-                                  srcbox->z + src_z, 0,
-                                  srcbox->x, srcbox->y,
-                                  srcbox->x + srcbox->width,
-                                  srcbox->y + srcbox->height, uses_txf);
-            blitter_draw(ctx, dstbox->x, dstbox->y,
-                         dstbox->x + dstbox->width,
-                         dstbox->y + dstbox->height, 0, 1);
+            blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+                             dstbox->x + dstbox->width,
+                             dstbox->y + dstbox->height,
+                             src, src_width0, src_height0,
+                             srcbox->x, srcbox->y,
+                             srcbox->x + srcbox->width,
+                             srcbox->y + srcbox->height,
+                             srcbox->z + src_z, 0, uses_txf,
+                             UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
          }
 
          /* Get the next surface or (if this is the last iteration)
           * just unreference the last one. */
          old = dst;
          if (dst_z < dstbox->depth-1) {
             dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
          }
          if (dst_z) {
             pipe_surface_reference(&old, NULL);
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 304d27e..3d1f285 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -34,28 +34,29 @@
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct pipe_context;
 
 enum blitter_attrib_type {
    UTIL_BLITTER_ATTRIB_NONE,
    UTIL_BLITTER_ATTRIB_COLOR,
-   UTIL_BLITTER_ATTRIB_TEXCOORD
+   UTIL_BLITTER_ATTRIB_TEXCOORD_XY,
+   UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
 };
 
 union blitter_attrib {
    float color[4];
 
    struct {
-      float x1, y1, x2, y2;
+      float x1, y1, x2, y2, z, w;
    } texcoord;
 };
 
 struct blitter_context
 {
    /**
     * Draw a rectangle.
     *
     * \param x1      An X coordinate of the top-left corner.
     * \param y1      A Y coordinate of the top-left corner.
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 1f896da..ddd2452 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -1118,54 +1118,55 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
                                  enum blitter_attrib_type type,
                                  const union blitter_attrib *attrib)
 {
     struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
     unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
     unsigned width = x2 - x1;
     unsigned height = y2 - y1;
     unsigned vertex_size =
             type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
     unsigned dwords = 13 + vertex_size +
-                      (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
+                      (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY ? 7 : 0);
     static const union blitter_attrib zeros;
     CS_LOCALS(r300);
 
     /* XXX workaround for a lockup in MSAA resolve on SWTCL chipsets, this
      * function most probably doesn't handle type=NONE correctly */
     if ((!r300->screen->caps.has_tcl && type == UTIL_BLITTER_ATTRIB_NONE) ||
+        type == UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW ||
         num_instances > 1) {
         util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth,
                                     num_instances, type, attrib);
         return;
     }
 
     if (r300->skip_rendering)
         return;
 
-    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
+    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY)
         r300->sprite_coord_enable = 1;
 
     r300_update_derived_state(r300);
 
     /* Mark some states we don't care about as non-dirty. */
     r300->viewport_state.dirty = FALSE;
 
     if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
         goto done;
 
     DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
 
     BEGIN_CS(dwords);
     /* Set up GA. */
     OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
 
-    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
+    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY) {
         /* Set up the GA to generate texcoords. */
         OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
                    (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
         OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
         OUT_CS_32F(attrib->texcoord.x1);
         OUT_CS_32F(attrib->texcoord.y2);
         OUT_CS_32F(attrib->texcoord.x2);
         OUT_CS_32F(attrib->texcoord.y1);
     }
 
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 90127dc..af4b4e8 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -256,21 +256,25 @@ void r600_draw_rectangle(struct blitter_context *blitter,
 	vb[17] = -1;
 	vb[18] = 0;
 	vb[19] = 1;
 
 	switch (type) {
 	case UTIL_BLITTER_ATTRIB_COLOR:
 		memcpy(vb+4, attrib->color, sizeof(float)*4);
 		memcpy(vb+12, attrib->color, sizeof(float)*4);
 		memcpy(vb+20, attrib->color, sizeof(float)*4);
 		break;
-	case UTIL_BLITTER_ATTRIB_TEXCOORD:
+	case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
+		vb[6] = vb[14] = vb[22] = attrib->texcoord.z;
+		vb[7] = vb[15] = vb[23] = attrib->texcoord.w;
+		/* fall through */
+	case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
 		vb[4] = attrib->texcoord.x1;
 		vb[5] = attrib->texcoord.y1;
 		vb[12] = attrib->texcoord.x1;
 		vb[13] = attrib->texcoord.y2;
 		vb[20] = attrib->texcoord.x2;
 		vb[21] = attrib->texcoord.y1;
 		break;
 	default:; /* Nothing to do. */
 	}
 
-- 
2.7.4



More information about the mesa-dev mailing list