From 271a3264f33766524224462537685b6e5c691f9d Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 11 Dec 2019 13:07:30 -0400 Subject: Shader_Ir: default failed tracks on bindless samplers to null values. --- src/video_core/shader/decode/texture.cpp | 97 ++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 22 deletions(-) (limited to 'src/video_core/shader/decode/texture.cpp') diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index da8e886df..67926afcb 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -129,7 +129,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { const Node component = Immediate(static_cast(instr.tld4s.component)); const SamplerInfo info{TextureType::Texture2D, false, depth_compare}; - const auto& sampler = GetSampler(instr.sampler, info); + const Sampler& sampler = *GetSampler(instr.sampler, info); Node4 values; for (u32 element = 0; element < values.size(); ++element) { @@ -154,9 +154,17 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { const auto texture_type = instr.txd.texture_type.Value(); const auto coord_count = GetCoordCount(texture_type); - const auto& sampler = is_bindless + const Sampler* sampler = is_bindless ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) : GetSampler(instr.sampler, {{texture_type, false, false}}); + Node4 values; + if (sampler == nullptr) { + for (u32 element = 0; element < values.size(); ++element) { + values[element] = Immediate(0); + } + WriteTexInstructionFloat(bb, instr, values); + break; + } if (is_bindless) { base_reg++; } @@ -170,9 +178,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { derivates.push_back(GetRegister(derivate_reg + derivate + 1)); } - Node4 values; for (u32 element = 0; element < values.size(); ++element) { - MetaTexture meta{sampler, {}, {}, {}, derivates, {}, {}, {}, element}; + MetaTexture meta{*sampler, {}, {}, {}, derivates, {}, {}, {}, element}; values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords); } @@ -187,9 +194,24 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { // TODO: The new commits on the texture refactor, change the way samplers work. // Sadly, not all texture instructions specify the type of texture their sampler // uses. This must be fixed at a later instance. - const auto& sampler = + const Sampler* sampler = is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler); + if (sampler == nullptr) { + u32 indexer = 0; + for (u32 element = 0; element < 4; ++element) { + if (!instr.txq.IsComponentEnabled(element)) { + continue; + } + const Node value = Immediate(0); + SetTemporary(bb, indexer++, value); + } + for (u32 i = 0; i < indexer; ++i) { + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); + } + break; + } + u32 indexer = 0; switch (instr.txq.query_type) { case Tegra::Shader::TextureQueryType::Dimension: { @@ -197,7 +219,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { if (!instr.txq.IsComponentEnabled(element)) { continue; } - MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; + MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element}; const Node value = Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); @@ -223,9 +245,24 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { auto texture_type = instr.tmml.texture_type.Value(); const bool is_array = instr.tmml.array != 0; - const auto& sampler = + const Sampler* sampler = is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler); + if (sampler == nullptr) { + u32 indexer = 0; + for (u32 element = 0; element < 2; ++element) { + if (!instr.tmml.IsComponentEnabled(element)) { + continue; + } + const Node value = Immediate(0); + SetTemporary(bb, indexer++, value); + } + for (u32 i = 0; i < indexer; ++i) { + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); + } + break; + } + std::vector coords; // TODO: Add coordinates for different samplers once other texture types are implemented. @@ -251,7 +288,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { continue; } auto params = coords; - MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; + MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element}; const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); SetTemporary(bb, indexer++, value); } @@ -307,7 +344,7 @@ ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional sample sampler->is_buffer != 0}; } -const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, +const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, std::optional sampler_info) { const auto offset = static_cast(sampler.index.Value()); const auto info = GetSamplerInfo(sampler_info, offset); @@ -319,21 +356,24 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, if (it != used_samplers.end()) { ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); - return *it; + return &(*it); } // Otherwise create a new mapping for this sampler const auto next_index = static_cast(used_samplers.size()); - return used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, + return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, info.is_buffer); } -const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, +const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, std::optional sampler_info) { const Node sampler_register = GetRegister(reg); const auto [base_sampler, buffer, offset] = TrackCbuf(sampler_register, global_code, static_cast(global_code.size())); ASSERT(base_sampler != nullptr); + if (base_sampler == nullptr) { + return nullptr; + } const auto info = GetSamplerInfo(sampler_info, offset, buffer); @@ -346,12 +386,12 @@ const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, if (it != used_samplers.end()) { ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow); - return *it; + return &(*it); } // Otherwise create a new mapping for this sampler const auto next_index = static_cast(used_samplers.size()); - return used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, + return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, info.is_shadow, info.is_buffer); } @@ -438,8 +478,15 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, "This method is not supported."); const SamplerInfo info{texture_type, is_array, is_shadow, false}; - const auto& sampler = + const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info); + Node4 values; + if (sampler == nullptr) { + for (u32 element = 0; element < values.size(); ++element) { + values[element] = Immediate(0); + } + return values; + } const bool lod_needed = process_mode == TextureProcessMode::LZ || process_mode == TextureProcessMode::LL || @@ -478,10 +525,10 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, } } - Node4 values; + for (u32 element = 0; element < values.size(); ++element) { auto copy_coords = coords; - MetaTexture meta{sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element}; + MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element}; values[element] = Operation(read_method, meta, std::move(copy_coords)); } @@ -594,8 +641,15 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de u64 parameter_register = instr.gpr20.Value(); const SamplerInfo info{texture_type, is_array, depth_compare, false}; - const auto& sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) + const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) : GetSampler(instr.sampler, info); + Node4 values; + if (sampler == nullptr) { + for (u32 element = 0; element < values.size(); ++element) { + values[element] = Immediate(0); + } + return values; + } std::vector aoffi; if (is_aoffi) { @@ -610,10 +664,9 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de const Node component = is_bindless ? Immediate(static_cast(instr.tld4_b.component)) : Immediate(static_cast(instr.tld4.component)); - Node4 values; for (u32 element = 0; element < values.size(); ++element) { auto coords_copy = coords; - MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, + MetaTexture meta{*sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, element}; values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); } @@ -642,7 +695,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) { // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr}; // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr}; - const auto& sampler = GetSampler(instr.sampler); + const auto& sampler = *GetSampler(instr.sampler); Node4 values; for (u32 element = 0; element < values.size(); ++element) { @@ -655,7 +708,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) { } Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { - const auto& sampler = GetSampler(instr.sampler); + const Sampler& sampler = *GetSampler(instr.sampler); const std::size_t type_coord_count = GetCoordCount(texture_type); const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; -- cgit v1.2.3 From af89723fa3d4ca13fc2ce7be545170d093eb4c31 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 11 Dec 2019 18:12:29 -0400 Subject: Shader_Ir: Correct TLD4S encoding and implement f16 flag. --- src/video_core/shader/decode/texture.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/video_core/shader/decode/texture.cpp') diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 67926afcb..9aef5ddd5 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -138,7 +138,11 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); } - WriteTexsInstructionFloat(bb, instr, values, true); + if (instr.tld4s.fp16_flag) { + WriteTexsInstructionHalfFloat(bb, instr, values, true); + } else { + WriteTexsInstructionFloat(bb, instr, values, true); + } break; } case OpCode::Id::TXD_B: @@ -155,8 +159,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { const auto coord_count = GetCoordCount(texture_type); const Sampler* sampler = is_bindless - ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) - : GetSampler(instr.sampler, {{texture_type, false, false}}); + ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) + : GetSampler(instr.sampler, {{texture_type, false, false}}); Node4 values; if (sampler == nullptr) { for (u32 element = 0; element < values.size(); ++element) { @@ -362,7 +366,7 @@ const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, // Otherwise create a new mapping for this sampler const auto next_index = static_cast(used_samplers.size()); return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, - info.is_buffer); + info.is_buffer); } const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, @@ -392,7 +396,7 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, // Otherwise create a new mapping for this sampler const auto next_index = static_cast(used_samplers.size()); return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, - info.is_shadow, info.is_buffer); + info.is_shadow, info.is_buffer); } void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { @@ -435,14 +439,14 @@ void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr, const } void ShaderIR::WriteTexsInstructionHalfFloat(NodeBlock& bb, Instruction instr, - const Node4& components) { + const Node4& components, bool ignore_mask) { // TEXS.F16 destionation registers are packed in two registers in pairs (just like any half // float instruction). Node4 values; u32 dest_elem = 0; for (u32 component = 0; component < 4; ++component) { - if (!instr.texs.IsComponentEnabled(component)) + if (!instr.texs.IsComponentEnabled(component) && !ignore_mask) continue; values[dest_elem++] = components[component]; } @@ -525,7 +529,6 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, } } - for (u32 element = 0; element < values.size(); ++element) { auto copy_coords = coords; MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element}; @@ -642,7 +645,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de const SamplerInfo info{texture_type, is_array, depth_compare, false}; const Sampler* sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) - : GetSampler(instr.sampler, info); + : GetSampler(instr.sampler, info); Node4 values; if (sampler == nullptr) { for (u32 element = 0; element < values.size(); ++element) { -- cgit v1.2.3 From c0ee0aa1a8266b0f5c5568cf1af3cb6247156720 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 11 Dec 2019 19:43:43 -0400 Subject: Shader_IR: Correct TLD4S Depth Compare. --- src/video_core/shader/decode/texture.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/video_core/shader/decode/texture.cpp') diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 9aef5ddd5..994c05611 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -107,8 +107,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { break; } case OpCode::Id::TLD4S: { - UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI), - "AOFFI is not implemented"); + const bool uses_aoffi = instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI); + UNIMPLEMENTED_IF_MSG(uses_aoffi, "AOFFI is not implemented"); const bool depth_compare = instr.tld4s.UsesMiscMode(TextureMiscMode::DC); const Node op_a = GetRegister(instr.gpr8); @@ -116,15 +116,22 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. std::vector coords; + Node dc_reg; if (depth_compare) { // Note: TLD4S coordinate encoding works just like TEXS's const Node op_y = GetRegister(instr.gpr8.Value() + 1); coords.push_back(op_a); coords.push_back(op_y); - coords.push_back(op_b); + dc_reg = uses_aoffi ? GetRegister(instr.gpr20.Value() + 1) : op_b; } else { coords.push_back(op_a); - coords.push_back(op_b); + if (uses_aoffi) { + const Node op_y = GetRegister(instr.gpr8.Value() + 1); + coords.push_back(op_y); + } else { + coords.push_back(op_b); + } + dc_reg = {}; } const Node component = Immediate(static_cast(instr.tld4s.component)); @@ -134,7 +141,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { Node4 values; for (u32 element = 0; element < values.size(); ++element) { auto coords_copy = coords; - MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, component, element}; + MetaTexture meta{sampler, {}, dc_reg, {}, {}, {}, {}, component, element}; values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); } -- cgit v1.2.3