summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp13
2 files changed, 17 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index dc3dd8a80..51dcc0d08 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -261,6 +261,10 @@ union Instruction {
} alu;
union {
+ BitField<48, 1, u64> is_signed;
+ } shift;
+
+ union {
BitField<39, 5, u64> shift_amount;
BitField<48, 1, u64> negate_b;
BitField<49, 1, u64> negate_a;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 4e248d328..07a90f5ad 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -979,6 +979,19 @@ private:
}
switch (opcode->GetId()) {
+ case OpCode::Id::SHR_C:
+ case OpCode::Id::SHR_R:
+ case OpCode::Id::SHR_IMM: {
+ if (!instr.shift.is_signed) {
+ // Logical shift right
+ op_a = "uint(" + op_a + ')';
+ }
+
+ // Cast to int is superfluous for arithmetic shift, it's only for a logical shift
+ regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')',
+ 1, 1);
+ break;
+ }
case OpCode::Id::SHL_C:
case OpCode::Id::SHL_R:
case OpCode::Id::SHL_IMM: