diff options
| author | 2019-12-06 18:18:16 -0500 | |
|---|---|---|
| committer | 2019-12-06 18:18:16 -0500 | |
| commit | e36814d6d592167cbb9c5440cb7b1f9bbb33449c (patch) | |
| tree | fb93c0eeaa46d1ee738f9373cbb1b858e79ca37a /src/video_core/shader/decode | |
| 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
Diffstat (limited to 'src/video_core/shader/decode')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 53 |
2 files changed, 65 insertions, 7 deletions
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; |