summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/Makefile.sources1
-rw-r--r--src/gallium/drivers/vc4/vc4_context.c6
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h6
-rw-r--r--src/gallium/drivers/vc4/vc4_formats.c169
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c32
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c9
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c52
7 files changed, 203 insertions, 72 deletions
diff --git a/src/gallium/drivers/vc4/Makefile.sources b/src/gallium/drivers/vc4/Makefile.sources
index 68badc495b9..f8e04e40009 100644
--- a/src/gallium/drivers/vc4/Makefile.sources
+++ b/src/gallium/drivers/vc4/Makefile.sources
@@ -4,6 +4,7 @@ C_SOURCES := \
vc4_context.c \
vc4_draw.c \
vc4_emit.c \
+ vc4_formats.c \
vc4_opt_algebraic.c \
vc4_opt_copy_propagation.c \
vc4_opt_dead_code.c \
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index 0a09d399261..91ff7d784e9 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -66,7 +66,9 @@ vc4_setup_rcl(struct vc4_context *vc4)
cl_u16(&vc4->rcl, height);
cl_u16(&vc4->rcl, ((csurf->tiling <<
VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT) |
- VC4_RENDER_CONFIG_FORMAT_RGBA8888 |
+ (vc4_rt_format_is_565(csurf->base.format) ?
+ VC4_RENDER_CONFIG_FORMAT_BGR565 :
+ VC4_RENDER_CONFIG_FORMAT_RGBA8888) |
VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE));
/* The tile buffer normally gets cleared when the previous tile is
@@ -100,6 +102,8 @@ vc4_setup_rcl(struct vc4_context *vc4)
(csurf->tiling <<
VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT));
cl_u8(&vc4->rcl,
+ vc4_rt_format_is_565(csurf->base.format) ?
+ VC4_LOADSTORE_TILE_BUFFER_BGR565 :
VC4_LOADSTORE_TILE_BUFFER_RGBA8888);
cl_reloc(vc4, &vc4->rcl, ctex->bo,
csurf->offset);
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 258852e2743..caf0e5a5824 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -231,4 +231,10 @@ void vc4_emit_state(struct pipe_context *pctx);
void vc4_generate_code(struct qcompile *c);
void vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode);
+bool vc4_rt_format_supported(enum pipe_format f);
+bool vc4_rt_format_is_565(enum pipe_format f);
+bool vc4_tex_format_supported(enum pipe_format f);
+uint8_t vc4_get_tex_format(enum pipe_format f);
+const uint8_t *vc4_get_format_swizzle(enum pipe_format f);
+
#endif /* VC4_CONTEXT_H */
diff --git a/src/gallium/drivers/vc4/vc4_formats.c b/src/gallium/drivers/vc4/vc4_formats.c
new file mode 100644
index 00000000000..770f8fb3311
--- /dev/null
+++ b/src/gallium/drivers/vc4/vc4_formats.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * @file vc4_formats.c
+ *
+ * Contains the table and accessors for VC4 texture and render target format
+ * support.
+ *
+ * The hardware has limited support for texture formats, and extremely limited
+ * support for render target formats. As a result, we emulate other formats
+ * in our shader code, and this stores the table for doing so.
+ */
+
+#include "util/u_format.h"
+#include "util/macros.h"
+
+#include "vc4_context.h"
+
+#define RT_NO 0
+#define RT_RGBA8888 1
+#define RT_RGB565 2
+
+struct vc4_format {
+ /** Set if the pipe format is defined in the table. */
+ bool present;
+
+ /** Set to 0 if unsupported, 1 if RGBA8888, 2 if rgb565. */
+ uint8_t rt_type;
+
+ /** One of VC4_TEXTURE_TYPE_*. */
+ uint8_t tex_type;
+
+ /**
+ * Swizzle to apply to the RGBA shader output for storing to the tile
+ * buffer, to the RGBA tile buffer to produce shader input (for
+ * blending), and for turning the rgba8888 texture sampler return
+ * value into shader rgba values.
+ */
+ uint8_t swizzle[4];
+};
+
+#define SWIZ(x,y,z,w) { \
+ UTIL_FORMAT_SWIZZLE_##x, \
+ UTIL_FORMAT_SWIZZLE_##y, \
+ UTIL_FORMAT_SWIZZLE_##z, \
+ UTIL_FORMAT_SWIZZLE_##w \
+}
+
+#define FORMAT(pipe, rt, tex, swiz) \
+ [PIPE_FORMAT_##pipe] = { true, RT_##rt, VC4_TEXTURE_TYPE_##tex, swiz }
+
+static const struct vc4_format vc4_format_table[] = {
+ FORMAT(R8G8B8A8_UNORM, RGBA8888, RGBA8888, SWIZ(X, Y, Z, W)),
+ FORMAT(R8G8B8X8_UNORM, RGBA8888, RGBA8888, SWIZ(X, Y, Z, 1)),
+ FORMAT(R8G8B8A8_SRGB, RGBA8888, RGBA8888, SWIZ(X, Y, Z, W)),
+ FORMAT(R8G8B8X8_SRGB, RGBA8888, RGBA8888, SWIZ(X, Y, Z, 1)),
+
+ FORMAT(B8G8R8A8_UNORM, RGBA8888, RGBA8888, SWIZ(Z, Y, X, W)),
+ FORMAT(B8G8R8X8_UNORM, RGBA8888, RGBA8888, SWIZ(Z, Y, X, 1)),
+ FORMAT(B8G8R8A8_SRGB, RGBA8888, RGBA8888, SWIZ(Z, Y, X, W)),
+ FORMAT(B8G8R8X8_SRGB, RGBA8888, RGBA8888, SWIZ(Z, Y, X, 1)),
+
+ FORMAT(B5G6R5_UNORM, RGB565, RGB565, SWIZ(X, Y, Z, 1)),
+
+ /* Depth sampling will be handled by doing nearest filtering and not
+ * unpacking the RGBA value.
+ */
+ FORMAT(Z24_UNORM_S8_UINT, NO, RGBA8888, SWIZ(X, Y, Z, W)),
+ FORMAT(Z24X8_UNORM, NO, RGBA8888, SWIZ(X, Y, Z, W)),
+
+ FORMAT(B4G4R4A4_UNORM, NO, RGBA4444, SWIZ(Y, Z, W, X)),
+ FORMAT(B4G4R4X4_UNORM, NO, RGBA4444, SWIZ(Y, Z, W, 1)),
+
+ /* It looks like 5551 in the hardware is the other way around from
+ * gallium.
+ */
+
+ FORMAT(A8_UNORM, NO, ALPHA, SWIZ(0, 0, 0, W)),
+ FORMAT(L8_UNORM, NO, ALPHA, SWIZ(W, W, W, 1)),
+ FORMAT(I8_UNORM, NO, ALPHA, SWIZ(W, W, W, W)),
+ FORMAT(R8_UNORM, NO, ALPHA, SWIZ(W, 0, 0, 1)),
+
+ FORMAT(L8A8_UNORM, NO, LUMALPHA, SWIZ(X, X, X, W)),
+ FORMAT(R8G8_UNORM, NO, LUMALPHA, SWIZ(X, W, 0, 1)),
+};
+
+static const struct vc4_format *
+get_format(enum pipe_format f)
+{
+ if (f > ARRAY_SIZE(vc4_format_table) ||
+ !vc4_format_table[f].present)
+ return NULL;
+ else
+ return &vc4_format_table[f];
+}
+
+bool
+vc4_rt_format_supported(enum pipe_format f)
+{
+ const struct vc4_format *vf = get_format(f);
+
+ if (!vf)
+ return false;
+
+ return vf->rt_type != RT_NO;
+}
+
+bool
+vc4_rt_format_is_565(enum pipe_format f)
+{
+ const struct vc4_format *vf = get_format(f);
+
+ if (!vf)
+ return false;
+
+ return vf->rt_type == RT_RGB565;
+}
+
+bool
+vc4_tex_format_supported(enum pipe_format f)
+{
+ const struct vc4_format *vf = get_format(f);
+
+ return vf != NULL;
+}
+
+uint8_t
+vc4_get_tex_format(enum pipe_format f)
+{
+ const struct vc4_format *vf = get_format(f);
+
+ if (!vf)
+ return 0;
+
+ return vf->tex_type;
+}
+
+const uint8_t *
+vc4_get_format_swizzle(enum pipe_format f)
+{
+ const struct vc4_format *vf = get_format(f);
+ static const uint8_t fallback[] = {0, 1, 2, 3};
+
+ if (!vf)
+ return fallback;
+
+ return vf->swizzle;
+}
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index eed0ee1543b..c11ee5aa1b1 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -368,18 +368,14 @@ tgsi_to_qir_tex(struct tgsi_to_qir *trans,
for (int i = 0; i < 4; i++)
unpacked[i] = qir_R4_UNPACK(c, i);
+ enum pipe_format format = trans->key->tex_format[unit];
+ const uint8_t *swiz = vc4_get_format_swizzle(format);
for (int i = 0; i < 4; i++) {
if (!(tgsi_inst->Dst[0].Register.WriteMask & (1 << i)))
continue;
- enum pipe_format format = trans->key->tex_format[unit];
- const struct util_format_description *desc =
- util_format_description(format);
-
- uint8_t swiz = desc->swizzle[i];
-
update_dst(trans, tgsi_inst, i,
- get_swizzled_channel(trans, unpacked, swiz));
+ get_swizzled_channel(trans, unpacked, swiz[i]));
}
}
@@ -934,24 +930,25 @@ emit_frag_end(struct tgsi_to_qir *trans)
struct qreg t = qir_get_temp(c);
- const struct util_format_description *format_desc =
- util_format_description(trans->fs_key->color_format);
-
struct qreg src_color[4] = {
trans->outputs[0], trans->outputs[1],
trans->outputs[2], trans->outputs[3],
};
+ enum pipe_format color_format = trans->fs_key->color_format;
+ const uint8_t *format_swiz = vc4_get_format_swizzle(color_format);
+ struct qreg tlb_read_color[4] = { c->undef, c->undef, c->undef, c->undef };
struct qreg dst_color[4] = { c->undef, c->undef, c->undef, c->undef };
if (trans->fs_key->blend.blend_enable ||
trans->fs_key->blend.colormask != 0xf) {
qir_emit(c, qir_inst(QOP_TLB_COLOR_READ, c->undef,
c->undef, c->undef));
- for (int i = 0; i < 4; i++) {
- dst_color[i] = qir_R4_UNPACK(c, i);
-
- /* XXX: Swizzles? */
- }
+ for (int i = 0; i < 4; i++)
+ tlb_read_color[i] = qir_R4_UNPACK(c, i);
+ for (int i = 0; i < 4; i++)
+ dst_color[i] = get_swizzled_channel(trans,
+ tlb_read_color,
+ format_swiz[i]);
}
struct qreg blend_color[4];
@@ -979,9 +976,8 @@ emit_frag_end(struct tgsi_to_qir *trans)
struct qreg swizzled_outputs[4];
for (int i = 0; i < 4; i++) {
- swizzled_outputs[i] =
- get_swizzled_channel(trans, blend_color,
- format_desc->swizzle[i]);
+ swizzled_outputs[i] = get_swizzled_channel(trans, blend_color,
+ format_swiz[i]);
}
if (trans->fs_key->depth_enabled) {
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index fb46be3916b..3048b23eec3 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -267,11 +267,14 @@ static enum vc4_texture_data_type
get_resource_texture_format(struct pipe_resource *prsc)
{
struct vc4_resource *rsc = vc4_resource(prsc);
+ uint8_t format = vc4_get_tex_format(prsc->format);
- if (rsc->tiled)
- return VC4_TEXTURE_TYPE_RGBA8888;
- else
+ if (!rsc->tiled) {
+ assert(format == VC4_TEXTURE_TYPE_RGBA8888);
return VC4_TEXTURE_TYPE_RGBA32R;
+ }
+
+ return format;
}
static struct pipe_resource *
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 0c62b446b4e..c28481564b0 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -302,46 +302,6 @@ vc4_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
return 0;
}
-static uint8_t
-vc4_get_texture_format(enum pipe_format format)
-{
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- return 0;
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- return 1;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return 0;
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- return 1;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- return 0;
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- return 1;
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- return 0;
- case PIPE_FORMAT_X8B8G8R8_UNORM:
- return 1;
-/*
- case PIPE_FORMAT_R4G4B4A4_UNORM:
- return 2;
- case PIPE_FORMAT_R5G5B5A1_UNORM:
- return 3;
- case PIPE_FORMAT_R5G6B5_UNORM:
- return 4;
-*/
- case PIPE_FORMAT_L8_UNORM:
- return 5;
- case PIPE_FORMAT_A8_UNORM:
- return 6;
- case PIPE_FORMAT_L8A8_UNORM:
- return 7;
- /* XXX: ETC1 and more*/
- default:
- return ~0;
- }
-}
-
static boolean
vc4_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
@@ -366,20 +326,12 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen,
}
if ((usage & PIPE_BIND_RENDER_TARGET) &&
- (format == PIPE_FORMAT_B8G8R8A8_UNORM ||
- format == PIPE_FORMAT_B8G8R8X8_UNORM || /* XXX: really? */
- format == PIPE_FORMAT_R8G8B8A8_UNORM ||
- format == PIPE_FORMAT_R8G8B8X8_UNORM || /* XXX: really? */
- format == PIPE_FORMAT_A8B8G8R8_UNORM ||
- format == PIPE_FORMAT_X8B8G8R8_UNORM || /* XXX: really? */
- format == PIPE_FORMAT_A8R8G8B8_UNORM ||
- format == PIPE_FORMAT_X8R8G8B8_UNORM || /* XXX: really? */
- format == PIPE_FORMAT_R16G16B16A16_FLOAT)) {
+ vc4_rt_format_supported(format)) {
retval |= PIPE_BIND_RENDER_TARGET;
}
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
- (vc4_get_texture_format(format) != ~0)) {
+ (vc4_tex_format_supported(format))) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}