Shader_Ir: default failed tracks on bindless samplers to null values.
This commit is contained in:
		
							parent
							
								
									900b2e5cae
								
							
						
					
					
						commit
						271a3264f3
					
				| @ -129,7 +129,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||||||
|         const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); |         const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); | ||||||
| 
 | 
 | ||||||
|         const SamplerInfo info{TextureType::Texture2D, false, depth_compare}; |         const SamplerInfo info{TextureType::Texture2D, false, depth_compare}; | ||||||
|         const auto& sampler = GetSampler(instr.sampler, info); |         const Sampler& sampler = *GetSampler(instr.sampler, info); | ||||||
| 
 | 
 | ||||||
|         Node4 values; |         Node4 values; | ||||||
|         for (u32 element = 0; element < values.size(); ++element) { |         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 texture_type = instr.txd.texture_type.Value(); | ||||||
|         const auto coord_count = GetCoordCount(texture_type); |         const auto coord_count = GetCoordCount(texture_type); | ||||||
| 
 | 
 | ||||||
|         const auto& sampler = is_bindless |         const Sampler* sampler = is_bindless | ||||||
|                                   ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) |                                   ? GetBindlessSampler(base_reg, {{texture_type, false, false}}) | ||||||
|                                   : GetSampler(instr.sampler, {{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) { |         if (is_bindless) { | ||||||
|             base_reg++; |             base_reg++; | ||||||
|         } |         } | ||||||
| @ -170,9 +178,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||||||
|             derivates.push_back(GetRegister(derivate_reg + derivate + 1)); |             derivates.push_back(GetRegister(derivate_reg + derivate + 1)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Node4 values; |  | ||||||
|         for (u32 element = 0; element < values.size(); ++element) { |         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); |             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.
 |         // 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
 |         // Sadly, not all texture instructions specify the type of texture their sampler
 | ||||||
|         // uses. This must be fixed at a later instance.
 |         // uses. This must be fixed at a later instance.
 | ||||||
|         const auto& sampler = |         const Sampler* sampler = | ||||||
|             is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.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; |         u32 indexer = 0; | ||||||
|         switch (instr.txq.query_type) { |         switch (instr.txq.query_type) { | ||||||
|         case Tegra::Shader::TextureQueryType::Dimension: { |         case Tegra::Shader::TextureQueryType::Dimension: { | ||||||
| @ -197,7 +219,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||||||
|                 if (!instr.txq.IsComponentEnabled(element)) { |                 if (!instr.txq.IsComponentEnabled(element)) { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; |                 MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element}; | ||||||
|                 const Node value = |                 const Node value = | ||||||
|                     Operation(OperationCode::TextureQueryDimensions, meta, |                     Operation(OperationCode::TextureQueryDimensions, meta, | ||||||
|                               GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); |                               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(); |         auto texture_type = instr.tmml.texture_type.Value(); | ||||||
|         const bool is_array = instr.tmml.array != 0; |         const bool is_array = instr.tmml.array != 0; | ||||||
|         const auto& sampler = |         const Sampler* sampler = | ||||||
|             is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.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<Node> coords; |         std::vector<Node> coords; | ||||||
| 
 | 
 | ||||||
|         // TODO: Add coordinates for different samplers once other texture types are implemented.
 |         // TODO: Add coordinates for different samplers once other texture types are implemented.
 | ||||||
| @ -251,7 +288,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             auto params = coords; |             auto params = coords; | ||||||
|             MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element}; |             MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element}; | ||||||
|             const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); |             const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); | ||||||
|             SetTemporary(bb, indexer++, value); |             SetTemporary(bb, indexer++, value); | ||||||
|         } |         } | ||||||
| @ -307,7 +344,7 @@ ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional<SamplerInfo> sample | |||||||
|                        sampler->is_buffer != 0}; |                        sampler->is_buffer != 0}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | ||||||
|                                     std::optional<SamplerInfo> sampler_info) { |                                     std::optional<SamplerInfo> sampler_info) { | ||||||
|     const auto offset = static_cast<u32>(sampler.index.Value()); |     const auto offset = static_cast<u32>(sampler.index.Value()); | ||||||
|     const auto info = GetSamplerInfo(sampler_info, offset); |     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()) { |     if (it != used_samplers.end()) { | ||||||
|         ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && |         ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && | ||||||
|                it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); |                it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); | ||||||
|         return *it; |         return &(*it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Otherwise create a new mapping for this sampler
 |     // Otherwise create a new mapping for this sampler
 | ||||||
|     const auto next_index = static_cast<u32>(used_samplers.size()); |     const auto next_index = static_cast<u32>(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); |                                       info.is_buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | ||||||
|                                             std::optional<SamplerInfo> sampler_info) { |                                             std::optional<SamplerInfo> sampler_info) { | ||||||
|     const Node sampler_register = GetRegister(reg); |     const Node sampler_register = GetRegister(reg); | ||||||
|     const auto [base_sampler, buffer, offset] = |     const auto [base_sampler, buffer, offset] = | ||||||
|         TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); |         TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); | ||||||
|     ASSERT(base_sampler != nullptr); |     ASSERT(base_sampler != nullptr); | ||||||
|  |     if (base_sampler == nullptr) { | ||||||
|  |         return nullptr; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     const auto info = GetSamplerInfo(sampler_info, offset, buffer); |     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()) { |     if (it != used_samplers.end()) { | ||||||
|         ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && |         ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && | ||||||
|                it->IsShadow() == info.is_shadow); |                it->IsShadow() == info.is_shadow); | ||||||
|         return *it; |         return &(*it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Otherwise create a new mapping for this sampler
 |     // Otherwise create a new mapping for this sampler
 | ||||||
|     const auto next_index = static_cast<u32>(used_samplers.size()); |     const auto next_index = static_cast<u32>(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); |                                       info.is_shadow, info.is_buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -438,8 +478,15 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, | |||||||
|                          "This method is not supported."); |                          "This method is not supported."); | ||||||
| 
 | 
 | ||||||
|     const SamplerInfo info{texture_type, is_array, is_shadow, false}; |     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); |         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 || |     const bool lod_needed = process_mode == TextureProcessMode::LZ || | ||||||
|                             process_mode == TextureProcessMode::LL || |                             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) { |     for (u32 element = 0; element < values.size(); ++element) { | ||||||
|         auto copy_coords = coords; |         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)); |         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(); |     u64 parameter_register = instr.gpr20.Value(); | ||||||
| 
 | 
 | ||||||
|     const SamplerInfo info{texture_type, is_array, depth_compare, false}; |     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); |                                       : 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<Node> aoffi; |     std::vector<Node> aoffi; | ||||||
|     if (is_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<u32>(instr.tld4_b.component)) |     const Node component = is_bindless ? Immediate(static_cast<u32>(instr.tld4_b.component)) | ||||||
|                                        : Immediate(static_cast<u32>(instr.tld4.component)); |                                        : Immediate(static_cast<u32>(instr.tld4.component)); | ||||||
| 
 | 
 | ||||||
|     Node4 values; |  | ||||||
|     for (u32 element = 0; element < values.size(); ++element) { |     for (u32 element = 0; element < values.size(); ++element) { | ||||||
|         auto coords_copy = coords; |         auto coords_copy = coords; | ||||||
|         MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, |         MetaTexture meta{*sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component, | ||||||
|                          element}; |                          element}; | ||||||
|         values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |         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 aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr};
 | ||||||
|     // const Node multisample{is_multisample ? 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; |     Node4 values; | ||||||
|     for (u32 element = 0; element < values.size(); ++element) { |     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) { | 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 std::size_t type_coord_count = GetCoordCount(texture_type); | ||||||
|     const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; |     const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; | ||||||
|  | |||||||
| @ -313,11 +313,11 @@ private: | |||||||
|                                std::optional<u32> buffer = std::nullopt); |                                std::optional<u32> buffer = std::nullopt); | ||||||
| 
 | 
 | ||||||
|     /// Accesses a texture sampler
 |     /// Accesses a texture sampler
 | ||||||
|     const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, |     const Sampler* GetSampler(const Tegra::Shader::Sampler& sampler, | ||||||
|                               std::optional<SamplerInfo> sampler_info = std::nullopt); |                               std::optional<SamplerInfo> sampler_info = std::nullopt); | ||||||
| 
 | 
 | ||||||
|     /// Accesses a texture sampler for a bindless texture.
 |     /// Accesses a texture sampler for a bindless texture.
 | ||||||
|     const Sampler& GetBindlessSampler(Tegra::Shader::Register reg, |     const Sampler* GetBindlessSampler(Tegra::Shader::Register reg, | ||||||
|                                       std::optional<SamplerInfo> sampler_info = std::nullopt); |                                       std::optional<SamplerInfo> sampler_info = std::nullopt); | ||||||
| 
 | 
 | ||||||
|     /// Accesses an image.
 |     /// Accesses an image.
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
						Fernando Sahmkow