From 1a58f45d76fe7756dd365e099d1536da769c1eab Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 23 Sep 2019 14:02:02 -0400 Subject: VideoCore: Unify const buffer accessing along engines and provide ConstBufferLocker class to shaders. --- src/video_core/shader/const_buffer_locker.h | 50 +++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/video_core/shader/const_buffer_locker.h (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h new file mode 100644 index 000000000..39e62584d --- /dev/null +++ b/src/video_core/shader/const_buffer_locker.h @@ -0,0 +1,50 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "common/common_types.h" +#include "common/hash.h" +#include "video_core/engines/const_buffer_engine_interface.h" + +namespace VideoCommon::Shader { + +class ConstBufferLocker { +public: + explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); + + explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, + Tegra::Engines::ConstBufferEngineInterface* engine); + + // Checks if an engine is setup, it may be possible that during disk shader + // cache run, the engines have not been created yet. + bool IsEngineSet() const; + + // Use this to set/change the engine used for this shader. + void SetEngine(Tegra::Engines::ConstBufferEngineInterface* engine); + + // Retrieves a key from the locker, if it's registered, it will give the + // registered value, if not it will obtain it from maxwell3d and register it. + std::optional ObtainKey(u32 buffer, u32 offset); + + // Manually inserts a key. + void InsertKey(u32 buffer, u32 offset, u32 value); + + // Retrieves the number of keys registered. + u32 NumKeys() const; + + // Gives an accessor to the key's database. + const std::unordered_map, u32, Common::PairHash>& AccessKeys() const; + + // Checks keys against maxwell3d's current const buffers. Returns true if they + // are the same value, false otherwise; + bool AreKeysConsistant() const; + +private: + Tegra::Engines::ConstBufferEngineInterface* engine; + Tegra::Engines::ShaderType shader_stage; + std::unordered_map, u32, Common::PairHash> keys{}; +}; +} // namespace VideoCommon::Shader -- cgit v1.2.3 From 33fcec3502f5dd5a99b7a8337128b7c99bfba908 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 25 Sep 2019 09:53:18 -0400 Subject: Shader_IR: allow lookup of texture samplers within the shader_ir for instructions that don't provide it --- src/video_core/shader/const_buffer_locker.h | 60 ++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 39e62584d..0bc257781 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -11,6 +11,11 @@ namespace VideoCommon::Shader { +using KeyMap = std::unordered_map, u32, Common::PairHash>; +using BoundSamplerMap = std::unordered_map; +using BindlessSamplerMap = + std::unordered_map, Tegra::Engines::SamplerDescriptor, Common::PairHash>; + class ConstBufferLocker { public: explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); @@ -29,22 +34,67 @@ public: // registered value, if not it will obtain it from maxwell3d and register it. std::optional ObtainKey(u32 buffer, u32 offset); + std::optional ObtainBoundSampler(u32 offset); + + std::optional ObtainBindlessSampler(u32 buffer, u32 offset); + // Manually inserts a key. void InsertKey(u32 buffer, u32 offset, u32 value); + void InsertBoundSampler(u32 offset, Tegra::Engines::SamplerDescriptor sampler); + + void InsertBindlessSampler(u32 buffer, u32 offset, Tegra::Engines::SamplerDescriptor sampler); + // Retrieves the number of keys registered. - u32 NumKeys() const; + std::size_t NumKeys() const { + if (!keys) { + return 0; + } + return keys->size(); + } + + std::size_t NumBoundSamplers() const { + if (!bound_samplers) { + return 0; + } + return bound_samplers->size(); + } + + std::size_t NumBindlessSamplers() const { + if (!bindless_samplers) { + return 0; + } + return bindless_samplers->size(); + } // Gives an accessor to the key's database. - const std::unordered_map, u32, Common::PairHash>& AccessKeys() const; + // Pre: NumKeys > 0 + const KeyMap& AccessKeys() const { + return *keys; + } + + // Gives an accessor to the sampler's database. + // Pre: NumBindlessSamplers > 0 + const BoundSamplerMap& AccessBoundSamplers() const { + return *bound_samplers; + } + + // Gives an accessor to the sampler's database. + // Pre: NumBindlessSamplers > 0 + const BindlessSamplerMap& AccessBindlessSamplers() const { + return *bindless_samplers; + } - // Checks keys against maxwell3d's current const buffers. Returns true if they + // Checks keys & samplers against engine's current const buffers. Returns true if they // are the same value, false otherwise; - bool AreKeysConsistant() const; + bool IsConsistant() const; private: Tegra::Engines::ConstBufferEngineInterface* engine; Tegra::Engines::ShaderType shader_stage; - std::unordered_map, u32, Common::PairHash> keys{}; + // All containers are lazy initialized as most shaders don't use them. + std::shared_ptr keys{}; + std::shared_ptr bound_samplers{}; + std::shared_ptr bindless_samplers{}; }; } // namespace VideoCommon::Shader -- cgit v1.2.3 From a05120ec0b8b1827ebeffd4e78a553f7886fa178 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 25 Sep 2019 15:03:13 -0400 Subject: Shader_IR: Correct typo in Consistent method. --- src/video_core/shader/const_buffer_locker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 0bc257781..13eeba320 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -87,7 +87,7 @@ public: // Checks keys & samplers against engine's current const buffers. Returns true if they // are the same value, false otherwise; - bool IsConsistant() const; + bool IsConsistent() const; private: Tegra::Engines::ConstBufferEngineInterface* engine; -- cgit v1.2.3 From 7b81ba4d8a9805f808fcc60a0905ac74d293b2ee Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 24 Sep 2019 23:34:18 -0300 Subject: gl_shader_decompiler: Move entries to a separate function --- src/video_core/shader/const_buffer_locker.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 13eeba320..54459977f 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -21,14 +21,14 @@ public: explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, - Tegra::Engines::ConstBufferEngineInterface* engine); + Tegra::Engines::ConstBufferEngineInterface& engine); // Checks if an engine is setup, it may be possible that during disk shader // cache run, the engines have not been created yet. bool IsEngineSet() const; // Use this to set/change the engine used for this shader. - void SetEngine(Tegra::Engines::ConstBufferEngineInterface* engine); + void SetEngine(Tegra::Engines::ConstBufferEngineInterface& engine); // Retrieves a key from the locker, if it's registered, it will give the // registered value, if not it will obtain it from maxwell3d and register it. -- cgit v1.2.3 From fa2c297f3eddc718123767142dbc296270f58f7a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Sep 2019 19:19:41 -0300 Subject: const_buffer_locker: Minor style changes --- src/video_core/shader/const_buffer_locker.h | 76 +++++++++-------------------- 1 file changed, 23 insertions(+), 53 deletions(-) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 54459977f..417d5a16f 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -23,78 +23,48 @@ public: explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, Tegra::Engines::ConstBufferEngineInterface& engine); - // Checks if an engine is setup, it may be possible that during disk shader - // cache run, the engines have not been created yet. - bool IsEngineSet() const; - - // Use this to set/change the engine used for this shader. - void SetEngine(Tegra::Engines::ConstBufferEngineInterface& engine); - - // Retrieves a key from the locker, if it's registered, it will give the - // registered value, if not it will obtain it from maxwell3d and register it. + /// Retrieves a key from the locker, if it's registered, it will give the registered value, if + /// not it will obtain it from maxwell3d and register it. std::optional ObtainKey(u32 buffer, u32 offset); std::optional ObtainBoundSampler(u32 offset); std::optional ObtainBindlessSampler(u32 buffer, u32 offset); - // Manually inserts a key. + /// Inserts a key. void InsertKey(u32 buffer, u32 offset, u32 value); + /// Inserts a bound sampler key. void InsertBoundSampler(u32 offset, Tegra::Engines::SamplerDescriptor sampler); + /// Inserts a bindless sampler key. void InsertBindlessSampler(u32 buffer, u32 offset, Tegra::Engines::SamplerDescriptor sampler); - // Retrieves the number of keys registered. - std::size_t NumKeys() const { - if (!keys) { - return 0; - } - return keys->size(); - } - - std::size_t NumBoundSamplers() const { - if (!bound_samplers) { - return 0; - } - return bound_samplers->size(); - } - - std::size_t NumBindlessSamplers() const { - if (!bindless_samplers) { - return 0; - } - return bindless_samplers->size(); - } + /// Checks keys and samplers against engine's current const buffers. Returns true if they are + /// the same value, false otherwise; + bool IsConsistent() const; - // Gives an accessor to the key's database. - // Pre: NumKeys > 0 - const KeyMap& AccessKeys() const { - return *keys; + /// Gives an getter to the const buffer keys in the database. + const KeyMap& GetKeys() const { + return keys; } - // Gives an accessor to the sampler's database. - // Pre: NumBindlessSamplers > 0 - const BoundSamplerMap& AccessBoundSamplers() const { - return *bound_samplers; + /// Gets samplers database. + const BoundSamplerMap& GetBoundSamplers() const { + return bound_samplers; } - // Gives an accessor to the sampler's database. - // Pre: NumBindlessSamplers > 0 - const BindlessSamplerMap& AccessBindlessSamplers() const { - return *bindless_samplers; + /// Gets bindless samplers database. + const BindlessSamplerMap& GetBindlessSamplers() const { + return bindless_samplers; } - // Checks keys & samplers against engine's current const buffers. Returns true if they - // are the same value, false otherwise; - bool IsConsistent() const; - private: - Tegra::Engines::ConstBufferEngineInterface* engine; - Tegra::Engines::ShaderType shader_stage; - // All containers are lazy initialized as most shaders don't use them. - std::shared_ptr keys{}; - std::shared_ptr bound_samplers{}; - std::shared_ptr bindless_samplers{}; + const Tegra::Engines::ShaderType stage; + Tegra::Engines::ConstBufferEngineInterface* engine = nullptr; + KeyMap keys; + BoundSamplerMap bound_samplers; + BindlessSamplerMap bindless_samplers; }; + } // namespace VideoCommon::Shader -- cgit v1.2.3 From 78f3e8a75792c976eb5bfa6df4c020d898642684 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Sep 2019 00:23:08 -0300 Subject: gl_shader_cache: Implement locker variants invalidation --- src/video_core/shader/const_buffer_locker.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 417d5a16f..966537fd6 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -44,6 +44,9 @@ public: /// the same value, false otherwise; bool IsConsistent() const; + /// Returns true if the keys are equal to the other ones in the locker. + bool HasEqualKeys(const ConstBufferLocker& rhs) const; + /// Gives an getter to the const buffer keys in the database. const KeyMap& GetKeys() const { return keys; -- cgit v1.2.3 From be856a38d6b0c7c90c861baf3204ac48a108f3d2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 17 Oct 2019 10:35:16 -0400 Subject: Shader_IR: Address Feedback. --- src/video_core/shader/const_buffer_locker.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/video_core/shader/const_buffer_locker.h') diff --git a/src/video_core/shader/const_buffer_locker.h b/src/video_core/shader/const_buffer_locker.h index 966537fd6..600e2f3c3 100644 --- a/src/video_core/shader/const_buffer_locker.h +++ b/src/video_core/shader/const_buffer_locker.h @@ -16,6 +16,11 @@ using BoundSamplerMap = std::unordered_map, Tegra::Engines::SamplerDescriptor, Common::PairHash>; +/** + * The ConstBufferLocker is a class use to interface the 3D and compute engines with the shader + * compiler. with it, the shader can obtain required data from GPU state and store it for disk + * shader compilation. + **/ class ConstBufferLocker { public: explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage); @@ -23,6 +28,8 @@ public: explicit ConstBufferLocker(Tegra::Engines::ShaderType shader_stage, Tegra::Engines::ConstBufferEngineInterface& engine); + ~ConstBufferLocker(); + /// Retrieves a key from the locker, if it's registered, it will give the registered value, if /// not it will obtain it from maxwell3d and register it. std::optional ObtainKey(u32 buffer, u32 offset); -- cgit v1.2.3