[Mesa-dev] [PATCH] radv/gfx9: add a workaround for viewing a slice of 3D as a 2D image
Samuel Pitoiset
samuel.pitoiset at gmail.com
Mon Feb 26 13:04:17 UTC 2018
Ported from RadeonSI.
That doesn't fix anything known but I think we need it.
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
src/amd/common/ac_nir_to_llvm.c | 45 +++++++++++++++++++++++++++++++++--------
1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 2c5a6e6cf6..06d1b31047 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -3524,7 +3524,8 @@ static LLVMValueRef adjust_sample_index_using_fmask(struct ac_llvm_context *ctx,
}
static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
- const nir_intrinsic_instr *instr)
+ const nir_intrinsic_instr *instr,
+ LLVMValueRef desc)
{
const struct glsl_type *type = glsl_without_array(instr->variables[0]->var->type);
@@ -3599,6 +3600,23 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
} else
coords[1] = ctx->ac.i32_0;
count++;
+ } else if (ctx->ac.chip_class >= GFX9 &&
+ dim == GLSL_SAMPLER_DIM_2D &&
+ !is_array) {
+ /* The hw can't bind a slice of a 3D image as a 2D
+ * image, because it ignores BASE_ARRAY if the target
+ * is 3D. The workaround is to read BASE_ARRAY and set
+ * it as the 3rd address operand for all 2D images.
+ */
+ LLVMValueRef first_layer, const5, mask;
+
+ const5 = LLVMConstInt(ctx->ac.i32, 5, 0);
+ mask = LLVMConstInt(ctx->ac.i32, S_008F24_BASE_ARRAY(~0), 0);
+ first_layer = LLVMBuildExtractElement(ctx->ac.builder, desc, const5, "");
+ first_layer = LLVMBuildAnd(ctx->ac.builder, first_layer, mask, "");
+
+ coords[2] = first_layer;
+ count++;
}
if (is_ms) {
@@ -3650,9 +3668,13 @@ static LLVMValueRef visit_image_load(struct ac_nir_context *ctx,
} else {
LLVMValueRef da = glsl_is_array_image(type) ? ctx->ac.i1true : ctx->ac.i1false;
LLVMValueRef slc = ctx->ac.i1false;
+ LLVMValueRef desc;
+
+ desc = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE,
+ NULL, true, false);
- params[0] = get_image_coords(ctx, instr);
- params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, false);
+ params[0] = get_image_coords(ctx, instr, desc);
+ params[1] = desc;
params[2] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */
params[3] = (var->data.image._volatile || var->data.image.coherent) ?
ctx->ac.i1true : ctx->ac.i1false;
@@ -3698,10 +3720,14 @@ static void visit_image_store(struct ac_nir_context *ctx,
} else {
LLVMValueRef da = glsl_is_array_image(type) ? ctx->ac.i1true : ctx->ac.i1false;
LLVMValueRef slc = ctx->ac.i1false;
+ LLVMValueRef desc;
+
+ desc = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE,
+ NULL, true, true);
params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[2]));
- params[1] = get_image_coords(ctx, instr); /* coords */
- params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, true);
+ params[1] = get_image_coords(ctx, instr, desc);
+ params[2] = desc;
params[3] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */
params[4] = (force_glc || var->data.image._volatile || var->data.image.coherent) ?
ctx->ac.i1true : ctx->ac.i1false;
@@ -3780,10 +3806,13 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
"llvm.amdgcn.buffer.atomic.%s", atomic_name);
} else {
char coords_type[8];
+ LLVMValueRef desc;
- LLVMValueRef coords = params[param_count++] = get_image_coords(ctx, instr);
- params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE,
- NULL, true, true);
+ desc = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE,
+ NULL, true, true);
+
+ LLVMValueRef coords = params[param_count++] = get_image_coords(ctx, instr, desc);
+ params[param_count++] = desc;
params[param_count++] = ctx->ac.i1false; /* r128 */
params[param_count++] = glsl_is_array_image(type) ? ctx->ac.i1true : ctx->ac.i1false; /* da */
params[param_count++] = ctx->ac.i1false; /* slc */
--
2.16.2
More information about the mesa-dev
mailing list