summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-03 17:10:02 -0500
committerGravatar GitHub2018-12-03 17:10:02 -0500
commit8a12daac8c15179d86b2050ad1218a9e7cb7c93e (patch)
treebbc6f10788e4a59adf2f2e1c04b62d50a3dc4c3e /src
parentMerge pull request #1803 from DarkLordZach/k-able-event (diff)
parentgl_shader_decompiler: Remove texture temporal in TLD4 (diff)
downloadyuzu-8a12daac8c15179d86b2050ad1218a9e7cb7c93e.tar.gz
yuzu-8a12daac8c15179d86b2050ad1218a9e7cb7c93e.tar.xz
yuzu-8a12daac8c15179d86b2050ad1218a9e7cb7c93e.zip
Merge pull request #1822 from ReinUsesLisp/glsl-scope
gl_shader_decompiler: Introduce a scoped object and style changes
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp463
1 files changed, 213 insertions, 250 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 0c1632bd1..d235bfcd4 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -201,14 +201,53 @@ private:
201 } 201 }
202}; 202};
203 203
204template <typename T>
205class ShaderScopedScope {
206public:
207 explicit ShaderScopedScope(T& writer, std::string_view begin_expr, std::string end_expr)
208 : writer(writer), end_expr(std::move(end_expr)) {
209
210 if (begin_expr.empty()) {
211 writer.AddLine('{');
212 } else {
213 writer.AddExpression(begin_expr);
214 writer.AddLine(" {");
215 }
216 ++writer.scope;
217 }
218
219 ShaderScopedScope(const ShaderScopedScope&) = delete;
220
221 ~ShaderScopedScope() {
222 --writer.scope;
223 if (end_expr.empty()) {
224 writer.AddLine('}');
225 } else {
226 writer.AddExpression("} ");
227 writer.AddExpression(end_expr);
228 writer.AddLine(';');
229 }
230 }
231
232 ShaderScopedScope& operator=(const ShaderScopedScope&) = delete;
233
234private:
235 T& writer;
236 std::string end_expr;
237};
238
204class ShaderWriter { 239class ShaderWriter {
205public: 240public:
206 void AddLine(std::string_view text) { 241 void AddExpression(std::string_view text) {
207 DEBUG_ASSERT(scope >= 0); 242 DEBUG_ASSERT(scope >= 0);
208 if (!text.empty()) { 243 if (!text.empty()) {
209 AppendIndentation(); 244 AppendIndentation();
210 } 245 }
211 shader_source += text; 246 shader_source += text;
247 }
248
249 void AddLine(std::string_view text) {
250 AddExpression(text);
212 AddNewLine(); 251 AddNewLine();
213 } 252 }
214 253
@@ -228,6 +267,11 @@ public:
228 return std::move(shader_source); 267 return std::move(shader_source);
229 } 268 }
230 269
270 ShaderScopedScope<ShaderWriter> Scope(std::string_view begin_expr = {},
271 std::string end_expr = {}) {
272 return ShaderScopedScope(*this, begin_expr, end_expr);
273 }
274
231 int scope = 0; 275 int scope = 0;
232 276
233private: 277private:
@@ -311,7 +355,7 @@ public:
311 // Default - do nothing 355 // Default - do nothing
312 return value; 356 return value;
313 default: 357 default:
314 UNIMPLEMENTED_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); 358 UNREACHABLE_MSG("Unimplemented conversion size: {}", static_cast<u32>(size));
315 } 359 }
316 } 360 }
317 361
@@ -816,14 +860,12 @@ private:
816 } 860 }
817 861
818 if (precise && stage != Maxwell3D::Regs::ShaderStage::Fragment) { 862 if (precise && stage != Maxwell3D::Regs::ShaderStage::Fragment) {
819 shader.AddLine('{'); 863 const auto scope = shader.Scope();
820 ++shader.scope; 864
821 // This avoids optimizations of constant propagation and keeps the code as the original 865 // This avoids optimizations of constant propagation and keeps the code as the original
822 // Sadly using the precise keyword causes "linking" errors on fragment shaders. 866 // Sadly using the precise keyword causes "linking" errors on fragment shaders.
823 shader.AddLine("precise float tmp = " + src + ';'); 867 shader.AddLine("precise float tmp = " + src + ';');
824 shader.AddLine(dest + " = tmp;"); 868 shader.AddLine(dest + " = tmp;");
825 --shader.scope;
826 shader.AddLine('}');
827 } else { 869 } else {
828 shader.AddLine(dest + " = " + src + ';'); 870 shader.AddLine(dest + " = " + src + ';');
829 } 871 }
@@ -1301,15 +1343,7 @@ private:
1301 regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); 1343 regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
1302 } 1344 }
1303 1345
1304 void WriteTexsInstruction(const Instruction& instr, const std::string& coord, 1346 void WriteTexsInstruction(const Instruction& instr, const std::string& texture) {
1305 const std::string& texture) {
1306 // Add an extra scope and declare the texture coords inside to prevent
1307 // overwriting them in case they are used as outputs of the texs instruction.
1308 shader.AddLine('{');
1309 ++shader.scope;
1310 shader.AddLine(coord);
1311 shader.AddLine("vec4 texture_tmp = " + texture + ';');
1312
1313 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle 1347 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
1314 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 1348 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
1315 1349
@@ -1321,19 +1355,17 @@ private:
1321 1355
1322 if (written_components < 2) { 1356 if (written_components < 2) {
1323 // Write the first two swizzle components to gpr0 and gpr0+1 1357 // Write the first two swizzle components to gpr0 and gpr0+1
1324 regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, 1358 regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false,
1325 written_components % 2); 1359 written_components % 2);
1326 } else { 1360 } else {
1327 ASSERT(instr.texs.HasTwoDestinations()); 1361 ASSERT(instr.texs.HasTwoDestinations());
1328 // Write the rest of the swizzle components to gpr28 and gpr28+1 1362 // Write the rest of the swizzle components to gpr28 and gpr28+1
1329 regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, 1363 regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false,
1330 written_components % 2); 1364 written_components % 2);
1331 } 1365 }
1332 1366
1333 ++written_components; 1367 ++written_components;
1334 } 1368 }
1335 --shader.scope;
1336 shader.AddLine('}');
1337 } 1369 }
1338 1370
1339 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { 1371 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
@@ -1356,12 +1388,10 @@ private:
1356 * top. 1388 * top.
1357 */ 1389 */
1358 void EmitPushToFlowStack(u32 target) { 1390 void EmitPushToFlowStack(u32 target) {
1359 shader.AddLine('{'); 1391 const auto scope = shader.Scope();
1360 ++shader.scope; 1392
1361 shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;"); 1393 shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;");
1362 shader.AddLine("flow_stack_top++;"); 1394 shader.AddLine("flow_stack_top++;");
1363 --shader.scope;
1364 shader.AddLine('}');
1365 } 1395 }
1366 1396
1367 /* 1397 /*
@@ -1369,13 +1399,11 @@ private:
1369 * popped address and decrementing the stack top. 1399 * popped address and decrementing the stack top.
1370 */ 1400 */
1371 void EmitPopFromFlowStack() { 1401 void EmitPopFromFlowStack() {
1372 shader.AddLine('{'); 1402 const auto scope = shader.Scope();
1373 ++shader.scope; 1403
1374 shader.AddLine("flow_stack_top--;"); 1404 shader.AddLine("flow_stack_top--;");
1375 shader.AddLine("jmp_to = flow_stack[flow_stack_top];"); 1405 shader.AddLine("jmp_to = flow_stack[flow_stack_top];");
1376 shader.AddLine("break;"); 1406 shader.AddLine("break;");
1377 --shader.scope;
1378 shader.AddLine('}');
1379 } 1407 }
1380 1408
1381 /// Writes the output values from a fragment shader to the corresponding GLSL output variables. 1409 /// Writes the output values from a fragment shader to the corresponding GLSL output variables.
@@ -2287,8 +2315,7 @@ private:
2287 UNIMPLEMENTED_IF(instr.conversion.selector); 2315 UNIMPLEMENTED_IF(instr.conversion.selector);
2288 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 2316 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
2289 "Condition codes generation in I2F is not implemented"); 2317 "Condition codes generation in I2F is not implemented");
2290 2318 std::string op_a;
2291 std::string op_a{};
2292 2319
2293 if (instr.is_b_gpr) { 2320 if (instr.is_b_gpr) {
2294 op_a = 2321 op_a =
@@ -2444,10 +2471,7 @@ private:
2444 case OpCode::Id::LD_C: { 2471 case OpCode::Id::LD_C: {
2445 UNIMPLEMENTED_IF(instr.ld_c.unknown != 0); 2472 UNIMPLEMENTED_IF(instr.ld_c.unknown != 0);
2446 2473
2447 // Add an extra scope and declare the index register inside to prevent 2474 const auto scope = shader.Scope();
2448 // overwriting it in case it is used as an output of the LD instruction.
2449 shader.AddLine("{");
2450 ++shader.scope;
2451 2475
2452 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + 2476 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
2453 " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); 2477 " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);");
@@ -2473,19 +2497,13 @@ private:
2473 UNIMPLEMENTED_MSG("Unhandled type: {}", 2497 UNIMPLEMENTED_MSG("Unhandled type: {}",
2474 static_cast<unsigned>(instr.ld_c.type.Value())); 2498 static_cast<unsigned>(instr.ld_c.type.Value()));
2475 } 2499 }
2476
2477 --shader.scope;
2478 shader.AddLine("}");
2479 break; 2500 break;
2480 } 2501 }
2481 case OpCode::Id::LD_L: { 2502 case OpCode::Id::LD_L: {
2482 UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", 2503 UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}",
2483 static_cast<unsigned>(instr.ld_l.unknown.Value())); 2504 static_cast<unsigned>(instr.ld_l.unknown.Value()));
2484 2505
2485 // Add an extra scope and declare the index register inside to prevent 2506 const auto scope = shader.Scope();
2486 // overwriting it in case it is used as an output of the LD instruction.
2487 shader.AddLine('{');
2488 ++shader.scope;
2489 2507
2490 std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + 2508 std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " +
2491 std::to_string(instr.smem_imm.Value()) + ')'; 2509 std::to_string(instr.smem_imm.Value()) + ')';
@@ -2502,9 +2520,6 @@ private:
2502 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", 2520 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}",
2503 static_cast<unsigned>(instr.ldst_sl.type.Value())); 2521 static_cast<unsigned>(instr.ldst_sl.type.Value()));
2504 } 2522 }
2505
2506 --shader.scope;
2507 shader.AddLine('}');
2508 break; 2523 break;
2509 } 2524 }
2510 case OpCode::Id::ST_A: { 2525 case OpCode::Id::ST_A: {
@@ -2539,10 +2554,7 @@ private:
2539 UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", 2554 UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}",
2540 static_cast<unsigned>(instr.st_l.unknown.Value())); 2555 static_cast<unsigned>(instr.st_l.unknown.Value()));
2541 2556
2542 // Add an extra scope and declare the index register inside to prevent 2557 const auto scope = shader.Scope();
2543 // overwriting it in case it is used as an output of the LD instruction.
2544 shader.AddLine('{');
2545 ++shader.scope;
2546 2558
2547 std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + 2559 std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " +
2548 std::to_string(instr.smem_imm.Value()) + ')'; 2560 std::to_string(instr.smem_imm.Value()) + ')';
@@ -2557,14 +2569,10 @@ private:
2557 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", 2569 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}",
2558 static_cast<unsigned>(instr.ldst_sl.type.Value())); 2570 static_cast<unsigned>(instr.ldst_sl.type.Value()));
2559 } 2571 }
2560
2561 --shader.scope;
2562 shader.AddLine('}');
2563 break; 2572 break;
2564 } 2573 }
2565 case OpCode::Id::TEX: { 2574 case OpCode::Id::TEX: {
2566 Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; 2575 Tegra::Shader::TextureType texture_type{instr.tex.texture_type};
2567 std::string coord;
2568 const bool is_array = instr.tex.array != 0; 2576 const bool is_array = instr.tex.array != 0;
2569 2577
2570 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2578 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
@@ -2597,21 +2605,23 @@ private:
2597 2605
2598 bool depth_compare_extra = false; 2606 bool depth_compare_extra = false;
2599 2607
2608 const auto scope = shader.Scope();
2609
2600 switch (num_coordinates) { 2610 switch (num_coordinates) {
2601 case 1: { 2611 case 1: {
2602 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); 2612 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2603 if (is_array) { 2613 if (is_array) {
2604 if (depth_compare) { 2614 if (depth_compare) {
2605 coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " + 2615 shader.AddLine("vec3 coords = vec3(" + x + ", " + depth_value + ", " +
2606 array_elem + ");"; 2616 array_elem + ");");
2607 } else { 2617 } else {
2608 coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");"; 2618 shader.AddLine("vec2 coords = vec2(" + x + ", " + array_elem + ");");
2609 } 2619 }
2610 } else { 2620 } else {
2611 if (depth_compare) { 2621 if (depth_compare) {
2612 coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");"; 2622 shader.AddLine("vec2 coords = vec2(" + x + ", " + depth_value + ");");
2613 } else { 2623 } else {
2614 coord = "float coords = " + x + ';'; 2624 shader.AddLine("float coords = " + x + ';');
2615 } 2625 }
2616 } 2626 }
2617 break; 2627 break;
@@ -2622,17 +2632,18 @@ private:
2622 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); 2632 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1);
2623 if (is_array) { 2633 if (is_array) {
2624 if (depth_compare) { 2634 if (depth_compare) {
2625 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value + 2635 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " +
2626 ", " + array_elem + ");"; 2636 depth_value + ", " + array_elem + ");");
2627 } else { 2637 } else {
2628 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");"; 2638 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2639 array_elem + ");");
2629 } 2640 }
2630 } else { 2641 } else {
2631 if (depth_compare) { 2642 if (depth_compare) {
2632 coord = 2643 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2633 "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");"; 2644 depth_value + ");");
2634 } else { 2645 } else {
2635 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2646 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2636 } 2647 }
2637 } 2648 }
2638 break; 2649 break;
@@ -2645,14 +2656,14 @@ private:
2645 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); 2656 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2);
2646 if (is_array) { 2657 if (is_array) {
2647 depth_compare_extra = depth_compare; 2658 depth_compare_extra = depth_compare;
2648 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + 2659 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2649 array_elem + ");"; 2660 array_elem + ");");
2650 } else { 2661 } else {
2651 if (depth_compare) { 2662 if (depth_compare) {
2652 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + 2663 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2653 depth_value + ");"; 2664 depth_value + ");");
2654 } else { 2665 } else {
2655 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2666 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");");
2656 } 2667 }
2657 } 2668 }
2658 break; 2669 break;
@@ -2664,7 +2675,7 @@ private:
2664 // Fallback to interpreting as a 2D texture for now 2675 // Fallback to interpreting as a 2D texture for now
2665 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2676 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2666 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2677 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2667 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2678 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2668 texture_type = Tegra::Shader::TextureType::Texture2D; 2679 texture_type = Tegra::Shader::TextureType::Texture2D;
2669 } 2680 }
2670 2681
@@ -2673,79 +2684,61 @@ private:
2673 // Add an extra scope and declare the texture coords inside to prevent 2684 // Add an extra scope and declare the texture coords inside to prevent
2674 // overwriting them in case they are used as outputs of the texs instruction. 2685 // overwriting them in case they are used as outputs of the texs instruction.
2675 2686
2676 shader.AddLine('{'); 2687 const std::string texture = [&]() {
2677 ++shader.scope; 2688 switch (instr.tex.GetTextureProcessMode()) {
2678 shader.AddLine(coord); 2689 case Tegra::Shader::TextureProcessMode::None:
2679 std::string texture; 2690 if (depth_compare_extra) {
2680 2691 return "texture(" + sampler + ", coords, " + depth_value + ')';
2681 switch (instr.tex.GetTextureProcessMode()) { 2692 }
2682 case Tegra::Shader::TextureProcessMode::None: { 2693 return "texture(" + sampler + ", coords)";
2683 if (!depth_compare_extra) { 2694 case Tegra::Shader::TextureProcessMode::LZ:
2684 texture = "texture(" + sampler + ", coords)"; 2695 if (depth_compare_extra) {
2685 } else { 2696 return "texture(" + sampler + ", coords, " + depth_value + ')';
2686 texture = "texture(" + sampler + ", coords, " + depth_value + ')'; 2697 }
2687 } 2698 return "textureLod(" + sampler + ", coords, 0.0)";
2688 break; 2699 case Tegra::Shader::TextureProcessMode::LB:
2689 } 2700 case Tegra::Shader::TextureProcessMode::LBA:
2690 case Tegra::Shader::TextureProcessMode::LZ: { 2701 // TODO: Figure if A suffix changes the equation at all.
2691 if (!depth_compare_extra) { 2702 if (depth_compare_extra) {
2692 texture = "textureLod(" + sampler + ", coords, 0.0)"; 2703 LOG_WARNING(
2693 } else { 2704 HW_GPU,
2694 texture = "texture(" + sampler + ", coords, " + depth_value + ')'; 2705 "OpenGL Limitation: can't set bias value along depth compare");
2695 } 2706 return "texture(" + sampler + ", coords, " + depth_value + ')';
2696 break; 2707 }
2697 } 2708 return "texture(" + sampler + ", coords, " + lod_value + ')';
2698 case Tegra::Shader::TextureProcessMode::LB: 2709 case Tegra::Shader::TextureProcessMode::LL:
2699 case Tegra::Shader::TextureProcessMode::LBA: { 2710 case Tegra::Shader::TextureProcessMode::LLA:
2700 // TODO: Figure if A suffix changes the equation at all. 2711 // TODO: Figure if A suffix changes the equation at all.
2701 if (!depth_compare_extra) { 2712 if (depth_compare_extra) {
2702 texture = "texture(" + sampler + ", coords, " + lod_value + ')'; 2713 LOG_WARNING(
2703 } else { 2714 HW_GPU,
2704 texture = "texture(" + sampler + ", coords, " + depth_value + ')'; 2715 "OpenGL Limitation: can't set lod value along depth compare");
2705 LOG_WARNING(HW_GPU, 2716 return "texture(" + sampler + ", coords, " + depth_value + ')';
2706 "OpenGL Limitation: can't set bias value along depth compare"); 2717 }
2707 } 2718 return "textureLod(" + sampler + ", coords, " + lod_value + ')';
2708 break; 2719 default:
2709 } 2720 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2710 case Tegra::Shader::TextureProcessMode::LL: 2721 static_cast<u32>(instr.tex.GetTextureProcessMode()));
2711 case Tegra::Shader::TextureProcessMode::LLA: { 2722 if (depth_compare_extra) {
2712 // TODO: Figure if A suffix changes the equation at all. 2723 return "texture(" + sampler + ", coords, " + depth_value + ')';
2713 if (!depth_compare_extra) { 2724 }
2714 texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; 2725 return "texture(" + sampler + ", coords)";
2715 } else {
2716 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2717 LOG_WARNING(HW_GPU,
2718 "OpenGL Limitation: can't set lod value along depth compare");
2719 }
2720 break;
2721 }
2722 default: {
2723 if (!depth_compare_extra) {
2724 texture = "texture(" + sampler + ", coords)";
2725 } else {
2726 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2727 } 2726 }
2728 UNIMPLEMENTED_MSG("Unhandled texture process mode {}", 2727 }();
2729 static_cast<u32>(instr.tex.GetTextureProcessMode())); 2728
2730 } 2729 if (depth_compare) {
2731 } 2730 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2732 if (!depth_compare) { 2731 } else {
2733 shader.AddLine("vec4 texture_tmp = " + texture + ';');
2734 std::size_t dest_elem{}; 2732 std::size_t dest_elem{};
2735 for (std::size_t elem = 0; elem < 4; ++elem) { 2733 for (std::size_t elem = 0; elem < 4; ++elem) {
2736 if (!instr.tex.IsComponentEnabled(elem)) { 2734 if (!instr.tex.IsComponentEnabled(elem)) {
2737 // Skip disabled components 2735 // Skip disabled components
2738 continue; 2736 continue;
2739 } 2737 }
2740 regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, 2738 regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem);
2741 dest_elem);
2742 ++dest_elem; 2739 ++dest_elem;
2743 } 2740 }
2744 } else {
2745 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2746 } 2741 }
2747 --shader.scope;
2748 shader.AddLine('}');
2749 break; 2742 break;
2750 } 2743 }
2751 case OpCode::Id::TEXS: { 2744 case OpCode::Id::TEXS: {
@@ -2755,26 +2748,28 @@ private:
2755 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2748 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2756 "NODEP is not implemented"); 2749 "NODEP is not implemented");
2757 2750
2751 const auto scope = shader.Scope();
2752
2758 const bool depth_compare = 2753 const bool depth_compare =
2759 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2754 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2760 u32 num_coordinates = TextureCoordinates(texture_type); 2755 u32 num_coordinates = TextureCoordinates(texture_type);
2761 const auto process_mode = instr.texs.GetTextureProcessMode(); 2756 const auto process_mode = instr.texs.GetTextureProcessMode();
2762 std::string lod_value;
2763 std::string coord;
2764 u32 lod_offset = 0; 2757 u32 lod_offset = 0;
2765 if (process_mode == Tegra::Shader::TextureProcessMode::LL) { 2758 if (process_mode == Tegra::Shader::TextureProcessMode::LL) {
2766 if (num_coordinates > 2) { 2759 if (num_coordinates > 2) {
2767 lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); 2760 shader.AddLine("float lod_value = " +
2761 regs.GetRegisterAsFloat(instr.gpr20.Value() + 1) + ';');
2768 lod_offset = 2; 2762 lod_offset = 2;
2769 } else { 2763 } else {
2770 lod_value = regs.GetRegisterAsFloat(instr.gpr20); 2764 shader.AddLine("float lod_value = " + regs.GetRegisterAsFloat(instr.gpr20) +
2765 ';');
2771 lod_offset = 1; 2766 lod_offset = 1;
2772 } 2767 }
2773 } 2768 }
2774 2769
2775 switch (num_coordinates) { 2770 switch (num_coordinates) {
2776 case 1: { 2771 case 1: {
2777 coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; 2772 shader.AddLine("float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';');
2778 break; 2773 break;
2779 } 2774 }
2780 case 2: { 2775 case 2: {
@@ -2784,13 +2779,14 @@ private:
2784 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2779 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2785 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2780 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2786 const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); 2781 const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1);
2787 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + 2782 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2788 ");"; 2783 index + ");");
2789 } else { 2784 } else {
2790 const std::string index = regs.GetRegisterAsInteger(instr.gpr8); 2785 const std::string index = regs.GetRegisterAsInteger(instr.gpr8);
2791 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2786 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2792 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2787 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2793 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; 2788 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index +
2789 ");");
2794 } 2790 }
2795 } else { 2791 } else {
2796 if (lod_offset != 0) { 2792 if (lod_offset != 0) {
@@ -2800,12 +2796,13 @@ private:
2800 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2796 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2801 const std::string z = 2797 const std::string z =
2802 regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); 2798 regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset);
2803 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2799 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z +
2800 ");");
2804 } else { 2801 } else {
2805 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2802 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2806 const std::string y = 2803 const std::string y =
2807 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2804 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2808 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2805 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2809 } 2806 }
2810 } else { 2807 } else {
2811 if (depth_compare) { 2808 if (depth_compare) {
@@ -2813,11 +2810,12 @@ private:
2813 const std::string y = 2810 const std::string y =
2814 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2811 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2815 const std::string z = regs.GetRegisterAsFloat(instr.gpr20); 2812 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2816 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2813 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z +
2814 ");");
2817 } else { 2815 } else {
2818 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2816 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2819 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2817 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2820 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2818 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2821 } 2819 }
2822 } 2820 }
2823 } 2821 }
@@ -2827,7 +2825,7 @@ private:
2827 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2825 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2828 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2826 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2829 const std::string z = regs.GetRegisterAsFloat(instr.gpr20); 2827 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2830 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2828 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");");
2831 break; 2829 break;
2832 } 2830 }
2833 default: 2831 default:
@@ -2837,42 +2835,37 @@ private:
2837 // Fallback to interpreting as a 2D texture for now 2835 // Fallback to interpreting as a 2D texture for now
2838 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2836 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2839 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2837 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2840 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2838 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2841 texture_type = Tegra::Shader::TextureType::Texture2D; 2839 texture_type = Tegra::Shader::TextureType::Texture2D;
2842 is_array = false; 2840 is_array = false;
2843 } 2841 }
2844 const std::string sampler = 2842 const std::string sampler =
2845 GetSampler(instr.sampler, texture_type, is_array, depth_compare); 2843 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
2846 std::string texture; 2844
2847 switch (process_mode) { 2845 std::string texture = [&]() {
2848 case Tegra::Shader::TextureProcessMode::None: { 2846 switch (process_mode) {
2849 texture = "texture(" + sampler + ", coords)"; 2847 case Tegra::Shader::TextureProcessMode::None:
2850 break; 2848 return "texture(" + sampler + ", coords)";
2851 } 2849 case Tegra::Shader::TextureProcessMode::LZ:
2852 case Tegra::Shader::TextureProcessMode::LZ: { 2850 if (depth_compare && is_array) {
2853 if (depth_compare && is_array) { 2851 return "texture(" + sampler + ", coords)";
2854 texture = "texture(" + sampler + ", coords)"; 2852 } else {
2855 } else { 2853 return "textureLod(" + sampler + ", coords, 0.0)";
2856 texture = "textureLod(" + sampler + ", coords, 0.0)"; 2854 }
2855 break;
2856 case Tegra::Shader::TextureProcessMode::LL:
2857 return "textureLod(" + sampler + ", coords, lod_value)";
2858 default:
2859 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2860 static_cast<u32>(instr.texs.GetTextureProcessMode()));
2861 return "texture(" + sampler + ", coords)";
2857 } 2862 }
2858 break; 2863 }();
2859 } 2864 if (depth_compare) {
2860 case Tegra::Shader::TextureProcessMode::LL: { 2865 texture = "vec4(" + texture + ')';
2861 texture = "textureLod(" + sampler + ", coords, " + lod_value + ')';
2862 break;
2863 }
2864 default: {
2865 texture = "texture(" + sampler + ", coords)";
2866 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2867 static_cast<u32>(instr.texs.GetTextureProcessMode()));
2868 }
2869 }
2870 if (!depth_compare) {
2871 WriteTexsInstruction(instr, coord, texture);
2872 } else {
2873 WriteTexsInstruction(instr, coord, "vec4(" + texture + ')');
2874 } 2866 }
2875 2867
2868 WriteTexsInstruction(instr, texture);
2876 break; 2869 break;
2877 } 2870 }
2878 case OpCode::Id::TLDS: { 2871 case OpCode::Id::TLDS: {
@@ -2891,15 +2884,12 @@ private:
2891 2884
2892 u32 extra_op_offset = 0; 2885 u32 extra_op_offset = 0;
2893 2886
2894 // Scope to avoid variable name overlaps. 2887 ShaderScopedScope scope = shader.Scope();
2895 shader.AddLine('{');
2896 ++shader.scope;
2897 std::string coords;
2898 2888
2899 switch (texture_type) { 2889 switch (texture_type) {
2900 case Tegra::Shader::TextureType::Texture1D: { 2890 case Tegra::Shader::TextureType::Texture1D: {
2901 const std::string x = regs.GetRegisterAsInteger(instr.gpr8); 2891 const std::string x = regs.GetRegisterAsInteger(instr.gpr8);
2902 coords = "float coords = " + x + ';'; 2892 shader.AddLine("float coords = " + x + ';');
2903 break; 2893 break;
2904 } 2894 }
2905 case Tegra::Shader::TextureType::Texture2D: { 2895 case Tegra::Shader::TextureType::Texture2D: {
@@ -2908,7 +2898,7 @@ private:
2908 const std::string x = regs.GetRegisterAsInteger(instr.gpr8); 2898 const std::string x = regs.GetRegisterAsInteger(instr.gpr8);
2909 const std::string y = regs.GetRegisterAsInteger(instr.gpr20); 2899 const std::string y = regs.GetRegisterAsInteger(instr.gpr20);
2910 // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); 2900 // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");");
2911 coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; 2901 shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");");
2912 extra_op_offset = 1; 2902 extra_op_offset = 1;
2913 break; 2903 break;
2914 } 2904 }
@@ -2917,35 +2907,29 @@ private:
2917 } 2907 }
2918 const std::string sampler = 2908 const std::string sampler =
2919 GetSampler(instr.sampler, texture_type, is_array, false); 2909 GetSampler(instr.sampler, texture_type, is_array, false);
2920 std::string texture = "texelFetch(" + sampler + ", coords, 0)";
2921 switch (instr.tlds.GetTextureProcessMode()) {
2922 case Tegra::Shader::TextureProcessMode::LZ: {
2923 texture = "texelFetch(" + sampler + ", coords, 0)";
2924 break;
2925 }
2926 case Tegra::Shader::TextureProcessMode::LL: {
2927 shader.AddLine(
2928 "float lod = " +
2929 regs.GetRegisterAsInteger(instr.gpr20.Value() + extra_op_offset) + ';');
2930 texture = "texelFetch(" + sampler + ", coords, lod)";
2931 break;
2932 }
2933 default: {
2934 texture = "texelFetch(" + sampler + ", coords, 0)";
2935 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2936 static_cast<u32>(instr.tlds.GetTextureProcessMode()));
2937 }
2938 }
2939 WriteTexsInstruction(instr, coords, texture);
2940 2910
2941 --shader.scope; 2911 const std::string texture = [&]() {
2942 shader.AddLine('}'); 2912 switch (instr.tlds.GetTextureProcessMode()) {
2913 case Tegra::Shader::TextureProcessMode::LZ:
2914 return "texelFetch(" + sampler + ", coords, 0)";
2915 case Tegra::Shader::TextureProcessMode::LL:
2916 shader.AddLine(
2917 "float lod = " +
2918 regs.GetRegisterAsInteger(instr.gpr20.Value() + extra_op_offset) + ';');
2919 return "texelFetch(" + sampler + ", coords, lod)";
2920 default:
2921 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2922 static_cast<u32>(instr.tlds.GetTextureProcessMode()));
2923 return "texelFetch(" + sampler + ", coords, 0)";
2924 }
2925 }();
2926
2927 WriteTexsInstruction(instr, texture);
2943 break; 2928 break;
2944 } 2929 }
2945 case OpCode::Id::TLD4: { 2930 case OpCode::Id::TLD4: {
2946 ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); 2931 ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D);
2947 ASSERT(instr.tld4.array == 0); 2932 ASSERT(instr.tld4.array == 0);
2948 std::string coord;
2949 2933
2950 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2934 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2951 "NODEP is not implemented"); 2935 "NODEP is not implemented");
@@ -2962,10 +2946,7 @@ private:
2962 if (depth_compare) 2946 if (depth_compare)
2963 num_coordinates += 1; 2947 num_coordinates += 1;
2964 2948
2965 // Add an extra scope and declare the texture coords inside to prevent 2949 const auto scope = shader.Scope();
2966 // overwriting them in case they are used as outputs of the texs instruction.
2967 shader.AddLine('{');
2968 ++shader.scope;
2969 2950
2970 switch (num_coordinates) { 2951 switch (num_coordinates) {
2971 case 2: { 2952 case 2: {
@@ -2996,23 +2977,19 @@ private:
2996 const std::string texture = "textureGather(" + sampler + ", coords, " + 2977 const std::string texture = "textureGather(" + sampler + ", coords, " +
2997 std::to_string(instr.tld4.component) + ')'; 2978 std::to_string(instr.tld4.component) + ')';
2998 2979
2999 if (!depth_compare) { 2980 if (depth_compare) {
3000 shader.AddLine("vec4 texture_tmp = " + texture + ';'); 2981 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2982 } else {
3001 std::size_t dest_elem{}; 2983 std::size_t dest_elem{};
3002 for (std::size_t elem = 0; elem < 4; ++elem) { 2984 for (std::size_t elem = 0; elem < 4; ++elem) {
3003 if (!instr.tex.IsComponentEnabled(elem)) { 2985 if (!instr.tex.IsComponentEnabled(elem)) {
3004 // Skip disabled components 2986 // Skip disabled components
3005 continue; 2987 continue;
3006 } 2988 }
3007 regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, 2989 regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem);
3008 dest_elem);
3009 ++dest_elem; 2990 ++dest_elem;
3010 } 2991 }
3011 } else {
3012 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
3013 } 2992 }
3014 --shader.scope;
3015 shader.AddLine('}');
3016 break; 2993 break;
3017 } 2994 }
3018 case OpCode::Id::TLD4S: { 2995 case OpCode::Id::TLD4S: {
@@ -3023,10 +3000,7 @@ private:
3023 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 3000 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
3024 "AOFFI is not implemented"); 3001 "AOFFI is not implemented");
3025 3002
3026 // Scope to avoid variable name overlaps. 3003 const auto scope = shader.Scope();
3027 shader.AddLine('{');
3028 ++shader.scope;
3029 std::string coords;
3030 3004
3031 const bool depth_compare = 3005 const bool depth_compare =
3032 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 3006 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
@@ -3035,33 +3009,29 @@ private:
3035 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. 3009 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction.
3036 const std::string sampler = GetSampler( 3010 const std::string sampler = GetSampler(
3037 instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); 3011 instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare);
3038 if (!depth_compare) { 3012 if (depth_compare) {
3039 coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
3040 } else {
3041 // Note: TLD4S coordinate encoding works just like TEXS's 3013 // Note: TLD4S coordinate encoding works just like TEXS's
3042 const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3014 const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3043 coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; 3015 shader.AddLine("vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");");
3044 }
3045 const std::string texture = "textureGather(" + sampler + ", coords, " +
3046 std::to_string(instr.tld4s.component) + ')';
3047
3048 if (!depth_compare) {
3049 WriteTexsInstruction(instr, coords, texture);
3050 } else { 3016 } else {
3051 WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); 3017 shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");");
3052 } 3018 }
3053 3019
3054 --shader.scope; 3020 std::string texture = "textureGather(" + sampler + ", coords, " +
3055 shader.AddLine('}'); 3021 std::to_string(instr.tld4s.component) + ')';
3022 if (depth_compare) {
3023 texture = "vec4(" + texture + ')';
3024 }
3025 WriteTexsInstruction(instr, texture);
3056 break; 3026 break;
3057 } 3027 }
3058 case OpCode::Id::TXQ: { 3028 case OpCode::Id::TXQ: {
3059 UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 3029 UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
3060 "NODEP is not implemented"); 3030 "NODEP is not implemented");
3061 3031
3062 ++shader.scope; 3032 const auto scope = shader.Scope();
3063 shader.AddLine('{'); 3033
3064 // TODO: the new commits on the texture refactor, change the way samplers work. 3034 // TODO: The new commits on the texture refactor, change the way samplers work.
3065 // Sadly, not all texture instructions specify the type of texture their sampler 3035 // Sadly, not all texture instructions specify the type of texture their sampler
3066 // uses. This must be fixed at a later instance. 3036 // uses. This must be fixed at a later instance.
3067 const std::string sampler = 3037 const std::string sampler =
@@ -3072,7 +3042,8 @@ private:
3072 regs.GetRegisterAsInteger(instr.gpr8) + ')'; 3042 regs.GetRegisterAsInteger(instr.gpr8) + ')';
3073 const std::string mip_level = "textureQueryLevels(" + sampler + ')'; 3043 const std::string mip_level = "textureQueryLevels(" + sampler + ')';
3074 shader.AddLine("ivec2 sizes = " + texture + ';'); 3044 shader.AddLine("ivec2 sizes = " + texture + ';');
3075 regs.SetRegisterToInteger(instr.gpr0, true, 0, "sizes.x", 1, 1); 3045
3046 regs.SetRegisterToInteger(instr.gpr0.Value() + 0, true, 0, "sizes.x", 1, 1);
3076 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1); 3047 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1);
3077 regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1); 3048 regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1);
3078 regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1); 3049 regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1);
@@ -3083,8 +3054,6 @@ private:
3083 static_cast<u32>(instr.txq.query_type.Value())); 3054 static_cast<u32>(instr.txq.query_type.Value()));
3084 } 3055 }
3085 } 3056 }
3086 --shader.scope;
3087 shader.AddLine('}');
3088 break; 3057 break;
3089 } 3058 }
3090 case OpCode::Id::TMML: { 3059 case OpCode::Id::TMML: {
@@ -3099,17 +3068,18 @@ private:
3099 const std::string sampler = 3068 const std::string sampler =
3100 GetSampler(instr.sampler, texture_type, is_array, false); 3069 GetSampler(instr.sampler, texture_type, is_array, false);
3101 3070
3102 // TODO: add coordinates for different samplers once other texture types are 3071 const auto scope = shader.Scope();
3072
3073 // TODO: Add coordinates for different samplers once other texture types are
3103 // implemented. 3074 // implemented.
3104 std::string coord;
3105 switch (texture_type) { 3075 switch (texture_type) {
3106 case Tegra::Shader::TextureType::Texture1D: { 3076 case Tegra::Shader::TextureType::Texture1D: {
3107 coord = "float coords = " + x + ';'; 3077 shader.AddLine("float coords = " + x + ';');
3108 break; 3078 break;
3109 } 3079 }
3110 case Tegra::Shader::TextureType::Texture2D: { 3080 case Tegra::Shader::TextureType::Texture2D: {
3111 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3081 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3112 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 3082 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
3113 break; 3083 break;
3114 } 3084 }
3115 default: 3085 default:
@@ -3117,22 +3087,15 @@ private:
3117 3087
3118 // Fallback to interpreting as a 2D texture for now 3088 // Fallback to interpreting as a 2D texture for now
3119 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 3089 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
3120 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 3090 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
3121 texture_type = Tegra::Shader::TextureType::Texture2D; 3091 texture_type = Tegra::Shader::TextureType::Texture2D;
3122 } 3092 }
3123 // Add an extra scope and declare the texture coords inside to prevent 3093
3124 // overwriting them in case they are used as outputs of the texs instruction.
3125 shader.AddLine('{');
3126 ++shader.scope;
3127 shader.AddLine(coord);
3128 const std::string texture = "textureQueryLod(" + sampler + ", coords)"; 3094 const std::string texture = "textureQueryLod(" + sampler + ", coords)";
3129 const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);"; 3095 shader.AddLine("vec2 tmp = " + texture + " * vec2(256.0, 256.0);");
3130 shader.AddLine(tmp);
3131 3096
3132 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1); 3097 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1);
3133 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1); 3098 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1);
3134 --shader.scope;
3135 shader.AddLine('}');
3136 break; 3099 break;
3137 } 3100 }
3138 default: { 3101 default: {