recompiler: added pattern check for s# anisotropy modification
This commit is contained in:
parent
1de2ea960c
commit
9633fea55a
|
@ -159,6 +159,50 @@ private:
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
std::pair<const IR::Inst*, bool> TryDisableAnisoLod0(const IR::Inst* inst) {
|
||||
std::pair not_found{inst, false};
|
||||
|
||||
// Assuming S# is in UD s[12:15] and T# is in s[4:11]
|
||||
// The next pattern:
|
||||
// s_bfe_u32 s0, s7, $0x0008000c
|
||||
// s_and_b32 s1, s12, $0xfffff1ff
|
||||
// s_cmp_eq_u32 s0, 0
|
||||
// s_cselect_b32 s0, s1, s12
|
||||
// is used to disable anisotropy in the sampler if the sampled texture doesn't have mips
|
||||
|
||||
if (inst->GetOpcode() != IR::Opcode::SelectU32) {
|
||||
return not_found;
|
||||
}
|
||||
|
||||
// Select should be based on zero check
|
||||
const auto* prod0 = inst->Arg(0).InstRecursive();
|
||||
if (prod0->GetOpcode() != IR::Opcode::IEqual ||
|
||||
!(prod0->Arg(1).IsImmediate() && prod0->Arg(1).U32() == 0u)) {
|
||||
return not_found;
|
||||
}
|
||||
|
||||
// The bits range is for lods
|
||||
const auto* prod0_arg0 = prod0->Arg(0).InstRecursive();
|
||||
if (prod0_arg0->GetOpcode() != IR::Opcode::BitFieldUExtract ||
|
||||
prod0_arg0->Arg(1).InstRecursive()->Arg(0).U32() != 0x0008000cu) {
|
||||
return not_found;
|
||||
}
|
||||
|
||||
// Make sure mask is masking out anisotropy
|
||||
const auto* prod1 = inst->Arg(1).InstRecursive();
|
||||
if (prod1->GetOpcode() != IR::Opcode::BitwiseAnd32 || prod1->Arg(1).U32() != 0xfffff1ff) {
|
||||
return not_found;
|
||||
}
|
||||
|
||||
// We're working on the first dword of s#
|
||||
const auto* prod2 = inst->Arg(2).InstRecursive();
|
||||
if (prod2->GetOpcode() != IR::Opcode::GetUserData) {
|
||||
return not_found;
|
||||
}
|
||||
|
||||
return {prod2, true};
|
||||
}
|
||||
|
||||
SharpLocation TrackSharp(const IR::Inst* inst) {
|
||||
while (inst->GetOpcode() == IR::Opcode::Phi) {
|
||||
inst = inst->Arg(0).InstRecursive();
|
||||
|
@ -294,10 +338,13 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
|
||||
// Read sampler sharp. This doesn't exist for IMAGE_LOAD/IMAGE_STORE instructions
|
||||
if (ssharp_handle) {
|
||||
const auto ssharp = TrackSharp(ssharp_handle);
|
||||
const auto& [ssharp_ud, disable_aniso] = TryDisableAnisoLod0(ssharp_handle);
|
||||
const auto ssharp = TrackSharp(ssharp_ud);
|
||||
const u32 sampler_binding = descriptors.Add(SamplerResource{
|
||||
.sgpr_base = ssharp.sgpr_base,
|
||||
.dword_offset = ssharp.dword_offset,
|
||||
.associated_image = image_binding,
|
||||
.disable_aniso = disable_aniso,
|
||||
});
|
||||
image_binding |= (sampler_binding << 16);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ using ImageResourceList = boost::container::static_vector<ImageResource, 16>;
|
|||
struct SamplerResource {
|
||||
u32 sgpr_base;
|
||||
u32 dword_offset;
|
||||
u32 associated_image : 4;
|
||||
u32 disable_aniso : 1;
|
||||
};
|
||||
using SamplerResourceList = boost::container::static_vector<SamplerResource, 16>;
|
||||
|
||||
|
|
|
@ -348,9 +348,10 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer&
|
|||
}
|
||||
}
|
||||
|
||||
boost::container::static_vector<AmdGpu::Image, 16> tsharps;
|
||||
for (const auto& image_desc : stage.images) {
|
||||
const auto tsharp =
|
||||
stage.ReadUd<AmdGpu::Image>(image_desc.sgpr_base, image_desc.dword_offset);
|
||||
const auto& tsharp = tsharps.emplace_back(
|
||||
stage.ReadUd<AmdGpu::Image>(image_desc.sgpr_base, image_desc.dword_offset));
|
||||
const auto& image_view = texture_cache.FindImageView(tsharp, image_desc.is_storage);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout);
|
||||
|
@ -369,8 +370,13 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer&
|
|||
}
|
||||
}
|
||||
for (const auto& sampler : stage.samplers) {
|
||||
const auto ssharp =
|
||||
stage.ReadUd<AmdGpu::Sampler>(sampler.sgpr_base, sampler.dword_offset);
|
||||
auto ssharp = stage.ReadUd<AmdGpu::Sampler>(sampler.sgpr_base, sampler.dword_offset);
|
||||
if (sampler.disable_aniso) {
|
||||
const auto& tsharp = tsharps[sampler.associated_image];
|
||||
if (tsharp.base_level == 0 && tsharp.last_level == 0) {
|
||||
ssharp.max_aniso.Assign(AmdGpu::AnisoRatio::One);
|
||||
}
|
||||
}
|
||||
const auto vk_sampler = texture_cache.GetSampler(ssharp);
|
||||
image_infos.emplace_back(vk_sampler, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
||||
set_writes.push_back({
|
||||
|
|
Loading…
Reference in New Issue