diff options
| author | 2020-01-05 18:36:21 -0400 | |
|---|---|---|
| committer | 2020-01-24 16:43:31 -0400 | |
| commit | 037ea431ceb93e93274fdcf9fb724819639d04fd (patch) | |
| tree | 7357dac5799959d2dc7dbe78346cb8cbd1a5400b /src | |
| parent | Shader_IR: Setup Indexed Samplers on the IR (diff) | |
| download | yuzu-037ea431ceb93e93274fdcf9fb724819639d04fd.tar.gz yuzu-037ea431ceb93e93274fdcf9fb724819639d04fd.tar.xz yuzu-037ea431ceb93e93274fdcf9fb724819639d04fd.zip | |
Shader_IR: deduce size of indexed samplers
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode.cpp | 36 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 22 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 1 |
4 files changed, 60 insertions, 8 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 507614d59..dd2f68a3e 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -56,6 +56,29 @@ void DeduceTextureHandlerSize(VideoCore::GuestDriverProfile* gpu_driver, | |||
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | std::optional<u32> TryDeduceSamplerSize(Sampler& sampler_to_deduce, | ||
| 60 | VideoCore::GuestDriverProfile* gpu_driver, | ||
| 61 | std::list<Sampler>& used_samplers) { | ||
| 62 | if (gpu_driver == nullptr) { | ||
| 63 | LOG_CRITICAL(HW_GPU, "GPU Driver profile has not been created yet"); | ||
| 64 | return std::nullopt; | ||
| 65 | } | ||
| 66 | const u32 base_offset = sampler_to_deduce.GetOffset(); | ||
| 67 | u32 max_offset{UINT_MAX}; | ||
| 68 | for (const auto& sampler : used_samplers) { | ||
| 69 | if (sampler.IsBindless()) { | ||
| 70 | continue; | ||
| 71 | } | ||
| 72 | if (sampler.GetOffset() > base_offset) { | ||
| 73 | max_offset = std::min(sampler.GetOffset(), max_offset); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | if (max_offset == UINT_MAX) { | ||
| 77 | return std::nullopt; | ||
| 78 | } | ||
| 79 | return ((max_offset - base_offset) * 4) / gpu_driver->GetTextureHandlerSize(); | ||
| 80 | } | ||
| 81 | |||
| 59 | } // Anonymous namespace | 82 | } // Anonymous namespace |
| 60 | 83 | ||
| 61 | class ASTDecoder { | 84 | class ASTDecoder { |
| @@ -342,6 +365,19 @@ void ShaderIR::PostDecode() { | |||
| 342 | // Deduce texture handler size if needed | 365 | // Deduce texture handler size if needed |
| 343 | auto gpu_driver = locker.AccessGuestDriverProfile(); | 366 | auto gpu_driver = locker.AccessGuestDriverProfile(); |
| 344 | DeduceTextureHandlerSize(gpu_driver, used_samplers); | 367 | DeduceTextureHandlerSize(gpu_driver, used_samplers); |
| 368 | // Deduce Indexed Samplers | ||
| 369 | if (uses_indexed_samplers) { | ||
| 370 | for (auto& sampler : used_samplers) { | ||
| 371 | if (sampler.IsIndexed()) { | ||
| 372 | auto size = TryDeduceSamplerSize(sampler, gpu_driver, used_samplers); | ||
| 373 | if (size) { | ||
| 374 | sampler.SetSize(*size); | ||
| 375 | } else { | ||
| 376 | sampler.SetSize(1); | ||
| 377 | } | ||
| 378 | } | ||
| 379 | } | ||
| 380 | } | ||
| 345 | } | 381 | } |
| 346 | 382 | ||
| 347 | } // namespace VideoCommon::Shader | 383 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 886650d9e..e7c38f5d6 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -383,7 +383,7 @@ const Sampler* ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 383 | // Otherwise create a new mapping for this sampler | 383 | // Otherwise create a new mapping for this sampler |
| 384 | const auto next_index = static_cast<u32>(used_samplers.size()); | 384 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 385 | return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, | 385 | return &used_samplers.emplace_back(next_index, offset, info.type, info.is_array, info.is_shadow, |
| 386 | info.is_buffer); | 386 | info.is_buffer, false); |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | 389 | const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, |
| @@ -417,7 +417,7 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | |||
| 417 | // Otherwise create a new mapping for this sampler | 417 | // Otherwise create a new mapping for this sampler |
| 418 | const auto next_index = static_cast<u32>(used_samplers.size()); | 418 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 419 | return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, | 419 | return &used_samplers.emplace_back(next_index, offset, buffer, info.type, info.is_array, |
| 420 | info.is_shadow, info.is_buffer); | 420 | info.is_shadow, info.is_buffer, false); |
| 421 | } else if (const auto array_sampler_info = | 421 | } else if (const auto array_sampler_info = |
| 422 | std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) { | 422 | std::get_if<ArraySamplerNode>(&*tracked_sampler_info)) { |
| 423 | const u32 base_offset = array_sampler_info->GetBaseOffset() / 4; | 423 | const u32 base_offset = array_sampler_info->GetBaseOffset() / 4; |
| @@ -430,14 +430,15 @@ const Sampler* ShaderIR::GetBindlessSampler(Tegra::Shader::Register reg, | |||
| 430 | if (it != used_samplers.end()) { | 430 | if (it != used_samplers.end()) { |
| 431 | ASSERT(!it->IsBindless() && it->GetType() == info.type && | 431 | ASSERT(!it->IsBindless() && it->GetType() == info.type && |
| 432 | it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow && | 432 | it->IsArray() == info.is_array && it->IsShadow() == info.is_shadow && |
| 433 | it->IsBuffer() == info.is_buffer); | 433 | it->IsBuffer() == info.is_buffer && it->IsIndexed()); |
| 434 | return &*it; | 434 | return &*it; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | uses_indexed_samplers = true; | ||
| 437 | // Otherwise create a new mapping for this sampler | 438 | // Otherwise create a new mapping for this sampler |
| 438 | const auto next_index = static_cast<u32>(used_samplers.size()); | 439 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 439 | return &used_samplers.emplace_back(next_index, base_offset, info.type, info.is_array, | 440 | return &used_samplers.emplace_back(next_index, base_offset, info.type, info.is_array, |
| 440 | info.is_shadow, info.is_buffer); | 441 | info.is_shadow, info.is_buffer, true); |
| 441 | } | 442 | } |
| 442 | return nullptr; | 443 | return nullptr; |
| 443 | } | 444 | } |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index b370df8f9..2f29b9506 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -240,15 +240,15 @@ class Sampler { | |||
| 240 | public: | 240 | public: |
| 241 | /// This constructor is for bound samplers | 241 | /// This constructor is for bound samplers |
| 242 | constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, | 242 | constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, |
| 243 | bool is_array, bool is_shadow, bool is_buffer) | 243 | bool is_array, bool is_shadow, bool is_buffer, bool is_indexed) |
| 244 | : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow}, | 244 | : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow}, |
| 245 | is_buffer{is_buffer} {} | 245 | is_buffer{is_buffer}, is_indexed{is_indexed} {} |
| 246 | 246 | ||
| 247 | /// This constructor is for bindless samplers | 247 | /// This constructor is for bindless samplers |
| 248 | constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, | 248 | constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, |
| 249 | bool is_array, bool is_shadow, bool is_buffer) | 249 | bool is_array, bool is_shadow, bool is_buffer, bool is_indexed) |
| 250 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, | 250 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, |
| 251 | is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true} {} | 251 | is_shadow{is_shadow}, is_buffer{is_buffer}, is_bindless{true}, is_indexed{is_indexed} {} |
| 252 | 252 | ||
| 253 | constexpr u32 GetIndex() const { | 253 | constexpr u32 GetIndex() const { |
| 254 | return index; | 254 | return index; |
| @@ -282,16 +282,30 @@ public: | |||
| 282 | return is_bindless; | 282 | return is_bindless; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | constexpr bool IsIndexed() const { | ||
| 286 | return is_indexed; | ||
| 287 | } | ||
| 288 | |||
| 289 | constexpr u32 Size() const { | ||
| 290 | return size; | ||
| 291 | } | ||
| 292 | |||
| 293 | void SetSize(u32 new_size) { | ||
| 294 | size = new_size; | ||
| 295 | } | ||
| 296 | |||
| 285 | private: | 297 | private: |
| 286 | u32 index{}; ///< Emulated index given for the this sampler. | 298 | u32 index{}; ///< Emulated index given for the this sampler. |
| 287 | u32 offset{}; ///< Offset in the const buffer from where the sampler is being read. | 299 | u32 offset{}; ///< Offset in the const buffer from where the sampler is being read. |
| 288 | u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers). | 300 | u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers). |
| 301 | u32 size{}; ///< Size of the sampler if indexed. | ||
| 289 | 302 | ||
| 290 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) | 303 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) |
| 291 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. | 304 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. |
| 292 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. | 305 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. |
| 293 | bool is_buffer{}; ///< Whether the texture is a texture buffer without sampler. | 306 | bool is_buffer{}; ///< Whether the texture is a texture buffer without sampler. |
| 294 | bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. | 307 | bool is_bindless{}; ///< Whether this sampler belongs to a bindless texture or not. |
| 308 | bool is_indexed{}; ///< Whether this sampler is an indexed array of textures. | ||
| 295 | }; | 309 | }; |
| 296 | 310 | ||
| 297 | /// Represents a tracked bindless sampler into a direct const buffer | 311 | /// Represents a tracked bindless sampler into a direct const buffer |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index d85f14c97..121528346 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -435,6 +435,7 @@ private: | |||
| 435 | bool uses_instance_id{}; | 435 | bool uses_instance_id{}; |
| 436 | bool uses_vertex_id{}; | 436 | bool uses_vertex_id{}; |
| 437 | bool uses_warps{}; | 437 | bool uses_warps{}; |
| 438 | bool uses_indexed_samplers{}; | ||
| 438 | 439 | ||
| 439 | Tegra::Shader::Header header; | 440 | Tegra::Shader::Header header; |
| 440 | }; | 441 | }; |