summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 6834d7085..dabf98b74 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -383,15 +383,13 @@ public:
383 } 383 }
384 } 384 }
385 385
386 std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg, 386 std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str,
387 GLSLRegister::Type type) { 387 GLSLRegister::Type type) {
388 declr_const_buffers[index].MarkAsUsedIndirect(index, stage); 388 declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage);
389 389
390 std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " + 390 std::string final_offset = fmt::format("({} + {})", index_str, offset / 4);
391 std::to_string(offset) + ") / 4)"; 391 std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" +
392 392 final_offset + " % 4]";
393 std::string value =
394 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]";
395 393
396 if (type == GLSLRegister::Type::Float) { 394 if (type == GLSLRegister::Type::Float) {
397 return value; 395 return value;
@@ -1355,11 +1353,16 @@ private:
1355 case OpCode::Id::LD_C: { 1353 case OpCode::Id::LD_C: {
1356 ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented"); 1354 ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented");
1357 1355
1356 // Add an extra scope and declare the index register inside to prevent
1357 // overwriting it in case it is used as an output of the LD instruction.
1358 shader.AddLine("{");
1359 ++shader.scope;
1360
1361 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
1362 " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);");
1363
1358 std::string op_a = 1364 std::string op_a =
1359 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, instr.gpr8, 1365 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index",
1360 GLSLRegister::Type::Float);
1361 std::string op_b =
1362 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, instr.gpr8,
1363 GLSLRegister::Type::Float); 1366 GLSLRegister::Type::Float);
1364 1367
1365 switch (instr.ld_c.type.Value()) { 1368 switch (instr.ld_c.type.Value()) {
@@ -1367,16 +1370,22 @@ private:
1367 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 1370 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
1368 break; 1371 break;
1369 1372
1370 case Tegra::Shader::UniformType::Double: 1373 case Tegra::Shader::UniformType::Double: {
1374 std::string op_b =
1375 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4,
1376 "index", GLSLRegister::Type::Float);
1371 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 1377 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
1372 regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1); 1378 regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1);
1373 break; 1379 break;
1374 1380 }
1375 default: 1381 default:
1376 LOG_CRITICAL(HW_GPU, "Unhandled type: {}", 1382 LOG_CRITICAL(HW_GPU, "Unhandled type: {}",
1377 static_cast<unsigned>(instr.ld_c.type.Value())); 1383 static_cast<unsigned>(instr.ld_c.type.Value()));
1378 UNREACHABLE(); 1384 UNREACHABLE();
1379 } 1385 }
1386
1387 --shader.scope;
1388 shader.AddLine("}");
1380 break; 1389 break;
1381 } 1390 }
1382 case OpCode::Id::ST_A: { 1391 case OpCode::Id::ST_A: {