diff options
author | Nicolai Hähnle <[email protected]> | 2017-02-20 12:07:21 +0100 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2017-03-01 13:34:41 +0000 |
commit | 42b73955808d7b33cf8f65fc8b4abe53aeaba135 (patch) | |
tree | 91bc2aab8774f847f71466c8426216ba3402ffcc | |
parent | 7cb353520d89e264e97b193b6f8a1710e378d33c (diff) |
radeonsi: fix UINT/SINT clamping for 10-bit formats on <= CIK
The same PS epilog workaround as for 8-bit integer formats is required,
since the CB doesn't do clamping.
Fixes GL45-CTS.gtf32.GL3Tests.packed_pixels.packed_pixels*.
Cc: [email protected]
Reviewed-by: Marek Olšák <[email protected]>
(cherry picked from commit 066a117be77fdc2b29c8eafabb4e2c2fa902a18e)
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 35 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 17 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 5 |
6 files changed, 43 insertions, 19 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 97e944186eb..e3a55a87010 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -315,6 +315,7 @@ struct r600_surface { bool alphatest_bypass; bool export_16bpc; bool color_is_int8; + bool color_is_int10; /* Color registers. */ unsigned cb_color_info; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 421e2a4cf6a..e105e229763 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -173,7 +173,8 @@ struct si_framebuffer { unsigned spi_shader_col_format_alpha; unsigned spi_shader_col_format_blend; unsigned spi_shader_col_format_blend_alpha; - unsigned color_is_int8; /* bitmask */ + unsigned color_is_int8; + unsigned color_is_int10; unsigned dirty_cbufs; bool dirty_zsbuf; bool any_dst_linear; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 10f40a925e4..af6543a152b 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1985,7 +1985,7 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, LLVMValueRef val[4]; unsigned spi_shader_col_format = V_028714_SPI_SHADER_32_ABGR; unsigned chan; - bool is_int8; + bool is_int8, is_int10; /* Default is 0xf. Adjusted below depending on the format. */ args[0] = lp_build_const_int32(base->gallivm, 0xf); /* writemask */ @@ -2007,6 +2007,7 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, assert(cbuf >= 0 && cbuf < 8); spi_shader_col_format = (col_formats >> (cbuf * 4)) & 0xf; is_int8 = (key->part.ps.epilog.color_is_int8 >> cbuf) & 0x1; + is_int10 = (key->part.ps.epilog.color_is_int10 >> cbuf) & 0x1; } args[4] = uint->zero; /* COMPR flag */ @@ -2106,13 +2107,17 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, break; case V_028714_SPI_SHADER_UINT16_ABGR: { - LLVMValueRef max = lp_build_const_int32(gallivm, is_int8 ? - 255 : 65535); + LLVMValueRef max_rgb = lp_build_const_int32(gallivm, + is_int8 ? 255 : is_int10 ? 1023 : 65535); + LLVMValueRef max_alpha = + !is_int10 ? max_rgb : lp_build_const_int32(gallivm, 3); + /* Clamp. */ for (chan = 0; chan < 4; chan++) { val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, values[chan]); val[chan] = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_UMIN, - val[chan], max); + val[chan], + chan == 3 ? max_alpha : max_rgb); } args[4] = uint->one; /* COMPR flag */ @@ -2124,19 +2129,24 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, } case V_028714_SPI_SHADER_SINT16_ABGR: { - LLVMValueRef max = lp_build_const_int32(gallivm, is_int8 ? - 127 : 32767); - LLVMValueRef min = lp_build_const_int32(gallivm, is_int8 ? - -128 : -32768); + LLVMValueRef max_rgb = lp_build_const_int32(gallivm, + is_int8 ? 127 : is_int10 ? 511 : 32767); + LLVMValueRef min_rgb = lp_build_const_int32(gallivm, + is_int8 ? -128 : is_int10 ? -512 : -32768); + LLVMValueRef max_alpha = + !is_int10 ? max_rgb : lp_build_const_int32(gallivm, 1); + LLVMValueRef min_alpha = + !is_int10 ? min_rgb : lp_build_const_int32(gallivm, -2); + /* Clamp. */ for (chan = 0; chan < 4; chan++) { val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, values[chan]); val[chan] = lp_build_emit_llvm_binary(bld_base, - TGSI_OPCODE_IMIN, - val[chan], max); + TGSI_OPCODE_IMIN, + val[chan], chan == 3 ? max_alpha : max_rgb); val[chan] = lp_build_emit_llvm_binary(bld_base, - TGSI_OPCODE_IMAX, - val[chan], min); + TGSI_OPCODE_IMAX, + val[chan], chan == 3 ? min_alpha : min_rgb); } args[4] = uint->one; /* COMPR flag */ @@ -6678,6 +6688,7 @@ static void si_dump_shader_key(unsigned shader, struct si_shader_key *key, fprintf(f, " part.ps.prolog.bc_optimize_for_linear = %u\n", key->part.ps.prolog.bc_optimize_for_linear); fprintf(f, " part.ps.epilog.spi_shader_col_format = 0x%x\n", key->part.ps.epilog.spi_shader_col_format); fprintf(f, " part.ps.epilog.color_is_int8 = 0x%X\n", key->part.ps.epilog.color_is_int8); + fprintf(f, " part.ps.epilog.color_is_int10 = 0x%X\n", key->part.ps.epilog.color_is_int10); fprintf(f, " part.ps.epilog.last_cbuf = %u\n", key->part.ps.epilog.last_cbuf); fprintf(f, " part.ps.epilog.alpha_func = %u\n", key->part.ps.epilog.alpha_func); fprintf(f, " part.ps.epilog.alpha_to_one = %u\n", key->part.ps.epilog.alpha_to_one); diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index cf4da85e11b..29e8ba3fe63 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -366,6 +366,7 @@ struct si_ps_prolog_bits { struct si_ps_epilog_bits { unsigned spi_shader_col_format; unsigned color_is_int8:8; + unsigned color_is_int10:8; unsigned last_cbuf:3; unsigned alpha_func:3; unsigned alpha_to_one:1; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 01edff9cc0c..0ce93c1400a 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2121,11 +2121,15 @@ static void si_initialize_color_surface(struct si_context *sctx, blend_bypass = 1; } - if ((ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT) && - (format == V_028C70_COLOR_8 || - format == V_028C70_COLOR_8_8 || - format == V_028C70_COLOR_8_8_8_8)) - surf->color_is_int8 = true; + if (ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT) { + if (format == V_028C70_COLOR_8 || + format == V_028C70_COLOR_8_8 || + format == V_028C70_COLOR_8_8_8_8) + surf->color_is_int8 = true; + else if (format == V_028C70_COLOR_10_10_10_2 || + format == V_028C70_COLOR_2_10_10_10) + surf->color_is_int10 = true; + } color_info = S_028C70_FORMAT(format) | S_028C70_COMP_SWAP(swap) | @@ -2388,6 +2392,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, sctx->framebuffer.spi_shader_col_format_blend = 0; sctx->framebuffer.spi_shader_col_format_blend_alpha = 0; sctx->framebuffer.color_is_int8 = 0; + sctx->framebuffer.color_is_int10 = 0; sctx->framebuffer.compressed_cb_mask = 0; sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state); @@ -2417,6 +2422,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, if (surf->color_is_int8) sctx->framebuffer.color_is_int8 |= 1 << i; + if (surf->color_is_int10) + sctx->framebuffer.color_is_int10 |= 1 << i; if (rtex->fmask.size) { sctx->framebuffer.compressed_cb_mask |= 1 << i; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 010ce15a8b5..76e748f1409 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1009,13 +1009,16 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, * to the range supported by the type if a channel has less * than 16 bits and the export format is 16_ABGR. */ - if (sctx->b.chip_class <= CIK && sctx->b.family != CHIP_HAWAII) + if (sctx->b.chip_class <= CIK && sctx->b.family != CHIP_HAWAII) { key->part.ps.epilog.color_is_int8 = sctx->framebuffer.color_is_int8; + key->part.ps.epilog.color_is_int10 = sctx->framebuffer.color_is_int10; + } /* Disable unwritten outputs (if WRITE_ALL_CBUFS isn't enabled). */ if (!key->part.ps.epilog.last_cbuf) { key->part.ps.epilog.spi_shader_col_format &= sel->colors_written_4bit; key->part.ps.epilog.color_is_int8 &= sel->info.colors_written; + key->part.ps.epilog.color_is_int10 &= sel->info.colors_written; } if (rs) { |