Ported from RadeonSI. That doesn't fix anything known but I think we need it.
Signed-off-by: Samuel Pitoiset <samuel.pitoi...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev