diff options
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 80 | ||||
-rw-r--r-- | src/amd/vulkan/radv_image.c | 10 |
2 files changed, 76 insertions, 14 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 8f9f771acf8..22e915dd0dd 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -3264,13 +3264,13 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, int count; 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 || dim == GLSL_SAMPLER_DIM_SUBPASS_MS); bool is_ms = (dim == GLSL_SAMPLER_DIM_MS || dim == GLSL_SAMPLER_DIM_SUBPASS_MS); - - count = image_type_to_components_count(dim, - glsl_sampler_type_is_array(type)); + bool gfx9_1d = ctx->abi->chip_class >= GFX9 && dim == GLSL_SAMPLER_DIM_1D; + count = image_type_to_components_count(dim, is_array); if (is_ms) { LLVMValueRef fmask_load_address[3]; @@ -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[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], ""); else fmask_load_address[2] = NULL; @@ -3297,7 +3297,7 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, sample_index, 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) res = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], ""); else @@ -3307,9 +3307,8 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, if (is_ms) count--; 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) { for (chan = 0; chan < 2; ++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, coords[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]); 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) { coords[count] = sample_index; count++; @@ -3561,14 +3570,22 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx, 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 && glsl_sampler_type_is_array(type)) { - LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false); LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false); LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, ""); z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); 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; } @@ -4495,23 +4512,39 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr) /* pack derivatives */ if (ddx || ddy) { + int num_src_deriv_channels, num_dest_deriv_channels; switch (instr->sampler_dim) { case GLSL_SAMPLER_DIM_3D: case GLSL_SAMPLER_DIM_CUBE: num_deriv_comp = 3; + num_src_deriv_channels = 3; + num_dest_deriv_channels = 3; break; case GLSL_SAMPLER_DIM_2D: default: + num_src_deriv_channels = 2; + num_dest_deriv_channels = 2; num_deriv_comp = 2; break; 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; } - 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[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) } 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 */ @@ -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, ""); z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); 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) result = trim_vector(&ctx->ac, result, instr->dest.ssa.num_components); diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 4d83ae564fc..df288666beb 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -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, - 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) 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) { case VK_IMAGE_TYPE_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, } 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) { height = 1; depth = image->info.array_size; @@ -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_Z(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[5] = S_008F24_BASE_ARRAY(first_layer); fmask_state[6] = 0; |