diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 71 |
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; |