diff options
-rw-r--r-- | src/gallium/drivers/vc4/Makefile.sources | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_formats.c | 169 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 32 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_resource.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_screen.c | 52 |
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; } |