mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: unpack buffer offsets from one load per packed word
This commit is contained in:
@@ -104,13 +104,13 @@ Prospero::BufferFormat StorageBufferFormat(const EmitterState& state, const IR::
|
|||||||
|
|
||||||
void EmitMemoryOffsets(EmitterState& state) {
|
void EmitMemoryOffsets(EmitterState& state) {
|
||||||
const auto count = state.program.bindings.descriptor_counts[static_cast<size_t>(IR::DescriptorBindingKind::Buffers)];
|
const auto count = state.program.bindings.descriptor_counts[static_cast<size_t>(IR::DescriptorBindingKind::Buffers)];
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i += 4u) {
|
||||||
const auto word =
|
const auto word =
|
||||||
EmitShaderDataDwordLoad(state, state.program.bindings.memory_offset_dword + i / 4u);
|
EmitShaderDataDwordLoad(state, state.program.bindings.memory_offset_dword + i / 4u);
|
||||||
const auto shift = ConstantU32(state, (i % 4u) * 8u);
|
for (uint32_t lane = 0; lane < std::min(4u, count - i); ++lane) {
|
||||||
state.memory_byte_offsets[i] = EmitBinaryU32(
|
state.memory_byte_offsets[i + lane] = EmitNative<spv::OpBitFieldUExtract, IR::Type::U32>(
|
||||||
state, spv::OpBitwiseAnd, EmitBinaryU32(state, spv::OpShiftRightLogical, word, shift),
|
state, word, ConstantU32(state, lane * 8u), ConstantU32(state, 8u));
|
||||||
ConstantU32(state, 0xffu));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28545,32 +28545,29 @@ TestCase BufferStoreDwordAppliesHostOffset() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase BufferOffsetsUsePackedLaneAndStorageFallback() {
|
TestCase BufferOffsetsUsePackedWords(bool storage) {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
constexpr std::array offsets{0u, 12u, 20u, 28u, 36u};
|
||||||
std::vector<u32> code;
|
|
||||||
for (u32 base : {0u, 4u}) {
|
|
||||||
AppendSMovLiteral(&code, base, 0x1000u + base * 0x1000u);
|
|
||||||
AppendSMovLiteral(&code, base + 1u, 4u << 16u);
|
|
||||||
AppendSMovLiteral(&code, base + 2u, 1u);
|
|
||||||
AppendSMovLiteral(&code, base + 3u, 1u << 24u);
|
|
||||||
}
|
|
||||||
AppendVMovLiteral(&code, 0, 0x12345678u);
|
|
||||||
code.push_back(EncodeMubuf0(0x1cu, 0, false, false));
|
|
||||||
code.push_back(EncodeMubuf1(0, 0, 20));
|
|
||||||
AppendVMovLiteral(&code, 1, 0xabcdef01u);
|
|
||||||
code.push_back(EncodeMubuf0(0x1cu, 0, false, false));
|
|
||||||
code.push_back(EncodeMubuf1(1, 1, 20));
|
|
||||||
AppendEnd(&code);
|
|
||||||
|
|
||||||
TestCase test;
|
TestCase test;
|
||||||
test.name = "BufferOffsetsUsePackedLaneAndStorageFallback";
|
test.name = storage ? "BufferOffsetsPackedWordsStorage" : "BufferOffsetsPackedWordsPush";
|
||||||
test.code = std::move(code);
|
test.initial.resize(10);
|
||||||
test.initial = {0, 0, 0, 0};
|
test.expected = test.initial;
|
||||||
test.expected = {0x12345678u, 0, 0, 0xabcdef01u};
|
for (u32 i = 0; i < offsets.size(); ++i) {
|
||||||
|
const auto base = i * 4u;
|
||||||
|
AppendSMovLiteral(&test.code, base, 0x1000u + base * 0x1000u);
|
||||||
|
AppendSMovLiteral(&test.code, base + 1u, 4u << 16u);
|
||||||
|
AppendSMovLiteral(&test.code, base + 2u, 1u);
|
||||||
|
AppendSMovLiteral(&test.code, base + 3u, 1u << 24u);
|
||||||
|
const auto value = 0x12345678u + i;
|
||||||
|
AppendVMovLiteral(&test.code, i, value);
|
||||||
|
test.code.push_back(EncodeMubuf0(0x1cu, 0, false, false));
|
||||||
|
test.code.push_back(EncodeMubuf1(i, i, 20));
|
||||||
|
test.expected[offsets[i] / 4u] = value;
|
||||||
|
}
|
||||||
|
AppendEnd(&test.code);
|
||||||
test.storage_buffer_range_bytes = 4;
|
test.storage_buffer_range_bytes = 4;
|
||||||
test.storage_buffer_offsets = {0, 12};
|
test.storage_buffer_offsets.assign(offsets.begin(), offsets.end());
|
||||||
test.expand_shader_data_storage = true;
|
test.expand_shader_data_storage = storage;
|
||||||
test.opcodes = {O::S_MOV_B32, O::V_MOV_B32, O::BUFFER_STORE_DWORD,
|
test.opcodes = {O::S_MOV_B32, O::V_MOV_B32, O::BUFFER_STORE_DWORD,
|
||||||
O::S_ENDPGM};
|
O::S_ENDPGM};
|
||||||
return test;
|
return test;
|
||||||
@@ -36576,7 +36573,8 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(BufferLoadDwordIdxenUsesDescriptorStride);
|
AddCase(BufferLoadDwordIdxenUsesDescriptorStride);
|
||||||
AddCase(BufferStoreDwordIdxenUsesDescriptorStride);
|
AddCase(BufferStoreDwordIdxenUsesDescriptorStride);
|
||||||
AddCase(BufferStoreDwordAppliesHostOffset);
|
AddCase(BufferStoreDwordAppliesHostOffset);
|
||||||
AddCase(BufferOffsetsUsePackedLaneAndStorageFallback);
|
cases.push_back(BufferOffsetsUsePackedWords(false));
|
||||||
|
cases.push_back(BufferOffsetsUsePackedWords(true));
|
||||||
AddCase(BufferLoadVariants);
|
AddCase(BufferLoadVariants);
|
||||||
for (const u32 component : {4u, 2u, 0u}) {
|
for (const u32 component : {4u, 2u, 0u}) {
|
||||||
cases.push_back(BufferSubwordLoadsAtHostOffset(2, component, false));
|
cases.push_back(BufferSubwordLoadsAtHostOffset(2, component, false));
|
||||||
@@ -42370,7 +42368,8 @@ int main(int argc, char **argv) {
|
|||||||
if (argc == 2 && std::strcmp(argv[1], "--shader-data-storage-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--shader-data-storage-only") == 0) {
|
||||||
CheckResourcePlanHandoff();
|
CheckResourcePlanHandoff();
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, BufferOffsetsUsePackedLaneAndStorageFallback());
|
RunCase(&vulkan, BufferOffsetsUsePackedWords(false));
|
||||||
|
RunCase(&vulkan, BufferOffsetsUsePackedWords(true));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--buffer-publication-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--buffer-publication-only") == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user