summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-12-23 00:38:01 -0300
committerGravatar ReinUsesLisp2019-01-15 17:54:52 -0300
commitec98e4d842d5ba04b329c866f5c9b1e7314069f2 (patch)
treee767cf2354e536cb45dcd2ce349153b8ee945c3a /src
parentshader_ir: Fixup TEX and TEXS and partially fix TLD4 decompiling (diff)
downloadyuzu-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.cpp101
-rw-r--r--src/video_core/shader/shader_ir.h3
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
563Node 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
598std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement( 595std::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);