Shader_IR: Setup Indexed Samplers on the IR

master
Fernando Sahmkow 2020-01-05 15:53:22 +07:00 committed by FernandoS27
parent 603c861532
commit f4603d23c5
1 changed files with 46 additions and 20 deletions

@ -389,31 +389,57 @@ const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
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_node, tracked_sampler_info] =
TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); TrackSampler(sampler_register, global_code, static_cast<s64>(global_code.size()));
ASSERT(base_sampler != nullptr); ASSERT(base_node != nullptr);
if (base_sampler == nullptr) { if (base_node == nullptr) {
return nullptr; return nullptr;
} }
const auto info = GetSamplerInfo(sampler_info, offset, buffer); if (const auto bindless_sampler_info =
std::get_if<BindlessSamplerNode>(&*tracked_sampler_info)) {
const u32 buffer = bindless_sampler_info->GetIndex();
const u32 offset = bindless_sampler_info->GetOffset();
const auto info = GetSamplerInfo(sampler_info, offset, buffer);
// If this sampler has already been used, return the existing mapping. // If this sampler has already been used, return the existing mapping.
const auto it = const auto it =
std::find_if(used_samplers.begin(), used_samplers.end(), std::find_if(used_samplers.begin(), used_samplers.end(),
[buffer = buffer, offset = offset](const Sampler& entry) { [buffer = buffer, offset = offset](const Sampler& entry) {
return entry.GetBuffer() == buffer && entry.GetOffset() == offset; return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
}); });
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->IsShadow() == info.is_shadow); 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,
info.is_shadow, info.is_buffer);
} else if (const auto array_sampler_info =
std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) {
const u32 base_offset = array_sampler_info->GetBaseOffset() / 4;
const auto info = GetSamplerInfo(sampler_info, base_offset);
// If this sampler has already been used, return the existing mapping.
const auto it = std::find_if(
used_samplers.begin(), used_samplers.end(),
[base_offset](const Sampler& entry) { return entry.GetOffset() == base_offset; });
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;
}
// 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, base_offset, info.type, info.is_array,
info.is_shadow, info.is_buffer);
} }
return nullptr;
// 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,
info.is_shadow, info.is_buffer);
} }
void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {