summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp14
-rw-r--r--src/video_core/shader/decode/other.cpp6
-rw-r--r--src/video_core/shader/node.h2
5 files changed, 46 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 7703a76a3..290d929df 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,
@@ -1546,6 +1555,11 @@ union Instruction {
} 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;
BitField<36, 2, VideoType> type_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 9700c2ebe..fa7049bbe 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<std::size_t>(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 8ad89b58a..6227bc70b 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<u32>(scope)),
+ Constant(t_uint, static_cast<u32>(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<u32>(builtin));
@@ -2374,6 +2386,8 @@ private:
&SPIRVDecompiler::ThreadId,
&SPIRVDecompiler::ShuffleIndexed,
+
+ &SPIRVDecompiler::MemoryBarrierGL,
};
static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount));
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index 5c802886b..7321698b2 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 1a4d28ae9..abd40f582 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,
};