freedreno: helper for a3xx/a4xx border-colors
authorRob Clark <robclark@freedesktop.org>
Tue, 15 Sep 2015 13:23:21 +0000 (09:23 -0400)
committerRob Clark <robclark@freedesktop.org>
Tue, 15 Sep 2015 21:29:01 +0000 (17:29 -0400)
Both use the same layout for the buffer containing border-color values,
so rather than duplicating the logic in a4xx, split it out into a
helper.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_context.h
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/freedreno_texture.c
src/gallium/drivers/freedreno/freedreno_texture.h

index 250bcf895962aa8906eec86a5783ac8fab341ea8..b4c2ebe570c20cae5fdd454266ab34e3003dd718 100644 (file)
@@ -73,22 +73,6 @@ struct fd3_context {
         */
        struct fd_vertex_state blit_vbuf_state;
 
-
-       /*
-        * Border color layout *appears* to be as arrays of 0x40 byte
-        * elements, with frag shader elements starting at (16 x 0x40).
-        * But at some point I should probably experiment more with
-        * samplers in vertex shaders to be sure.  Unclear about why
-        * there is this offset when there are separate VS and FS base
-        * addr regs.
-        *
-        * The first 8 bytes of each entry are the requested border
-        * color in fp16.  Unclear about the rest.. could be used for
-        * other formats, or could simply be for aligning the pitch
-        * to 32 pixels.
-        */
-#define BORDERCOLOR_SIZE 0x40
-
        struct u_upload_mgr *border_color_uploader;
        struct pipe_resource *border_color_buf;
 
index 6f514ed05df1de00cfea7d7489b2f11097e1bd8f..b81bc5a90a49cd5556dcbc699636a86f255d01fe 100644 (file)
@@ -149,6 +149,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        &fd3_ctx->border_color_buf,
                        &ptr);
 
+       fd_setup_border_colors(tex, ptr, tex_off[sb]);
+
        if (tex->num_samplers > 0) {
                /* output sampler state: */
                OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
@@ -163,57 +165,6 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
                                        fd3_sampler_stateobj(tex->samplers[i]) :
                                        &dummy_sampler;
-                       uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
-                                       (BORDERCOLOR_SIZE * tex_off[sb]) +
-                                       (BORDERCOLOR_SIZE * i));
-                       uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
-
-                       /*
-                        * XXX HACK ALERT XXX
-                        *
-                        * The border colors need to be swizzled in a particular
-                        * format-dependent order. Even though samplers don't know about
-                        * formats, we can assume that with a GL state tracker, there's a
-                        * 1:1 correspondence between sampler and texture. Take advantage
-                        * of that knowledge.
-                        */
-                       if (i < tex->num_textures && tex->textures[i]) {
-                               const struct util_format_description *desc =
-                                       util_format_description(tex->textures[i]->format);
-                               for (j = 0; j < 4; j++) {
-                                       if (desc->swizzle[j] >= 4)
-                                               continue;
-
-                                       const struct util_format_channel_description *chan =
-                                               &desc->channel[desc->swizzle[j]];
-                                       int size = chan->size;
-
-                                       /* The Z16 texture format we use seems to look in the
-                                        * 32-bit border color slots
-                                        */
-                                       if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
-                                               size = 32;
-
-                                       /* Formats like R11G11B10 or RGB9_E5 don't specify
-                                        * per-channel sizes properly.
-                                        */
-                                       if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
-                                               size = 16;
-
-                                       if (chan->pure_integer && size > 16)
-                                               bcolor32[desc->swizzle[j] + 4] =
-                                                       sampler->base.border_color.i[j];
-                                       else if (size > 16)
-                                               bcolor32[desc->swizzle[j]] =
-                                                       fui(sampler->base.border_color.f[j]);
-                                       else if (chan->pure_integer)
-                                               bcolor[desc->swizzle[j] + 8] =
-                                                       sampler->base.border_color.i[j];
-                                       else
-                                               bcolor[desc->swizzle[j]] =
-                                                       util_float_to_half(sampler->base.border_color.f[j]);
-                               }
-                       }
 
                        OUT_RING(ring, sampler->texsamp0);
                        OUT_RING(ring, sampler->texsamp1);
index eaa6629f2b80c50e45760db0d5bd30adc6ec4639..04e4643b4c99e5c8372615d7d8125f139d4f9130 100644 (file)
@@ -162,3 +162,69 @@ fd_texture_init(struct pipe_context *pctx)
 
        pctx->sampler_view_destroy = fd_sampler_view_destroy;
 }
+
+/* helper for setting up border-color buffer for a3xx/a4xx: */
+void
+fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
+               unsigned offset)
+{
+       unsigned i, j;
+
+       for (i = 0; i < tex->num_samplers; i++) {
+               struct pipe_sampler_state *sampler = tex->samplers[i];
+               uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
+                               (BORDERCOLOR_SIZE * offset) +
+                               (BORDERCOLOR_SIZE * i));
+               uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
+
+               if (!sampler)
+                       continue;
+
+               /*
+                * XXX HACK ALERT XXX
+                *
+                * The border colors need to be swizzled in a particular
+                * format-dependent order. Even though samplers don't know about
+                * formats, we can assume that with a GL state tracker, there's a
+                * 1:1 correspondence between sampler and texture. Take advantage
+                * of that knowledge.
+                */
+               if (i < tex->num_textures && tex->textures[i]) {
+                       const struct util_format_description *desc =
+                                       util_format_description(tex->textures[i]->format);
+                       for (j = 0; j < 4; j++) {
+                               if (desc->swizzle[j] >= 4)
+                                       continue;
+
+                               const struct util_format_channel_description *chan =
+                                               &desc->channel[desc->swizzle[j]];
+                               int size = chan->size;
+
+                               /* The Z16 texture format we use seems to look in the
+                                * 32-bit border color slots
+                                */
+                               if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
+                                       size = 32;
+
+                               /* Formats like R11G11B10 or RGB9_E5 don't specify
+                                * per-channel sizes properly.
+                                */
+                               if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
+                                       size = 16;
+
+                               if (chan->pure_integer && size > 16)
+                                       bcolor32[desc->swizzle[j] + 4] =
+                                                       sampler->border_color.i[j];
+                               else if (size > 16)
+                                       bcolor32[desc->swizzle[j]] =
+                                                       fui(sampler->border_color.f[j]);
+                               else if (chan->pure_integer)
+                                       bcolor[desc->swizzle[j] + 8] =
+                                                       sampler->border_color.i[j];
+                               else
+                                       bcolor[desc->swizzle[j]] =
+                                                       util_float_to_half(sampler->border_color.f[j]);
+                       }
+               }
+       }
+}
index 43571a9fa61270579d891fd4db805ce3083b129e..fa27d1c32afb9fcc542a313e05a47243437f87fb 100644 (file)
@@ -41,4 +41,35 @@ void fd_set_sampler_views(struct pipe_context *pctx, unsigned shader,
 
 void fd_texture_init(struct pipe_context *pctx);
 
+struct fd_texture_stateobj;
+
+/* Both a3xx/a4xx share the same layout for the border-color buffer,
+ * which contains the pre-swizzled (based on texture format) border
+ * color value, with the following layout (per sampler):
+ *
+ *  offset | description
+ *  -------+-------------
+ *  0x00:  | fp16[0]   \
+ *         | fp16[1]   |___ swizzled fp16 channel values for "small float"
+ *         | fp16[2]   |    formats (<= 16 bits per component, !integer)
+ *         | fp16[3]   /
+ *  0x08:  | padding
+ *  0x10:  | int16[0]  \
+ *         | int16[1]  |___ swizzled int16 channels for for "small integer"
+ *         | int16[2]  |    formats (<= 16 bits per component, integer)
+ *         | int16[3]  /
+ *  0x18:  | padding
+ *  0x20:  | fp32[0]   \
+ *         | fp32[1]   |___ swizzled fp32 channel values for "large float"
+ *         | fp32[2]   |    formats (> 16 bits per component, !integer)
+ *         | fp32[3]   /
+ *  0x30:  | int32[0]  \
+ *         | int32[1]  |___ swizzled int32 channel values for "large int"
+ *         | int32[2]  |    formats (> 16 bits per component, integer)
+ *         | int32[3]  /
+ */
+#define BORDERCOLOR_SIZE 0x40
+void fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
+               unsigned offset);
+
 #endif /* FREEDRENO_TEXTURE_H_ */