Commit 1bcb953e authored by Dave Airlie's avatar Dave Airlie
Browse files

radv: handle GFX9 1D textures



As GFX9 can't handle 1D depth textures, radeonsi and
apparantly pro just update all 1D textures to 2D,
and work around it.

This ports the workarounds from radeonsi.
Reviewed-by: default avatarBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Cc: "17.2" <mesa-stable@lists.freedesktop.org>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 2f5b4490
...@@ -3264,13 +3264,13 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, ...@@ -3264,13 +3264,13 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
int count; int count;
enum glsl_sampler_dim dim = glsl_get_sampler_dim(type); enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
bool is_array = glsl_sampler_type_is_array(type);
bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS || bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS ||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS); dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
bool is_ms = (dim == GLSL_SAMPLER_DIM_MS || bool is_ms = (dim == GLSL_SAMPLER_DIM_MS ||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS); dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
bool gfx9_1d = ctx->abi->chip_class >= GFX9 && dim == GLSL_SAMPLER_DIM_1D;
count = image_type_to_components_count(dim, count = image_type_to_components_count(dim, is_array);
glsl_sampler_type_is_array(type));
if (is_ms) { if (is_ms) {
LLVMValueRef fmask_load_address[3]; LLVMValueRef fmask_load_address[3];
...@@ -3278,7 +3278,7 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, ...@@ -3278,7 +3278,7 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
fmask_load_address[0] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], ""); fmask_load_address[0] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], "");
fmask_load_address[1] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[1], ""); fmask_load_address[1] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[1], "");
if (glsl_sampler_type_is_array(type)) if (is_array)
fmask_load_address[2] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[2], ""); fmask_load_address[2] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[2], "");
else else
fmask_load_address[2] = NULL; fmask_load_address[2] = NULL;
...@@ -3297,7 +3297,7 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, ...@@ -3297,7 +3297,7 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
sample_index, sample_index,
get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, true, false)); get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, true, false));
} }
if (count == 1) { if (count == 1 && !gfx9_1d) {
if (instr->src[0].ssa->num_components) if (instr->src[0].ssa->num_components)
res = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], ""); res = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], "");
else else
...@@ -3307,9 +3307,8 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, ...@@ -3307,9 +3307,8 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
if (is_ms) if (is_ms)
count--; count--;
for (chan = 0; chan < count; ++chan) { for (chan = 0; chan < count; ++chan) {
coords[chan] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[chan], ""); coords[chan] = llvm_extract_elem(&ctx->ac, src0, chan);
} }
if (add_frag_pos) { if (add_frag_pos) {
for (chan = 0; chan < 2; ++chan) for (chan = 0; chan < 2; ++chan)
coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan], coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan],
...@@ -3317,6 +3316,16 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, ...@@ -3317,6 +3316,16 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
coords[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]); coords[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
count++; count++;
} }
if (gfx9_1d) {
if (is_array) {
coords[2] = coords[1];
coords[1] = ctx->ac.i32_0;
} else
coords[1] = ctx->ac.i32_0;
count++;
}
if (is_ms) { if (is_ms) {
coords[count] = sample_index; coords[count] = sample_index;
count++; count++;
...@@ -3561,14 +3570,22 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx, ...@@ -3561,14 +3570,22 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
res = ac_build_image_opcode(&ctx->ac, &args); res = ac_build_image_opcode(&ctx->ac, &args);
LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false);
if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE && if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE &&
glsl_sampler_type_is_array(type)) { glsl_sampler_type_is_array(type)) {
LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false);
LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false); LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false);
LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, ""); LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, "");
z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); z = LLVMBuildSDiv(ctx->ac.builder, z, six, "");
res = LLVMBuildInsertElement(ctx->ac.builder, res, z, two, ""); res = LLVMBuildInsertElement(ctx->ac.builder, res, z, two, "");
} }
if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_1D &&
glsl_sampler_type_is_array(type)) {
LLVMValueRef layers = LLVMBuildExtractElement(ctx->ac.builder, res, two, "");
res = LLVMBuildInsertElement(ctx->ac.builder, res, layers,
ctx->ac.i32_1, "");
}
return res; return res;
} }
...@@ -4495,23 +4512,39 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr) ...@@ -4495,23 +4512,39 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
/* pack derivatives */ /* pack derivatives */
if (ddx || ddy) { if (ddx || ddy) {
int num_src_deriv_channels, num_dest_deriv_channels;
switch (instr->sampler_dim) { switch (instr->sampler_dim) {
case GLSL_SAMPLER_DIM_3D: case GLSL_SAMPLER_DIM_3D:
case GLSL_SAMPLER_DIM_CUBE: case GLSL_SAMPLER_DIM_CUBE:
num_deriv_comp = 3; num_deriv_comp = 3;
num_src_deriv_channels = 3;
num_dest_deriv_channels = 3;
break; break;
case GLSL_SAMPLER_DIM_2D: case GLSL_SAMPLER_DIM_2D:
default: default:
num_src_deriv_channels = 2;
num_dest_deriv_channels = 2;
num_deriv_comp = 2; num_deriv_comp = 2;
break; break;
case GLSL_SAMPLER_DIM_1D: case GLSL_SAMPLER_DIM_1D:
num_deriv_comp = 1; num_src_deriv_channels = 1;
if (ctx->abi->chip_class >= GFX9) {
num_dest_deriv_channels = 2;
num_deriv_comp = 2;
} else {
num_dest_deriv_channels = 1;
num_deriv_comp = 1;
}
break; break;
} }
for (unsigned i = 0; i < num_deriv_comp; i++) { for (unsigned i = 0; i < num_src_deriv_channels; i++) {
derivs[i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddx, i)); derivs[i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddx, i));
derivs[num_deriv_comp + i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddy, i)); derivs[num_dest_deriv_channels + i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddy, i));
}
for (unsigned i = num_src_deriv_channels; i < num_dest_deriv_channels; i++) {
derivs[i] = ctx->ac.f32_0;
derivs[num_dest_deriv_channels + i] = ctx->ac.f32_0;
} }
} }
...@@ -4552,6 +4585,23 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr) ...@@ -4552,6 +4585,23 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
} }
address[count++] = coords[2]; address[count++] = coords[2];
} }
if (ctx->abi->chip_class >= GFX9) {
LLVMValueRef filler;
if (instr->op == nir_texop_txf)
filler = ctx->ac.i32_0;
else
filler = LLVMConstReal(ctx->ac.f32, 0.5);
if (instr->sampler_dim == GLSL_SAMPLER_DIM_1D) {
if (instr->is_array) {
address[count] = address[count - 1];
address[count - 1] = filler;
count++;
} else
address[count++] = filler;
}
}
} }
/* Pack LOD */ /* Pack LOD */
...@@ -4648,6 +4698,14 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr) ...@@ -4648,6 +4698,14 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, result, two, ""); LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, result, two, "");
z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); z = LLVMBuildSDiv(ctx->ac.builder, z, six, "");
result = LLVMBuildInsertElement(ctx->ac.builder, result, z, two, ""); result = LLVMBuildInsertElement(ctx->ac.builder, result, z, two, "");
} else if (ctx->abi->chip_class >= GFX9 &&
instr->op == nir_texop_txs &&
instr->sampler_dim == GLSL_SAMPLER_DIM_1D &&
instr->is_array) {
LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false);
LLVMValueRef layers = LLVMBuildExtractElement(ctx->ac.builder, result, two, "");
result = LLVMBuildInsertElement(ctx->ac.builder, result, layers,
ctx->ac.i32_1, "");
} else if (instr->dest.ssa.num_components != 4) } else if (instr->dest.ssa.num_components != 4)
result = trim_vector(&ctx->ac, result, instr->dest.ssa.num_components); result = trim_vector(&ctx->ac, result, instr->dest.ssa.num_components);
......
...@@ -281,10 +281,14 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, ...@@ -281,10 +281,14 @@ si_set_mutable_tex_desc_fields(struct radv_device *device,
} }
static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type, static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
unsigned nr_layers, unsigned nr_samples, bool is_storage_image) unsigned nr_layers, unsigned nr_samples, bool is_storage_image, bool gfx9)
{ {
if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE; return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
/* GFX9 allocates 1D textures as 2D. */
if (gfx9 && image_type == VK_IMAGE_TYPE_1D)
image_type = VK_IMAGE_TYPE_2D;
switch (image_type) { switch (image_type) {
case VK_IMAGE_TYPE_1D: case VK_IMAGE_TYPE_1D:
return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D; return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
...@@ -375,7 +379,7 @@ si_make_texture_descriptor(struct radv_device *device, ...@@ -375,7 +379,7 @@ si_make_texture_descriptor(struct radv_device *device,
} }
type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples, type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
is_storage_image); is_storage_image, device->physical_device->rad_info.chip_class >= GFX9);
if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) { if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
height = 1; height = 1;
depth = image->info.array_size; depth = image->info.array_size;
...@@ -495,7 +499,7 @@ si_make_texture_descriptor(struct radv_device *device, ...@@ -495,7 +499,7 @@ si_make_texture_descriptor(struct radv_device *device,
S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
S_008F1C_TYPE(radv_tex_dim(image->type, view_type, 1, 0, false)); S_008F1C_TYPE(radv_tex_dim(image->type, view_type, 1, 0, false, false));
fmask_state[4] = 0; fmask_state[4] = 0;
fmask_state[5] = S_008F24_BASE_ARRAY(first_layer); fmask_state[5] = S_008F24_BASE_ARRAY(first_layer);
fmask_state[6] = 0; fmask_state[6] = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment