mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +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:
@@ -22529,6 +22529,75 @@ TestCase BufferLoadDwordx4ZeroesOnlyOutOfBoundsTail() {
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase BufferLoadsGpuSelectedDescriptors() {
|
||||
using O = ShaderOpcode;
|
||||
constexpr uint64_t GuestBase = 0x0000000110000000ull;
|
||||
struct DescriptorCase {
|
||||
u32 stride, records, mode, soffset;
|
||||
bool swizzle, bound;
|
||||
std::array<u32, 6> expected;
|
||||
};
|
||||
const DescriptorCase cases[] = {
|
||||
{24, 2, 0, 0, false, true, {7, 8, 9, 10, 11, 12}},
|
||||
{12, 2, 0, 0, false, true, {4, 5, 6, 0, 0, 0}},
|
||||
{12, 2, 1, 0, false, true, {4, 5, 6, 7, 8, 9}},
|
||||
{12, 1, 2, 0, false, true, {4, 5, 6, 7, 8, 9}},
|
||||
{12, 0, 2, 0, false, true, {}},
|
||||
// OOB3 checks offset + soffset, independently of index * stride.
|
||||
{12, 20, 3, 4, false, true, {5, 6, 7, 8, 0, 0}},
|
||||
{12, 2, 0, 0, false, false, {}},
|
||||
// RDNA2 swizzling uses four-byte elements; soffset is added afterward.
|
||||
{12, 2, 0, 4, true, true, {3, 11, 19, 0, 0, 0}},
|
||||
{12, 8, 3, 4, true, true, {3, 11, 19, 0, 0, 0}},
|
||||
{12, 4, 3, 4, true, true, {}},
|
||||
};
|
||||
TestCase test;
|
||||
test.name = "BufferLoadsGpuSelectedDescriptors";
|
||||
test.initial.resize(2048);
|
||||
for (u32 i = 0; i < std::size(cases); ++i) {
|
||||
const auto &input = cases[i];
|
||||
const u32 data_offset = 4096 + i * 128;
|
||||
// 120-byte table entries with a descriptor at byte 8, as in PPSA04677.
|
||||
const std::array<u32, 4> descriptor{
|
||||
static_cast<u32>(GuestBase + data_offset),
|
||||
(input.stride << 16u) | (input.swizzle ? 1u << 31u : 0u) | 1u,
|
||||
input.records, (input.bound ? 0x5204u : 0x204u) | (input.mode << 28u)};
|
||||
std::copy(descriptor.begin(), descriptor.end(), test.initial.begin() + 130 + i * 30);
|
||||
for (u32 word = 0; word < 32; ++word) {
|
||||
test.initial[data_offset / 4 + word] = i * 100 + word + 1;
|
||||
}
|
||||
// Reverse the table order through a GPU load and readfirstlane, not host constants.
|
||||
const u32 selected = static_cast<u32>(std::size(cases)) - 1 - i;
|
||||
test.initial[64 + i] = selected;
|
||||
AppendVMovU32(&test.code, 30, (64 + i) * 4);
|
||||
AppendBufferLoadDword(&test.code, 0, 30);
|
||||
test.code.push_back(EncodeVop1(0x02, 20, Vgpr(0)));
|
||||
test.code.push_back(EncodeSop2(0x26, 20, 20, 255)); // s_mul_i32 s20, s20, 120
|
||||
test.code.push_back(120);
|
||||
test.code.push_back(EncodeSmem0(0x0a, 8, 0));
|
||||
test.code.push_back(EncodeSmem1(520, 20));
|
||||
AppendSMovLiteral(&test.code, 22, cases[selected].soffset);
|
||||
AppendVMovU32(&test.code, 21, 1);
|
||||
test.code.push_back(EncodeMubuf0(0x0e, 0, true, false));
|
||||
test.code.push_back(EncodeMubuf1(0, 2, 21, 22));
|
||||
test.code.push_back(EncodeMubuf0(0x0d, 16, true, false));
|
||||
test.code.push_back(EncodeMubuf1(4, 2, 21, 22));
|
||||
for (u32 component = 0; component < 6; ++component) {
|
||||
AppendStoreVgpr(&test.code, component, i * 6 + component);
|
||||
const u32 expected = cases[selected].expected[component];
|
||||
test.expected.push_back(expected == 0 ? 0 : selected * 100 + expected);
|
||||
}
|
||||
}
|
||||
AppendEnd(&test.code);
|
||||
test.bda_mappings = {{GuestBase, 0}};
|
||||
test.opcodes = {O::V_MOV_B32, O::S_MOV_B32, O::BUFFER_LOAD_DWORD,
|
||||
O::V_READFIRSTLANE_B32, O::S_MUL_I32, O::S_BUFFER_LOAD_DWORDX4,
|
||||
O::BUFFER_LOAD_DWORDX4, O::BUFFER_LOAD_DWORDX2,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.required_spirv = {"OpConvertUToPtr", "PhysicalStorageBuffer"};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase BufferStoreDwordx4DropsOnlyOutOfBoundsTail() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -27572,6 +27641,7 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(BufferLoadDwordx3SnapshotsOverlappingAddress);
|
||||
AddCase(BufferLoadDwordx4SnapshotsOverlappingAddress);
|
||||
AddCase(BufferLoadDwordx4ZeroesOnlyOutOfBoundsTail);
|
||||
AddCase(BufferLoadsGpuSelectedDescriptors);
|
||||
AddCase(BufferStoreDwordx4DropsOnlyOutOfBoundsTail);
|
||||
AddCase(BufferLoadFormatXyzwRejectsPartialRecord);
|
||||
AddCase(BufferStoreFormatXyzwDropsPartialRecord);
|
||||
@@ -32298,6 +32368,16 @@ int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (argc == 2 && std::strcmp(argv[1], "--indirect-buffer-only") == 0) {
|
||||
VulkanHarness vulkan;
|
||||
RunCase(&vulkan, BufferLoadsGpuSelectedDescriptors());
|
||||
RunCase(&vulkan, BufferLoadDwordx4SnapshotsOverlappingAddress());
|
||||
RunCase(&vulkan, BufferLoadDwordx4ZeroesOnlyOutOfBoundsTail());
|
||||
RunCase(&vulkan, BufferLoadDwordIdxenUsesDescriptorStride());
|
||||
RunCase(&vulkan, BufferStoreFormatXAddTidUsesLaneIndex());
|
||||
RunCase(&vulkan, FlatVirtualAddressRebasesGuestAllocation());
|
||||
return 0;
|
||||
}
|
||||
if (argc == 2 && std::strcmp(argv[1], "--wave64-only") == 0) {
|
||||
VulkanHarness vulkan;
|
||||
RunCase(&vulkan, Wave32VccMasksPreserveOtherHalf());
|
||||
|
||||
Reference in New Issue
Block a user