From 476469955225e15f454e01dc80047dd5fa5c9f97 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 29 Dec 2017 11:48:41 -0800 Subject: [PATCH] braodcom/vc5: Rely on OVRTMUOUT always being set. It seems that the HW team has decided that it's the only supported mode, and it's the mode I actually meant to be using but forgot. Our table of return_32_bit should have matched the default non-OVRTMUOUT behavior, so this change should be invisible. However, the change revealed that some my return_size checks for swizzling were a bit confused in the shadow case, so I had to move them to draw time once we have both the sampler and the view together. Fixes assertion failures in the updated simulator, where the non-OVRTMUOUT support has been removed. --- src/broadcom/cle/v3d_packet_v33.xml | 2 ++ src/gallium/drivers/vc5/vc5_context.h | 3 +- src/gallium/drivers/vc5/vc5_emit.c | 47 +++++++++++++++++++++++-- src/gallium/drivers/vc5/vc5_formats.c | 5 ++- src/gallium/drivers/vc5/vc5_program.c | 5 +-- src/gallium/drivers/vc5/vc5_simulator.c | 16 +++++++++ src/gallium/drivers/vc5/vc5_state.c | 35 ------------------ 7 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/broadcom/cle/v3d_packet_v33.xml b/src/broadcom/cle/v3d_packet_v33.xml index f18954d64c8..0402484dd71 100644 --- a/src/broadcom/cle/v3d_packet_v33.xml +++ b/src/broadcom/cle/v3d_packet_v33.xml @@ -818,6 +818,8 @@ + + diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h index 73fb0d0bc53..04ab506f035 100644 --- a/src/gallium/drivers/vc5/vc5_context.h +++ b/src/gallium/drivers/vc5/vc5_context.h @@ -493,7 +493,8 @@ bool vc5_rt_format_supported(enum pipe_format f); bool vc5_tex_format_supported(enum pipe_format f); uint8_t vc5_get_rt_format(enum pipe_format f); uint8_t vc5_get_tex_format(enum pipe_format f); -uint8_t vc5_get_tex_return_size(enum pipe_format f); +uint8_t vc5_get_tex_return_size(enum pipe_format f, + enum pipe_tex_compare compare); uint8_t vc5_get_tex_return_channels(enum pipe_format f); const uint8_t *vc5_get_format_swizzle(enum pipe_format f); void vc5_get_internal_type_bpp_for_output_format(uint32_t format, diff --git a/src/gallium/drivers/vc5/vc5_emit.c b/src/gallium/drivers/vc5/vc5_emit.c index d5356673e7e..413059efa4a 100644 --- a/src/gallium/drivers/vc5/vc5_emit.c +++ b/src/gallium/drivers/vc5/vc5_emit.c @@ -91,7 +91,8 @@ swizzled_border_color(struct pipe_sampler_state *sampler, * For swizzling in the shader, we don't do any pre-swizzling of the * border color. */ - if (vc5_get_tex_return_size(sview->base.format) != 32) + if (vc5_get_tex_return_size(sview->base.format, + sampler->compare_mode) != 32) swiz = desc->swizzle[swiz]; switch (swiz) { @@ -104,6 +105,24 @@ swizzled_border_color(struct pipe_sampler_state *sampler, } } +static uint32_t +translate_swizzle(unsigned char pipe_swizzle) +{ + switch (pipe_swizzle) { + case PIPE_SWIZZLE_0: + return 0; + case PIPE_SWIZZLE_1: + return 1; + case PIPE_SWIZZLE_X: + case PIPE_SWIZZLE_Y: + case PIPE_SWIZZLE_Z: + case PIPE_SWIZZLE_W: + return 2 + pipe_swizzle; + default: + unreachable("unknown swizzle"); + } +} + static void emit_one_texture(struct vc5_context *vc5, struct vc5_texture_stateobj *stage_tex, int i) @@ -123,6 +142,9 @@ emit_one_texture(struct vc5_context *vc5, struct vc5_texture_stateobj *stage_tex vc5_bo_set_reference(&stage_tex->texture_state[i].bo, job->indirect.bo); + uint32_t return_size = vc5_get_tex_return_size(psview->format, + psampler->compare_mode); + struct V3D33_TEXTURE_SHADER_STATE unpacked = { /* XXX */ .border_color_red = swizzled_border_color(psampler, sview, 0), @@ -150,13 +172,34 @@ emit_one_texture(struct vc5_context *vc5, struct vc5_texture_stateobj *stage_tex .texture_base_pointer = cl_address(rsc->bo, rsc->slices[0].offset), + + .output_32_bit = return_size == 32, }; + /* Set up the sampler swizzle if we're doing 16-bit sampling. For + * 32-bit, we leave swizzling up to the shader compiler. + * + * Note: Contrary to the docs, the swizzle still applies even if the + * return size is 32. It's just that you probably want to swizzle in + * the shader, because you need the Y/Z/W channels to be defined. + */ + if (return_size == 32) { + unpacked.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X); + unpacked.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y); + unpacked.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z); + unpacked.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W); + } else { + unpacked.swizzle_r = translate_swizzle(sview->swizzle[0]); + unpacked.swizzle_g = translate_swizzle(sview->swizzle[1]); + unpacked.swizzle_b = translate_swizzle(sview->swizzle[2]); + unpacked.swizzle_a = translate_swizzle(sview->swizzle[3]); + } + int min_img_filter = psampler->min_img_filter; int min_mip_filter = psampler->min_mip_filter; int mag_img_filter = psampler->mag_img_filter; - if (vc5_get_tex_return_size(psview->format) == 32) { + if (return_size == 32) { min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; mag_img_filter = PIPE_TEX_FILTER_NEAREST; mag_img_filter = PIPE_TEX_FILTER_NEAREST; diff --git a/src/gallium/drivers/vc5/vc5_formats.c b/src/gallium/drivers/vc5/vc5_formats.c index c9a8f19cf4f..6c541ea47ea 100644 --- a/src/gallium/drivers/vc5/vc5_formats.c +++ b/src/gallium/drivers/vc5/vc5_formats.c @@ -259,13 +259,16 @@ vc5_get_tex_format(enum pipe_format f) } uint8_t -vc5_get_tex_return_size(enum pipe_format f) +vc5_get_tex_return_size(enum pipe_format f, enum pipe_tex_compare compare) { const struct vc5_format *vf = get_format(f); if (!vf) return 0; + if (compare == PIPE_TEX_COMPARE_R_TO_TEXTURE) + return 16; + return vf->return_size; } diff --git a/src/gallium/drivers/vc5/vc5_program.c b/src/gallium/drivers/vc5/vc5_program.c index a356d0645d8..4232d6aeb83 100644 --- a/src/gallium/drivers/vc5/vc5_program.c +++ b/src/gallium/drivers/vc5/vc5_program.c @@ -273,7 +273,8 @@ vc5_setup_shared_key(struct vc5_context *vc5, struct v3d_key *key, continue; key->tex[i].return_size = - vc5_get_tex_return_size(sampler->format); + vc5_get_tex_return_size(sampler->format, + sampler_state->compare_mode); /* For 16-bit, we set up the sampler to always return 2 * channels (meaning no recompiles for most statechanges), @@ -286,7 +287,7 @@ vc5_setup_shared_key(struct vc5_context *vc5, struct v3d_key *key, vc5_get_tex_return_channels(sampler->format); } - if (vc5_get_tex_return_size(sampler->format) == 32) { + if (key->tex[i].return_size == 32) { memcpy(key->tex[i].swizzle, vc5_sampler->swizzle, sizeof(vc5_sampler->swizzle)); diff --git a/src/gallium/drivers/vc5/vc5_simulator.c b/src/gallium/drivers/vc5/vc5_simulator.c index 4539cef5fa6..95aa79d0a08 100644 --- a/src/gallium/drivers/vc5/vc5_simulator.c +++ b/src/gallium/drivers/vc5/vc5_simulator.c @@ -661,6 +661,20 @@ vc5_simulator_ioctl(int fd, unsigned long request, void *args) } } +static void +vc5_simulator_init_regs(void) +{ + /* Set OVRTMUOUT to match kernel behavior. + * + * This means that the texture sampler uniform configuration's tmu + * output type field is used, instead of using the hardware default + * behavior based on the texture type. If you want the default + * behavior, you can still put "2" in the indirect texture state's + * output_type field. + */ + V3D_WRITE(V3D_CTL_0_MISCCFG, V3D_CTL_1_MISCCFG_OVRTMUOUT_SET); +} + static void vc5_simulator_init_global(void) { @@ -690,6 +704,8 @@ vc5_simulator_init_global(void) _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); + + vc5_simulator_init_regs(); } void diff --git a/src/gallium/drivers/vc5/vc5_state.c b/src/gallium/drivers/vc5/vc5_state.c index 04ce3075a8f..8bc575f6f1d 100644 --- a/src/gallium/drivers/vc5/vc5_state.c +++ b/src/gallium/drivers/vc5/vc5_state.c @@ -556,24 +556,6 @@ vc5_sampler_states_bind(struct pipe_context *pctx, stage_tex->num_samplers = new_nr; } -static uint32_t -translate_swizzle(unsigned char pipe_swizzle) -{ - switch (pipe_swizzle) { - case PIPE_SWIZZLE_0: - return 0; - case PIPE_SWIZZLE_1: - return 1; - case PIPE_SWIZZLE_X: - case PIPE_SWIZZLE_Y: - case PIPE_SWIZZLE_Z: - case PIPE_SWIZZLE_W: - return 2 + pipe_swizzle; - default: - unreachable("unknown swizzle"); - } -} - static struct pipe_sampler_view * vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, const struct pipe_sampler_view *cso) @@ -663,23 +645,6 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, tex.texture_type = vc5_get_tex_format(cso->format); } - /* Note: Contrary to the docs, the swizzle still applies even - * if the return size is 32. It's just that you probably want - * to swizzle in the shader, because you need the Y/Z/W - * channels to be defined. - */ - if (vc5_get_tex_return_size(cso->format) != 32) { - tex.swizzle_r = translate_swizzle(so->swizzle[0]); - tex.swizzle_g = translate_swizzle(so->swizzle[1]); - tex.swizzle_b = translate_swizzle(so->swizzle[2]); - tex.swizzle_a = translate_swizzle(so->swizzle[3]); - } else { - tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X); - tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y); - tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z); - tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W); - } - tex.uif_xor_disable = (rsc->slices[0].tiling == VC5_TILING_UIF_NO_XOR); -- 2.30.2