summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-09-15 09:23:21 -0400
committerRob Clark <[email protected]>2015-09-15 17:29:01 -0400
commit9124a49d54af5d7bd8230af4ba3eebfb167a7655 (patch)
tree2459d22c222a38509fa4c2ba126b5c0f0296f9bb /src/gallium/drivers/freedreno
parent76977222af3dcf6c0915830c7b7af06505f8cd9a (diff)
freedreno: helper for a3xx/a4xx border-colors
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_context.h16
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c53
-rw-r--r--src/gallium/drivers/freedreno/freedreno_texture.c66
-rw-r--r--src/gallium/drivers/freedreno/freedreno_texture.h31
4 files changed, 99 insertions, 67 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
index 250bcf89596..b4c2ebe570c 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
@@ -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;
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 6f514ed05df..b81bc5a90a4 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/freedreno_texture.c b/src/gallium/drivers/freedreno/freedreno_texture.c
index eaa6629f2b8..04e4643b4c9 100644
--- a/src/gallium/drivers/freedreno/freedreno_texture.c
+++ b/src/gallium/drivers/freedreno/freedreno_texture.c
@@ -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]);
+ }
+ }
+ }
+}
diff --git a/src/gallium/drivers/freedreno/freedreno_texture.h b/src/gallium/drivers/freedreno/freedreno_texture.h
index 43571a9fa61..fa27d1c32af 100644
--- a/src/gallium/drivers/freedreno/freedreno_texture.h
+++ b/src/gallium/drivers/freedreno/freedreno_texture.h
@@ -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_ */