mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +02:00
Resolve GPU-selected raw buffer descriptors through shared RDNA2 addressing
Co-authored-by: Bipin <87369440+bipinkrish@users.noreply.github.com>
This commit is contained in:
@@ -447,13 +447,20 @@ void ValidateProgram(const Program& program, bool require_ssa) {
|
||||
ValueOpcodeName(inst.GetOpcode())));
|
||||
}
|
||||
const auto& memory = program.memory_info[memory_index];
|
||||
if (memory.kind != ResourceKind::Buffer &&
|
||||
memory.kind != ResourceKind::ScalarBuffer) {
|
||||
const bool vector_buffer = memory.kind == ResourceKind::Buffer ||
|
||||
memory.kind == ResourceKind::IndirectBuffer;
|
||||
if (!vector_buffer && memory.kind != ResourceKind::ScalarBuffer) {
|
||||
return Fail(fmt::format("{} has a non-buffer resource kind",
|
||||
ValueOpcodeName(inst.GetOpcode())));
|
||||
}
|
||||
if (memory.kind == ResourceKind::IndirectBuffer &&
|
||||
(memory.formatted || memory.typed ||
|
||||
(inst.GetOpcode() != ValueOpcode::LoadBufferU32x2 &&
|
||||
inst.GetOpcode() != ValueOpcode::LoadBufferU32x4))) {
|
||||
return Fail("indirect buffer requires a raw DWORD x2/x4 load");
|
||||
}
|
||||
if (buffer_components > 1u &&
|
||||
(memory.kind != ResourceKind::Buffer || memory.data_bits != 32u ||
|
||||
(!vector_buffer || memory.data_bits != 32u ||
|
||||
memory.data_dwords != buffer_components || memory.component_index != 0u)) {
|
||||
return Fail(fmt::format("{} has inconsistent native-wide metadata",
|
||||
ValueOpcodeName(inst.GetOpcode())));
|
||||
|
||||
@@ -27,6 +27,7 @@ enum class ResourceKind {
|
||||
ScalarBuffer,
|
||||
ScalarAddress,
|
||||
Buffer,
|
||||
IndirectBuffer,
|
||||
Flat,
|
||||
Global,
|
||||
Scratch,
|
||||
|
||||
@@ -526,7 +526,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void GetHandle(Value value, ValueOpcode expected, uint32_t width, uint32_t pc, Inst*& handle,
|
||||
bool GetHandle(Value value, ValueOpcode expected, uint32_t width, uint32_t pc, Inst*& handle,
|
||||
uint32_t& source, bool sampler = false, bool sample_adjust = false) {
|
||||
handle = value.Resolve().TryInstruction();
|
||||
if (handle == nullptr || handle->GetOpcode() != expected) {
|
||||
@@ -546,10 +546,16 @@ private:
|
||||
bad_dword = 0;
|
||||
}
|
||||
if (!ValidateSource(descriptor, bad_dword)) {
|
||||
if (expected == ValueOpcode::GetBufferResource &&
|
||||
std::all_of(descriptor.dwords.begin(), descriptor.dwords.begin() + width,
|
||||
[](Value word) { return word.Resolve().GetType() == Type::U32; })) {
|
||||
return false;
|
||||
}
|
||||
Fail(pc, fmt::format("{} dword {} is not a valid runtime value",
|
||||
ValueOpcodeName(expected), bad_dword));
|
||||
}
|
||||
source = InternSource(descriptor);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ValidateAddressHandle(Value value, uint32_t pc) const {
|
||||
@@ -720,7 +726,18 @@ private:
|
||||
uint32_t resource = 0;
|
||||
|
||||
if (buffer != BufferAccess::None) {
|
||||
GetHandle(inst.Arg(0), ValueOpcode::GetBufferResource, 4, flags.pc, handle, source);
|
||||
if (!GetHandle(inst.Arg(0), ValueOpcode::GetBufferResource, 4, flags.pc, handle,
|
||||
source)) {
|
||||
if (memory.kind != ResourceKind::Buffer || memory.formatted || memory.typed ||
|
||||
(op != ValueOpcode::LoadBufferU32x2 && op != ValueOpcode::LoadBufferU32x4)) {
|
||||
Fail(flags.pc,
|
||||
"buffer descriptor is not a valid runtime value; GPU-selected access "
|
||||
"requires a raw DWORD x2/x4 load");
|
||||
}
|
||||
m_program.memory_info[flags.index].kind = ResourceKind::IndirectBuffer;
|
||||
m_info.uses_dma = true;
|
||||
return;
|
||||
}
|
||||
resource = AddBuffer(source, memory, op, flags.pc);
|
||||
if (resource == UINT32_MAX) {
|
||||
Fail(flags.pc, "buffer resource limit exceeded");
|
||||
|
||||
Reference in New Issue
Block a user