summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/texture.cpp71
1 files changed, 28 insertions, 43 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 351c8c2f1..542636430 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -522,68 +522,53 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
522 Node array, Node depth_compare, u32 bias_offset, 522 Node array, Node depth_compare, u32 bias_offset,
523 std::vector<Node> aoffi, 523 std::vector<Node> aoffi,
524 std::optional<Tegra::Shader::Register> bindless_reg) { 524 std::optional<Tegra::Shader::Register> bindless_reg) {
525 const auto is_array = static_cast<bool>(array); 525 const bool is_array = array != nullptr;
526 const auto is_shadow = static_cast<bool>(depth_compare); 526 const bool is_shadow = depth_compare != nullptr;
527 const bool is_bindless = bindless_reg.has_value(); 527 const bool is_bindless = bindless_reg.has_value();
528 528
529 UNIMPLEMENTED_IF_MSG((texture_type == TextureType::Texture3D && (is_array || is_shadow)) || 529 UNIMPLEMENTED_IF(texture_type == TextureType::TextureCube && is_array && is_shadow);
530 (texture_type == TextureType::TextureCube && is_array && is_shadow), 530 ASSERT_MSG(texture_type != TextureType::Texture3D || is_array || is_shadow,
531 "This method is not supported."); 531 "Illegal texture type");
532 532
533 const SamplerInfo info{texture_type, is_array, is_shadow, false}; 533 const SamplerInfo info{texture_type, is_array, is_shadow, false};
534 Node index_var{}; 534 Node index_var;
535 const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info) 535 const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info)
536 : GetSampler(instr.sampler, info); 536 : GetSampler(instr.sampler, info);
537 Node4 values; 537 if (!sampler) {
538 if (sampler == nullptr) { 538 return {Immediate(0), Immediate(0), Immediate(0), Immediate(0)};
539 for (u32 element = 0; element < values.size(); ++element) {
540 values[element] = Immediate(0);
541 }
542 return values;
543 } 539 }
544 540
545 const bool lod_needed = process_mode == TextureProcessMode::LZ || 541 const bool lod_needed = process_mode == TextureProcessMode::LZ ||
546 process_mode == TextureProcessMode::LL || 542 process_mode == TextureProcessMode::LL ||
547 process_mode == TextureProcessMode::LLA; 543 process_mode == TextureProcessMode::LLA;
548 544 const OperationCode opcode = lod_needed ? OperationCode::TextureLod : OperationCode::Texture;
549 // LOD selection (either via bias or explicit textureLod) not supported in GL for
550 // sampler2DArrayShadow and samplerCubeArrayShadow.
551 const bool gl_lod_supported =
552 !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) ||
553 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
554
555 const OperationCode read_method =
556 (lod_needed && gl_lod_supported) ? OperationCode::TextureLod : OperationCode::Texture;
557
558 UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
559 545
560 Node bias; 546 Node bias;
561 Node lod; 547 Node lod;
562 if (process_mode != TextureProcessMode::None && gl_lod_supported) { 548 switch (process_mode) {
563 switch (process_mode) { 549 case TextureProcessMode::None:
564 case TextureProcessMode::LZ: 550 break;
565 lod = Immediate(0.0f); 551 case TextureProcessMode::LZ:
566 break; 552 lod = Immediate(0.0f);
567 case TextureProcessMode::LB: 553 break;
568 // If present, lod or bias are always stored in the register 554 case TextureProcessMode::LB:
569 // indexed by the gpr20 field with an offset depending on the 555 // If present, lod or bias are always stored in the register indexed by the gpr20 field with
570 // usage of the other registers 556 // an offset depending on the usage of the other registers.
571 bias = GetRegister(instr.gpr20.Value() + bias_offset); 557 bias = GetRegister(instr.gpr20.Value() + bias_offset);
572 break; 558 break;
573 case TextureProcessMode::LL: 559 case TextureProcessMode::LL:
574 lod = GetRegister(instr.gpr20.Value() + bias_offset); 560 lod = GetRegister(instr.gpr20.Value() + bias_offset);
575 break; 561 break;
576 default: 562 default:
577 UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode)); 563 UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode));
578 break; 564 break;
579 }
580 } 565 }
581 566
567 Node4 values;
582 for (u32 element = 0; element < values.size(); ++element) { 568 for (u32 element = 0; element < values.size(); ++element) {
583 auto copy_coords = coords;
584 MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias, 569 MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias,
585 lod, {}, element, index_var}; 570 lod, {}, element, index_var};
586 values[element] = Operation(read_method, meta, std::move(copy_coords)); 571 values[element] = Operation(opcode, meta, coords);
587 } 572 }
588 573
589 return values; 574 return values;