summaryrefslogtreecommitdiff
path: root/src/video_core/shader/registry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader/registry.cpp')
-rw-r--r--src/video_core/shader/registry.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp
new file mode 100644
index 000000000..7126caf98
--- /dev/null
+++ b/src/video_core/shader/registry.cpp
@@ -0,0 +1,127 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <tuple>
7
8#include "common/common_types.h"
9#include "video_core/engines/maxwell_3d.h"
10#include "video_core/engines/shader_type.h"
11#include "video_core/shader/registry.h"
12
13namespace VideoCommon::Shader {
14
15using Tegra::Engines::SamplerDescriptor;
16
17Registry::Registry(Tegra::Engines::ShaderType shader_stage,
18 VideoCore::GuestDriverProfile stored_guest_driver_profile)
19 : stage{shader_stage}, stored_guest_driver_profile{stored_guest_driver_profile} {}
20
21Registry::Registry(Tegra::Engines::ShaderType shader_stage,
22 Tegra::Engines::ConstBufferEngineInterface& engine)
23 : stage{shader_stage}, engine{&engine} {}
24
25Registry::~Registry() = default;
26
27std::optional<u32> Registry::ObtainKey(u32 buffer, u32 offset) {
28 const std::pair<u32, u32> key = {buffer, offset};
29 const auto iter = keys.find(key);
30 if (iter != keys.end()) {
31 return iter->second;
32 }
33 if (!engine) {
34 return std::nullopt;
35 }
36 const u32 value = engine->AccessConstBuffer32(stage, buffer, offset);
37 keys.emplace(key, value);
38 return value;
39}
40
41std::optional<SamplerDescriptor> Registry::ObtainBoundSampler(u32 offset) {
42 const u32 key = offset;
43 const auto iter = bound_samplers.find(key);
44 if (iter != bound_samplers.end()) {
45 return iter->second;
46 }
47 if (!engine) {
48 return std::nullopt;
49 }
50 const SamplerDescriptor value = engine->AccessBoundSampler(stage, offset);
51 bound_samplers.emplace(key, value);
52 return value;
53}
54
55std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer,
56 u32 offset) {
57 const std::pair key = {buffer, offset};
58 const auto iter = bindless_samplers.find(key);
59 if (iter != bindless_samplers.end()) {
60 return iter->second;
61 }
62 if (!engine) {
63 return std::nullopt;
64 }
65 const SamplerDescriptor value = engine->AccessBindlessSampler(stage, buffer, offset);
66 bindless_samplers.emplace(key, value);
67 return value;
68}
69
70std::optional<u32> Registry::ObtainBoundBuffer() {
71 if (bound_buffer_saved) {
72 return bound_buffer;
73 }
74 if (!engine) {
75 return std::nullopt;
76 }
77 bound_buffer_saved = true;
78 bound_buffer = engine->GetBoundBuffer();
79 return bound_buffer;
80}
81
82void Registry::InsertKey(u32 buffer, u32 offset, u32 value) {
83 keys.insert_or_assign({buffer, offset}, value);
84}
85
86void Registry::InsertBoundSampler(u32 offset, SamplerDescriptor sampler) {
87 bound_samplers.insert_or_assign(offset, sampler);
88}
89
90void Registry::InsertBindlessSampler(u32 buffer, u32 offset, SamplerDescriptor sampler) {
91 bindless_samplers.insert_or_assign({buffer, offset}, sampler);
92}
93
94void Registry::SetBoundBuffer(u32 buffer) {
95 bound_buffer_saved = true;
96 bound_buffer = buffer;
97}
98
99bool Registry::IsConsistent() const {
100 if (!engine) {
101 return true;
102 }
103 return std::all_of(keys.begin(), keys.end(),
104 [this](const auto& pair) {
105 const auto [cbuf, offset] = pair.first;
106 const auto value = pair.second;
107 return value == engine->AccessConstBuffer32(stage, cbuf, offset);
108 }) &&
109 std::all_of(bound_samplers.begin(), bound_samplers.end(),
110 [this](const auto& sampler) {
111 const auto [key, value] = sampler;
112 return value == engine->AccessBoundSampler(stage, key);
113 }) &&
114 std::all_of(bindless_samplers.begin(), bindless_samplers.end(),
115 [this](const auto& sampler) {
116 const auto [cbuf, offset] = sampler.first;
117 const auto value = sampler.second;
118 return value == engine->AccessBindlessSampler(stage, cbuf, offset);
119 });
120}
121
122bool Registry::HasEqualKeys(const Registry& rhs) const {
123 return std::tie(keys, bound_samplers, bindless_samplers) ==
124 std::tie(rhs.keys, rhs.bound_samplers, rhs.bindless_samplers);
125}
126
127} // namespace VideoCommon::Shader