summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Marcos2018-12-04 14:24:35 -0300
committerGravatar bunnei2018-12-04 12:24:35 -0500
commitab2108fb2a485abd50c4ea9459c807f37e8bc3dd (patch)
tree3036e6edf8cd10af87b90b2ab54efa2a5359bc00
parentMerge pull request #1857 from lioncash/res-info (diff)
downloadyuzu-ab2108fb2a485abd50c4ea9459c807f37e8bc3dd.tar.gz
yuzu-ab2108fb2a485abd50c4ea9459c807f37e8bc3dd.tar.xz
yuzu-ab2108fb2a485abd50c4ea9459c807f37e8bc3dd.zip
Rewrited TEX/TEXS (TEX Scalar). (#1826)
* Rewrited TEX/TEXS (TEX Scalar). * Style fixes. * Styles issues.
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp436
1 files changed, 177 insertions, 259 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index d235bfcd4..8d68156bf 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1515,6 +1515,161 @@ private:
1515 } 1515 }
1516 } 1516 }
1517 1517
1518 std::pair<size_t, std::string> ValidateAndGetCoordinateElement(
1519 const Tegra::Shader::TextureType texture_type, const bool depth_compare,
1520 const bool is_array, const bool lod_bias_enabled, size_t max_coords, size_t max_inputs) {
1521 const size_t coord_count = TextureCoordinates(texture_type);
1522
1523 size_t total_coord_count = coord_count + (is_array ? 1 : 0) + (depth_compare ? 1 : 0);
1524 const size_t total_reg_count = total_coord_count + (lod_bias_enabled ? 1 : 0);
1525 if (total_coord_count > max_coords || total_reg_count > max_inputs) {
1526 UNIMPLEMENTED_MSG("Unsupported Texture operation");
1527 total_coord_count = std::min(total_coord_count, max_coords);
1528 }
1529 // 1D.DC opengl is using a vec3 but 2nd component is ignored later.
1530 total_coord_count +=
1531 (depth_compare && !is_array && texture_type == Tegra::Shader::TextureType::Texture1D)
1532 ? 1
1533 : 0;
1534
1535 constexpr std::array<const char*, 5> coord_container{
1536 {"", "float coord = (", "vec2 coord = vec2(", "vec3 coord = vec3(",
1537 "vec4 coord = vec4("}};
1538
1539 return std::pair<size_t, std::string>(coord_count, coord_container[total_coord_count]);
1540 }
1541
1542 std::string GetTextureCode(const Tegra::Shader::Instruction& instr,
1543 const Tegra::Shader::TextureType texture_type,
1544 const Tegra::Shader::TextureProcessMode process_mode,
1545 const bool depth_compare, const bool is_array,
1546 const size_t bias_offset) {
1547
1548 if ((texture_type == Tegra::Shader::TextureType::Texture3D &&
1549 (is_array || depth_compare)) ||
1550 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array &&
1551 depth_compare)) {
1552 UNIMPLEMENTED_MSG("This method is not supported.");
1553 }
1554
1555 const std::string sampler =
1556 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
1557
1558 const bool lod_needed = process_mode == Tegra::Shader::TextureProcessMode::LZ ||
1559 process_mode == Tegra::Shader::TextureProcessMode::LL ||
1560 process_mode == Tegra::Shader::TextureProcessMode::LLA;
1561
1562 const bool gl_lod_supported = !(
1563 (texture_type == Tegra::Shader::TextureType::Texture2D && is_array && depth_compare) ||
1564 (texture_type == Tegra::Shader::TextureType::TextureCube && !is_array &&
1565 depth_compare));
1566
1567 const std::string read_method = lod_needed && gl_lod_supported ? "textureLod(" : "texture(";
1568 std::string texture = read_method + sampler + ", coord";
1569
1570 if (process_mode != Tegra::Shader::TextureProcessMode::None) {
1571 if (process_mode == Tegra::Shader::TextureProcessMode::LZ) {
1572 if (gl_lod_supported) {
1573 texture += ", 0";
1574 } else {
1575 // Lod 0 is emulated by a big negative bias
1576 // in scenarios that are not supported by glsl
1577 texture += ", -1000";
1578 }
1579 } else {
1580 // If present, lod or bias are always stored in the register indexed by the
1581 // gpr20
1582 // field with an offset depending on the usage of the other registers
1583 texture += ',' + regs.GetRegisterAsFloat(instr.gpr20.Value() + bias_offset);
1584 }
1585 }
1586 texture += ")";
1587 return texture;
1588 }
1589
1590 std::pair<std::string, std::string> GetTEXCode(
1591 const Instruction& instr, const Tegra::Shader::TextureType texture_type,
1592 const Tegra::Shader::TextureProcessMode process_mode, const bool depth_compare,
1593 const bool is_array) {
1594 const bool lod_bias_enabled = (process_mode != Tegra::Shader::TextureProcessMode::None &&
1595 process_mode != Tegra::Shader::TextureProcessMode::LZ);
1596
1597 const auto [coord_count, coord_dcl] = ValidateAndGetCoordinateElement(
1598 texture_type, depth_compare, is_array, lod_bias_enabled, 4, 5);
1599 // If enabled arrays index is always stored in the gpr8 field
1600 const u64 array_register = instr.gpr8.Value();
1601 // First coordinate index is the gpr8 or gpr8 + 1 when arrays are used
1602 const u64 coord_register = array_register + (is_array ? 1 : 0);
1603
1604 std::string coord = coord_dcl;
1605 for (size_t i = 0; i < coord_count;) {
1606 coord += regs.GetRegisterAsFloat(coord_register + i);
1607 ++i;
1608 if (i != coord_count) {
1609 coord += ',';
1610 }
1611 }
1612 // 1D.DC in opengl the 2nd component is ignored.
1613 if (depth_compare && !is_array && texture_type == Tegra::Shader::TextureType::Texture1D) {
1614 coord += ",0.0";
1615 }
1616 if (depth_compare) {
1617 // Depth is always stored in the register signaled by gpr20
1618 // or in the next register if lod or bias are used
1619 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
1620 coord += ',' + regs.GetRegisterAsFloat(depth_register);
1621 }
1622 if (is_array) {
1623 coord += ',' + regs.GetRegisterAsInteger(array_register);
1624 }
1625 coord += ");";
1626 return std::make_pair(
1627 coord, GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, 0));
1628 }
1629
1630 std::pair<std::string, std::string> GetTEXSCode(
1631 const Instruction& instr, const Tegra::Shader::TextureType texture_type,
1632 const Tegra::Shader::TextureProcessMode process_mode, const bool depth_compare,
1633 const bool is_array) {
1634 const bool lod_bias_enabled = (process_mode != Tegra::Shader::TextureProcessMode::None &&
1635 process_mode != Tegra::Shader::TextureProcessMode::LZ);
1636
1637 const auto [coord_count, coord_dcl] = ValidateAndGetCoordinateElement(
1638 texture_type, depth_compare, is_array, lod_bias_enabled, 4, 4);
1639 // If enabled arrays index is always stored in the gpr8 field
1640 const u64 array_register = instr.gpr8.Value();
1641 // First coordinate index is stored in gpr8 field or (gpr8 + 1) when arrays are used
1642 const u64 coord_register = array_register + (is_array ? 1 : 0);
1643 const u64 last_coord_register =
1644 (is_array || !(lod_bias_enabled || depth_compare) || (coord_count > 2))
1645 ? static_cast<u64>(instr.gpr20.Value())
1646 : coord_register + 1;
1647
1648 std::string coord = coord_dcl;
1649 for (size_t i = 0; i < coord_count; ++i) {
1650 const bool last = (i == (coord_count - 1)) && (coord_count > 1);
1651 coord += regs.GetRegisterAsFloat(last ? last_coord_register : coord_register + i);
1652 if (!last) {
1653 coord += ',';
1654 }
1655 }
1656
1657 if (depth_compare) {
1658 // Depth is always stored in the register signaled by gpr20
1659 // or in the next register if lod or bias are used
1660 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
1661 coord += ',' + regs.GetRegisterAsFloat(depth_register);
1662 }
1663 if (is_array) {
1664 coord += ',' + regs.GetRegisterAsInteger(array_register);
1665 }
1666 coord += ");";
1667
1668 return std::make_pair(coord,
1669 GetTextureCode(instr, texture_type, process_mode, depth_compare,
1670 is_array, (coord_count > 2 ? 1 : 0)));
1671 }
1672
1518 /** 1673 /**
1519 * Compiles a single instruction from Tegra to GLSL. 1674 * Compiles a single instruction from Tegra to GLSL.
1520 * @param offset the offset of the Tegra shader instruction. 1675 * @param offset the offset of the Tegra shader instruction.
@@ -2574,168 +2729,32 @@ private:
2574 case OpCode::Id::TEX: { 2729 case OpCode::Id::TEX: {
2575 Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; 2730 Tegra::Shader::TextureType texture_type{instr.tex.texture_type};
2576 const bool is_array = instr.tex.array != 0; 2731 const bool is_array = instr.tex.array != 0;
2577 2732 const bool depth_compare =
2733 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2734 const auto process_mode = instr.tex.GetTextureProcessMode();
2578 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2735 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2579 "NODEP is not implemented"); 2736 "NODEP is not implemented");
2580 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 2737 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
2581 "AOFFI is not implemented"); 2738 "AOFFI is not implemented");
2582 2739
2583 const bool depth_compare = 2740 const auto [coord, texture] =
2584 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2741 GetTEXCode(instr, texture_type, process_mode, depth_compare, is_array);
2585 u32 num_coordinates = TextureCoordinates(texture_type);
2586 u32 start_index = 0;
2587 std::string array_elem;
2588 if (is_array) {
2589 array_elem = regs.GetRegisterAsInteger(instr.gpr8);
2590 start_index = 1;
2591 }
2592 const auto process_mode = instr.tex.GetTextureProcessMode();
2593 u32 start_index_b = 0;
2594 std::string lod_value;
2595 if (process_mode != Tegra::Shader::TextureProcessMode::LZ &&
2596 process_mode != Tegra::Shader::TextureProcessMode::None) {
2597 start_index_b = 1;
2598 lod_value = regs.GetRegisterAsFloat(instr.gpr20);
2599 }
2600
2601 std::string depth_value;
2602 if (depth_compare) {
2603 depth_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + start_index_b);
2604 }
2605
2606 bool depth_compare_extra = false;
2607 2742
2608 const auto scope = shader.Scope(); 2743 const auto scope = shader.Scope();
2609 2744 shader.AddLine(coord);
2610 switch (num_coordinates) {
2611 case 1: {
2612 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2613 if (is_array) {
2614 if (depth_compare) {
2615 shader.AddLine("vec3 coords = vec3(" + x + ", " + depth_value + ", " +
2616 array_elem + ");");
2617 } else {
2618 shader.AddLine("vec2 coords = vec2(" + x + ", " + array_elem + ");");
2619 }
2620 } else {
2621 if (depth_compare) {
2622 shader.AddLine("vec2 coords = vec2(" + x + ", " + depth_value + ");");
2623 } else {
2624 shader.AddLine("float coords = " + x + ';');
2625 }
2626 }
2627 break;
2628 }
2629 case 2: {
2630 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2631 const std::string y =
2632 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1);
2633 if (is_array) {
2634 if (depth_compare) {
2635 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " +
2636 depth_value + ", " + array_elem + ");");
2637 } else {
2638 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2639 array_elem + ");");
2640 }
2641 } else {
2642 if (depth_compare) {
2643 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " +
2644 depth_value + ");");
2645 } else {
2646 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2647 }
2648 }
2649 break;
2650 }
2651 case 3: {
2652 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2653 const std::string y =
2654 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1);
2655 const std::string z =
2656 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2);
2657 if (is_array) {
2658 depth_compare_extra = depth_compare;
2659 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2660 array_elem + ");");
2661 } else {
2662 if (depth_compare) {
2663 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2664 depth_value + ");");
2665 } else {
2666 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");");
2667 }
2668 }
2669 break;
2670 }
2671 default:
2672 UNIMPLEMENTED_MSG("Unhandled coordinates number {}",
2673 static_cast<u32>(num_coordinates));
2674
2675 // Fallback to interpreting as a 2D texture for now
2676 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2677 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2678 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2679 texture_type = Tegra::Shader::TextureType::Texture2D;
2680 }
2681
2682 const std::string sampler =
2683 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
2684 // Add an extra scope and declare the texture coords inside to prevent
2685 // overwriting them in case they are used as outputs of the texs instruction.
2686
2687 const std::string texture = [&]() {
2688 switch (instr.tex.GetTextureProcessMode()) {
2689 case Tegra::Shader::TextureProcessMode::None:
2690 if (depth_compare_extra) {
2691 return "texture(" + sampler + ", coords, " + depth_value + ')';
2692 }
2693 return "texture(" + sampler + ", coords)";
2694 case Tegra::Shader::TextureProcessMode::LZ:
2695 if (depth_compare_extra) {
2696 return "texture(" + sampler + ", coords, " + depth_value + ')';
2697 }
2698 return "textureLod(" + sampler + ", coords, 0.0)";
2699 case Tegra::Shader::TextureProcessMode::LB:
2700 case Tegra::Shader::TextureProcessMode::LBA:
2701 // TODO: Figure if A suffix changes the equation at all.
2702 if (depth_compare_extra) {
2703 LOG_WARNING(
2704 HW_GPU,
2705 "OpenGL Limitation: can't set bias value along depth compare");
2706 return "texture(" + sampler + ", coords, " + depth_value + ')';
2707 }
2708 return "texture(" + sampler + ", coords, " + lod_value + ')';
2709 case Tegra::Shader::TextureProcessMode::LL:
2710 case Tegra::Shader::TextureProcessMode::LLA:
2711 // TODO: Figure if A suffix changes the equation at all.
2712 if (depth_compare_extra) {
2713 LOG_WARNING(
2714 HW_GPU,
2715 "OpenGL Limitation: can't set lod value along depth compare");
2716 return "texture(" + sampler + ", coords, " + depth_value + ')';
2717 }
2718 return "textureLod(" + sampler + ", coords, " + lod_value + ')';
2719 default:
2720 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2721 static_cast<u32>(instr.tex.GetTextureProcessMode()));
2722 if (depth_compare_extra) {
2723 return "texture(" + sampler + ", coords, " + depth_value + ')';
2724 }
2725 return "texture(" + sampler + ", coords)";
2726 }
2727 }();
2728 2745
2729 if (depth_compare) { 2746 if (depth_compare) {
2730 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); 2747 regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false);
2731 } else { 2748 } else {
2749 shader.AddLine("vec4 texture_tmp = " + texture + ';');
2732 std::size_t dest_elem{}; 2750 std::size_t dest_elem{};
2733 for (std::size_t elem = 0; elem < 4; ++elem) { 2751 for (std::size_t elem = 0; elem < 4; ++elem) {
2734 if (!instr.tex.IsComponentEnabled(elem)) { 2752 if (!instr.tex.IsComponentEnabled(elem)) {
2735 // Skip disabled components 2753 // Skip disabled components
2736 continue; 2754 continue;
2737 } 2755 }
2738 regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); 2756 regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false,
2757 dest_elem);
2739 ++dest_elem; 2758 ++dest_elem;
2740 } 2759 }
2741 } 2760 }
@@ -2743,129 +2762,28 @@ private:
2743 } 2762 }
2744 case OpCode::Id::TEXS: { 2763 case OpCode::Id::TEXS: {
2745 Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; 2764 Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()};
2746 bool is_array{instr.texs.IsArrayTexture()}; 2765 const bool is_array{instr.texs.IsArrayTexture()};
2747 2766 const bool depth_compare =
2767 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2768 const auto process_mode = instr.texs.GetTextureProcessMode();
2748 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2769 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2749 "NODEP is not implemented"); 2770 "NODEP is not implemented");
2750 2771
2751 const auto scope = shader.Scope(); 2772 const auto scope = shader.Scope();
2752 2773
2753 const bool depth_compare = 2774 const auto [coord, texture] =
2754 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2775 GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array);
2755 u32 num_coordinates = TextureCoordinates(texture_type);
2756 const auto process_mode = instr.texs.GetTextureProcessMode();
2757 u32 lod_offset = 0;
2758 if (process_mode == Tegra::Shader::TextureProcessMode::LL) {
2759 if (num_coordinates > 2) {
2760 shader.AddLine("float lod_value = " +
2761 regs.GetRegisterAsFloat(instr.gpr20.Value() + 1) + ';');
2762 lod_offset = 2;
2763 } else {
2764 shader.AddLine("float lod_value = " + regs.GetRegisterAsFloat(instr.gpr20) +
2765 ';');
2766 lod_offset = 1;
2767 }
2768 }
2769 2776
2770 switch (num_coordinates) { 2777 shader.AddLine(coord);
2771 case 1: {
2772 shader.AddLine("float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';');
2773 break;
2774 }
2775 case 2: {
2776 if (is_array) {
2777 if (depth_compare) {
2778 const std::string index = regs.GetRegisterAsInteger(instr.gpr8);
2779 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2780 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2781 const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1);
2782 shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2783 index + ");");
2784 } else {
2785 const std::string index = regs.GetRegisterAsInteger(instr.gpr8);
2786 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2787 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2788 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index +
2789 ");");
2790 }
2791 } else {
2792 if (lod_offset != 0) {
2793 if (depth_compare) {
2794 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2795 const std::string y =
2796 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2797 const std::string z =
2798 regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset);
2799 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z +
2800 ");");
2801 } else {
2802 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2803 const std::string y =
2804 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2805 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2806 }
2807 } else {
2808 if (depth_compare) {
2809 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2810 const std::string y =
2811 regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2812 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2813 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z +
2814 ");");
2815 } else {
2816 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2817 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2818 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2819 }
2820 }
2821 }
2822 break;
2823 }
2824 case 3: {
2825 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2826 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2827 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2828 shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");");
2829 break;
2830 }
2831 default:
2832 UNIMPLEMENTED_MSG("Unhandled coordinates number {}",
2833 static_cast<u32>(num_coordinates));
2834 2778
2835 // Fallback to interpreting as a 2D texture for now 2779 if (!depth_compare) {
2836 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2780 shader.AddLine("vec4 texture_tmp = " + texture + ';');
2837 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
2838 shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");");
2839 texture_type = Tegra::Shader::TextureType::Texture2D;
2840 is_array = false;
2841 }
2842 const std::string sampler =
2843 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
2844 2781
2845 std::string texture = [&]() { 2782 } else {
2846 switch (process_mode) { 2783 shader.AddLine("vec4 texture_tmp = vec4(" + texture + ");");
2847 case Tegra::Shader::TextureProcessMode::None:
2848 return "texture(" + sampler + ", coords)";
2849 case Tegra::Shader::TextureProcessMode::LZ:
2850 if (depth_compare && is_array) {
2851 return "texture(" + sampler + ", coords)";
2852 } else {
2853 return "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)";
2862 }
2863 }();
2864 if (depth_compare) {
2865 texture = "vec4(" + texture + ')';
2866 } 2784 }
2867 2785
2868 WriteTexsInstruction(instr, texture); 2786 WriteTexsInstruction(instr, "texture_tmp");
2869 break; 2787 break;
2870 } 2788 }
2871 case OpCode::Id::TLDS: { 2789 case OpCode::Id::TLDS: {
@@ -3934,4 +3852,4 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u
3934 return {}; 3852 return {};
3935} 3853}
3936 3854
3937} // namespace OpenGL::GLShader::Decompiler 3855} // namespace OpenGL::GLShader::Decompiler \ No newline at end of file