diff options
| author | 2019-11-06 04:32:43 -0300 | |
|---|---|---|
| committer | 2019-11-22 21:28:47 -0300 | |
| commit | 32c1bc6a67820f9df21c8f64f4df078b015aa7da (patch) | |
| tree | 141df885726a01fbd7d999d6ee314b4d11c8ce56 /src/video_core/shader/decode | |
| parent | Merge pull request #3142 from ReinUsesLisp/depbar-log (diff) | |
| download | yuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.tar.gz yuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.tar.xz yuzu-32c1bc6a67820f9df21c8f64f4df078b015aa7da.zip | |
shader/texture: Deduce texture buffers from locker
Instead of specializing shaders to separate texture buffers from 1D
textures, use the locker to deduce them while they are being decoded.
Diffstat (limited to 'src/video_core/shader/decode')
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 102 |
1 files changed, 41 insertions, 61 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index bb926a132..695fdbd24 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -128,8 +128,8 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 128 | } | 128 | } |
| 129 | const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); | 129 | const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); |
| 130 | 130 | ||
| 131 | const auto& sampler = | 131 | const SamplerInfo info{TextureType::Texture2D, false, depth_compare}; |
| 132 | GetSampler(instr.sampler, {{TextureType::Texture2D, false, depth_compare}}); | 132 | const auto& sampler = GetSampler(instr.sampler, info); |
| 133 | 133 | ||
| 134 | Node4 values; | 134 | Node4 values; |
| 135 | for (u32 element = 0; element < values.size(); ++element) { | 135 | for (u32 element = 0; element < values.size(); ++element) { |
| @@ -149,7 +149,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 149 | // Sadly, not all texture instructions specify the type of texture their sampler | 149 | // Sadly, not all texture instructions specify the type of texture their sampler |
| 150 | // uses. This must be fixed at a later instance. | 150 | // uses. This must be fixed at a later instance. |
| 151 | const auto& sampler = | 151 | const auto& sampler = |
| 152 | is_bindless ? GetBindlessSampler(instr.gpr8, {}) : GetSampler(instr.sampler, {}); | 152 | is_bindless ? GetBindlessSampler(instr.gpr8) : GetSampler(instr.sampler); |
| 153 | 153 | ||
| 154 | u32 indexer = 0; | 154 | u32 indexer = 0; |
| 155 | switch (instr.txq.query_type) { | 155 | switch (instr.txq.query_type) { |
| @@ -185,8 +185,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 185 | auto texture_type = instr.tmml.texture_type.Value(); | 185 | auto texture_type = instr.tmml.texture_type.Value(); |
| 186 | const bool is_array = instr.tmml.array != 0; | 186 | const bool is_array = instr.tmml.array != 0; |
| 187 | const auto& sampler = | 187 | const auto& sampler = |
| 188 | is_bindless ? GetBindlessSampler(instr.gpr20, {{texture_type, is_array, false}}) | 188 | is_bindless ? GetBindlessSampler(instr.gpr20) : GetSampler(instr.sampler); |
| 189 | : GetSampler(instr.sampler, {{texture_type, is_array, false}}); | ||
| 190 | 189 | ||
| 191 | std::vector<Node> coords; | 190 | std::vector<Node> coords; |
| 192 | 191 | ||
| @@ -254,67 +253,50 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 254 | return pc; | 253 | return pc; |
| 255 | } | 254 | } |
| 256 | 255 | ||
| 257 | const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | 256 | ShaderIR::SamplerInfo ShaderIR::GetSamplerInfo(std::optional<SamplerInfo> sampler_info, u32 offset, |
| 258 | std::optional<SamplerInfo> sampler_info) { | 257 | std::optional<u32> buffer) { |
| 259 | const auto offset = static_cast<u32>(sampler.index.Value()); | ||
| 260 | |||
| 261 | TextureType type; | ||
| 262 | bool is_array; | ||
| 263 | bool is_shadow; | ||
| 264 | if (sampler_info) { | 258 | if (sampler_info) { |
| 265 | type = sampler_info->type; | 259 | return *sampler_info; |
| 266 | is_array = sampler_info->is_array; | 260 | } |
| 267 | is_shadow = sampler_info->is_shadow; | 261 | const auto sampler = |
| 268 | } else if (const auto sampler = locker.ObtainBoundSampler(offset)) { | 262 | buffer ? locker.ObtainBindlessSampler(*buffer, offset) : locker.ObtainBoundSampler(offset); |
| 269 | type = sampler->texture_type.Value(); | 263 | if (!sampler) { |
| 270 | is_array = sampler->is_array.Value() != 0; | ||
| 271 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 272 | } else { | ||
| 273 | LOG_WARNING(HW_GPU, "Unknown sampler info"); | 264 | LOG_WARNING(HW_GPU, "Unknown sampler info"); |
| 274 | type = TextureType::Texture2D; | 265 | return SamplerInfo{TextureType::Texture2D, false, false, false}; |
| 275 | is_array = false; | ||
| 276 | is_shadow = false; | ||
| 277 | } | 266 | } |
| 267 | return SamplerInfo{sampler->texture_type, sampler->is_array != 0, sampler->is_shadow != 0, | ||
| 268 | sampler->is_buffer != 0}; | ||
| 269 | } | ||
| 270 | |||
| 271 | const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | ||
| 272 | std::optional<SamplerInfo> sampler_info) { | ||
| 273 | const auto offset = static_cast<u32>(sampler.index.Value()); | ||
| 274 | const auto info = GetSamplerInfo(sampler_info, offset); | ||
| 278 | 275 | ||
| 279 | // If this sampler has already been used, return the existing mapping. | 276 | // If this sampler has already been used, return the existing mapping. |
| 280 | const auto it = | 277 | const auto it = |
| 281 | std::find_if(used_samplers.begin(), used_samplers.end(), | 278 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 282 | [offset](const Sampler& entry) { return entry.GetOffset() == offset; }); | 279 | [offset](const Sampler& entry) { return entry.GetOffset() == offset; }); |
| 283 | if (it != used_samplers.end()) { | 280 | if (it != used_samplers.end()) { |
| 284 | ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && | 281 | ASSERT(!it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && |
| 285 | it->IsShadow() == is_shadow); | 282 | it->IsShadow() == info.is_shadow && it->IsBuffer() == info.is_buffer); |
| 286 | return *it; | 283 | return *it; |
| 287 | } | 284 | } |
| 288 | 285 | ||
| 289 | // Otherwise create a new mapping for this sampler | 286 | // Otherwise create a new mapping for this sampler |
| 290 | const auto next_index = static_cast<u32>(used_samplers.size()); | 287 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 291 | return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow)); | 288 | return used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, |
| 289 | info.is_buffer); | ||
| 292 | } | 290 | } |
| 293 | 291 | ||
| 294 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | 292 | const Sampler& ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, |
| 295 | std::optional<SamplerInfo> sampler_info) { | 293 | std::optional<SamplerInfo> sampler_info) { |
| 296 | const Node sampler_register = GetRegister(reg); | 294 | const Node sampler_register = GetRegister(reg); |
| 297 | const auto [base_sampler, buffer, offset] = | 295 | const auto [base_sampler, buffer, offset] = |
| 298 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); | 296 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); |
| 299 | ASSERT(base_sampler != nullptr); | 297 | ASSERT(base_sampler != nullptr); |
| 300 | 298 | ||
| 301 | TextureType type; | 299 | const auto info = GetSamplerInfo(sampler_info, offset, buffer); |
| 302 | bool is_array; | ||
| 303 | bool is_shadow; | ||
| 304 | if (sampler_info) { | ||
| 305 | type = sampler_info->type; | ||
| 306 | is_array = sampler_info->is_array; | ||
| 307 | is_shadow = sampler_info->is_shadow; | ||
| 308 | } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) { | ||
| 309 | type = sampler->texture_type.Value(); | ||
| 310 | is_array = sampler->is_array.Value() != 0; | ||
| 311 | is_shadow = sampler->is_shadow.Value() != 0; | ||
| 312 | } else { | ||
| 313 | LOG_WARNING(HW_GPU, "Unknown sampler info"); | ||
| 314 | type = TextureType::Texture2D; | ||
| 315 | is_array = false; | ||
| 316 | is_shadow = false; | ||
| 317 | } | ||
| 318 | 300 | ||
| 319 | // If this sampler has already been used, return the existing mapping. | 301 | // If this sampler has already been used, return the existing mapping. |
| 320 | const auto it = | 302 | const auto it = |
| @@ -323,15 +305,15 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | |||
| 323 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; | 305 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; |
| 324 | }); | 306 | }); |
| 325 | if (it != used_samplers.end()) { | 307 | if (it != used_samplers.end()) { |
| 326 | ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && | 308 | ASSERT(it->IsBindless() && it->GetType() == info.type && it->IsArray() == info.is_array && |
| 327 | it->IsShadow() == is_shadow); | 309 | it->IsShadow() == info.is_shadow); |
| 328 | return *it; | 310 | return *it; |
| 329 | } | 311 | } |
| 330 | 312 | ||
| 331 | // Otherwise create a new mapping for this sampler | 313 | // Otherwise create a new mapping for this sampler |
| 332 | const auto next_index = static_cast<u32>(used_samplers.size()); | 314 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 333 | return used_samplers.emplace_back( | 315 | return used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, |
| 334 | Sampler(next_index, offset, buffer, type, is_array, is_shadow)); | 316 | info.is_shadow, info.is_buffer); |
| 335 | } | 317 | } |
| 336 | 318 | ||
| 337 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { | 319 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { |
| @@ -416,17 +398,16 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, | |||
| 416 | (texture_type == TextureType::TextureCube && is_array && is_shadow), | 398 | (texture_type == TextureType::TextureCube && is_array && is_shadow), |
| 417 | "This method is not supported."); | 399 | "This method is not supported."); |
| 418 | 400 | ||
| 401 | const SamplerInfo info{texture_type, is_array, is_shadow, false}; | ||
| 419 | const auto& sampler = | 402 | const auto& sampler = |
| 420 | is_bindless ? GetBindlessSampler(*bindless_reg, {{texture_type, is_array, is_shadow}}) | 403 | is_bindless ? GetBindlessSampler(*bindless_reg, info) : GetSampler(instr.sampler, info); |
| 421 | : GetSampler(instr.sampler, {{texture_type, is_array, is_shadow}}); | ||
| 422 | 404 | ||
| 423 | const bool lod_needed = process_mode == TextureProcessMode::LZ || | 405 | const bool lod_needed = process_mode == TextureProcessMode::LZ || |
| 424 | process_mode == TextureProcessMode::LL || | 406 | process_mode == TextureProcessMode::LL || |
| 425 | process_mode == TextureProcessMode::LLA; | 407 | process_mode == TextureProcessMode::LLA; |
| 426 | 408 | ||
| 427 | // LOD selection (either via bias or explicit textureLod) not | 409 | // LOD selection (either via bias or explicit textureLod) not supported in GL for |
| 428 | // supported in GL for sampler2DArrayShadow and | 410 | // sampler2DArrayShadow and samplerCubeArrayShadow. |
| 429 | // samplerCubeArrayShadow. | ||
| 430 | const bool gl_lod_supported = | 411 | const bool gl_lod_supported = |
| 431 | !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) || | 412 | !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) || |
| 432 | (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); | 413 | (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); |
| @@ -436,8 +417,8 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, | |||
| 436 | 417 | ||
| 437 | UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); | 418 | UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); |
| 438 | 419 | ||
| 439 | Node bias = {}; | 420 | Node bias; |
| 440 | Node lod = {}; | 421 | Node lod; |
| 441 | if (process_mode != TextureProcessMode::None && gl_lod_supported) { | 422 | if (process_mode != TextureProcessMode::None && gl_lod_supported) { |
| 442 | switch (process_mode) { | 423 | switch (process_mode) { |
| 443 | case TextureProcessMode::LZ: | 424 | case TextureProcessMode::LZ: |
| @@ -573,10 +554,9 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de | |||
| 573 | 554 | ||
| 574 | u64 parameter_register = instr.gpr20.Value(); | 555 | u64 parameter_register = instr.gpr20.Value(); |
| 575 | 556 | ||
| 576 | const auto& sampler = | 557 | const SamplerInfo info{texture_type, is_array, depth_compare, false}; |
| 577 | is_bindless | 558 | const auto& sampler = is_bindless ? GetBindlessSampler(parameter_register++, info) |
| 578 | ? GetBindlessSampler(parameter_register++, {{texture_type, is_array, depth_compare}}) | 559 | : GetSampler(instr.sampler, info); |
| 579 | : GetSampler(instr.sampler, {{texture_type, is_array, depth_compare}}); | ||
| 580 | 560 | ||
| 581 | std::vector<Node> aoffi; | 561 | std::vector<Node> aoffi; |
| 582 | if (is_aoffi) { | 562 | if (is_aoffi) { |
| @@ -623,7 +603,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) { | |||
| 623 | // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr}; | 603 | // const Node aoffi_register{is_aoffi ? GetRegister(gpr20_cursor++) : nullptr}; |
| 624 | // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr}; | 604 | // const Node multisample{is_multisample ? GetRegister(gpr20_cursor++) : nullptr}; |
| 625 | 605 | ||
| 626 | const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, false}}); | 606 | const auto& sampler = GetSampler(instr.sampler); |
| 627 | 607 | ||
| 628 | Node4 values; | 608 | Node4 values; |
| 629 | for (u32 element = 0; element < values.size(); ++element) { | 609 | for (u32 element = 0; element < values.size(); ++element) { |
| @@ -659,7 +639,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 659 | // When lod is used always is in gpr20 | 639 | // When lod is used always is in gpr20 |
| 660 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); | 640 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); |
| 661 | 641 | ||
| 662 | const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, false}}); | 642 | const auto& sampler = GetSampler(instr.sampler); |
| 663 | 643 | ||
| 664 | Node4 values; | 644 | Node4 values; |
| 665 | for (u32 element = 0; element < values.size(); ++element) { | 645 | for (u32 element = 0; element < values.size(); ++element) { |