diff options
| author | 2018-11-25 22:36:25 -0500 | |
|---|---|---|
| committer | 2018-11-25 22:36:25 -0500 | |
| commit | 03948134019e75c2e090db42a470d8cded96de4d (patch) | |
| tree | 3e89cac69fc21a847b735282466d55e01f32e2da /src | |
| parent | Merge pull request #1783 from ReinUsesLisp/clip-distances (diff) | |
| parent | Fix Texture Overlapping (diff) | |
| download | yuzu-03948134019e75c2e090db42a470d8cded96de4d.tar.gz yuzu-03948134019e75c2e090db42a470d8cded96de4d.tar.xz yuzu-03948134019e75c2e090db42a470d8cded96de4d.zip | |
Merge pull request #1782 from FernandoS27/dc
Fixed Coordinate Encodings in TEX and TEXS instructions
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 304 |
1 files changed, 188 insertions, 116 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 3b7841715..9dbaf26d4 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1292,7 +1292,15 @@ private: | |||
| 1292 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | 1292 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |
| 1293 | } | 1293 | } |
| 1294 | 1294 | ||
| 1295 | void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { | 1295 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, |
| 1296 | const std::string& texture) { | ||
| 1297 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1298 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1299 | shader.AddLine('{'); | ||
| 1300 | ++shader.scope; | ||
| 1301 | shader.AddLine(coord); | ||
| 1302 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 1303 | |||
| 1296 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 1304 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 1297 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 1305 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 1298 | 1306 | ||
| @@ -1304,17 +1312,19 @@ private: | |||
| 1304 | 1312 | ||
| 1305 | if (written_components < 2) { | 1313 | if (written_components < 2) { |
| 1306 | // Write the first two swizzle components to gpr0 and gpr0+1 | 1314 | // Write the first two swizzle components to gpr0 and gpr0+1 |
| 1307 | regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false, | 1315 | regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, |
| 1308 | written_components % 2); | 1316 | written_components % 2); |
| 1309 | } else { | 1317 | } else { |
| 1310 | ASSERT(instr.texs.HasTwoDestinations()); | 1318 | ASSERT(instr.texs.HasTwoDestinations()); |
| 1311 | // Write the rest of the swizzle components to gpr28 and gpr28+1 | 1319 | // Write the rest of the swizzle components to gpr28 and gpr28+1 |
| 1312 | regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false, | 1320 | regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, |
| 1313 | written_components % 2); | 1321 | written_components % 2); |
| 1314 | } | 1322 | } |
| 1315 | 1323 | ||
| 1316 | ++written_components; | 1324 | ++written_components; |
| 1317 | } | 1325 | } |
| 1326 | --shader.scope; | ||
| 1327 | shader.AddLine('}'); | ||
| 1318 | } | 1328 | } |
| 1319 | 1329 | ||
| 1320 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | 1330 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |
| @@ -2536,61 +2546,83 @@ private: | |||
| 2536 | const bool depth_compare = | 2546 | const bool depth_compare = |
| 2537 | instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2547 | instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2538 | u32 num_coordinates = TextureCoordinates(texture_type); | 2548 | u32 num_coordinates = TextureCoordinates(texture_type); |
| 2539 | if (depth_compare) | 2549 | u32 start_index = 0; |
| 2540 | num_coordinates += 1; | 2550 | std::string array_elem; |
| 2551 | if (is_array) { | ||
| 2552 | array_elem = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2553 | start_index = 1; | ||
| 2554 | } | ||
| 2555 | const auto process_mode = instr.tex.GetTextureProcessMode(); | ||
| 2556 | u32 start_index_b = 0; | ||
| 2557 | std::string lod_value; | ||
| 2558 | if (process_mode != Tegra::Shader::TextureProcessMode::LZ && | ||
| 2559 | process_mode != Tegra::Shader::TextureProcessMode::None) { | ||
| 2560 | start_index_b = 1; | ||
| 2561 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2562 | } | ||
| 2563 | |||
| 2564 | std::string depth_value; | ||
| 2565 | if (depth_compare) { | ||
| 2566 | depth_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + start_index_b); | ||
| 2567 | } | ||
| 2568 | |||
| 2569 | bool depth_compare_extra = false; | ||
| 2541 | 2570 | ||
| 2542 | switch (num_coordinates) { | 2571 | switch (num_coordinates) { |
| 2543 | case 1: { | 2572 | case 1: { |
| 2573 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||
| 2544 | if (is_array) { | 2574 | if (is_array) { |
| 2545 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2575 | if (depth_compare) { |
| 2546 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2576 | coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " + |
| 2547 | coord = "vec2 coords = vec2(" + x + ", " + index + ");"; | 2577 | array_elem + ");"; |
| 2578 | } else { | ||
| 2579 | coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");"; | ||
| 2580 | } | ||
| 2548 | } else { | 2581 | } else { |
| 2549 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2582 | if (depth_compare) { |
| 2550 | coord = "float coords = " + x + ';'; | 2583 | coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");"; |
| 2584 | } else { | ||
| 2585 | coord = "float coords = " + x + ';'; | ||
| 2586 | } | ||
| 2551 | } | 2587 | } |
| 2552 | break; | 2588 | break; |
| 2553 | } | 2589 | } |
| 2554 | case 2: { | 2590 | case 2: { |
| 2591 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||
| 2592 | const std::string y = | ||
| 2593 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | ||
| 2555 | if (is_array) { | 2594 | if (is_array) { |
| 2556 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2595 | if (depth_compare) { |
| 2557 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2596 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value + |
| 2558 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | 2597 | ", " + array_elem + ");"; |
| 2559 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | 2598 | } else { |
| 2599 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");"; | ||
| 2600 | } | ||
| 2560 | } else { | 2601 | } else { |
| 2561 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2602 | if (depth_compare) { |
| 2562 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2603 | coord = |
| 2563 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2604 | "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");"; |
| 2605 | } else { | ||
| 2606 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2607 | } | ||
| 2564 | } | 2608 | } |
| 2565 | break; | 2609 | break; |
| 2566 | } | 2610 | } |
| 2567 | case 3: { | 2611 | case 3: { |
| 2568 | if (depth_compare) { | 2612 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); |
| 2569 | if (is_array) { | 2613 | const std::string y = |
| 2570 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2614 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); |
| 2571 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2615 | const std::string z = |
| 2572 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2616 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); |
| 2573 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2617 | if (is_array) { |
| 2574 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | 2618 | depth_compare_extra = depth_compare; |
| 2575 | ");"; | 2619 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |
| 2576 | } else { | 2620 | array_elem + ");"; |
| 2577 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2578 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2579 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2580 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2581 | } | ||
| 2582 | } else { | 2621 | } else { |
| 2583 | if (is_array) { | 2622 | if (depth_compare) { |
| 2584 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2623 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |
| 2585 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2624 | depth_value + ");"; |
| 2586 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | ||
| 2587 | const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 3); | ||
| 2588 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | ||
| 2589 | ");"; | ||
| 2590 | } else { | 2625 | } else { |
| 2591 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2592 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2593 | const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | ||
| 2594 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | 2626 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |
| 2595 | } | 2627 | } |
| 2596 | } | 2628 | } |
| @@ -2606,82 +2638,85 @@ private: | |||
| 2606 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 2638 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 2607 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2639 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2608 | } | 2640 | } |
| 2609 | // TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias | ||
| 2610 | // or lod. | ||
| 2611 | 2641 | ||
| 2612 | const std::string sampler = | 2642 | const std::string sampler = |
| 2613 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | 2643 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); |
| 2614 | // Add an extra scope and declare the texture coords inside to prevent | 2644 | // Add an extra scope and declare the texture coords inside to prevent |
| 2615 | // overwriting them in case they are used as outputs of the texs instruction. | 2645 | // overwriting them in case they are used as outputs of the texs instruction. |
| 2616 | 2646 | ||
| 2617 | shader.AddLine("{"); | 2647 | shader.AddLine('{'); |
| 2618 | ++shader.scope; | 2648 | ++shader.scope; |
| 2619 | shader.AddLine(coord); | 2649 | shader.AddLine(coord); |
| 2620 | std::string texture; | 2650 | std::string texture; |
| 2621 | 2651 | ||
| 2622 | switch (instr.tex.GetTextureProcessMode()) { | 2652 | switch (instr.tex.GetTextureProcessMode()) { |
| 2623 | case Tegra::Shader::TextureProcessMode::None: { | 2653 | case Tegra::Shader::TextureProcessMode::None: { |
| 2624 | texture = "texture(" + sampler + ", coords)"; | 2654 | if (!depth_compare_extra) { |
| 2655 | texture = "texture(" + sampler + ", coords)"; | ||
| 2656 | } else { | ||
| 2657 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2658 | } | ||
| 2625 | break; | 2659 | break; |
| 2626 | } | 2660 | } |
| 2627 | case Tegra::Shader::TextureProcessMode::LZ: { | 2661 | case Tegra::Shader::TextureProcessMode::LZ: { |
| 2628 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | 2662 | if (!depth_compare_extra) { |
| 2663 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | ||
| 2664 | } else { | ||
| 2665 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2666 | } | ||
| 2629 | break; | 2667 | break; |
| 2630 | } | 2668 | } |
| 2631 | case Tegra::Shader::TextureProcessMode::LB: | 2669 | case Tegra::Shader::TextureProcessMode::LB: |
| 2632 | case Tegra::Shader::TextureProcessMode::LBA: { | 2670 | case Tegra::Shader::TextureProcessMode::LBA: { |
| 2633 | const std::string bias = [&]() { | ||
| 2634 | if (depth_compare) { | ||
| 2635 | if (is_array) | ||
| 2636 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 2); | ||
| 2637 | else | ||
| 2638 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2639 | } else { | ||
| 2640 | return regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2641 | } | ||
| 2642 | }(); | ||
| 2643 | shader.AddLine("float bias = " + bias + ';'); | ||
| 2644 | |||
| 2645 | // TODO: Figure if A suffix changes the equation at all. | 2671 | // TODO: Figure if A suffix changes the equation at all. |
| 2646 | texture = "texture(" + sampler + ", coords, bias)"; | 2672 | if (!depth_compare_extra) { |
| 2673 | texture = "texture(" + sampler + ", coords, " + lod_value + ')'; | ||
| 2674 | } else { | ||
| 2675 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2676 | LOG_WARNING(HW_GPU, | ||
| 2677 | "OpenGL Limitation: can't set bias value along depth compare"); | ||
| 2678 | } | ||
| 2647 | break; | 2679 | break; |
| 2648 | } | 2680 | } |
| 2649 | case Tegra::Shader::TextureProcessMode::LL: | 2681 | case Tegra::Shader::TextureProcessMode::LL: |
| 2650 | case Tegra::Shader::TextureProcessMode::LLA: { | 2682 | case Tegra::Shader::TextureProcessMode::LLA: { |
| 2651 | const std::string lod = [&]() { | ||
| 2652 | if (num_coordinates <= 2) { | ||
| 2653 | return regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2654 | } else { | ||
| 2655 | return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2656 | } | ||
| 2657 | }(); | ||
| 2658 | shader.AddLine("float lod = " + lod + ';'); | ||
| 2659 | |||
| 2660 | // TODO: Figure if A suffix changes the equation at all. | 2683 | // TODO: Figure if A suffix changes the equation at all. |
| 2661 | texture = "textureLod(" + sampler + ", coords, lod)"; | 2684 | if (!depth_compare_extra) { |
| 2685 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | ||
| 2686 | } else { | ||
| 2687 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2688 | LOG_WARNING(HW_GPU, | ||
| 2689 | "OpenGL Limitation: can't set lod value along depth compare"); | ||
| 2690 | } | ||
| 2662 | break; | 2691 | break; |
| 2663 | } | 2692 | } |
| 2664 | default: { | 2693 | default: { |
| 2665 | texture = "texture(" + sampler + ", coords)"; | 2694 | if (!depth_compare_extra) { |
| 2695 | texture = "texture(" + sampler + ", coords)"; | ||
| 2696 | } else { | ||
| 2697 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2698 | } | ||
| 2666 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | 2699 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", |
| 2667 | static_cast<u32>(instr.tex.GetTextureProcessMode())); | 2700 | static_cast<u32>(instr.tex.GetTextureProcessMode())); |
| 2668 | } | 2701 | } |
| 2669 | } | 2702 | } |
| 2670 | if (!depth_compare) { | 2703 | if (!depth_compare) { |
| 2704 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 2671 | std::size_t dest_elem{}; | 2705 | std::size_t dest_elem{}; |
| 2672 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2706 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| 2673 | if (!instr.tex.IsComponentEnabled(elem)) { | 2707 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 2674 | // Skip disabled components | 2708 | // Skip disabled components |
| 2675 | continue; | 2709 | continue; |
| 2676 | } | 2710 | } |
| 2677 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); | 2711 | regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, |
| 2712 | dest_elem); | ||
| 2678 | ++dest_elem; | 2713 | ++dest_elem; |
| 2679 | } | 2714 | } |
| 2680 | } else { | 2715 | } else { |
| 2681 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | 2716 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |
| 2682 | } | 2717 | } |
| 2683 | --shader.scope; | 2718 | --shader.scope; |
| 2684 | shader.AddLine("}"); | 2719 | shader.AddLine('}'); |
| 2685 | break; | 2720 | break; |
| 2686 | } | 2721 | } |
| 2687 | case OpCode::Id::TEXS: { | 2722 | case OpCode::Id::TEXS: { |
| @@ -2694,41 +2729,76 @@ private: | |||
| 2694 | const bool depth_compare = | 2729 | const bool depth_compare = |
| 2695 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2730 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2696 | u32 num_coordinates = TextureCoordinates(texture_type); | 2731 | u32 num_coordinates = TextureCoordinates(texture_type); |
| 2697 | if (depth_compare) | 2732 | const auto process_mode = instr.texs.GetTextureProcessMode(); |
| 2698 | num_coordinates += 1; | 2733 | std::string lod_value; |
| 2699 | 2734 | std::string coord; | |
| 2700 | // Scope to avoid variable name overlaps. | 2735 | u32 lod_offset = 0; |
| 2701 | shader.AddLine('{'); | 2736 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { |
| 2702 | ++shader.scope; | 2737 | if (num_coordinates > 2) { |
| 2738 | lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2739 | lod_offset = 2; | ||
| 2740 | } else { | ||
| 2741 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2742 | lod_offset = 1; | ||
| 2743 | } | ||
| 2744 | } | ||
| 2703 | 2745 | ||
| 2704 | switch (num_coordinates) { | 2746 | switch (num_coordinates) { |
| 2747 | case 1: { | ||
| 2748 | coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; | ||
| 2749 | break; | ||
| 2750 | } | ||
| 2705 | case 2: { | 2751 | case 2: { |
| 2706 | if (is_array) { | 2752 | if (is_array) { |
| 2707 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2753 | if (depth_compare) { |
| 2708 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2754 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| 2709 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2755 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2710 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); | 2756 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2757 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2758 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | ||
| 2759 | ");"; | ||
| 2760 | } else { | ||
| 2761 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2762 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2763 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2764 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | ||
| 2765 | } | ||
| 2711 | } else { | 2766 | } else { |
| 2712 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2767 | if (lod_offset != 0) { |
| 2713 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2768 | if (depth_compare) { |
| 2714 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); | 2769 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2770 | const std::string y = | ||
| 2771 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2772 | const std::string z = | ||
| 2773 | regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | ||
| 2774 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2775 | } else { | ||
| 2776 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2777 | const std::string y = | ||
| 2778 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2779 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2780 | } | ||
| 2781 | } else { | ||
| 2782 | if (depth_compare) { | ||
| 2783 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2784 | const std::string y = | ||
| 2785 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2786 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2787 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2788 | } else { | ||
| 2789 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2790 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2791 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2792 | } | ||
| 2793 | } | ||
| 2715 | } | 2794 | } |
| 2716 | break; | 2795 | break; |
| 2717 | } | 2796 | } |
| 2718 | case 3: { | 2797 | case 3: { |
| 2719 | if (is_array) { | 2798 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2720 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 2799 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2721 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2800 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |
| 2722 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); | 2801 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |
| 2723 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2724 | shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||
| 2725 | index + ");"); | ||
| 2726 | } else { | ||
| 2727 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2728 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2729 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2730 | shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); | ||
| 2731 | } | ||
| 2732 | break; | 2802 | break; |
| 2733 | } | 2803 | } |
| 2734 | default: | 2804 | default: |
| @@ -2738,14 +2808,14 @@ private: | |||
| 2738 | // Fallback to interpreting as a 2D texture for now | 2808 | // Fallback to interpreting as a 2D texture for now |
| 2739 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 2809 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 2740 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 2810 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 2741 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); | 2811 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 2742 | texture_type = Tegra::Shader::TextureType::Texture2D; | 2812 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 2743 | is_array = false; | 2813 | is_array = false; |
| 2744 | } | 2814 | } |
| 2745 | const std::string sampler = | 2815 | const std::string sampler = |
| 2746 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | 2816 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); |
| 2747 | std::string texture; | 2817 | std::string texture; |
| 2748 | switch (instr.texs.GetTextureProcessMode()) { | 2818 | switch (process_mode) { |
| 2749 | case Tegra::Shader::TextureProcessMode::None: { | 2819 | case Tegra::Shader::TextureProcessMode::None: { |
| 2750 | texture = "texture(" + sampler + ", coords)"; | 2820 | texture = "texture(" + sampler + ", coords)"; |
| 2751 | break; | 2821 | break; |
| @@ -2759,8 +2829,7 @@ private: | |||
| 2759 | break; | 2829 | break; |
| 2760 | } | 2830 | } |
| 2761 | case Tegra::Shader::TextureProcessMode::LL: { | 2831 | case Tegra::Shader::TextureProcessMode::LL: { |
| 2762 | const std::string op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | 2832 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; |
| 2763 | texture = "textureLod(" + sampler + ", coords, " + op_c + ')'; | ||
| 2764 | break; | 2833 | break; |
| 2765 | } | 2834 | } |
| 2766 | default: { | 2835 | default: { |
| @@ -2770,13 +2839,11 @@ private: | |||
| 2770 | } | 2839 | } |
| 2771 | } | 2840 | } |
| 2772 | if (!depth_compare) { | 2841 | if (!depth_compare) { |
| 2773 | WriteTexsInstruction(instr, texture); | 2842 | WriteTexsInstruction(instr, coord, texture); |
| 2774 | } else { | 2843 | } else { |
| 2775 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); | 2844 | WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); |
| 2776 | } | 2845 | } |
| 2777 | 2846 | ||
| 2778 | shader.AddLine('}'); | ||
| 2779 | --shader.scope; | ||
| 2780 | break; | 2847 | break; |
| 2781 | } | 2848 | } |
| 2782 | case OpCode::Id::TLDS: { | 2849 | case OpCode::Id::TLDS: { |
| @@ -2798,11 +2865,12 @@ private: | |||
| 2798 | // Scope to avoid variable name overlaps. | 2865 | // Scope to avoid variable name overlaps. |
| 2799 | shader.AddLine('{'); | 2866 | shader.AddLine('{'); |
| 2800 | ++shader.scope; | 2867 | ++shader.scope; |
| 2868 | std::string coords; | ||
| 2801 | 2869 | ||
| 2802 | switch (texture_type) { | 2870 | switch (texture_type) { |
| 2803 | case Tegra::Shader::TextureType::Texture1D: { | 2871 | case Tegra::Shader::TextureType::Texture1D: { |
| 2804 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2872 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2805 | shader.AddLine("int coords = " + x + ';'); | 2873 | coords = "float coords = " + x + ';'; |
| 2806 | break; | 2874 | break; |
| 2807 | } | 2875 | } |
| 2808 | case Tegra::Shader::TextureType::Texture2D: { | 2876 | case Tegra::Shader::TextureType::Texture2D: { |
| @@ -2810,7 +2878,8 @@ private: | |||
| 2810 | 2878 | ||
| 2811 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2879 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2812 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 2880 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 2813 | shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); | 2881 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2882 | coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | ||
| 2814 | extra_op_offset = 1; | 2883 | extra_op_offset = 1; |
| 2815 | break; | 2884 | break; |
| 2816 | } | 2885 | } |
| @@ -2838,7 +2907,7 @@ private: | |||
| 2838 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); | 2907 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); |
| 2839 | } | 2908 | } |
| 2840 | } | 2909 | } |
| 2841 | WriteTexsInstruction(instr, texture); | 2910 | WriteTexsInstruction(instr, coords, texture); |
| 2842 | 2911 | ||
| 2843 | --shader.scope; | 2912 | --shader.scope; |
| 2844 | shader.AddLine('}'); | 2913 | shader.AddLine('}'); |
| @@ -2897,14 +2966,17 @@ private: | |||
| 2897 | 2966 | ||
| 2898 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2967 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2899 | std::to_string(instr.tld4.component) + ')'; | 2968 | std::to_string(instr.tld4.component) + ')'; |
| 2969 | |||
| 2900 | if (!depth_compare) { | 2970 | if (!depth_compare) { |
| 2971 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 2901 | std::size_t dest_elem{}; | 2972 | std::size_t dest_elem{}; |
| 2902 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2973 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| 2903 | if (!instr.tex.IsComponentEnabled(elem)) { | 2974 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 2904 | // Skip disabled components | 2975 | // Skip disabled components |
| 2905 | continue; | 2976 | continue; |
| 2906 | } | 2977 | } |
| 2907 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); | 2978 | regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, |
| 2979 | dest_elem); | ||
| 2908 | ++dest_elem; | 2980 | ++dest_elem; |
| 2909 | } | 2981 | } |
| 2910 | } else { | 2982 | } else { |
| @@ -2925,6 +2997,7 @@ private: | |||
| 2925 | // Scope to avoid variable name overlaps. | 2997 | // Scope to avoid variable name overlaps. |
| 2926 | shader.AddLine('{'); | 2998 | shader.AddLine('{'); |
| 2927 | ++shader.scope; | 2999 | ++shader.scope; |
| 3000 | std::string coords; | ||
| 2928 | 3001 | ||
| 2929 | const bool depth_compare = | 3002 | const bool depth_compare = |
| 2930 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 3003 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| @@ -2934,20 +3007,19 @@ private: | |||
| 2934 | const std::string sampler = GetSampler( | 3007 | const std::string sampler = GetSampler( |
| 2935 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | 3008 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |
| 2936 | if (!depth_compare) { | 3009 | if (!depth_compare) { |
| 2937 | shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); | 3010 | coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; |
| 2938 | } else { | 3011 | } else { |
| 2939 | // Note: TLD4S coordinate encoding works just like TEXS's | 3012 | // Note: TLD4S coordinate encoding works just like TEXS's |
| 2940 | shader.AddLine( | 3013 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 2941 | "float op_y = " + regs.GetRegisterAsFloat(instr.gpr8.Value() + 1) + ';'); | 3014 | coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; |
| 2942 | shader.AddLine("vec3 coords = vec3(" + op_a + ", op_y, " + op_b + ");"); | ||
| 2943 | } | 3015 | } |
| 2944 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 3016 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2945 | std::to_string(instr.tld4s.component) + ')'; | 3017 | std::to_string(instr.tld4s.component) + ')'; |
| 2946 | 3018 | ||
| 2947 | if (!depth_compare) { | 3019 | if (!depth_compare) { |
| 2948 | WriteTexsInstruction(instr, texture); | 3020 | WriteTexsInstruction(instr, coords, texture); |
| 2949 | } else { | 3021 | } else { |
| 2950 | WriteTexsInstruction(instr, "vec4(" + texture + ')'); | 3022 | WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); |
| 2951 | } | 3023 | } |
| 2952 | 3024 | ||
| 2953 | --shader.scope; | 3025 | --shader.scope; |