diff options
| author | 2019-12-06 18:18:16 -0500 | |
|---|---|---|
| committer | 2019-12-06 18:18:16 -0500 | |
| commit | e36814d6d592167cbb9c5440cb7b1f9bbb33449c (patch) | |
| tree | fb93c0eeaa46d1ee738f9373cbb1b858e79ca37a | |
| parent | Merge pull request #3196 from jmerdich/fix-ea-source-build (diff) | |
| parent | Shader_IR: Address Feedback (diff) | |
| download | yuzu-e36814d6d592167cbb9c5440cb7b1f9bbb33449c.tar.gz yuzu-e36814d6d592167cbb9c5440cb7b1f9bbb33449c.tar.xz yuzu-e36814d6d592167cbb9c5440cb7b1f9bbb33449c.zip | |
Merge pull request #3109 from FernandoS27/new-instr
Implement FLO & TXD Instructions on GPU Shaders
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 44 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 51 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 53 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 4 |
6 files changed, 171 insertions, 8 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 9fafed4a2..9c7b9b370 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -800,6 +800,12 @@ union Instruction { | |||
| 800 | } popc; | 800 | } popc; |
| 801 | 801 | ||
| 802 | union { | 802 | union { |
| 803 | BitField<41, 1, u64> sh; | ||
| 804 | BitField<40, 1, u64> invert; | ||
| 805 | BitField<48, 1, u64> is_signed; | ||
| 806 | } flo; | ||
| 807 | |||
| 808 | union { | ||
| 803 | BitField<39, 3, u64> pred; | 809 | BitField<39, 3, u64> pred; |
| 804 | BitField<42, 1, u64> neg_pred; | 810 | BitField<42, 1, u64> neg_pred; |
| 805 | } sel; | 811 | } sel; |
| @@ -1440,6 +1446,26 @@ union Instruction { | |||
| 1440 | } tlds; | 1446 | } tlds; |
| 1441 | 1447 | ||
| 1442 | union { | 1448 | union { |
| 1449 | BitField<28, 1, u64> is_array; | ||
| 1450 | BitField<29, 2, TextureType> texture_type; | ||
| 1451 | BitField<35, 1, u64> aoffi_flag; | ||
| 1452 | BitField<49, 1, u64> nodep_flag; | ||
| 1453 | |||
| 1454 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 1455 | switch (mode) { | ||
| 1456 | case TextureMiscMode::AOFFI: | ||
| 1457 | return aoffi_flag != 0; | ||
| 1458 | case TextureMiscMode::NODEP: | ||
| 1459 | return nodep_flag != 0; | ||
| 1460 | default: | ||
| 1461 | break; | ||
| 1462 | } | ||
| 1463 | return false; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | } txd; | ||
| 1467 | |||
| 1468 | union { | ||
| 1443 | BitField<24, 2, StoreCacheManagement> cache_management; | 1469 | BitField<24, 2, StoreCacheManagement> cache_management; |
| 1444 | BitField<33, 3, ImageType> image_type; | 1470 | BitField<33, 3, ImageType> image_type; |
| 1445 | BitField<49, 2, OutOfBoundsStore> out_of_bounds_store; | 1471 | BitField<49, 2, OutOfBoundsStore> out_of_bounds_store; |
| @@ -1632,6 +1658,8 @@ public: | |||
| 1632 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations | 1658 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations |
| 1633 | TMML_B, // Texture Mip Map Level | 1659 | TMML_B, // Texture Mip Map Level |
| 1634 | TMML, // Texture Mip Map Level | 1660 | TMML, // Texture Mip Map Level |
| 1661 | TXD, // Texture Gradient/Load with Derivates | ||
| 1662 | TXD_B, // Texture Gradient/Load with Derivates Bindless | ||
| 1635 | SUST, // Surface Store | 1663 | SUST, // Surface Store |
| 1636 | SULD, // Surface Load | 1664 | SULD, // Surface Load |
| 1637 | SUATOM, // Surface Atomic Operation | 1665 | SUATOM, // Surface Atomic Operation |
| @@ -1664,6 +1692,9 @@ public: | |||
| 1664 | ISCADD_C, // Scale and Add | 1692 | ISCADD_C, // Scale and Add |
| 1665 | ISCADD_R, | 1693 | ISCADD_R, |
| 1666 | ISCADD_IMM, | 1694 | ISCADD_IMM, |
| 1695 | FLO_R, | ||
| 1696 | FLO_C, | ||
| 1697 | FLO_IMM, | ||
| 1667 | LEA_R1, | 1698 | LEA_R1, |
| 1668 | LEA_R2, | 1699 | LEA_R2, |
| 1669 | LEA_RZ, | 1700 | LEA_RZ, |
| @@ -1727,6 +1758,10 @@ public: | |||
| 1727 | SHR_C, | 1758 | SHR_C, |
| 1728 | SHR_R, | 1759 | SHR_R, |
| 1729 | SHR_IMM, | 1760 | SHR_IMM, |
| 1761 | SHF_RIGHT_R, | ||
| 1762 | SHF_RIGHT_IMM, | ||
| 1763 | SHF_LEFT_R, | ||
| 1764 | SHF_LEFT_IMM, | ||
| 1730 | FMNMX_C, | 1765 | FMNMX_C, |
| 1731 | FMNMX_R, | 1766 | FMNMX_R, |
| 1732 | FMNMX_IMM, | 1767 | FMNMX_IMM, |
| @@ -1924,6 +1959,8 @@ private: | |||
| 1924 | INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"), | 1959 | INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"), |
| 1925 | INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"), | 1960 | INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"), |
| 1926 | INST("1101111101011---", Id::TMML, Type::Texture, "TMML"), | 1961 | INST("1101111101011---", Id::TMML, Type::Texture, "TMML"), |
| 1962 | INST("11011110011110--", Id::TXD_B, Type::Texture, "TXD_B"), | ||
| 1963 | INST("11011110001110--", Id::TXD, Type::Texture, "TXD"), | ||
| 1927 | INST("11101011001-----", Id::SUST, Type::Image, "SUST"), | 1964 | INST("11101011001-----", Id::SUST, Type::Image, "SUST"), |
| 1928 | INST("11101011000-----", Id::SULD, Type::Image, "SULD"), | 1965 | INST("11101011000-----", Id::SULD, Type::Image, "SULD"), |
| 1929 | INST("1110101000------", Id::SUATOM, Type::Image, "SUATOM_D"), | 1966 | INST("1110101000------", Id::SUATOM, Type::Image, "SUATOM_D"), |
| @@ -1965,6 +2002,9 @@ private: | |||
| 1965 | INST("010110110100----", Id::ICMP_R, Type::ArithmeticInteger, "ICMP_R"), | 2002 | INST("010110110100----", Id::ICMP_R, Type::ArithmeticInteger, "ICMP_R"), |
| 1966 | INST("010010110100----", Id::ICMP_CR, Type::ArithmeticInteger, "ICMP_CR"), | 2003 | INST("010010110100----", Id::ICMP_CR, Type::ArithmeticInteger, "ICMP_CR"), |
| 1967 | INST("0011011-0100----", Id::ICMP_IMM, Type::ArithmeticInteger, "ICMP_IMM"), | 2004 | INST("0011011-0100----", Id::ICMP_IMM, Type::ArithmeticInteger, "ICMP_IMM"), |
| 2005 | INST("0101110000110---", Id::FLO_R, Type::ArithmeticInteger, "FLO_R"), | ||
| 2006 | INST("0100110000110---", Id::FLO_C, Type::ArithmeticInteger, "FLO_C"), | ||
| 2007 | INST("0011100-00110---", Id::FLO_IMM, Type::ArithmeticInteger, "FLO_IMM"), | ||
| 1968 | INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"), | 2008 | INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"), |
| 1969 | INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"), | 2009 | INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"), |
| 1970 | INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"), | 2010 | INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"), |
| @@ -2022,6 +2062,10 @@ private: | |||
| 2022 | INST("0100110000101---", Id::SHR_C, Type::Shift, "SHR_C"), | 2062 | INST("0100110000101---", Id::SHR_C, Type::Shift, "SHR_C"), |
| 2023 | INST("0101110000101---", Id::SHR_R, Type::Shift, "SHR_R"), | 2063 | INST("0101110000101---", Id::SHR_R, Type::Shift, "SHR_R"), |
| 2024 | INST("0011100-00101---", Id::SHR_IMM, Type::Shift, "SHR_IMM"), | 2064 | INST("0011100-00101---", Id::SHR_IMM, Type::Shift, "SHR_IMM"), |
| 2065 | INST("0101110011111---", Id::SHF_RIGHT_R, Type::Shift, "SHF_RIGHT_R"), | ||
| 2066 | INST("0011100-11111---", Id::SHF_RIGHT_IMM, Type::Shift, "SHF_RIGHT_IMM"), | ||
| 2067 | INST("0101101111111---", Id::SHF_LEFT_R, Type::Shift, "SHF_LEFT_R"), | ||
| 2068 | INST("0011011-11111---", Id::SHF_LEFT_IMM, Type::Shift, "SHF_LEFT_IMM"), | ||
| 2025 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), | 2069 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), |
| 2026 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), | 2070 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), |
| 2027 | INST("0011101-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), | 2071 | INST("0011101-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 0e644564a..3d3cd21f3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -49,8 +49,9 @@ class ExprDecompiler; | |||
| 49 | enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat }; | 49 | enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat }; |
| 50 | 50 | ||
| 51 | struct TextureAoffi {}; | 51 | struct TextureAoffi {}; |
| 52 | struct TextureDerivates {}; | ||
| 52 | using TextureArgument = std::pair<Type, Node>; | 53 | using TextureArgument = std::pair<Type, Node>; |
| 53 | using TextureIR = std::variant<TextureAoffi, TextureArgument>; | 54 | using TextureIR = std::variant<TextureAoffi, TextureDerivates, TextureArgument>; |
| 54 | 55 | ||
| 55 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = | 56 | constexpr u32 MAX_CONSTBUFFER_ELEMENTS = |
| 56 | static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float)); | 57 | static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float)); |
| @@ -1112,6 +1113,8 @@ private: | |||
| 1112 | expr += GenerateTextureArgument(*argument); | 1113 | expr += GenerateTextureArgument(*argument); |
| 1113 | } else if (std::holds_alternative<TextureAoffi>(variant)) { | 1114 | } else if (std::holds_alternative<TextureAoffi>(variant)) { |
| 1114 | expr += GenerateTextureAoffi(meta->aoffi); | 1115 | expr += GenerateTextureAoffi(meta->aoffi); |
| 1116 | } else if (std::holds_alternative<TextureDerivates>(variant)) { | ||
| 1117 | expr += GenerateTextureDerivates(meta->derivates); | ||
| 1115 | } else { | 1118 | } else { |
| 1116 | UNREACHABLE(); | 1119 | UNREACHABLE(); |
| 1117 | } | 1120 | } |
| @@ -1181,6 +1184,36 @@ private: | |||
| 1181 | return expr; | 1184 | return expr; |
| 1182 | } | 1185 | } |
| 1183 | 1186 | ||
| 1187 | std::string GenerateTextureDerivates(const std::vector<Node>& derivates) { | ||
| 1188 | if (derivates.empty()) { | ||
| 1189 | return {}; | ||
| 1190 | } | ||
| 1191 | constexpr std::array coord_constructors = {"float", "vec2", "vec3"}; | ||
| 1192 | std::string expr = ", "; | ||
| 1193 | const std::size_t components = derivates.size() / 2; | ||
| 1194 | std::string dx = coord_constructors.at(components - 1); | ||
| 1195 | std::string dy = coord_constructors.at(components - 1); | ||
| 1196 | dx += '('; | ||
| 1197 | dy += '('; | ||
| 1198 | |||
| 1199 | for (std::size_t index = 0; index < components; ++index) { | ||
| 1200 | const auto operand_x{derivates.at(index * 2)}; | ||
| 1201 | const auto operand_y{derivates.at(index * 2 + 1)}; | ||
| 1202 | dx += Visit(operand_x).AsFloat(); | ||
| 1203 | dy += Visit(operand_y).AsFloat(); | ||
| 1204 | |||
| 1205 | if (index + 1 < components) { | ||
| 1206 | dx += ", "; | ||
| 1207 | dy += ", "; | ||
| 1208 | } | ||
| 1209 | } | ||
| 1210 | dx += ')'; | ||
| 1211 | dy += ')'; | ||
| 1212 | expr += dx + ", " + dy; | ||
| 1213 | |||
| 1214 | return expr; | ||
| 1215 | } | ||
| 1216 | |||
| 1184 | std::string BuildIntegerCoordinates(Operation operation) { | 1217 | std::string BuildIntegerCoordinates(Operation operation) { |
| 1185 | constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("}; | 1218 | constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("}; |
| 1186 | const std::size_t coords_count{operation.GetOperandsCount()}; | 1219 | const std::size_t coords_count{operation.GetOperandsCount()}; |
| @@ -1450,6 +1483,11 @@ private: | |||
| 1450 | return GenerateUnary(operation, "bitCount", type, type); | 1483 | return GenerateUnary(operation, "bitCount", type, type); |
| 1451 | } | 1484 | } |
| 1452 | 1485 | ||
| 1486 | template <Type type> | ||
| 1487 | Expression BitMSB(Operation operation) { | ||
| 1488 | return GenerateUnary(operation, "findMSB", type, type); | ||
| 1489 | } | ||
| 1490 | |||
| 1453 | Expression HNegate(Operation operation) { | 1491 | Expression HNegate(Operation operation) { |
| 1454 | const auto GetNegate = [&](std::size_t index) { | 1492 | const auto GetNegate = [&](std::size_t index) { |
| 1455 | return VisitOperand(operation, index).AsBool() + " ? -1 : 1"; | 1493 | return VisitOperand(operation, index).AsBool() + " ? -1 : 1"; |
| @@ -1738,6 +1776,14 @@ private: | |||
| 1738 | return {std::move(expr), Type::Float}; | 1776 | return {std::move(expr), Type::Float}; |
| 1739 | } | 1777 | } |
| 1740 | 1778 | ||
| 1779 | Expression TextureGradient(Operation operation) { | ||
| 1780 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | ||
| 1781 | ASSERT(meta); | ||
| 1782 | |||
| 1783 | std::string expr = GenerateTexture(operation, "Grad", {TextureDerivates{}, TextureAoffi{}}); | ||
| 1784 | return {std::move(expr) + GetSwizzle(meta->element), Type::Float}; | ||
| 1785 | } | ||
| 1786 | |||
| 1741 | Expression ImageLoad(Operation operation) { | 1787 | Expression ImageLoad(Operation operation) { |
| 1742 | if (!device.HasImageLoadFormatted()) { | 1788 | if (!device.HasImageLoadFormatted()) { |
| 1743 | LOG_ERROR(Render_OpenGL, | 1789 | LOG_ERROR(Render_OpenGL, |
| @@ -2003,6 +2049,7 @@ private: | |||
| 2003 | &GLSLDecompiler::BitfieldInsert<Type::Int>, | 2049 | &GLSLDecompiler::BitfieldInsert<Type::Int>, |
| 2004 | &GLSLDecompiler::BitfieldExtract<Type::Int>, | 2050 | &GLSLDecompiler::BitfieldExtract<Type::Int>, |
| 2005 | &GLSLDecompiler::BitCount<Type::Int>, | 2051 | &GLSLDecompiler::BitCount<Type::Int>, |
| 2052 | &GLSLDecompiler::BitMSB<Type::Int>, | ||
| 2006 | 2053 | ||
| 2007 | &GLSLDecompiler::Add<Type::Uint>, | 2054 | &GLSLDecompiler::Add<Type::Uint>, |
| 2008 | &GLSLDecompiler::Mul<Type::Uint>, | 2055 | &GLSLDecompiler::Mul<Type::Uint>, |
| @@ -2021,6 +2068,7 @@ private: | |||
| 2021 | &GLSLDecompiler::BitfieldInsert<Type::Uint>, | 2068 | &GLSLDecompiler::BitfieldInsert<Type::Uint>, |
| 2022 | &GLSLDecompiler::BitfieldExtract<Type::Uint>, | 2069 | &GLSLDecompiler::BitfieldExtract<Type::Uint>, |
| 2023 | &GLSLDecompiler::BitCount<Type::Uint>, | 2070 | &GLSLDecompiler::BitCount<Type::Uint>, |
| 2071 | &GLSLDecompiler::BitMSB<Type::Uint>, | ||
| 2024 | 2072 | ||
| 2025 | &GLSLDecompiler::Add<Type::HalfFloat>, | 2073 | &GLSLDecompiler::Add<Type::HalfFloat>, |
| 2026 | &GLSLDecompiler::Mul<Type::HalfFloat>, | 2074 | &GLSLDecompiler::Mul<Type::HalfFloat>, |
| @@ -2084,6 +2132,7 @@ private: | |||
| 2084 | &GLSLDecompiler::TextureQueryDimensions, | 2132 | &GLSLDecompiler::TextureQueryDimensions, |
| 2085 | &GLSLDecompiler::TextureQueryLod, | 2133 | &GLSLDecompiler::TextureQueryLod, |
| 2086 | &GLSLDecompiler::TexelFetch, | 2134 | &GLSLDecompiler::TexelFetch, |
| 2135 | &GLSLDecompiler::TextureGradient, | ||
| 2087 | 2136 | ||
| 2088 | &GLSLDecompiler::ImageLoad, | 2137 | &GLSLDecompiler::ImageLoad, |
| 2089 | &GLSLDecompiler::ImageStore, | 2138 | &GLSLDecompiler::ImageStore, |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 80738d3d0..76894275b 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -983,6 +983,11 @@ private: | |||
| 983 | return {}; | 983 | return {}; |
| 984 | } | 984 | } |
| 985 | 985 | ||
| 986 | Id TextureGradient(Operation operation) { | ||
| 987 | UNIMPLEMENTED(); | ||
| 988 | return {}; | ||
| 989 | } | ||
| 990 | |||
| 986 | Id ImageLoad(Operation operation) { | 991 | Id ImageLoad(Operation operation) { |
| 987 | UNIMPLEMENTED(); | 992 | UNIMPLEMENTED(); |
| 988 | return {}; | 993 | return {}; |
| @@ -1391,6 +1396,7 @@ private: | |||
| 1391 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>, | 1396 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>, |
| 1392 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>, | 1397 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>, |
| 1393 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>, | 1398 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>, |
| 1399 | &SPIRVDecompiler::Unary<&Module::OpFindSMsb, Type::Int>, | ||
| 1394 | 1400 | ||
| 1395 | &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>, | 1401 | &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>, |
| 1396 | &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>, | 1402 | &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>, |
| @@ -1409,6 +1415,7 @@ private: | |||
| 1409 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>, | 1415 | &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>, |
| 1410 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>, | 1416 | &SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>, |
| 1411 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>, | 1417 | &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>, |
| 1418 | &SPIRVDecompiler::Unary<&Module::OpFindUMsb, Type::Uint>, | ||
| 1412 | 1419 | ||
| 1413 | &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>, | 1420 | &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>, |
| 1414 | &SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>, | 1421 | &SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>, |
| @@ -1473,6 +1480,7 @@ private: | |||
| 1473 | &SPIRVDecompiler::TextureQueryDimensions, | 1480 | &SPIRVDecompiler::TextureQueryDimensions, |
| 1474 | &SPIRVDecompiler::TextureQueryLod, | 1481 | &SPIRVDecompiler::TextureQueryLod, |
| 1475 | &SPIRVDecompiler::TexelFetch, | 1482 | &SPIRVDecompiler::TexelFetch, |
| 1483 | &SPIRVDecompiler::TextureGradient, | ||
| 1476 | 1484 | ||
| 1477 | &SPIRVDecompiler::ImageLoad, | 1485 | &SPIRVDecompiler::ImageLoad, |
| 1478 | &SPIRVDecompiler::ImageStore, | 1486 | &SPIRVDecompiler::ImageStore, |
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index a33d242e9..371fae127 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp | |||
| @@ -130,6 +130,25 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) { | |||
| 130 | SetRegister(bb, instr.gpr0, value); | 130 | SetRegister(bb, instr.gpr0, value); |
| 131 | break; | 131 | break; |
| 132 | } | 132 | } |
| 133 | case OpCode::Id::FLO_R: | ||
| 134 | case OpCode::Id::FLO_C: | ||
| 135 | case OpCode::Id::FLO_IMM: { | ||
| 136 | Node value; | ||
| 137 | if (instr.flo.invert) { | ||
| 138 | op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_b)); | ||
| 139 | } | ||
| 140 | if (instr.flo.is_signed) { | ||
| 141 | value = Operation(OperationCode::IBitMSB, NO_PRECISE, std::move(op_b)); | ||
| 142 | } else { | ||
| 143 | value = Operation(OperationCode::UBitMSB, NO_PRECISE, std::move(op_b)); | ||
| 144 | } | ||
| 145 | if (instr.flo.sh) { | ||
| 146 | value = | ||
| 147 | Operation(OperationCode::UBitwiseXor, NO_PRECISE, std::move(value), Immediate(31)); | ||
| 148 | } | ||
| 149 | SetRegister(bb, instr.gpr0, std::move(value)); | ||
| 150 | break; | ||
| 151 | } | ||
| 133 | case OpCode::Id::SEL_C: | 152 | case OpCode::Id::SEL_C: |
| 134 | case OpCode::Id::SEL_R: | 153 | case OpCode::Id::SEL_R: |
| 135 | case OpCode::Id::SEL_IMM: { | 154 | case OpCode::Id::SEL_IMM: { |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index b094e5a06..da8e886df 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -134,13 +134,52 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 134 | Node4 values; | 134 | Node4 values; |
| 135 | for (u32 element = 0; element < values.size(); ++element) { | 135 | for (u32 element = 0; element < values.size(); ++element) { |
| 136 | auto coords_copy = coords; | 136 | auto coords_copy = coords; |
| 137 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, component, element}; | 137 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, component, element}; |
| 138 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); | 138 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | WriteTexsInstructionFloat(bb, instr, values, true); | 141 | WriteTexsInstructionFloat(bb, instr, values, true); |
| 142 | break; | 142 | break; |
| 143 | } | 143 | } |
| 144 | case OpCode::Id::TXD_B: | ||
| 145 | is_bindless = true; | ||
| 146 | [[fallthrough]]; | ||
| 147 | case OpCode::Id::TXD: { | ||
| 148 | UNIMPLEMENTED_IF_MSG(instr.txd.UsesMiscMode(TextureMiscMode::AOFFI), | ||
| 149 | "AOFFI is not implemented"); | ||
| 150 | UNIMPLEMENTED_IF_MSG(instr.txd.is_array != 0, "TXD Array is not implemented"); | ||
| 151 | |||
| 152 | u64 base_reg = instr.gpr8.Value(); | ||
| 153 | const auto derivate_reg = instr.gpr20.Value(); | ||
| 154 | const auto texture_type = instr.txd.texture_type.Value(); | ||
| 155 | const auto coord_count = GetCoordCount(texture_type); | ||
| 156 | |||
| 157 | const auto& sampler = is_bindless | ||
| 158 | ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) | ||
| 159 | : GetSampler(instr.sampler, {{texture_type, false, false}}); | ||
| 160 | if (is_bindless) { | ||
| 161 | base_reg++; | ||
| 162 | } | ||
| 163 | |||
| 164 | std::vector<Node> coords; | ||
| 165 | std::vector<Node> derivates; | ||
| 166 | for (std::size_t i = 0; i < coord_count; ++i) { | ||
| 167 | coords.push_back(GetRegister(base_reg + i)); | ||
| 168 | const std::size_t derivate = i * 2; | ||
| 169 | derivates.push_back(GetRegister(derivate_reg + derivate)); | ||
| 170 | derivates.push_back(GetRegister(derivate_reg + derivate + 1)); | ||
| 171 | } | ||
| 172 | |||
| 173 | Node4 values; | ||
| 174 | for (u32 element = 0; element < values.size(); ++element) { | ||
| 175 | MetaTexture meta{sampler, {}, {}, {}, derivates, {}, {}, {}, element}; | ||
| 176 | values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords); | ||
| 177 | } | ||
| 178 | |||
| 179 | WriteTexInstructionFloat(bb, instr, values); | ||
| 180 | |||
| 181 | break; | ||
| 182 | } | ||
| 144 | case OpCode::Id::TXQ_B: | 183 | case OpCode::Id::TXQ_B: |
| 145 | is_bindless = true; | 184 | is_bindless = true; |
| 146 | [[fallthrough]]; | 185 | [[fallthrough]]; |
| @@ -158,7 +197,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 158 | if (!instr.txq.IsComponentEnabled(element)) { | 197 | if (!instr.txq.IsComponentEnabled(element)) { |
| 159 | continue; | 198 | continue; |
| 160 | } | 199 | } |
| 161 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; | 200 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; |
| 162 | const Node value = | 201 | const Node value = |
| 163 | Operation(OperationCode::TextureQueryDimensions, meta, | 202 | Operation(OperationCode::TextureQueryDimensions, meta, |
| 164 | GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); | 203 | GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); |
| @@ -212,7 +251,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 212 | continue; | 251 | continue; |
| 213 | } | 252 | } |
| 214 | auto params = coords; | 253 | auto params = coords; |
| 215 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; | 254 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; |
| 216 | const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); | 255 | const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); |
| 217 | SetTemporary(bb, indexer++, value); | 256 | SetTemporary(bb, indexer++, value); |
| 218 | } | 257 | } |
| @@ -442,7 +481,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, | |||
| 442 | Node4 values; | 481 | Node4 values; |
| 443 | for (u32 element = 0; element < values.size(); ++element) { | 482 | for (u32 element = 0; element < values.size(); ++element) { |
| 444 | auto copy_coords = coords; | 483 | auto copy_coords = coords; |
| 445 | MetaTexture meta{sampler, array, depth_compare, aoffi, bias, lod, {}, element}; | 484 | MetaTexture meta{sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element}; |
| 446 | values[element] = Operation(read_method, meta, std::move(copy_coords)); | 485 | values[element] = Operation(read_method, meta, std::move(copy_coords)); |
| 447 | } | 486 | } |
| 448 | 487 | ||
| @@ -574,7 +613,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de | |||
| 574 | Node4 values; | 613 | Node4 values; |
| 575 | for (u32 element = 0; element < values.size(); ++element) { | 614 | for (u32 element = 0; element < values.size(); ++element) { |
| 576 | auto coords_copy = coords; | 615 | auto coords_copy = coords; |
| 577 | MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, component, | 616 | MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, |
| 578 | element}; | 617 | element}; |
| 579 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); | 618 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |
| 580 | } | 619 | } |
| @@ -608,7 +647,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) { | |||
| 608 | Node4 values; | 647 | Node4 values; |
| 609 | for (u32 element = 0; element < values.size(); ++element) { | 648 | for (u32 element = 0; element < values.size(); ++element) { |
| 610 | auto coords_copy = coords; | 649 | auto coords_copy = coords; |
| 611 | MetaTexture meta{sampler, array_register, {}, {}, {}, lod, {}, element}; | 650 | MetaTexture meta{sampler, array_register, {}, {}, {}, {}, lod, {}, element}; |
| 612 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); | 651 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); |
| 613 | } | 652 | } |
| 614 | 653 | ||
| @@ -653,7 +692,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 653 | Node4 values; | 692 | Node4 values; |
| 654 | for (u32 element = 0; element < values.size(); ++element) { | 693 | for (u32 element = 0; element < values.size(); ++element) { |
| 655 | auto coords_copy = coords; | 694 | auto coords_copy = coords; |
| 656 | MetaTexture meta{sampler, array, {}, {}, {}, lod, {}, element}; | 695 | MetaTexture meta{sampler, array, {}, {}, {}, {}, lod, {}, element}; |
| 657 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); | 696 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); |
| 658 | } | 697 | } |
| 659 | return values; | 698 | return values; |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 44d85d434..b2576bdd6 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -68,6 +68,7 @@ enum class OperationCode { | |||
| 68 | IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int | 68 | IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int |
| 69 | IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int | 69 | IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int |
| 70 | IBitCount, /// (MetaArithmetic, int) -> int | 70 | IBitCount, /// (MetaArithmetic, int) -> int |
| 71 | IBitMSB, /// (MetaArithmetic, int) -> int | ||
| 71 | 72 | ||
| 72 | UAdd, /// (MetaArithmetic, uint a, uint b) -> uint | 73 | UAdd, /// (MetaArithmetic, uint a, uint b) -> uint |
| 73 | UMul, /// (MetaArithmetic, uint a, uint b) -> uint | 74 | UMul, /// (MetaArithmetic, uint a, uint b) -> uint |
| @@ -86,6 +87,7 @@ enum class OperationCode { | |||
| 86 | UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint | 87 | UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint |
| 87 | UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint | 88 | UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint |
| 88 | UBitCount, /// (MetaArithmetic, uint) -> uint | 89 | UBitCount, /// (MetaArithmetic, uint) -> uint |
| 90 | UBitMSB, /// (MetaArithmetic, uint) -> uint | ||
| 89 | 91 | ||
| 90 | HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 | 92 | HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 |
| 91 | HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 | 93 | HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 |
| @@ -149,6 +151,7 @@ enum class OperationCode { | |||
| 149 | TextureQueryDimensions, /// (MetaTexture, float a) -> float4 | 151 | TextureQueryDimensions, /// (MetaTexture, float a) -> float4 |
| 150 | TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 | 152 | TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 |
| 151 | TexelFetch, /// (MetaTexture, int[N], int) -> float4 | 153 | TexelFetch, /// (MetaTexture, int[N], int) -> float4 |
| 154 | TextureGradient, /// (MetaTexture, float[N] coords, float[N*2] derivates) -> float4 | ||
| 152 | 155 | ||
| 153 | ImageLoad, /// (MetaImage, int[N] coords) -> void | 156 | ImageLoad, /// (MetaImage, int[N] coords) -> void |
| 154 | ImageStore, /// (MetaImage, int[N] coords) -> void | 157 | ImageStore, /// (MetaImage, int[N] coords) -> void |
| @@ -367,6 +370,7 @@ struct MetaTexture { | |||
| 367 | Node array; | 370 | Node array; |
| 368 | Node depth_compare; | 371 | Node depth_compare; |
| 369 | std::vector<Node> aoffi; | 372 | std::vector<Node> aoffi; |
| 373 | std::vector<Node> derivates; | ||
| 370 | Node bias; | 374 | Node bias; |
| 371 | Node lod; | 375 | Node lod; |
| 372 | Node component{}; | 376 | Node component{}; |