diff options
| author | 2018-08-14 23:14:09 -0400 | |
|---|---|---|
| committer | 2018-08-14 23:14:09 -0400 | |
| commit | c8cd1785e6a708c9e49f6d4da9289d15f7e73bc3 (patch) | |
| tree | 81b9089292d1a9a58ea4652c5c8a71738c7d5071 /src | |
| parent | Merge pull request #1068 from bunnei/g8r8s (diff) | |
| parent | gl_shader_decompiler: Several fixes for indirect constant buffer loads. (diff) | |
| download | yuzu-c8cd1785e6a708c9e49f6d4da9289d15f7e73bc3.tar.gz yuzu-c8cd1785e6a708c9e49f6d4da9289d15f7e73bc3.tar.xz yuzu-c8cd1785e6a708c9e49f6d4da9289d15f7e73bc3.zip | |
Merge pull request #1071 from bunnei/fix-ldc
gl_shader_decompiler: Several fixes for indirect constant buffer loads.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 35 |
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: { |