mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 10:35:03 +00:00
Simplify inline sampler handling
This commit is contained in:
parent
ce63e18e5e
commit
bfefae55cd
@ -531,8 +531,7 @@ IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::Scal
|
|||||||
// Load first dword of T# and S#. We will use them as the handle that will guide resource
|
// Load first dword of T# and S#. We will use them as the handle that will guide resource
|
||||||
// tracking pass where to read the sharps. This will later also get patched to the SPIRV texture
|
// tracking pass where to read the sharps. This will later also get patched to the SPIRV texture
|
||||||
// binding index.
|
// binding index.
|
||||||
const IR::Value handle =
|
const IR::Value handle = ir.GetScalarReg(tsharp_reg);
|
||||||
ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(sampler_reg));
|
|
||||||
const IR::Value inline_sampler =
|
const IR::Value inline_sampler =
|
||||||
ir.CompositeConstruct(ir.GetScalarReg(sampler_reg), ir.GetScalarReg(sampler_reg + 1),
|
ir.CompositeConstruct(ir.GetScalarReg(sampler_reg), ir.GetScalarReg(sampler_reg + 1),
|
||||||
ir.GetScalarReg(sampler_reg + 2), ir.GetScalarReg(sampler_reg + 3));
|
ir.GetScalarReg(sampler_reg + 2), ir.GetScalarReg(sampler_reg + 3));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
@ -351,8 +351,7 @@ void PatchBufferSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) {
|
void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) {
|
||||||
const auto pred = [](const IR::Inst* inst) -> std::optional<const IR::Inst*> {
|
const auto pred = [](const IR::Inst* inst) -> std::optional<const IR::Inst*> {
|
||||||
const auto opcode = inst->GetOpcode();
|
const auto opcode = inst->GetOpcode();
|
||||||
if (opcode == IR::Opcode::CompositeConstructU32x2 || // IMAGE_SAMPLE (image+sampler)
|
if (opcode == IR::Opcode::ReadConst || // IMAGE_LOAD (image only)
|
||||||
opcode == IR::Opcode::ReadConst || // IMAGE_LOAD (image only)
|
|
||||||
opcode == IR::Opcode::GetUserData) {
|
opcode == IR::Opcode::GetUserData) {
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
@ -360,9 +359,7 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
};
|
};
|
||||||
const auto result = IR::BreadthFirstSearch(&inst, pred);
|
const auto result = IR::BreadthFirstSearch(&inst, pred);
|
||||||
ASSERT_MSG(result, "Unable to find image sharp source");
|
ASSERT_MSG(result, "Unable to find image sharp source");
|
||||||
const IR::Inst* producer = result.value();
|
const IR::Inst* tsharp_handle = result.value();
|
||||||
const bool has_sampler = producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2;
|
|
||||||
const auto tsharp_handle = has_sampler ? producer->Arg(0).InstRecursive() : producer;
|
|
||||||
|
|
||||||
// Read image sharp.
|
// Read image sharp.
|
||||||
const auto tsharp = TrackSharp(tsharp_handle, info);
|
const auto tsharp = TrackSharp(tsharp_handle, info);
|
||||||
@ -428,28 +425,14 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
if (inst.GetOpcode() == IR::Opcode::ImageSampleRaw) {
|
if (inst.GetOpcode() == IR::Opcode::ImageSampleRaw) {
|
||||||
// Read sampler sharp.
|
// Read sampler sharp.
|
||||||
const auto sampler_binding = [&] -> u32 {
|
const auto sampler_binding = [&] -> u32 {
|
||||||
ASSERT(producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2);
|
const auto sampler = inst.Arg(5).InstRecursive();
|
||||||
const IR::Value& handle = producer->Arg(1);
|
ASSERT(sampler && sampler->GetOpcode() == IR::Opcode::CompositeConstructU32x4);
|
||||||
|
const auto handle = sampler->Arg(0);
|
||||||
// Inline sampler resource.
|
// Inline sampler resource.
|
||||||
if (handle.IsImmediate()) {
|
if (handle.IsImmediate()) {
|
||||||
LOG_WARNING(Render_Vulkan, "Inline sampler detected");
|
LOG_DEBUG(Render_Vulkan, "Inline sampler detected");
|
||||||
const auto inline_sampler_arg = inst.Arg(5).InstRecursive();
|
|
||||||
const auto pred = [](const IR::Inst* inst) -> std::optional<const IR::Inst*> {
|
|
||||||
const auto opcode = inst->GetOpcode();
|
|
||||||
if (opcode == IR::Opcode::CompositeConstructU32x4) {
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
};
|
|
||||||
const auto result = IR::BreadthFirstSearch(inline_sampler_arg, pred);
|
|
||||||
ASSERT_MSG(result, "Unable to find immediate sampler");
|
|
||||||
const IR::Inst* inline_producer = result.value();
|
|
||||||
ASSERT(inline_producer &&
|
|
||||||
inline_producer->GetOpcode() == IR::Opcode::CompositeConstructU32x4);
|
|
||||||
|
|
||||||
const auto [s1, s2, s3, s4] =
|
const auto [s1, s2, s3, s4] =
|
||||||
std::tuple{inline_producer->Arg(0), inline_producer->Arg(1),
|
std::tuple{sampler->Arg(0), sampler->Arg(1), sampler->Arg(2), sampler->Arg(3)};
|
||||||
inline_producer->Arg(2), inline_producer->Arg(3)};
|
|
||||||
ASSERT(s1.IsImmediate() && s2.IsImmediate() && s3.IsImmediate() &&
|
ASSERT(s1.IsImmediate() && s2.IsImmediate() && s3.IsImmediate() &&
|
||||||
s4.IsImmediate());
|
s4.IsImmediate());
|
||||||
const auto inline_sampler = AmdGpu::Sampler{
|
const auto inline_sampler = AmdGpu::Sampler{
|
||||||
@ -458,14 +441,15 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
};
|
};
|
||||||
const auto binding = descriptors.Add(SamplerResource{inline_sampler});
|
const auto binding = descriptors.Add(SamplerResource{inline_sampler});
|
||||||
return binding;
|
return binding;
|
||||||
|
} else {
|
||||||
|
// Normal sampler resource.
|
||||||
|
const auto ssharp_handle = handle.InstRecursive();
|
||||||
|
const auto& [ssharp_ud, disable_aniso] = TryDisableAnisoLod0(ssharp_handle);
|
||||||
|
const auto ssharp = TrackSharp(ssharp_ud, info);
|
||||||
|
const auto binding =
|
||||||
|
descriptors.Add(SamplerResource{ssharp, image_binding, disable_aniso});
|
||||||
|
return binding;
|
||||||
}
|
}
|
||||||
// Normal sampler resource.
|
|
||||||
const auto ssharp_handle = handle.InstRecursive();
|
|
||||||
const auto& [ssharp_ud, disable_aniso] = TryDisableAnisoLod0(ssharp_handle);
|
|
||||||
const auto ssharp = TrackSharp(ssharp_ud, info);
|
|
||||||
const auto binding =
|
|
||||||
descriptors.Add(SamplerResource{ssharp, image_binding, disable_aniso});
|
|
||||||
return binding;
|
|
||||||
}();
|
}();
|
||||||
// Patch image and sampler handle.
|
// Patch image and sampler handle.
|
||||||
inst.SetArg(0, ir.Imm32(image_binding | sampler_binding << 16));
|
inst.SetArg(0, ir.Imm32(image_binding | sampler_binding << 16));
|
||||||
|
Loading…
Reference in New Issue
Block a user