diff options
| author | 2019-11-06 04:54:11 +0000 | |
|---|---|---|
| committer | 2019-11-06 04:54:11 +0000 | |
| commit | 654b77d2ec372bd986d472da7491d0156d0af52e (patch) | |
| tree | 163ac38e64ed94bdcf3a4ee3c50816c6882cc138 /src/video_core/shader/decode | |
| parent | Merge pull request #3073 from DarkLordZach/azure-rename-partial (diff) | |
| parent | shader/node: Unpack bindless texture encoding (diff) | |
| download | yuzu-654b77d2ec372bd986d472da7491d0156d0af52e.tar.gz yuzu-654b77d2ec372bd986d472da7491d0156d0af52e.tar.xz yuzu-654b77d2ec372bd986d472da7491d0156d0af52e.zip | |
Merge pull request #3039 from ReinUsesLisp/cleanup-samplers
shader/node: Unpack bindless texture encoding
Diffstat (limited to 'src/video_core/shader/decode')
| -rw-r--r-- | src/video_core/shader/decode/image.cpp | 50 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 59 |
2 files changed, 55 insertions, 54 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index b02d2cb95..d2fe4ec5d 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp | |||
| @@ -143,39 +143,37 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { | 145 | Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { |
| 146 | const auto offset{static_cast<std::size_t>(image.index.Value())}; | 146 | const auto offset = static_cast<u32>(image.index.Value()); |
| 147 | if (const auto existing_image = TryUseExistingImage(offset, type)) { | 147 | |
| 148 | return *existing_image; | 148 | const auto it = |
| 149 | std::find_if(std::begin(used_images), std::end(used_images), | ||
| 150 | [offset](const Image& entry) { return entry.GetOffset() == offset; }); | ||
| 151 | if (it != std::end(used_images)) { | ||
| 152 | ASSERT(!it->IsBindless() && it->GetType() == it->GetType()); | ||
| 153 | return *it; | ||
| 149 | } | 154 | } |
| 150 | 155 | ||
| 151 | const std::size_t next_index{used_images.size()}; | 156 | const auto next_index = static_cast<u32>(used_images.size()); |
| 152 | return used_images.emplace(offset, Image{offset, next_index, type}).first->second; | 157 | return used_images.emplace_back(next_index, offset, type); |
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { | 160 | Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { |
| 156 | const Node image_register{GetRegister(reg)}; | 161 | const Node image_register = GetRegister(reg); |
| 157 | const auto [base_image, cbuf_index, cbuf_offset]{ | 162 | const auto [base_image, buffer, offset] = |
| 158 | TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))}; | 163 | TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size())); |
| 159 | const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)}; | 164 | |
| 160 | 165 | const auto it = | |
| 161 | if (const auto image = TryUseExistingImage(cbuf_key, type)) { | 166 | std::find_if(std::begin(used_images), std::end(used_images), |
| 162 | return *image; | 167 | [buffer = buffer, offset = offset](const Image& entry) { |
| 163 | } | 168 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; |
| 164 | 169 | }); | |
| 165 | const std::size_t next_index{used_images.size()}; | 170 | if (it != std::end(used_images)) { |
| 166 | return used_images.emplace(cbuf_key, Image{cbuf_index, cbuf_offset, next_index, type}) | 171 | ASSERT(it->IsBindless() && it->GetType() == it->GetType()); |
| 167 | .first->second; | 172 | return *it; |
| 168 | } | ||
| 169 | |||
| 170 | Image* ShaderIR::TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type) { | ||
| 171 | auto it = used_images.find(offset); | ||
| 172 | if (it == used_images.end()) { | ||
| 173 | return nullptr; | ||
| 174 | } | 173 | } |
| 175 | auto& image = it->second; | ||
| 176 | ASSERT(image.GetType() == type); | ||
| 177 | 174 | ||
| 178 | return ℑ | 175 | const auto next_index = static_cast<u32>(used_images.size()); |
| 176 | return used_images.emplace_back(next_index, offset, buffer, type); | ||
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | } // namespace VideoCommon::Shader | 179 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 4c838c8bb..ca690b58b 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -262,7 +262,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 262 | break; | 262 | break; |
| 263 | } | 263 | } |
| 264 | case OpCode::Id::TLDS: { | 264 | case OpCode::Id::TLDS: { |
| 265 | const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; | 265 | const TextureType texture_type{instr.tlds.GetTextureType()}; |
| 266 | const bool is_array{instr.tlds.IsArrayTexture()}; | 266 | const bool is_array{instr.tlds.IsArrayTexture()}; |
| 267 | 267 | ||
| 268 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), | 268 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), |
| @@ -293,77 +293,80 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 293 | std::optional<SamplerInfo> sampler_info) { | 293 | std::optional<SamplerInfo> sampler_info) { |
| 294 | const auto offset = static_cast<u32>(sampler.index.Value()); | 294 | const auto offset = static_cast<u32>(sampler.index.Value()); |
| 295 | 295 | ||
| 296 | Tegra::Shader::TextureType type; | 296 | TextureType type; |
| 297 | bool is_array; | 297 | bool is_array; |
| 298 | bool is_shadow; | 298 | bool is_shadow; |
| 299 | if (sampler_info) { | 299 | if (sampler_info) { |
| 300 | type = sampler_info->type; | 300 | type = sampler_info->type; |
| 301 | is_array = sampler_info->is_array; | 301 | is_array = sampler_info->is_array; |
| 302 | is_shadow = sampler_info->is_shadow; | 302 | is_shadow = sampler_info->is_shadow; |
| 303 | } else if (auto sampler = locker.ObtainBoundSampler(offset); sampler) { | 303 | } else if (const auto sampler = locker.ObtainBoundSampler(offset)) { |
| 304 | type = sampler->texture_type.Value(); | 304 | type = sampler->texture_type.Value(); |
| 305 | is_array = sampler->is_array.Value() != 0; | 305 | is_array = sampler->is_array.Value() != 0; |
| 306 | is_shadow = sampler->is_shadow.Value() != 0; | 306 | is_shadow = sampler->is_shadow.Value() != 0; |
| 307 | } else { | 307 | } else { |
| 308 | type = Tegra::Shader::TextureType::Texture2D; | 308 | LOG_WARNING(HW_GPU, "Unknown sampler info"); |
| 309 | type = TextureType::Texture2D; | ||
| 309 | is_array = false; | 310 | is_array = false; |
| 310 | is_shadow = false; | 311 | is_shadow = false; |
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | // If this sampler has already been used, return the existing mapping. | 314 | // If this sampler has already been used, return the existing mapping. |
| 314 | const auto itr = | 315 | const auto it = |
| 315 | std::find_if(used_samplers.begin(), used_samplers.end(), | 316 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 316 | [&](const Sampler& entry) { return entry.GetOffset() == offset; }); | 317 | [offset](const Sampler& entry) { return entry.GetOffset() == offset; }); |
| 317 | if (itr != used_samplers.end()) { | 318 | if (it != used_samplers.end()) { |
| 318 | ASSERT(itr->GetType() == type && itr->IsArray() == is_array && | 319 | ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && |
| 319 | itr->IsShadow() == is_shadow); | 320 | it->IsShadow() == is_shadow); |
| 320 | return *itr; | 321 | return *it; |
| 321 | } | 322 | } |
| 322 | 323 | ||
| 323 | // Otherwise create a new mapping for this sampler | 324 | // Otherwise create a new mapping for this sampler |
| 324 | const std::size_t next_index = used_samplers.size(); | 325 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 325 | const Sampler entry{offset, next_index, type, is_array, is_shadow}; | 326 | return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow)); |
| 326 | return *used_samplers.emplace(entry).first; | 327 | } |
| 327 | } // namespace VideoCommon::Shader | ||
| 328 | 328 | ||
| 329 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | 329 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, |
| 330 | std::optional<SamplerInfo> sampler_info) { | 330 | std::optional<SamplerInfo> sampler_info) { |
| 331 | const Node sampler_register = GetRegister(reg); | 331 | const Node sampler_register = GetRegister(reg); |
| 332 | const auto [base_sampler, cbuf_index, cbuf_offset] = | 332 | const auto [base_sampler, buffer, offset] = |
| 333 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); | 333 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); |
| 334 | ASSERT(base_sampler != nullptr); | 334 | ASSERT(base_sampler != nullptr); |
| 335 | const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset); | 335 | |
| 336 | Tegra::Shader::TextureType type; | 336 | TextureType type; |
| 337 | bool is_array; | 337 | bool is_array; |
| 338 | bool is_shadow; | 338 | bool is_shadow; |
| 339 | if (sampler_info) { | 339 | if (sampler_info) { |
| 340 | type = sampler_info->type; | 340 | type = sampler_info->type; |
| 341 | is_array = sampler_info->is_array; | 341 | is_array = sampler_info->is_array; |
| 342 | is_shadow = sampler_info->is_shadow; | 342 | is_shadow = sampler_info->is_shadow; |
| 343 | } else if (auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); sampler) { | 343 | } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) { |
| 344 | type = sampler->texture_type.Value(); | 344 | type = sampler->texture_type.Value(); |
| 345 | is_array = sampler->is_array.Value() != 0; | 345 | is_array = sampler->is_array.Value() != 0; |
| 346 | is_shadow = sampler->is_shadow.Value() != 0; | 346 | is_shadow = sampler->is_shadow.Value() != 0; |
| 347 | } else { | 347 | } else { |
| 348 | type = Tegra::Shader::TextureType::Texture2D; | 348 | LOG_WARNING(HW_GPU, "Unknown sampler info"); |
| 349 | type = TextureType::Texture2D; | ||
| 349 | is_array = false; | 350 | is_array = false; |
| 350 | is_shadow = false; | 351 | is_shadow = false; |
| 351 | } | 352 | } |
| 352 | 353 | ||
| 353 | // If this sampler has already been used, return the existing mapping. | 354 | // If this sampler has already been used, return the existing mapping. |
| 354 | const auto itr = | 355 | const auto it = |
| 355 | std::find_if(used_samplers.begin(), used_samplers.end(), | 356 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 356 | [&](const Sampler& entry) { return entry.GetOffset() == cbuf_key; }); | 357 | [buffer = buffer, offset = offset](const Sampler& entry) { |
| 357 | if (itr != used_samplers.end()) { | 358 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; |
| 358 | ASSERT(itr->GetType() == type && itr->IsArray() == is_array && | 359 | }); |
| 359 | itr->IsShadow() == is_shadow); | 360 | if (it != used_samplers.end()) { |
| 360 | return *itr; | 361 | ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && |
| 362 | it->IsShadow() == is_shadow); | ||
| 363 | return *it; | ||
| 361 | } | 364 | } |
| 362 | 365 | ||
| 363 | // Otherwise create a new mapping for this sampler | 366 | // Otherwise create a new mapping for this sampler |
| 364 | const std::size_t next_index = used_samplers.size(); | 367 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 365 | const Sampler entry{cbuf_index, cbuf_offset, next_index, type, is_array, is_shadow}; | 368 | return used_samplers.emplace_back( |
| 366 | return *used_samplers.emplace(entry).first; | 369 | Sampler(next_index, offset, buffer, type, is_array, is_shadow)); |
| 367 | } | 370 | } |
| 368 | 371 | ||
| 369 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { | 372 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { |