diff --git a/bin/.cherry-ignore b/bin/.cherry-ignore index 6926ebe9105..94b65c723a4 100644 --- a/bin/.cherry-ignore +++ b/bin/.cherry-ignore @@ -62,3 +62,6 @@ e4211b36bba4acde3e56ce1e22b12759e820a241 mesa: revert GL_[SECONDARY_]COLOR_ARRAY # stable: The commit requires earlier commits ab0e625a671 and 62510846b6e which # did not land in branch. b16fc6cda11576a4dd6c8d95f7bee94121c4b8e7 radv/resolve: do fmask decompress on all layers. + +# stable: There is a specific port for this patch for stable branch. +3d4d388e3929d7948b62d90867357aecbfba5aeb radv: Fix up 2_10_10_10 alpha sign. diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index d82a059df84..f3afb237038 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -5335,6 +5335,48 @@ static void visit_cf_list(struct ac_nir_context *ctx, } } +/* For 2_10_10_10 formats the alpha is handled as unsigned by pre-vega HW. + * so we may need to fix it up. */ +static LLVMValueRef +adjust_vertex_fetch_alpha(struct nir_to_llvm_context *ctx, + unsigned adjustment, + LLVMValueRef alpha) +{ + if (adjustment == RADV_ALPHA_ADJUST_NONE) + return alpha; + + LLVMValueRef c30 = LLVMConstInt(ctx->ac.i32, 30, 0); + + if (adjustment == RADV_ALPHA_ADJUST_SSCALED) + alpha = LLVMBuildFPToUI(ctx->ac.builder, alpha, ctx->ac.i32, ""); + else + alpha = ac_to_integer(&ctx->ac, alpha); + + /* For the integer-like cases, do a natural sign extension. + * + * For the SNORM case, the values are 0.0, 0.333, 0.666, 1.0 + * and happen to contain 0, 1, 2, 3 as the two LSBs of the + * exponent. + */ + alpha = LLVMBuildShl(ctx->ac.builder, alpha, + adjustment == RADV_ALPHA_ADJUST_SNORM ? + LLVMConstInt(ctx->ac.i32, 7, 0) : c30, ""); + alpha = LLVMBuildAShr(ctx->ac.builder, alpha, c30, ""); + + /* Convert back to the right type. */ + if (adjustment == RADV_ALPHA_ADJUST_SNORM) { + LLVMValueRef clamp; + LLVMValueRef neg_one = LLVMConstReal(ctx->ac.f32, -1.0); + alpha = LLVMBuildSIToFP(ctx->ac.builder, alpha, ctx->ac.f32, ""); + clamp = LLVMBuildFCmp(ctx->ac.builder, LLVMRealULT, alpha, neg_one, ""); + alpha = LLVMBuildSelect(ctx->ac.builder, clamp, neg_one, alpha, ""); + } else if (adjustment == RADV_ALPHA_ADJUST_SSCALED) { + alpha = LLVMBuildSIToFP(ctx->ac.builder, alpha, ctx->ac.f32, ""); + } + + return alpha; +} + static void handle_vs_input_decl(struct nir_to_llvm_context *ctx, struct nir_variable *variable) @@ -5344,14 +5386,15 @@ handle_vs_input_decl(struct nir_to_llvm_context *ctx, LLVMValueRef t_list; LLVMValueRef input; LLVMValueRef buffer_index; - int index = variable->data.location - VERT_ATTRIB_GENERIC0; - int idx = variable->data.location; unsigned attrib_count = glsl_count_attribute_slots(variable->type, true); - variable->data.driver_location = idx * 4; + variable->data.driver_location = variable->data.location * 4; - for (unsigned i = 0; i < attrib_count; ++i, ++idx) { - if (ctx->options->key.vs.instance_rate_inputs & (1u << (index + i))) { + for (unsigned i = 0; i < attrib_count; ++i) { + LLVMValueRef output[4]; + unsigned attrib_index = variable->data.location + i - VERT_ATTRIB_GENERIC0; + + if (ctx->options->key.vs.instance_rate_inputs & (1u << attrib_index)) { buffer_index = LLVMBuildAdd(ctx->builder, ctx->abi.instance_id, ctx->abi.start_instance, ""); if (ctx->options->key.vs.as_ls) { @@ -5364,7 +5407,7 @@ handle_vs_input_decl(struct nir_to_llvm_context *ctx, } else buffer_index = LLVMBuildAdd(ctx->builder, ctx->abi.vertex_id, ctx->abi.base_vertex, ""); - t_offset = LLVMConstInt(ctx->ac.i32, index + i, false); + t_offset = LLVMConstInt(ctx->ac.i32, attrib_index, false); t_list = ac_build_load_to_sgpr(&ctx->ac, t_list_ptr, t_offset); @@ -5375,9 +5418,15 @@ handle_vs_input_decl(struct nir_to_llvm_context *ctx, for (unsigned chan = 0; chan < 4; chan++) { LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false); - ctx->inputs[radeon_llvm_reg_index_soa(idx, chan)] = - ac_to_integer(&ctx->ac, LLVMBuildExtractElement(ctx->builder, - input, llvm_chan, "")); + output[chan] = LLVMBuildExtractElement(ctx->builder, input, llvm_chan, ""); + } + + unsigned alpha_adjust = (ctx->options->key.vs.alpha_adjust >> (attrib_index * 2)) & 3; + output[3] = adjust_vertex_fetch_alpha(ctx, alpha_adjust, output[3]); + + for (unsigned chan = 0; chan < 4; chan++) { + ctx->inputs[radeon_llvm_reg_index_soa(variable->data.location + i, chan)] = + ac_to_integer(&ctx->ac, output[chan]); } } } diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 1656289e06e..ab8221ee31a 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -39,8 +39,20 @@ struct radv_pipeline_layout; struct ac_llvm_context; struct ac_shader_abi; +enum { + RADV_ALPHA_ADJUST_NONE = 0, + RADV_ALPHA_ADJUST_SNORM = 1, + RADV_ALPHA_ADJUST_SINT = 2, + RADV_ALPHA_ADJUST_SSCALED = 3, +}; + struct ac_vs_variant_key { uint32_t instance_rate_inputs; + + /* For 2_10_10_10 formats the alpha is handled as unsigned by pre-vega HW. + * so we may need to fix it up. */ + uint64_t alpha_adjust; + uint32_t as_es:1; uint32_t as_ls:1; uint32_t export_prim_id:1; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 7b3e565db89..6a990d95bdd 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1796,10 +1796,34 @@ radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline, } for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) { - unsigned binding; - binding = input_state->pVertexAttributeDescriptions[i].binding; + unsigned location = input_state->pVertexAttributeDescriptions[i].location; + unsigned binding = input_state->pVertexAttributeDescriptions[i].binding; if (binding_input_rate & (1u << binding)) key.instance_rate_inputs |= 1u << input_state->pVertexAttributeDescriptions[i].location; + + if (pipeline->device->physical_device->rad_info.chip_class <= VI && + pipeline->device->physical_device->rad_info.family != CHIP_STONEY) { + VkFormat format = input_state->pVertexAttributeDescriptions[i].format; + uint64_t adjust; + switch(format) { + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + adjust = RADV_ALPHA_ADJUST_SNORM; + break; + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + adjust = RADV_ALPHA_ADJUST_SSCALED; + break; + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + adjust = RADV_ALPHA_ADJUST_SINT; + break; + default: + adjust = 0; + break; + } + key.vertex_alpha_adjust |= adjust << (2 * location); + } } if (pCreateInfo->pTessellationState) @@ -1828,6 +1852,7 @@ radv_fill_shader_keys(struct ac_shader_variant_key *keys, nir_shader **nir) { keys[MESA_SHADER_VERTEX].vs.instance_rate_inputs = key->instance_rate_inputs; + keys[MESA_SHADER_VERTEX].vs.alpha_adjust = key->vertex_alpha_adjust; if (nir[MESA_SHADER_TESS_CTRL]) { keys[MESA_SHADER_VERTEX].vs.as_ls = true; diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index ca338c9e050..c7b6913b34b 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -329,6 +329,7 @@ struct radv_pipeline_cache { struct radv_pipeline_key { uint32_t instance_rate_inputs; + uint64_t vertex_alpha_adjust; unsigned tess_input_vertices; uint32_t col_format; uint32_t is_int8;