1
0
Fork 0
forked from suyu/suyu

shader/other: Implement MEMBAR.CTS

This silences an assertion we were hitting and uses workgroup memory
barriers when the game requests it.
This commit is contained in:
ReinUsesLisp 2020-05-15 02:52:35 -03:00
parent 508242c267
commit 32e6727dae
4 changed files with 27 additions and 9 deletions

View file

@ -2344,7 +2344,12 @@ private:
return {}; return {};
} }
Expression MemoryBarrierGL(Operation) { Expression MemoryBarrierGroup(Operation) {
code.AddLine("groupMemoryBarrier();");
return {};
}
Expression MemoryBarrierGlobal(Operation) {
code.AddLine("memoryBarrier();"); code.AddLine("memoryBarrier();");
return {}; return {};
} }
@ -2591,7 +2596,8 @@ private:
&GLSLDecompiler::ShuffleIndexed, &GLSLDecompiler::ShuffleIndexed,
&GLSLDecompiler::Barrier, &GLSLDecompiler::Barrier,
&GLSLDecompiler::MemoryBarrierGL, &GLSLDecompiler::MemoryBarrierGroup,
&GLSLDecompiler::MemoryBarrierGlobal,
}; };
static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount));

View file

@ -2215,8 +2215,8 @@ private:
return {}; return {};
} }
Expression MemoryBarrierGL(Operation) { template <spv::Scope scope>
const auto scope = spv::Scope::Device; Expression MemoryBarrier(Operation) {
const auto semantics = const auto semantics =
spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory |
spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::WorkgroupMemory |
@ -2681,7 +2681,8 @@ private:
&SPIRVDecompiler::ShuffleIndexed, &SPIRVDecompiler::ShuffleIndexed,
&SPIRVDecompiler::Barrier, &SPIRVDecompiler::Barrier,
&SPIRVDecompiler::MemoryBarrierGL, &SPIRVDecompiler::MemoryBarrier<spv::Scope::Workgroup>,
&SPIRVDecompiler::MemoryBarrier<spv::Scope::Device>,
}; };
static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount));

View file

@ -299,9 +299,19 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
break; break;
} }
case OpCode::Id::MEMBAR: { case OpCode::Id::MEMBAR: {
UNIMPLEMENTED_IF(instr.membar.type != Tegra::Shader::MembarType::GL);
UNIMPLEMENTED_IF(instr.membar.unknown != Tegra::Shader::MembarUnknown::Default); UNIMPLEMENTED_IF(instr.membar.unknown != Tegra::Shader::MembarUnknown::Default);
bb.push_back(Operation(OperationCode::MemoryBarrierGL)); const OperationCode type = [instr] {
switch (instr.membar.type) {
case Tegra::Shader::MembarType::CTA:
return OperationCode::MemoryBarrierGroup;
case Tegra::Shader::MembarType::GL:
return OperationCode::MemoryBarrierGlobal;
default:
UNIMPLEMENTED_MSG("MEMBAR type={}", static_cast<int>(instr.membar.type.Value()));
return OperationCode::MemoryBarrierGlobal;
}
}();
bb.push_back(Operation(type));
break; break;
} }
case OpCode::Id::DEPBAR: { case OpCode::Id::DEPBAR: {

View file

@ -233,8 +233,9 @@ enum class OperationCode {
ThreadLtMask, /// () -> uint ThreadLtMask, /// () -> uint
ShuffleIndexed, /// (uint value, uint index) -> uint ShuffleIndexed, /// (uint value, uint index) -> uint
Barrier, /// () -> void Barrier, /// () -> void
MemoryBarrierGL, /// () -> void MemoryBarrierGroup, /// () -> void
MemoryBarrierGlobal, /// () -> void
Amount, Amount,
}; };