From 425a254fa24d7179124b4544ffeb2b1fe4fa99dc Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 9 Dec 2019 21:46:12 -0300 Subject: [PATCH] shader: Implement MEMBAR.GL Implement using memoryBarrier in GLSL and OpMemoryBarrier on SPIR-V. --- externals/sirit | 2 +- src/video_core/engines/shader_bytecode.h | 18 +++++++++++++++++- .../renderer_opengl/gl_shader_decompiler.cpp | 7 +++++++ .../renderer_vulkan/vk_shader_decompiler.cpp | 14 ++++++++++++++ src/video_core/shader/decode/other.cpp | 6 ++++++ src/video_core/shader/node.h | 2 ++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/externals/sirit b/externals/sirit index e1a6729df7..12f40a8032 160000 --- a/externals/sirit +++ b/externals/sirit @@ -1 +1 @@ -Subproject commit e1a6729df7f11e33f6dc0939b18995a57c8bf3d8 +Subproject commit 12f40a80324d7c154f19f25c448a5ce27d38cd18 diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 7703a76a36..290d929df1 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -384,6 +384,15 @@ enum class IsberdMode : u64 { enum class IsberdShift : u64 { None = 0, U16 = 1, B32 = 2 }; +enum class MembarType : u64 { + CTA = 0, + GL = 1, + SYS = 2, + VC = 3, +}; + +enum class MembarUnknown : u64 { Default = 0, IVALLD = 1, IVALLT = 2, IVALLTD = 3 }; + enum class HalfType : u64 { H0_H1 = 0, F32 = 1, @@ -1545,6 +1554,11 @@ union Instruction { BitField<47, 2, IsberdShift> shift; } isberd; + union { + BitField<8, 2, MembarType> type; + BitField<0, 2, MembarUnknown> unknown; + } membar; + union { BitField<48, 1, u64> signed_a; BitField<38, 1, u64> is_byte_chunk_a; @@ -1669,6 +1683,7 @@ public: IPA, OUT_R, // Emit vertex/primitive ISBERD, + MEMBAR, VMAD, VSETP, FFMA_IMM, // Fused Multiply and Add @@ -1930,7 +1945,7 @@ private: INST("111000100100----", Id::BRA, Type::Flow, "BRA"), INST("111000100101----", Id::BRX, Type::Flow, "BRX"), INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"), - INST("111000110100---", Id::BRK, Type::Flow, "BRK"), + INST("111000110100----", Id::BRK, Type::Flow, "BRK"), INST("111000110000----", Id::EXIT, Type::Flow, "EXIT"), INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), INST("0101000011011---", Id::VOTE, Type::Warp, "VOTE"), @@ -1969,6 +1984,7 @@ private: INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), INST("1111101111100---", Id::OUT_R, Type::Trivial, "OUT_R"), INST("1110111111010---", Id::ISBERD, Type::Trivial, "ISBERD"), + INST("1110111110011---", Id::MEMBAR, Type::Trivial, "MEMBAR"), INST("01011111--------", Id::VMAD, Type::Video, "VMAD"), INST("0101000011110---", Id::VSETP, Type::Video, "VSETP"), INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 9700c2ebef..fa7049bbe8 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1992,6 +1992,11 @@ private: return {fmt::format("readInvocationARB({}, {})", value, index), Type::Float}; } + Expression MemoryBarrierGL(Operation) { + code.AddLine("memoryBarrier();"); + return {}; + } + struct Func final { Func() = delete; ~Func() = delete; @@ -2173,6 +2178,8 @@ private: &GLSLDecompiler::ThreadId, &GLSLDecompiler::ShuffleIndexed, + + &GLSLDecompiler::MemoryBarrierGL, }; static_assert(operation_decompilers.size() == static_cast(OperationCode::Amount)); diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 8ad89b58a4..6227bc70be 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -1971,6 +1971,18 @@ private: return {OpSubgroupReadInvocationKHR(t_float, value, index), Type::Float}; } + Expression MemoryBarrierGL(Operation) { + const auto scope = spv::Scope::Device; + const auto semantics = + spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::WorkgroupMemory | + spv::MemorySemanticsMask::AtomicCounterMemory | spv::MemorySemanticsMask::ImageMemory; + + OpMemoryBarrier(Constant(t_uint, static_cast(scope)), + Constant(t_uint, static_cast(semantics))); + return {}; + } + Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, std::string name) { const Id id = OpVariable(type, storage); Decorate(id, spv::Decoration::BuiltIn, static_cast(builtin)); @@ -2374,6 +2386,8 @@ private: &SPIRVDecompiler::ThreadId, &SPIRVDecompiler::ShuffleIndexed, + + &SPIRVDecompiler::MemoryBarrierGL, }; static_assert(operation_decompilers.size() == static_cast(OperationCode::Amount)); diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index 5c802886b6..7321698b26 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp @@ -257,6 +257,12 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { SetRegister(bb, instr.gpr0, GetRegister(instr.gpr8)); break; } + case OpCode::Id::MEMBAR: { + UNIMPLEMENTED_IF(instr.membar.type != Tegra::Shader::MembarType::GL); + UNIMPLEMENTED_IF(instr.membar.unknown != Tegra::Shader::MembarUnknown::Default); + bb.push_back(Operation(OperationCode::MemoryBarrierGL)); + break; + } case OpCode::Id::DEPBAR: { LOG_DEBUG(HW_GPU, "DEPBAR instruction is stubbed"); break; diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 1a4d28ae90..abd40f5828 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -189,6 +189,8 @@ enum class OperationCode { ThreadId, /// () -> uint ShuffleIndexed, /// (uint value, uint index) -> uint + MemoryBarrierGL, /// () -> void + Amount, };