diff options
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/shader/const_buffer_locker.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 111 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 14 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 13 |
5 files changed, 72 insertions, 70 deletions
diff --git a/src/video_core/shader/const_buffer_locker.cpp b/src/video_core/shader/const_buffer_locker.cpp index fe467608e..b65399f91 100644 --- a/src/video_core/shader/const_buffer_locker.cpp +++ b/src/video_core/shader/const_buffer_locker.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "video_core/engines/maxwell_3d.h" | 11 | #include "video_core/engines/maxwell_3d.h" |
| 12 | #include "video_core/engines/shader_type.h" | ||
| 12 | #include "video_core/shader/const_buffer_locker.h" | 13 | #include "video_core/shader/const_buffer_locker.h" |
| 13 | 14 | ||
| 14 | namespace VideoCommon::Shader { | 15 | namespace VideoCommon::Shader { |
diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 600e2f3c3..50a8ce42a 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/hash.h" | 9 | #include "common/hash.h" |
| 10 | #include "video_core/engines/const_buffer_engine_interface.h" | 10 | #include "video_core/engines/const_buffer_engine_interface.h" |
| 11 | #include "video_core/engines/shader_type.h" | ||
| 11 | 12 | ||
| 12 | namespace VideoCommon::Shader { | 13 | namespace VideoCommon::Shader { |
| 13 | 14 | ||
| @@ -20,7 +21,7 @@ using BindlessSamplerMap = | |||
| 20 | * The ConstBufferLocker is a class use to interface the 3D and compute engines with the shader | 21 | * The ConstBufferLocker is a class use to interface the 3D and compute engines with the shader |
| 21 | * compiler. with it, the shader can obtain required data from GPU state and store it for disk | 22 | * compiler. with it, the shader can obtain required data from GPU state and store it for disk |
| 22 | * shader compilation. | 23 | * shader compilation. |
| 23 | **/ | 24 | */ |
| 24 | class ConstBufferLocker { | 25 | class ConstBufferLocker { |
| 25 | public: | 26 | public: |
| 26 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); | 27 | explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index bb926a132..b094e5a06 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) { |
| @@ -636,6 +616,8 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) { | |||
| 636 | } | 616 | } |
| 637 | 617 | ||
| 638 | Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { | 618 | Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { |
| 619 | const auto& sampler = GetSampler(instr.sampler); | ||
| 620 | |||
| 639 | const std::size_t type_coord_count = GetCoordCount(texture_type); | 621 | const std::size_t type_coord_count = GetCoordCount(texture_type); |
| 640 | const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; | 622 | const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; |
| 641 | 623 | ||
| @@ -659,7 +641,14 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 659 | // When lod is used always is in gpr20 | 641 | // When lod is used always is in gpr20 |
| 660 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); | 642 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); |
| 661 | 643 | ||
| 662 | const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, false}}); | 644 | // Fill empty entries from the guest sampler. |
| 645 | const std::size_t entry_coord_count = GetCoordCount(sampler.GetType()); | ||
| 646 | if (type_coord_count != entry_coord_count) { | ||
| 647 | LOG_WARNING(HW_GPU, "Bound and built texture types mismatch"); | ||
| 648 | } | ||
| 649 | for (std::size_t i = type_coord_count; i < entry_coord_count; ++i) { | ||
| 650 | coords.push_back(GetRegister(Register::ZeroIndex)); | ||
| 651 | } | ||
| 663 | 652 | ||
| 664 | Node4 values; | 653 | Node4 values; |
| 665 | for (u32 element = 0; element < values.size(); ++element) { | 654 | for (u32 element = 0; element < values.size(); ++element) { |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 54217e6a4..44d85d434 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -225,14 +225,15 @@ class Sampler { | |||
| 225 | public: | 225 | public: |
| 226 | /// This constructor is for bound samplers | 226 | /// This constructor is for bound samplers |
| 227 | constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, | 227 | constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, |
| 228 | bool is_array, bool is_shadow) | 228 | bool is_array, bool is_shadow, bool is_buffer) |
| 229 | : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow} {} | 229 | : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow}, |
| 230 | is_buffer{is_buffer} {} | ||
| 230 | 231 | ||
| 231 | /// This constructor is for bindless samplers | 232 | /// This constructor is for bindless samplers |
| 232 | constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, | 233 | constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, |
| 233 | bool is_array, bool is_shadow) | 234 | bool is_array, bool is_shadow, bool is_buffer) |
| 234 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, | 235 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, |
| 235 | is_shadow{is_shadow}, is_bindless{true} {} | 236 | is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true} {} |
| 236 | 237 | ||
| 237 | constexpr u32 GetIndex() const { | 238 | constexpr u32 GetIndex() const { |
| 238 | return index; | 239 | return index; |
| @@ -258,6 +259,10 @@ public: | |||
| 258 | return is_shadow; | 259 | return is_shadow; |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 262 | constexpr bool IsBuffer() const { | ||
| 263 | return is_buffer; | ||
| 264 | } | ||
| 265 | |||
| 261 | constexpr bool IsBindless() const { | 266 | constexpr bool IsBindless() const { |
| 262 | return is_bindless; | 267 | return is_bindless; |
| 263 | } | 268 | } |
| @@ -270,6 +275,7 @@ private: | |||
| 270 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) | 275 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) |
| 271 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. | 276 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. |
| 272 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. | 277 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. |
| 278 | bool is_buffer{}; ///< Whether the texture is a texture buffer without sampler. | ||
| 273 | bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. | 279 | bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. |
| 274 | }; | 280 | }; |
| 275 | 281 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 76a849818..2f71a50d2 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -179,6 +179,7 @@ private: | |||
| 179 | Tegra::Shader::TextureType type; | 179 | Tegra::Shader::TextureType type; |
| 180 | bool is_array; | 180 | bool is_array; |
| 181 | bool is_shadow; | 181 | bool is_shadow; |
| 182 | bool is_buffer; | ||
| 182 | }; | 183 | }; |
| 183 | 184 | ||
| 184 | void Decode(); | 185 | void Decode(); |
| @@ -303,13 +304,17 @@ private: | |||
| 303 | /// Returns a predicate combiner operation | 304 | /// Returns a predicate combiner operation |
| 304 | OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation); | 305 | OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation); |
| 305 | 306 | ||
| 307 | /// Queries the missing sampler info from the execution context. | ||
| 308 | SamplerInfo GetSamplerInfo(std::optional<SamplerInfo> sampler_info, u32 offset, | ||
| 309 | std::optional<u32> buffer = std::nullopt); | ||
| 310 | |||
| 306 | /// Accesses a texture sampler | 311 | /// Accesses a texture sampler |
| 307 | const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, | 312 | const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, |
| 308 | std::optional<SamplerInfo> sampler_info); | 313 | std::optional<SamplerInfo> sampler_info = std::nullopt); |
| 309 | 314 | ||
| 310 | // Accesses a texture sampler for a bindless texture. | 315 | /// Accesses a texture sampler for a bindless texture. |
| 311 | const Sampler& GetBindlessSampler(const Tegra::Shader::Register& reg, | 316 | const Sampler& GetBindlessSampler(Tegra::Shader::Register reg, |
| 312 | std::optional<SamplerInfo> sampler_info); | 317 | std::optional<SamplerInfo> sampler_info = std::nullopt); |
| 313 | 318 | ||
| 314 | /// Accesses an image. | 319 | /// Accesses an image. |
| 315 | Image& GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type); | 320 | Image& GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type); |