shader_recompiler: Cleanup fragment attribute handling (#3076)

* image: Take minimum of mip levels

Avoids validation error

* texture_cache: Update depth target image

Avoids using undefined depth target in rendering

* shader_recompiler: Cleanup fragment attribute handling
This commit is contained in:
TheTurtle 2025-06-10 18:57:16 +03:00 committed by GitHub
parent e2b726382e
commit e0c930f2d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 20 deletions

View file

@ -299,8 +299,7 @@ void EmitContext::DefineInterpolatedAttribs() {
// Iterate all input attributes, load them and manually interpolate.
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
const auto& input = runtime_info.fs_info.inputs[i];
const u32 semantic = input.param_index;
auto& params = input_params[semantic];
auto& params = input_params[i];
if (input.is_flat || params.is_loaded) {
continue;
}
@ -318,7 +317,7 @@ void EmitContext::DefineInterpolatedAttribs() {
const Id p10_y{OpVectorTimesScalar(F32[4], p10, bary_coord_y)};
const Id p20_z{OpVectorTimesScalar(F32[4], p20, bary_coord_z)};
params.id = OpFAdd(F32[4], p0, OpFAdd(F32[4], p10_y, p20_z));
Name(params.id, fmt::format("fs_in_attr{}", semantic));
Name(params.id, fmt::format("fs_in_attr{}", i));
params.is_loaded = true;
}
}
@ -427,25 +426,28 @@ void EmitContext::DefineInputs() {
}
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
const auto& input = runtime_info.fs_info.inputs[i];
const u32 semantic = input.param_index;
ASSERT(semantic < IR::NumParams);
if (input.IsDefault()) {
input_params[semantic] = {
MakeDefaultValue(*this, input.default_value), input_f32, F32[1], 4, false, true,
input_params[i] = {
.id = MakeDefaultValue(*this, input.default_value),
.pointer_type = input_f32,
.component_type = F32[1],
.num_components = 4,
.is_integer = false,
.is_loaded = true,
};
continue;
}
const IR::Attribute param{IR::Attribute::Param0 + input.param_index};
const IR::Attribute param{IR::Attribute::Param0 + i};
const u32 num_components = info.loads.NumComponents(param);
const Id type{F32[num_components]};
Id attr_id{};
if (profile.needs_manual_interpolation && !input.is_flat) {
attr_id = DefineInput(TypeArray(type, ConstU32(3U)), semantic);
attr_id = DefineInput(TypeArray(type, ConstU32(3U)), input.param_index);
Decorate(attr_id, spv::Decoration::PerVertexKHR);
Name(attr_id, fmt::format("fs_in_attr{}_p", semantic));
Name(attr_id, fmt::format("fs_in_attr{}_p", i));
} else {
attr_id = DefineInput(type, semantic);
Name(attr_id, fmt::format("fs_in_attr{}", semantic));
attr_id = DefineInput(type, input.param_index);
Name(attr_id, fmt::format("fs_in_attr{}", i));
if (input.is_flat) {
Decorate(attr_id, spv::Decoration::Flat);
@ -453,7 +455,7 @@ void EmitContext::DefineInputs() {
Decorate(attr_id, spv::Decoration::NoPerspective);
}
}
input_params[semantic] =
input_params[i] =
GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, num_components, false);
}
break;

View file

@ -22,15 +22,17 @@ void Translator::EmitVectorInterpolation(const GcnInst& inst) {
// VINTRP
void Translator::V_INTERP_P2_F32(const GcnInst& inst) {
const auto& attr = runtime_info.fs_info.inputs.at(inst.control.vintrp.attr);
info.interp_qualifiers[attr.param_index] = vgpr_to_interp[inst.src[0].code];
const IR::Attribute attrib{IR::Attribute::Param0 + attr.param_index};
const u32 attr_index = inst.control.vintrp.attr;
const auto& attr = runtime_info.fs_info.inputs.at(attr_index);
info.interp_qualifiers[attr_index] = vgpr_to_interp[inst.src[0].code];
const IR::Attribute attrib{IR::Attribute::Param0 + attr_index};
SetDst(inst.dst[0], ir.GetAttribute(attrib, inst.control.vintrp.chan));
}
void Translator::V_INTERP_MOV_F32(const GcnInst& inst) {
const auto& attr = runtime_info.fs_info.inputs.at(inst.control.vintrp.attr);
const IR::Attribute attrib{IR::Attribute::Param0 + attr.param_index};
const u32 attr_index = inst.control.vintrp.attr;
const auto& attr = runtime_info.fs_info.inputs.at(attr_index);
const IR::Attribute attrib{IR::Attribute::Param0 + attr_index};
SetDst(inst.dst[0], ir.GetAttribute(attrib, inst.control.vintrp.chan));
}

View file

@ -319,7 +319,8 @@ void Image::CopyImage(const Image& image) {
auto cmdbuf = scheduler->CommandBuffer();
boost::container::small_vector<vk::ImageCopy, 14> image_copy{};
for (u32 m = 0; m < image.info.resources.levels; ++m) {
const u32 num_mips = std::min(image.info.resources.levels, info.resources.levels);
for (u32 m = 0; m < num_mips; ++m) {
const auto mip_w = std::max(image.info.size.width >> m, 1u);
const auto mip_h = std::max(image.info.size.height >> m, 1u);
const auto mip_d = std::max(image.info.size.depth >> m, 1u);

View file

@ -461,9 +461,9 @@ ImageView& TextureCache::FindDepthTarget(BaseDesc& desc) {
const ImageId image_id = FindImage(desc);
Image& image = slot_images[image_id];
image.flags |= ImageFlagBits::GpuModified;
image.flags &= ~ImageFlagBits::Dirty;
image.usage.depth_target = 1u;
image.usage.stencil = image.info.HasStencil();
UpdateImage(image_id);
// Register meta data for this depth buffer
if (!(image.flags & ImageFlagBits::MetaRegistered)) {