diff options
| author | 2020-01-05 15:53:22 -0400 | |
|---|---|---|
| committer | 2020-01-24 16:43:30 -0400 | |
| commit | f4603d23c551ece65cd205a850a31a84531daf43 (patch) | |
| tree | ecc6c703c75fec113d1ea3266ec1f399a5c9483d /src/video_core | |
| parent | Shader_IR: Implement initial code for tracking indexed samplers. (diff) | |
| download | yuzu-f4603d23c551ece65cd205a850a31a84531daf43.tar.gz yuzu-f4603d23c551ece65cd205a850a31a84531daf43.tar.xz yuzu-f4603d23c551ece65cd205a850a31a84531daf43.zip | |
Shader_IR: Setup Indexed Samplers on the IR
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 0b567e39d..886650d9e 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -389,31 +389,57 @@ const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 389 | const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | 389 | const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, |
| 390 | std::optional<SamplerInfo> sampler_info) { | 390 | std::optional<SamplerInfo> sampler_info) { |
| 391 | const Node sampler_register = GetRegister(reg); | 391 | const Node sampler_register = GetRegister(reg); |
| 392 | const auto [base_sampler, buffer, offset] = | 392 | const auto [base_node, tracked_sampler_info] = |
| 393 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); | 393 | TrackSampler(sampler_register, global_code, static_cast<s64>(global_code.size())); |
| 394 | ASSERT(base_sampler != nullptr); | 394 | ASSERT(base_node != nullptr); |
| 395 | if (base_sampler == nullptr) { | 395 | if (base_node == nullptr) { |
| 396 | return nullptr; | 396 | return nullptr; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | const auto info = GetSamplerInfo(sampler_info, offset, buffer); | 399 | if (const auto bindless_sampler_info = |
| 400 | std::get_if<BindlessSamplerNode>(&*tracked_sampler_info)) { | ||
| 401 | const u32 buffer = bindless_sampler_info->GetIndex(); | ||
| 402 | const u32 offset = bindless_sampler_info->GetOffset(); | ||
| 403 | const auto info = GetSamplerInfo(sampler_info, offset, buffer); | ||
| 404 | |||
| 405 | // If this sampler has already been used, return the existing mapping. | ||
| 406 | const auto it = | ||
| 407 | std::find_if(used_samplers.begin(), used_samplers.end(), | ||
| 408 | [buffer = buffer, offset = offset](const Sampler& entry) { | ||
| 409 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; | ||
| 410 | }); | ||
| 411 | if (it != used_samplers.end()) { | ||
| 412 | ASSERT(it->IsBindless() && it->GetType() == info.type && | ||
| 413 | it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow); | ||
| 414 | return &*it; | ||
| 415 | } | ||
| 400 | 416 | ||
| 401 | // If this sampler has already been used, return the existing mapping. | 417 | // Otherwise create a new mapping for this sampler |
| 402 | const auto it = | 418 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 403 | std::find_if(used_samplers.begin(), used_samplers.end(), | 419 | return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, |
| 404 | [buffer = buffer, offset = offset](const Sampler& entry) { | 420 | info.is_shadow, info.is_buffer); |
| 405 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; | 421 | } else if (const auto array_sampler_info = |
| 406 | }); | 422 | std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) { |
| 407 | if (it != used_samplers.end()) { | 423 | const u32 base_offset = array_sampler_info->GetBaseOffset() / 4; |
| 408 | ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && | 424 | const auto info = GetSamplerInfo(sampler_info, base_offset); |
| 409 | it->IsShadow() == info.is_shadow); | 425 | |
| 410 | return &*it; | 426 | // If this sampler has already been used, return the existing mapping. |
| 411 | } | 427 | const auto it = std::find_if( |
| 428 | used_samplers.begin(), used_samplers.end(), | ||
| 429 | [base_offset](const Sampler& entry) { return entry.GetOffset() == base_offset; }); | ||
| 430 | if (it != used_samplers.end()) { | ||
| 431 | ASSERT(!it->IsBindless() && it->GetType() == info.type && | ||
| 432 | it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow && | ||
| 433 | it->IsBuffer() == info.is_buffer); | ||
| 434 | return &*it; | ||
| 435 | } | ||
| 412 | 436 | ||
| 413 | // Otherwise create a new mapping for this sampler | 437 | // Otherwise create a new mapping for this sampler |
| 414 | const auto next_index = static_cast<u32>(used_samplers.size()); | 438 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 415 | return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, | 439 | return &used_samplers.emplace_back(next_index, base_offset, info.type, info.is_array, |
| 416 | info.is_shadow, info.is_buffer); | 440 | info.is_shadow, info.is_buffer); |
| 441 | } | ||
| 442 | return nullptr; | ||
| 417 | } | 443 | } |
| 418 | 444 | ||
| 419 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { | 445 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { |