diff options
author | Marek Olšák <[email protected]> | 2017-01-24 21:39:42 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-03-30 14:44:33 +0200 |
commit | 566defad138161a321ef11b528a7c4fcae273f6e (patch) | |
tree | c3f2d7e80b1bca7cc8c4796f053f3ed8a8dc11cc /src/gallium/drivers/radeonsi/si_shader.c | |
parent | fc3c503b5d7fc9843220c8d89c6394f145f096af (diff) |
radeonsi/gfx9: add a workaround for 1D depth textures
The same workaround is used by Vulkan.
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_shader.c')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 20d6bd732b2..20686bd331c 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -3297,6 +3297,7 @@ static LLVMValueRef image_fetch_coords( const struct tgsi_full_instruction *inst, unsigned src) { + struct si_shader_context *ctx = si_shader_context(bld_base); struct gallivm_state *gallivm = bld_base->base.gallivm; LLVMBuilderRef builder = gallivm->builder; unsigned target = inst->Memory.Texture; @@ -3311,6 +3312,17 @@ static LLVMValueRef image_fetch_coords( coords[chan] = tmp; } + /* 1D textures are allocated and used as 2D on GFX9. */ + if (ctx->screen->b.chip_class >= GFX9) { + if (target == TGSI_TEXTURE_1D) { + coords[1] = bld_base->uint_bld.zero; + num_coords++; + } else if (target == TGSI_TEXTURE_1D_ARRAY) { + coords[2] = coords[1]; + coords[1] = bld_base->uint_bld.zero; + } + } + if (num_coords == 1) return coords[0]; @@ -4440,11 +4452,12 @@ static void tex_fetch_args( /* Pack user derivatives */ if (opcode == TGSI_OPCODE_TXD) { - int param, num_src_deriv_channels; + int param, num_src_deriv_channels, num_dst_deriv_channels; switch (target) { case TGSI_TEXTURE_3D: num_src_deriv_channels = 3; + num_dst_deriv_channels = 3; num_deriv_channels = 3; break; case TGSI_TEXTURE_2D: @@ -4454,6 +4467,7 @@ static void tex_fetch_args( case TGSI_TEXTURE_2D_ARRAY: case TGSI_TEXTURE_SHADOW2D_ARRAY: num_src_deriv_channels = 2; + num_dst_deriv_channels = 2; num_deriv_channels = 2; break; case TGSI_TEXTURE_CUBE: @@ -4462,6 +4476,7 @@ static void tex_fetch_args( case TGSI_TEXTURE_SHADOWCUBE_ARRAY: /* Cube derivatives will be converted to 2D. */ num_src_deriv_channels = 3; + num_dst_deriv_channels = 3; num_deriv_channels = 2; break; case TGSI_TEXTURE_1D: @@ -4469,16 +4484,31 @@ static void tex_fetch_args( case TGSI_TEXTURE_1D_ARRAY: case TGSI_TEXTURE_SHADOW1D_ARRAY: num_src_deriv_channels = 1; - num_deriv_channels = 1; + + /* 1D textures are allocated and used as 2D on GFX9. */ + if (ctx->screen->b.chip_class >= GFX9) { + num_dst_deriv_channels = 2; + num_deriv_channels = 2; + } else { + num_dst_deriv_channels = 1; + num_deriv_channels = 1; + } break; default: unreachable("invalid target"); } - for (param = 0; param < 2; param++) + for (param = 0; param < 2; param++) { for (chan = 0; chan < num_src_deriv_channels; chan++) - derivs[param * num_src_deriv_channels + chan] = + derivs[param * num_dst_deriv_channels + chan] = lp_build_emit_fetch(bld_base, inst, param+1, chan); + + /* Fill in the rest with zeros. */ + for (chan = num_src_deriv_channels; + chan < num_dst_deriv_channels; chan++) + derivs[param * num_dst_deriv_channels + chan] = + bld_base->base.zero; + } } if (target == TGSI_TEXTURE_CUBE || @@ -4502,6 +4532,27 @@ static void tex_fetch_args( if (num_coords > 2) address[count++] = coords[2]; + /* 1D textures are allocated and used as 2D on GFX9. */ + if (ctx->screen->b.chip_class >= GFX9) { + LLVMValueRef filler; + + /* Use 0.5, so that we don't sample the border color. */ + if (opcode == TGSI_OPCODE_TXF) + filler = bld_base->uint_bld.zero; + else + filler = LLVMConstReal(ctx->f32, 0.5); + + if (target == TGSI_TEXTURE_1D || + target == TGSI_TEXTURE_SHADOW1D) { + address[count++] = filler; + } else if (target == TGSI_TEXTURE_1D_ARRAY || + target == TGSI_TEXTURE_SHADOW1D_ARRAY) { + address[count] = coords[count - 1]; + address[count - 1] = filler; + count++; + } + } + /* Pack LOD or sample index */ if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXF) address[count++] = coords[3]; |