diff options
| author | 2018-12-23 00:38:01 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:52 -0300 | |
| commit | ec98e4d842d5ba04b329c866f5c9b1e7314069f2 (patch) | |
| tree | e767cf2354e536cb45dcd2ce349153b8ee945c3a /src | |
| parent | shader_ir: Fixup TEX and TEXS and partially fix TLD4 decompiling (diff) | |
| download | yuzu-ec98e4d842d5ba04b329c866f5c9b1e7314069f2.tar.gz yuzu-ec98e4d842d5ba04b329c866f5c9b1e7314069f2.tar.xz yuzu-ec98e4d842d5ba04b329c866f5c9b1e7314069f2.zip | |
shader_decode: Update TLD4 reflecting #1862 changes
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 101 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 3 |
2 files changed, 52 insertions, 52 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 500a32af5..cfdb92807 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -225,7 +225,6 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, u32 pc) { | |||
| 225 | break; | 225 | break; |
| 226 | } | 226 | } |
| 227 | case OpCode::Id::TLD4: { | 227 | case OpCode::Id::TLD4: { |
| 228 | ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); | ||
| 229 | ASSERT(instr.tld4.array == 0); | 228 | ASSERT(instr.tld4.array == 0); |
| 230 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI), | 229 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI), |
| 231 | "AOFFI is not implemented"); | 230 | "AOFFI is not implemented"); |
| @@ -238,63 +237,29 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, u32 pc) { | |||
| 238 | LOG_WARNING(HW_GPU, "TLD4.NODEP implementation is incomplete"); | 237 | LOG_WARNING(HW_GPU, "TLD4.NODEP implementation is incomplete"); |
| 239 | } | 238 | } |
| 240 | 239 | ||
| 240 | const auto texture_type = instr.tld4.texture_type.Value(); | ||
| 241 | const bool depth_compare = instr.tld4.UsesMiscMode(TextureMiscMode::DC); | 241 | const bool depth_compare = instr.tld4.UsesMiscMode(TextureMiscMode::DC); |
| 242 | auto texture_type = instr.tld4.texture_type.Value(); | 242 | const bool is_array = instr.tld4.array != 0; |
| 243 | u32 num_coordinates = static_cast<u32>(GetCoordCount(texture_type)); | 243 | const Node texture = GetTld4Code(instr, texture_type, depth_compare, is_array); |
| 244 | if (depth_compare) | ||
| 245 | num_coordinates += 1; | ||
| 246 | 244 | ||
| 247 | std::vector<Node> params; | 245 | MetaComponents meta_components; |
| 248 | 246 | std::array<Node, 4> dest; | |
| 249 | switch (num_coordinates) { | ||
| 250 | case 2: { | ||
| 251 | params.push_back(GetRegister(instr.gpr8)); | ||
| 252 | params.push_back(GetRegister(instr.gpr8.Value() + 1)); | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | case 3: { | ||
| 256 | params.push_back(GetRegister(instr.gpr8)); | ||
| 257 | params.push_back(GetRegister(instr.gpr8.Value() + 1)); | ||
| 258 | params.push_back(GetRegister(instr.gpr8.Value() + 2)); | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | default: | ||
| 262 | UNIMPLEMENTED_MSG("Unhandled coordinates number {}", static_cast<u32>(num_coordinates)); | ||
| 263 | params.push_back(GetRegister(instr.gpr8)); | ||
| 264 | params.push_back(GetRegister(instr.gpr8.Value() + 1)); | ||
| 265 | num_coordinates = 2; | ||
| 266 | texture_type = Tegra::Shader::TextureType::Texture2D; | ||
| 267 | } | ||
| 268 | params.push_back(Immediate(static_cast<u32>(instr.tld4.component))); | ||
| 269 | |||
| 270 | const auto& sampler = GetSampler(instr.sampler, texture_type, false, depth_compare); | ||
| 271 | MetaTexture meta{sampler, num_coordinates}; | ||
| 272 | |||
| 273 | const Node texture = | ||
| 274 | Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params)); | ||
| 275 | |||
| 276 | if (depth_compare) { | ||
| 277 | SetRegister(bb, instr.gpr0, texture); | ||
| 278 | } else { | ||
| 279 | MetaComponents meta; | ||
| 280 | std::array<Node, 4> dest; | ||
| 281 | |||
| 282 | std::size_t dest_elem = 0; | ||
| 283 | for (std::size_t elem = 0; elem < 4; ++elem) { | ||
| 284 | if (!instr.tex.IsComponentEnabled(elem)) { | ||
| 285 | // Skip disabled components | ||
| 286 | continue; | ||
| 287 | } | ||
| 288 | meta.components_map[dest_elem] = static_cast<u32>(elem); | ||
| 289 | dest[dest_elem] = GetRegister(instr.gpr0.Value() + dest_elem); | ||
| 290 | 247 | ||
| 291 | ++dest_elem; | 248 | std::size_t dest_elem = 0; |
| 249 | for (std::size_t elem = 0; elem < 4; ++elem) { | ||
| 250 | if (!instr.tex.IsComponentEnabled(elem)) { | ||
| 251 | // Skip disabled components | ||
| 252 | continue; | ||
| 292 | } | 253 | } |
| 293 | std::generate(dest.begin() + dest_elem, dest.end(), [&]() { return GetRegister(RZ); }); | 254 | meta_components.components_map[dest_elem] = static_cast<u32>(elem); |
| 255 | dest[dest_elem] = GetRegister(instr.gpr0.Value() + dest_elem); | ||
| 294 | 256 | ||
| 295 | bb.push_back(Operation(OperationCode::AssignComposite, std::move(meta), texture, | 257 | ++dest_elem; |
| 296 | dest[0], dest[1], dest[2], dest[3])); | ||
| 297 | } | 258 | } |
| 259 | std::generate(dest.begin() + dest_elem, dest.end(), [&]() { return GetRegister(RZ); }); | ||
| 260 | |||
| 261 | bb.push_back(Operation(OperationCode::AssignComposite, std::move(meta_components), texture, | ||
| 262 | dest[0], dest[1], dest[2], dest[3])); | ||
| 298 | break; | 263 | break; |
| 299 | } | 264 | } |
| 300 | case OpCode::Id::TLD4S: { | 265 | case OpCode::Id::TLD4S: { |
| @@ -595,6 +560,38 @@ Node ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type, | |||
| 595 | (coord_count > 2 ? 1 : 0), std::move(coords)); | 560 | (coord_count > 2 ? 1 : 0), std::move(coords)); |
| 596 | } | 561 | } |
| 597 | 562 | ||
| 563 | Node ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare, | ||
| 564 | bool is_array) { | ||
| 565 | const std::size_t coord_count = GetCoordCount(texture_type); | ||
| 566 | const std::size_t total_coord_count = coord_count + (is_array ? 1 : 0); | ||
| 567 | const std::size_t total_reg_count = total_coord_count + (depth_compare ? 1 : 0); | ||
| 568 | |||
| 569 | // If enabled arrays index is always stored in the gpr8 field | ||
| 570 | const u64 array_register = instr.gpr8.Value(); | ||
| 571 | // First coordinate index is the gpr8 or gpr8 + 1 when arrays are used | ||
| 572 | const u64 coord_register = array_register + (is_array ? 1 : 0); | ||
| 573 | |||
| 574 | std::vector<Node> params; | ||
| 575 | |||
| 576 | for (size_t i = 0; i < coord_count; ++i) { | ||
| 577 | params.push_back(GetRegister(coord_register + i)); | ||
| 578 | } | ||
| 579 | std::size_t array_offset{}; | ||
| 580 | if (is_array) { | ||
| 581 | array_offset = params.size(); | ||
| 582 | params.push_back(GetRegister(array_register)); | ||
| 583 | } | ||
| 584 | |||
| 585 | const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||
| 586 | |||
| 587 | std::optional<u32> array_offset_value; | ||
| 588 | if (is_array) | ||
| 589 | array_offset_value = static_cast<u32>(array_offset); | ||
| 590 | MetaTexture meta{sampler, static_cast<u32>(params.size()), array_offset_value}; | ||
| 591 | |||
| 592 | return Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params)); | ||
| 593 | } | ||
| 594 | |||
| 598 | std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement( | 595 | std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement( |
| 599 | TextureType texture_type, bool depth_compare, bool is_array, bool lod_bias_enabled, | 596 | TextureType texture_type, bool depth_compare, bool is_array, bool lod_bias_enabled, |
| 600 | std::size_t max_coords, std::size_t max_inputs) { | 597 | std::size_t max_coords, std::size_t max_inputs) { |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 5939318c1..691bd6d72 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -691,6 +691,9 @@ private: | |||
| 691 | Tegra::Shader::TextureProcessMode process_mode, bool depth_compare, | 691 | Tegra::Shader::TextureProcessMode process_mode, bool depth_compare, |
| 692 | bool is_array); | 692 | bool is_array); |
| 693 | 693 | ||
| 694 | Node GetTld4Code(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | ||
| 695 | bool depth_compare, bool is_array); | ||
| 696 | |||
| 694 | std::tuple<std::size_t, std::size_t> ValidateAndGetCoordinateElement( | 697 | std::tuple<std::size_t, std::size_t> ValidateAndGetCoordinateElement( |
| 695 | Tegra::Shader::TextureType texture_type, bool depth_compare, bool is_array, | 698 | Tegra::Shader::TextureType texture_type, bool depth_compare, bool is_array, |
| 696 | bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs); | 699 | bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs); |