shader_recompiler: Fix cube sampling coordinates. (#2266)

This commit is contained in:
squidbus 2025-01-29 18:14:36 -08:00 committed by GitHub
parent 4bb578f9fb
commit 929e15260d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 6 deletions

View file

@ -583,6 +583,18 @@ void PatchTextureBufferArgs(IR::Block& block, IR::Inst& inst, Info& info) {
} }
} }
IR::Value FixCubeCoords(IR::IREmitter& ir, const AmdGpu::Image& image, const IR::Value& x,
const IR::Value& y, const IR::Value& face) {
if (!image.IsCube()) {
return ir.CompositeConstruct(x, y, face);
}
// AMD cube math results in coordinates in the range [1.0, 2.0]. We need
// to convert this to the range [0.0, 1.0] to get correct results.
const auto fixed_x = ir.FPSub(IR::F32{x}, ir.Imm32(1.f));
const auto fixed_y = ir.FPSub(IR::F32{y}, ir.Imm32(1.f));
return ir.CompositeConstruct(fixed_x, fixed_y, face);
}
void PatchImageSampleArgs(IR::Block& block, IR::Inst& inst, Info& info, void PatchImageSampleArgs(IR::Block& block, IR::Inst& inst, Info& info,
const ImageResource& image_res, const AmdGpu::Image& image) { const ImageResource& image_res, const AmdGpu::Image& image) {
const auto handle = inst.Arg(0); const auto handle = inst.Arg(0);
@ -643,8 +655,8 @@ void PatchImageSampleArgs(IR::Block& block, IR::Inst& inst, Info& info,
case AmdGpu::ImageType::Color1DArray: case AmdGpu::ImageType::Color1DArray:
return read(0); return read(0);
case AmdGpu::ImageType::Color2D: case AmdGpu::ImageType::Color2D:
case AmdGpu::ImageType::Color2DArray:
case AmdGpu::ImageType::Color2DMsaa: case AmdGpu::ImageType::Color2DMsaa:
case AmdGpu::ImageType::Color2DArray:
return ir.CompositeConstruct(read(0), read(8)); return ir.CompositeConstruct(read(0), read(8));
case AmdGpu::ImageType::Color3D: case AmdGpu::ImageType::Color3D:
return ir.CompositeConstruct(read(0), read(8), read(16)); return ir.CompositeConstruct(read(0), read(8), read(16));
@ -665,8 +677,8 @@ void PatchImageSampleArgs(IR::Block& block, IR::Inst& inst, Info& info,
addr_reg = addr_reg + 2; addr_reg = addr_reg + 2;
return {get_addr_reg(addr_reg - 2), get_addr_reg(addr_reg - 1)}; return {get_addr_reg(addr_reg - 2), get_addr_reg(addr_reg - 1)};
case AmdGpu::ImageType::Color2D: case AmdGpu::ImageType::Color2D:
case AmdGpu::ImageType::Color2DArray:
case AmdGpu::ImageType::Color2DMsaa: case AmdGpu::ImageType::Color2DMsaa:
case AmdGpu::ImageType::Color2DArray:
// (du/dx, dv/dx), (du/dy, dv/dy) // (du/dx, dv/dx), (du/dy, dv/dy)
addr_reg = addr_reg + 4; addr_reg = addr_reg + 4;
return {ir.CompositeConstruct(get_addr_reg(addr_reg - 4), get_addr_reg(addr_reg - 3)), return {ir.CompositeConstruct(get_addr_reg(addr_reg - 4), get_addr_reg(addr_reg - 3)),
@ -711,12 +723,13 @@ void PatchImageSampleArgs(IR::Block& block, IR::Inst& inst, Info& info,
case AmdGpu::ImageType::Color2D: // x, y case AmdGpu::ImageType::Color2D: // x, y
addr_reg = addr_reg + 2; addr_reg = addr_reg + 2;
return ir.CompositeConstruct(get_coord(addr_reg - 2, 0), get_coord(addr_reg - 1, 1)); return ir.CompositeConstruct(get_coord(addr_reg - 2, 0), get_coord(addr_reg - 1, 1));
case AmdGpu::ImageType::Color2DArray: // x, y, slice
[[fallthrough]];
case AmdGpu::ImageType::Color2DMsaa: // x, y, frag case AmdGpu::ImageType::Color2DMsaa: // x, y, frag
[[fallthrough]];
case AmdGpu::ImageType::Color2DArray: // x, y, slice
addr_reg = addr_reg + 3; addr_reg = addr_reg + 3;
return ir.CompositeConstruct(get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1), // Note we can use FixCubeCoords with fallthrough cases since it checks for image type.
get_addr_reg(addr_reg - 1)); return FixCubeCoords(ir, image, get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1),
get_addr_reg(addr_reg - 1));
case AmdGpu::ImageType::Color3D: // x, y, z case AmdGpu::ImageType::Color3D: // x, y, z
addr_reg = addr_reg + 3; addr_reg = addr_reg + 3;
return ir.CompositeConstruct(get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1), return ir.CompositeConstruct(get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1),

View file

@ -47,6 +47,7 @@ struct ImageSpecialization {
AmdGpu::ImageType type = AmdGpu::ImageType::Color2D; AmdGpu::ImageType type = AmdGpu::ImageType::Color2D;
bool is_integer = false; bool is_integer = false;
bool is_storage = false; bool is_storage = false;
bool is_cube = false;
AmdGpu::CompMapping dst_select{}; AmdGpu::CompMapping dst_select{};
AmdGpu::NumberConversion num_conversion{}; AmdGpu::NumberConversion num_conversion{};
@ -127,6 +128,7 @@ struct StageSpecialization {
spec.type = sharp.GetViewType(desc.is_array); spec.type = sharp.GetViewType(desc.is_array);
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
spec.is_storage = desc.is_written; spec.is_storage = desc.is_written;
spec.is_cube = sharp.IsCube();
if (spec.is_storage) { if (spec.is_storage) {
spec.dst_select = sharp.DstSelect(); spec.dst_select = sharp.DstSelect();
} }