mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 07:52:39 +00:00
shader: acquire stored buffers and images at S_BARRIER
This commit is contained in:
1 parent
26ca609236
commit
ceb154d9e4
2 files changed
+35
-3
No files matched your search
@@ -712,9 +712,16 @@ void EmitBarrier(EmitterState& state) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto memory_scope = tessellation ? spv::ScopeInvocation : spv::ScopeWorkgroup;
|
const auto memory_scope = tessellation ? spv::ScopeInvocation : spv::ScopeWorkgroup;
|
||||||
const auto memory = state.lds_storage_class == spv::StorageClassStorageBuffer
|
auto memory = state.lds_storage_class == spv::StorageClassStorageBuffer
|
||||||
? spv::MemorySemanticsUniformMemoryMask
|
? spv::MemorySemanticsUniformMemoryMask
|
||||||
: spv::MemorySemanticsWorkgroupMemoryMask;
|
: spv::MemorySemanticsWorkgroupMemoryMask;
|
||||||
|
// Shaders read other waves' buffer and image stores with plain loads right after S_BARRIER.
|
||||||
|
const auto written = [](const auto& resource) { return resource.written; };
|
||||||
|
if (std::ranges::any_of(state.program.info.buffers, written) ||
|
||||||
|
std::ranges::any_of(state.program.info.images, written)) {
|
||||||
|
memory = memory | spv::MemorySemanticsUniformMemoryMask |
|
||||||
|
spv::MemorySemanticsImageMemoryMask;
|
||||||
|
}
|
||||||
const auto semantics = tessellation ? spv::MemorySemanticsMaskNone
|
const auto semantics = tessellation ? spv::MemorySemanticsMaskNone
|
||||||
: spv::MemorySemanticsAcquireReleaseMask | memory;
|
: spv::MemorySemanticsAcquireReleaseMask | memory;
|
||||||
state.builder.AddFunction(spv::OpControlBarrier, ConstantU32(state, spv::ScopeWorkgroup),
|
state.builder.AddFunction(spv::OpControlBarrier, ConstantU32(state, spv::ScopeWorkgroup),
|
||||||
|
|||||||
@@ -1847,6 +1847,31 @@ void TestShaderStageBarriers() {
|
|||||||
"SPIR-V barrier does not use workgroup acquire-release memory semantics");
|
"SPIR-V barrier does not use workgroup acquire-release memory semantics");
|
||||||
CheckSpirvBinaryValidates(result.spirv);
|
CheckSpirvBinaryValidates(result.spirv);
|
||||||
|
|
||||||
|
// s_barrier also acquires other waves' buffer and image stores.
|
||||||
|
const auto acquires = [](std::span<const uint32_t> code,
|
||||||
|
const ShaderRecompiler::CompileOptions &options) {
|
||||||
|
const auto result = RecompileForTest(code, options);
|
||||||
|
CheckSpirvBinaryValidates(result.spirv);
|
||||||
|
// AcquireRelease | UniformMemory | WorkgroupMemory | ImageMemory.
|
||||||
|
return DisassembleSpirvBinary(result.spirv).find(
|
||||||
|
"OpControlBarrier %uint_2 %uint_2 %uint_2376") != std::string::npos;
|
||||||
|
};
|
||||||
|
const uint32_t buffer_store[] = {
|
||||||
|
EncodeMubuf0(0x1c, 0, false), EncodeMubuf1(1, 0, 0), // buffer_store_dword
|
||||||
|
EncodeSopp(0x0a), EncodeSopp(0x01),
|
||||||
|
};
|
||||||
|
Check(acquires(buffer_store, MakeCompileOptions(ShaderType::Compute)),
|
||||||
|
"s_barrier after buffer stores does not acquire buffer memory");
|
||||||
|
const uint32_t image_store[] = {
|
||||||
|
EncodeMimg0(0x08, 0xf), EncodeMimg1(20, 0, 0, 4), // image_store
|
||||||
|
EncodeSopp(0x0a), EncodeSopp(0x01),
|
||||||
|
};
|
||||||
|
const auto image_user_data = ImageTestUserData();
|
||||||
|
auto image_options = MakeCompileOptions(ShaderType::Compute);
|
||||||
|
image_options.user_data = image_user_data;
|
||||||
|
Check(acquires(image_store, image_options),
|
||||||
|
"s_barrier after image stores does not acquire image memory");
|
||||||
|
|
||||||
const auto vertex_result =
|
const auto vertex_result =
|
||||||
RecompileForTest(shader, MakeCompileOptions(ShaderType::Vertex));
|
RecompileForTest(shader, MakeCompileOptions(ShaderType::Vertex));
|
||||||
CheckSpirvBinaryValidates(vertex_result.spirv);
|
CheckSpirvBinaryValidates(vertex_result.spirv);
|
||||||
|
|||||||
Reference in new issue
Block a user