Shader_Ir: default failed tracks on bindless samplers to null values.
This commit is contained in:
		 Fernando Sahmkow
					Fernando Sahmkow
				
			
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			 FernandoS27
						FernandoS27
					
				
			
						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 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<Node> 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<SamplerInfo> 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<SamplerInfo> sampler_info) { | ||||
|     const auto offset = static_cast<u32>(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<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); | ||||
| } | ||||
|  | ||||
| const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | ||||
| const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | ||||
|                                             std::optional<SamplerInfo> sampler_info) { | ||||
|     const Node sampler_register = GetRegister(reg); | ||||
|     const auto [base_sampler, buffer, offset] = | ||||
|         TrackCbuf(sampler_register, global_code, static_cast<s64>(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<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); | ||||
| } | ||||
|  | ||||
| @@ -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<Node> 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)) | ||||
|                                        : Immediate(static_cast<u32>(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; | ||||
|   | ||||
| @@ -313,11 +313,11 @@ private: | ||||
|                                std::optional<u32> buffer = std::nullopt); | ||||
|  | ||||
|     /// 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); | ||||
|  | ||||
|     /// 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); | ||||
|  | ||||
|     /// Accesses an image. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user