summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h26
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp6
-rw-r--r--src/video_core/shader/decode/image.cpp4
-rw-r--r--src/video_core/shader/decode/other.cpp2
-rw-r--r--src/video_core/shader/decode/shift.cpp2
-rw-r--r--src/video_core/shader/decode/texture.cpp8
-rw-r--r--src/video_core/shader/decode/video.cpp2
-rw-r--r--src/video_core/shader/decode/warp.cpp7
-rw-r--r--src/video_core/shader/shader_ir.h2
9 files changed, 30 insertions, 29 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 7a6355ce2..d3d05a866 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -574,7 +574,7 @@ enum class ShuffleOperation : u64 {
574}; 574};
575 575
576union Instruction { 576union Instruction {
577 Instruction& operator=(const Instruction& instr) { 577 constexpr Instruction& operator=(const Instruction& instr) {
578 value = instr.value; 578 value = instr.value;
579 return *this; 579 return *this;
580 } 580 }
@@ -1760,22 +1760,22 @@ public:
1760 1760
1761 class Matcher { 1761 class Matcher {
1762 public: 1762 public:
1763 Matcher(const char* const name, u16 mask, u16 expected, OpCode::Id id, OpCode::Type type) 1763 constexpr Matcher(const char* const name, u16 mask, u16 expected, Id id, Type type)
1764 : name{name}, mask{mask}, expected{expected}, id{id}, type{type} {} 1764 : name{name}, mask{mask}, expected{expected}, id{id}, type{type} {}
1765 1765
1766 const char* GetName() const { 1766 constexpr const char* GetName() const {
1767 return name; 1767 return name;
1768 } 1768 }
1769 1769
1770 u16 GetMask() const { 1770 constexpr u16 GetMask() const {
1771 return mask; 1771 return mask;
1772 } 1772 }
1773 1773
1774 Id GetId() const { 1774 constexpr Id GetId() const {
1775 return id; 1775 return id;
1776 } 1776 }
1777 1777
1778 Type GetType() const { 1778 constexpr Type GetType() const {
1779 return type; 1779 return type;
1780 } 1780 }
1781 1781
@@ -1784,7 +1784,7 @@ public:
1784 * @param instruction The instruction to test 1784 * @param instruction The instruction to test
1785 * @returns true if the given instruction matches. 1785 * @returns true if the given instruction matches.
1786 */ 1786 */
1787 bool Matches(u16 instruction) const { 1787 constexpr bool Matches(u16 instruction) const {
1788 return (instruction & mask) == expected; 1788 return (instruction & mask) == expected;
1789 } 1789 }
1790 1790
@@ -1818,7 +1818,7 @@ private:
1818 * A '0' in a bitstring indicates that a zero must be present at that bit position. 1818 * A '0' in a bitstring indicates that a zero must be present at that bit position.
1819 * A '1' in a bitstring indicates that a one must be present at that bit position. 1819 * A '1' in a bitstring indicates that a one must be present at that bit position.
1820 */ 1820 */
1821 static auto GetMaskAndExpect(const char* const bitstring) { 1821 static constexpr auto GetMaskAndExpect(const char* const bitstring) {
1822 u16 mask = 0, expect = 0; 1822 u16 mask = 0, expect = 0;
1823 for (std::size_t i = 0; i < opcode_bitsize; i++) { 1823 for (std::size_t i = 0; i < opcode_bitsize; i++) {
1824 const std::size_t bit_position = opcode_bitsize - i - 1; 1824 const std::size_t bit_position = opcode_bitsize - i - 1;
@@ -1835,15 +1835,15 @@ private:
1835 break; 1835 break;
1836 } 1836 }
1837 } 1837 }
1838 return std::make_tuple(mask, expect); 1838 return std::make_pair(mask, expect);
1839 } 1839 }
1840 1840
1841 public: 1841 public:
1842 /// Creates a matcher that can match and parse instructions based on bitstring. 1842 /// Creates a matcher that can match and parse instructions based on bitstring.
1843 static auto GetMatcher(const char* const bitstring, OpCode::Id op, OpCode::Type type, 1843 static constexpr auto GetMatcher(const char* const bitstring, Id op, Type type,
1844 const char* const name) { 1844 const char* const name) {
1845 const auto mask_expect = GetMaskAndExpect(bitstring); 1845 const auto [mask, expected] = GetMaskAndExpect(bitstring);
1846 return Matcher(name, std::get<0>(mask_expect), std::get<1>(mask_expect), op, type); 1846 return Matcher(name, mask, expected, op, type);
1847 } 1847 }
1848 }; 1848 };
1849 1849
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index b73f6536e..a33d242e9 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -144,7 +144,7 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
144 case OpCode::Id::ICMP_IMM: { 144 case OpCode::Id::ICMP_IMM: {
145 const Node zero = Immediate(0); 145 const Node zero = Immediate(0);
146 146
147 const auto [op_b, test] = [&]() -> std::pair<Node, Node> { 147 const auto [op_rhs, test] = [&]() -> std::pair<Node, Node> {
148 switch (opcode->get().GetId()) { 148 switch (opcode->get().GetId()) {
149 case OpCode::Id::ICMP_CR: 149 case OpCode::Id::ICMP_CR:
150 return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), 150 return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset),
@@ -161,10 +161,10 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
161 return {zero, zero}; 161 return {zero, zero};
162 } 162 }
163 }(); 163 }();
164 const Node op_a = GetRegister(instr.gpr8); 164 const Node op_lhs = GetRegister(instr.gpr8);
165 const Node comparison = 165 const Node comparison =
166 GetPredicateComparisonInteger(instr.icmp.cond, instr.icmp.is_signed != 0, test, zero); 166 GetPredicateComparisonInteger(instr.icmp.cond, instr.icmp.is_signed != 0, test, zero);
167 SetRegister(bb, instr.gpr0, Operation(OperationCode::Select, comparison, op_a, op_b)); 167 SetRegister(bb, instr.gpr0, Operation(OperationCode::Select, comparison, op_lhs, op_rhs));
168 break; 168 break;
169 } 169 }
170 case OpCode::Id::LOP_C: 170 case OpCode::Id::LOP_C:
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 95ec1cdd9..b02d2cb95 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -144,8 +144,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
144 144
145Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { 145Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) {
146 const auto offset{static_cast<std::size_t>(image.index.Value())}; 146 const auto offset{static_cast<std::size_t>(image.index.Value())};
147 if (const auto image = TryUseExistingImage(offset, type)) { 147 if (const auto existing_image = TryUseExistingImage(offset, type)) {
148 return *image; 148 return *existing_image;
149 } 149 }
150 150
151 const std::size_t next_index{used_images.size()}; 151 const std::size_t next_index{used_images.size()};
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index d46e0f823..116b95f76 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -67,7 +67,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
67 break; 67 break;
68 } 68 }
69 case OpCode::Id::MOV_SYS: { 69 case OpCode::Id::MOV_SYS: {
70 const Node value = [&]() { 70 const Node value = [this, instr] {
71 switch (instr.sys20) { 71 switch (instr.sys20) {
72 case SystemVariable::Ydirection: 72 case SystemVariable::Ydirection:
73 return Operation(OperationCode::YNegate); 73 return Operation(OperationCode::YNegate);
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index f6ee68a54..d419e9c45 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -18,7 +18,7 @@ u32 ShaderIR::DecodeShift(NodeBlock& bb, u32 pc) {
18 const auto opcode = OpCode::Decode(instr); 18 const auto opcode = OpCode::Decode(instr);
19 19
20 Node op_a = GetRegister(instr.gpr8); 20 Node op_a = GetRegister(instr.gpr8);
21 Node op_b = [&]() { 21 Node op_b = [this, instr] {
22 if (instr.is_b_imm) { 22 if (instr.is_b_imm) {
23 return Immediate(instr.alu.GetSignedImm20_20()); 23 return Immediate(instr.alu.GetSignedImm20_20());
24 } else if (instr.is_b_gpr) { 24 } else if (instr.is_b_gpr) {
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 0b934a069..295445498 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -150,7 +150,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
150 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 150 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
151 } 151 }
152 152
153 WriteTexsInstructionFloat(bb, instr, values); 153 WriteTexsInstructionFloat(bb, instr, values, true);
154 break; 154 break;
155 } 155 }
156 case OpCode::Id::TXQ_B: 156 case OpCode::Id::TXQ_B:
@@ -344,14 +344,14 @@ void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const
344 } 344 }
345} 345}
346 346
347void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr, 347void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components,
348 const Node4& components) { 348 bool ignore_mask) {
349 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle 349 // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
350 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 350 // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
351 351
352 u32 dest_elem = 0; 352 u32 dest_elem = 0;
353 for (u32 component = 0; component < 4; ++component) { 353 for (u32 component = 0; component < 4; ++component) {
354 if (!instr.texs.IsComponentEnabled(component)) 354 if (!instr.texs.IsComponentEnabled(component) && !ignore_mask)
355 continue; 355 continue;
356 SetTemporary(bb, dest_elem++, components[component]); 356 SetTemporary(bb, dest_elem++, components[component]);
357 } 357 }
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index 97fc6f9b1..b047cf870 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -23,7 +23,7 @@ u32 ShaderIR::DecodeVideo(NodeBlock& bb, u32 pc) {
23 const Node op_a = 23 const Node op_a =
24 GetVideoOperand(GetRegister(instr.gpr8), instr.video.is_byte_chunk_a, instr.video.signed_a, 24 GetVideoOperand(GetRegister(instr.gpr8), instr.video.is_byte_chunk_a, instr.video.signed_a,
25 instr.video.type_a, instr.video.byte_height_a); 25 instr.video.type_a, instr.video.byte_height_a);
26 const Node op_b = [&]() { 26 const Node op_b = [this, instr] {
27 if (instr.video.use_register_b) { 27 if (instr.video.use_register_b) {
28 return GetVideoOperand(GetRegister(instr.gpr20), instr.video.is_byte_chunk_b, 28 return GetVideoOperand(GetRegister(instr.gpr20), instr.video.is_byte_chunk_b,
29 instr.video.signed_b, instr.video.type_b, 29 instr.video.signed_b, instr.video.type_b,
diff --git a/src/video_core/shader/decode/warp.cpp b/src/video_core/shader/decode/warp.cpp
index a8e481b3c..fa8a250cc 100644
--- a/src/video_core/shader/decode/warp.cpp
+++ b/src/video_core/shader/decode/warp.cpp
@@ -46,9 +46,10 @@ u32 ShaderIR::DecodeWarp(NodeBlock& bb, u32 pc) {
46 break; 46 break;
47 } 47 }
48 case OpCode::Id::SHFL: { 48 case OpCode::Id::SHFL: {
49 Node mask = instr.shfl.is_mask_imm ? Immediate(static_cast<u32>(instr.shfl.mask_imm)) 49 Node width = [this, instr] {
50 : GetRegister(instr.gpr39); 50 Node mask = instr.shfl.is_mask_imm ? Immediate(static_cast<u32>(instr.shfl.mask_imm))
51 Node width = [&] { 51 : GetRegister(instr.gpr39);
52
52 // Convert the obscure SHFL mask back into GL_NV_shader_thread_shuffle's width. This has 53 // Convert the obscure SHFL mask back into GL_NV_shader_thread_shuffle's width. This has
53 // been done reversing Nvidia's math. It won't work on all cases due to SHFL having 54 // been done reversing Nvidia's math. It won't work on all cases due to SHFL having
54 // different parameters that don't properly map to GLSL's interface, but it should work 55 // different parameters that don't properly map to GLSL's interface, but it should work
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 91cd0a534..02ddf2a75 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -322,7 +322,7 @@ private:
322 const Node4& components); 322 const Node4& components);
323 323
324 void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 324 void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
325 const Node4& components); 325 const Node4& components, bool ignore_mask = false);
326 void WriteTexsInstructionHalfFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 326 void WriteTexsInstructionHalfFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
327 const Node4& components); 327 const Node4& components);
328 328