summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h57
-rw-r--r--src/video_core/shader/decode/video.cpp58
-rw-r--r--src/video_core/shader/shader_ir.h3
3 files changed, 117 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 498936f0c..c66c66f6c 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -290,6 +290,23 @@ enum class VmadShr : u64 {
290 Shr15 = 2, 290 Shr15 = 2,
291}; 291};
292 292
293enum class VmnmxType : u64 {
294 Bits8,
295 Bits16,
296 Bits32,
297};
298
299enum class VmnmxOperation : u64 {
300 Mrg_16H = 0,
301 Mrg_16L = 1,
302 Mrg_8B0 = 2,
303 Mrg_8B2 = 3,
304 Acc = 4,
305 Min = 5,
306 Max = 6,
307 Nop = 7,
308};
309
293enum class XmadMode : u64 { 310enum class XmadMode : u64 {
294 None = 0, 311 None = 0,
295 CLo = 1, 312 CLo = 1,
@@ -1651,6 +1668,42 @@ union Instruction {
1651 } vmad; 1668 } vmad;
1652 1669
1653 union { 1670 union {
1671 BitField<54, 1, u64> is_dest_signed;
1672 BitField<48, 1, u64> is_src_a_signed;
1673 BitField<49, 1, u64> is_src_b_signed;
1674 BitField<37, 2, u64> src_format_a;
1675 BitField<29, 2, u64> src_format_b;
1676 BitField<56, 1, u64> mx;
1677 BitField<55, 1, u64> sat;
1678 BitField<36, 2, u64> selector_a;
1679 BitField<28, 2, u64> selector_b;
1680 BitField<50, 1, u64> is_op_b_register;
1681 BitField<51, 3, VmnmxOperation> operation;
1682
1683 VmnmxType SourceFormatA() const {
1684 switch (src_format_a) {
1685 case 0b11:
1686 return VmnmxType::Bits32;
1687 case 0b10:
1688 return VmnmxType::Bits16;
1689 default:
1690 return VmnmxType::Bits8;
1691 }
1692 }
1693
1694 VmnmxType SourceFormatB() const {
1695 switch (src_format_b) {
1696 case 0b11:
1697 return VmnmxType::Bits32;
1698 case 0b10:
1699 return VmnmxType::Bits16;
1700 default:
1701 return VmnmxType::Bits8;
1702 }
1703 }
1704 } vmnmx;
1705
1706 union {
1654 BitField<20, 16, u64> imm20_16; 1707 BitField<20, 16, u64> imm20_16;
1655 BitField<35, 1, u64> high_b_rr; // used on RR 1708 BitField<35, 1, u64> high_b_rr; // used on RR
1656 BitField<36, 1, u64> product_shift_left; 1709 BitField<36, 1, u64> product_shift_left;
@@ -1763,6 +1816,7 @@ public:
1763 MEMBAR, 1816 MEMBAR,
1764 VMAD, 1817 VMAD,
1765 VSETP, 1818 VSETP,
1819 VMNMX,
1766 FFMA_IMM, // Fused Multiply and Add 1820 FFMA_IMM, // Fused Multiply and Add
1767 FFMA_CR, 1821 FFMA_CR,
1768 FFMA_RC, 1822 FFMA_RC,
@@ -2070,6 +2124,7 @@ private:
2070 INST("1110111110011---", Id::MEMBAR, Type::Trivial, "MEMBAR"), 2124 INST("1110111110011---", Id::MEMBAR, Type::Trivial, "MEMBAR"),
2071 INST("01011111--------", Id::VMAD, Type::Video, "VMAD"), 2125 INST("01011111--------", Id::VMAD, Type::Video, "VMAD"),
2072 INST("0101000011110---", Id::VSETP, Type::Video, "VSETP"), 2126 INST("0101000011110---", Id::VSETP, Type::Video, "VSETP"),
2127 INST("0011101---------", Id::VMNMX, Type::Video, "VMNMX"),
2073 INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), 2128 INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"),
2074 INST("010010011-------", Id::FFMA_CR, Type::Ffma, "FFMA_CR"), 2129 INST("010010011-------", Id::FFMA_CR, Type::Ffma, "FFMA_CR"),
2075 INST("010100011-------", Id::FFMA_RC, Type::Ffma, "FFMA_RC"), 2130 INST("010100011-------", Id::FFMA_RC, Type::Ffma, "FFMA_RC"),
@@ -2170,7 +2225,7 @@ private:
2170 INST("0011011-11111---", Id::SHF_LEFT_IMM, Type::Shift, "SHF_LEFT_IMM"), 2225 INST("0011011-11111---", Id::SHF_LEFT_IMM, Type::Shift, "SHF_LEFT_IMM"),
2171 INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), 2226 INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"),
2172 INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), 2227 INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"),
2173 INST("0011101-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), 2228 INST("0011100-11100---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"),
2174 INST("0100110010111---", Id::I2F_C, Type::Conversion, "I2F_C"), 2229 INST("0100110010111---", Id::I2F_C, Type::Conversion, "I2F_C"),
2175 INST("0101110010111---", Id::I2F_R, Type::Conversion, "I2F_R"), 2230 INST("0101110010111---", Id::I2F_R, Type::Conversion, "I2F_R"),
2176 INST("0011100-10111---", Id::I2F_IMM, Type::Conversion, "I2F_IMM"), 2231 INST("0011100-10111---", Id::I2F_IMM, Type::Conversion, "I2F_IMM"),
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index b047cf870..64ba60ea2 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -10,16 +10,24 @@
10 10
11namespace VideoCommon::Shader { 11namespace VideoCommon::Shader {
12 12
13using std::move;
13using Tegra::Shader::Instruction; 14using Tegra::Shader::Instruction;
14using Tegra::Shader::OpCode; 15using Tegra::Shader::OpCode;
15using Tegra::Shader::Pred; 16using Tegra::Shader::Pred;
16using Tegra::Shader::VideoType; 17using Tegra::Shader::VideoType;
17using Tegra::Shader::VmadShr; 18using Tegra::Shader::VmadShr;
19using Tegra::Shader::VmnmxOperation;
20using Tegra::Shader::VmnmxType;
18 21
19u32 ShaderIR::DecodeVideo(NodeBlock& bb, u32 pc) { 22u32 ShaderIR::DecodeVideo(NodeBlock& bb, u32 pc) {
20 const Instruction instr = {program_code[pc]}; 23 const Instruction instr = {program_code[pc]};
21 const auto opcode = OpCode::Decode(instr); 24 const auto opcode = OpCode::Decode(instr);
22 25
26 if (opcode->get().GetId() == OpCode::Id::VMNMX) {
27 DecodeVMNMX(bb, instr);
28 return pc;
29 }
30
23 const Node op_a = 31 const Node op_a =
24 GetVideoOperand(GetRegister(instr.gpr8), instr.video.is_byte_chunk_a, instr.video.signed_a, 32 GetVideoOperand(GetRegister(instr.gpr8), instr.video.is_byte_chunk_a, instr.video.signed_a,
25 instr.video.type_a, instr.video.byte_height_a); 33 instr.video.type_a, instr.video.byte_height_a);
@@ -109,4 +117,54 @@ Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed,
109 } 117 }
110} 118}
111 119
120void ShaderIR::DecodeVMNMX(NodeBlock& bb, Tegra::Shader::Instruction instr) {
121 UNIMPLEMENTED_IF(!instr.vmnmx.is_op_b_register);
122 UNIMPLEMENTED_IF(instr.vmnmx.SourceFormatA() != VmnmxType::Bits32);
123 UNIMPLEMENTED_IF(instr.vmnmx.SourceFormatB() != VmnmxType::Bits32);
124 UNIMPLEMENTED_IF(instr.vmnmx.is_src_a_signed != instr.vmnmx.is_src_b_signed);
125 UNIMPLEMENTED_IF(instr.vmnmx.sat);
126 UNIMPLEMENTED_IF(instr.generates_cc);
127
128 Node op_a = GetRegister(instr.gpr8);
129 Node op_b = GetRegister(instr.gpr20);
130 Node op_c = GetRegister(instr.gpr39);
131
132 const bool is_oper1_signed = instr.vmnmx.is_src_a_signed; // Stubbed
133 const bool is_oper2_signed = instr.vmnmx.is_dest_signed;
134
135 const auto operation_a = instr.vmnmx.mx ? OperationCode::IMax : OperationCode::IMin;
136 Node value = SignedOperation(operation_a, is_oper1_signed, move(op_a), move(op_b));
137
138 switch (instr.vmnmx.operation) {
139 case VmnmxOperation::Mrg_16H:
140 value = BitfieldInsert(move(op_c), move(value), 16, 16);
141 break;
142 case VmnmxOperation::Mrg_16L:
143 value = BitfieldInsert(move(op_c), move(value), 0, 16);
144 break;
145 case VmnmxOperation::Mrg_8B0:
146 value = BitfieldInsert(move(op_c), move(value), 0, 8);
147 break;
148 case VmnmxOperation::Mrg_8B2:
149 value = BitfieldInsert(move(op_c), move(value), 16, 8);
150 break;
151 case VmnmxOperation::Acc:
152 value = Operation(OperationCode::IAdd, move(value), move(op_c));
153 break;
154 case VmnmxOperation::Min:
155 value = SignedOperation(OperationCode::IMin, is_oper2_signed, move(value), move(op_c));
156 break;
157 case VmnmxOperation::Max:
158 value = SignedOperation(OperationCode::IMax, is_oper2_signed, move(value), move(op_c));
159 break;
160 case VmnmxOperation::Nop:
161 break;
162 default:
163 UNREACHABLE();
164 break;
165 }
166
167 SetRegister(bb, instr.gpr0, move(value));
168}
169
112} // namespace VideoCommon::Shader 170} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index ca6c976c9..c6e7bdf50 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -354,6 +354,9 @@ private:
354 /// Marks the usage of a input or output attribute. 354 /// Marks the usage of a input or output attribute.
355 void MarkAttributeUsage(Tegra::Shader::Attribute::Index index, u64 element); 355 void MarkAttributeUsage(Tegra::Shader::Attribute::Index index, u64 element);
356 356
357 /// Decodes VMNMX instruction and inserts its code into the passed basic block.
358 void DecodeVMNMX(NodeBlock& bb, Tegra::Shader::Instruction instr);
359
357 void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 360 void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
358 const Node4& components); 361 const Node4& components);
359 362