summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp41
-rw-r--r--src/video_core/engines/maxwell_3d.h4
-rw-r--r--src/video_core/rasterizer_interface.h5
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp201
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.h123
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp30
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
7 files changed, 328 insertions, 86 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index fe91ff6a0..9add2bc94 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -556,23 +556,13 @@ void Maxwell3D::ProcessQueryGet() {
556 // matches the current payload. 556 // matches the current payload.
557 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); 557 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE");
558 break; 558 break;
559 case Regs::QueryOperation::Counter: { 559 case Regs::QueryOperation::Counter:
560 u64 result; 560 if (const std::optional<u64> result = GetQueryResult()) {
561 switch (regs.query.query_get.select) { 561 // If the query returns an empty optional it means it's cached and deferred.
562 case Regs::QuerySelect::Zero: 562 // In this case we have a non-empty result, so we stamp it immediately.
563 result = 0; 563 StampQueryResult(*result, regs.query.query_get.short_query == 0);
564 break;
565 case Regs::QuerySelect::SamplesPassed:
566 result = rasterizer.Query(VideoCore::QueryType::SamplesPassed);
567 break;
568 default:
569 result = 1;
570 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
571 static_cast<u32>(regs.query.query_get.select.Value()));
572 } 564 }
573 StampQueryResult(result, regs.query.query_get.short_query == 0);
574 break; 565 break;
575 }
576 case Regs::QueryOperation::Trap: 566 case Regs::QueryOperation::Trap:
577 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); 567 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP");
578 break; 568 break;
@@ -595,20 +585,20 @@ void Maxwell3D::ProcessQueryCondition() {
595 } 585 }
596 case Regs::ConditionMode::ResNonZero: { 586 case Regs::ConditionMode::ResNonZero: {
597 Regs::QueryCompare cmp; 587 Regs::QueryCompare cmp;
598 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp)); 588 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
599 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U; 589 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
600 break; 590 break;
601 } 591 }
602 case Regs::ConditionMode::Equal: { 592 case Regs::ConditionMode::Equal: {
603 Regs::QueryCompare cmp; 593 Regs::QueryCompare cmp;
604 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp)); 594 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
605 execute_on = 595 execute_on =
606 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode; 596 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
607 break; 597 break;
608 } 598 }
609 case Regs::ConditionMode::NotEqual: { 599 case Regs::ConditionMode::NotEqual: {
610 Regs::QueryCompare cmp; 600 Regs::QueryCompare cmp;
611 memory_manager.ReadBlockUnsafe(condition_address, &cmp, sizeof(cmp)); 601 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
612 execute_on = 602 execute_on =
613 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode; 603 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
614 break; 604 break;
@@ -674,6 +664,21 @@ void Maxwell3D::DrawArrays() {
674 } 664 }
675} 665}
676 666
667std::optional<u64> Maxwell3D::GetQueryResult() {
668 switch (regs.query.query_get.select) {
669 case Regs::QuerySelect::Zero:
670 return 0;
671 case Regs::QuerySelect::SamplesPassed:
672 // Deferred.
673 rasterizer.Query(regs.query.QueryAddress(), VideoCore::QueryType::SamplesPassed);
674 return {};
675 default:
676 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
677 static_cast<u32>(regs.query.query_get.select.Value()));
678 return 1;
679 }
680}
681
677void Maxwell3D::ProcessCBBind(std::size_t stage_index) { 682void Maxwell3D::ProcessCBBind(std::size_t stage_index) {
678 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. 683 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
679 auto& shader = state.shader_stages[stage_index]; 684 auto& shader = state.shader_stages[stage_index];
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index d21f678ed..26939be3f 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <bitset> 8#include <bitset>
9#include <optional>
9#include <type_traits> 10#include <type_traits>
10#include <unordered_map> 11#include <unordered_map>
11#include <vector> 12#include <vector>
@@ -1462,6 +1463,9 @@ private:
1462 1463
1463 // Handles a instance drawcall from MME 1464 // Handles a instance drawcall from MME
1464 void StepInstance(MMEDrawMode expected_mode, u32 count); 1465 void StepInstance(MMEDrawMode expected_mode, u32 count);
1466
1467 /// Returns a query's value or an empty object if the value will be deferred through a cache.
1468 std::optional<u64> GetQueryResult();
1465}; 1469};
1466 1470
1467#define ASSERT_REG_POSITION(field_name, position) \ 1471#define ASSERT_REG_POSITION(field_name, position) \
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 2fc627539..a394f2d3e 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -20,6 +20,7 @@ namespace VideoCore {
20enum class QueryType { 20enum class QueryType {
21 SamplesPassed, 21 SamplesPassed,
22}; 22};
23constexpr std::size_t NumQueryTypes = 1;
23 24
24enum class LoadCallbackStage { 25enum class LoadCallbackStage {
25 Prepare, 26 Prepare,
@@ -48,8 +49,8 @@ public:
48 /// Resets the counter of a query 49 /// Resets the counter of a query
49 virtual void ResetCounter(QueryType type) = 0; 50 virtual void ResetCounter(QueryType type) = 0;
50 51
51 /// Returns the value of a GPU query 52 /// Records a GPU query and caches it
52 virtual u64 Query(QueryType type) = 0; 53 virtual void Query(GPUVAddr gpu_addr, QueryType type) = 0;
53 54
54 /// Notify rasterizer that all caches should be flushed to Switch memory 55 /// Notify rasterizer that all caches should be flushed to Switch memory
55 virtual void FlushAll() = 0; 56 virtual void FlushAll() = 0;
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp
index 1c7dc999a..8f0e8241d 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_query_cache.cpp
@@ -2,58 +2,203 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
6#include <memory>
7#include <utility>
8#include <vector>
9
5#include <glad/glad.h> 10#include <glad/glad.h>
6 11
12#include "common/assert.h"
13#include "core/core.h"
14#include "video_core/engines/maxwell_3d.h"
15#include "video_core/memory_manager.h"
7#include "video_core/renderer_opengl/gl_query_cache.h" 16#include "video_core/renderer_opengl/gl_query_cache.h"
17#include "video_core/renderer_opengl/gl_rasterizer.h"
8 18
9namespace OpenGL { 19namespace OpenGL {
10 20
11HostCounter::HostCounter(GLenum target) { 21using VideoCore::QueryType;
12 query.Create(target); 22
23namespace {
24
25constexpr std::array<GLenum, VideoCore::NumQueryTypes> QueryTargets = {GL_SAMPLES_PASSED};
26
27constexpr GLenum GetTarget(QueryType type) {
28 return QueryTargets[static_cast<std::size_t>(type)];
13} 29}
14 30
15HostCounter::~HostCounter() = default; 31} // Anonymous namespace
32
33CounterStream::CounterStream(QueryCache& cache, QueryType type)
34 : cache{cache}, type{type}, target{GetTarget(type)} {}
16 35
17void HostCounter::UpdateState(bool enabled) { 36CounterStream::~CounterStream() = default;
37
38void CounterStream::Update(bool enabled, bool any_command_queued) {
18 if (enabled) { 39 if (enabled) {
19 Enable(); 40 if (!current) {
20 } else { 41 current = cache.GetHostCounter(last, type);
21 Disable(); 42 }
43 return;
22 } 44 }
45
46 if (current) {
47 EndQuery(any_command_queued);
48 }
49 last = std::exchange(current, nullptr);
23} 50}
24 51
25void HostCounter::Reset() { 52void CounterStream::Reset(bool any_command_queued) {
26 counter = 0; 53 if (current) {
27 Disable(); 54 EndQuery(any_command_queued);
55 }
56 current = nullptr;
57 last = nullptr;
28} 58}
29 59
30u64 HostCounter::Query() { 60std::shared_ptr<HostCounter> CounterStream::GetCurrent(bool any_command_queued) {
31 if (!is_beginned) { 61 if (!current) {
32 return counter; 62 return nullptr;
63 }
64 EndQuery(any_command_queued);
65 last = std::move(current);
66 current = cache.GetHostCounter(last, type);
67 return last;
68}
69
70void CounterStream::EndQuery(bool any_command_queued) {
71 if (!any_command_queued) {
72 // There are chances a query waited on without commands (glDraw, glClear, glDispatch). Not
73 // having any of these causes a lock. glFlush is considered a command, so we can safely wait
74 // for this. Insert to the OpenGL command stream a flush.
75 glFlush();
76 }
77 glEndQuery(target);
78}
79
80QueryCache::QueryCache(Core::System& system, RasterizerOpenGL& rasterizer)
81 : RasterizerCache{rasterizer}, system{system},
82 rasterizer{rasterizer}, streams{{CounterStream{*this, QueryType::SamplesPassed}}} {}
83
84QueryCache::~QueryCache() = default;
85
86void QueryCache::Query(GPUVAddr gpu_addr, QueryType type) {
87 auto& memory_manager = system.GPU().MemoryManager();
88 const auto host_ptr = memory_manager.GetPointer(gpu_addr);
89
90 auto query = TryGet(host_ptr);
91 if (!query) {
92 const auto cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr);
93 ASSERT_OR_EXECUTE(cpu_addr, return;);
94
95 query = std::make_shared<CachedQuery>(type, *cpu_addr, host_ptr);
96 Register(query);
97 }
98
99 query->SetCounter(GetStream(type).GetCurrent(rasterizer.AnyCommandQueued()));
100 query->MarkAsModified(true, *this);
101}
102
103void QueryCache::UpdateCounters() {
104 auto& samples_passed = GetStream(QueryType::SamplesPassed);
105
106 const auto& regs = system.GPU().Maxwell3D().regs;
107 samples_passed.Update(regs.samplecnt_enable, rasterizer.AnyCommandQueued());
108}
109
110void QueryCache::ResetCounter(QueryType type) {
111 GetStream(type).Reset(rasterizer.AnyCommandQueued());
112}
113
114void QueryCache::Reserve(QueryType type, OGLQuery&& query) {
115 reserved_queries[static_cast<std::size_t>(type)].push_back(std::move(query));
116}
117
118std::shared_ptr<HostCounter> QueryCache::GetHostCounter(std::shared_ptr<HostCounter> dependency,
119 QueryType type) {
120 const auto type_index = static_cast<std::size_t>(type);
121 auto& reserve = reserved_queries[type_index];
122
123 if (reserve.empty()) {
124 return std::make_shared<HostCounter>(*this, std::move(dependency), type);
33 } 125 }
34 Disable();
35 u64 value;
36 glGetQueryObjectui64v(query.handle, GL_QUERY_RESULT, &value);
37 Enable();
38 126
39 counter += value; 127 auto counter = std::make_shared<HostCounter>(*this, std::move(dependency), type,
128 std::move(reserve.back()));
129 reserve.pop_back();
40 return counter; 130 return counter;
41} 131}
42 132
43void HostCounter::Enable() { 133void QueryCache::FlushObjectInner(const std::shared_ptr<CachedQuery>& counter_) {
44 if (is_beginned) { 134 auto& counter = *counter_;
45 return; 135 auto& stream = GetStream(counter.GetType());
136
137 // Waiting for a query while another query of the same target is enabled locks Nvidia's driver.
138 // To avoid this disable and re-enable keeping the dependency stream.
139 const bool is_enabled = stream.IsEnabled();
140 if (is_enabled) {
141 stream.Update(false, false);
142 }
143
144 counter.Flush();
145
146 if (is_enabled) {
147 stream.Update(true, false);
46 } 148 }
47 is_beginned = true;
48 glBeginQuery(GL_SAMPLES_PASSED, query.handle);
49} 149}
50 150
51void HostCounter::Disable() { 151CounterStream& QueryCache::GetStream(QueryType type) {
52 if (!is_beginned) { 152 return streams[static_cast<std::size_t>(type)];
53 return; 153}
154
155HostCounter::HostCounter(QueryCache& cache, std::shared_ptr<HostCounter> dependency, QueryType type)
156 : cache{cache}, type{type}, dependency{std::move(dependency)} {
157 const GLenum target = GetTarget(type);
158 query.Create(target);
159 glBeginQuery(target, query.handle);
160}
161
162HostCounter::HostCounter(QueryCache& cache, std::shared_ptr<HostCounter> dependency, QueryType type,
163 OGLQuery&& query_)
164 : cache{cache}, type{type}, dependency{std::move(dependency)}, query{std::move(query_)} {
165 glBeginQuery(GetTarget(type), query.handle);
166}
167
168HostCounter::~HostCounter() {
169 cache.Reserve(type, std::move(query));
170}
171
172u64 HostCounter::Query() {
173 if (query.handle == 0) {
174 return result;
175 }
176
177 glGetQueryObjectui64v(query.handle, GL_QUERY_RESULT, &result);
178
179 if (dependency) {
180 result += dependency->Query();
54 } 181 }
55 glEndQuery(GL_SAMPLES_PASSED); 182
56 is_beginned = false; 183 return result;
184}
185
186CachedQuery::CachedQuery(QueryType type, VAddr cpu_addr, u8* host_ptr)
187 : RasterizerCacheObject{host_ptr}, type{type}, cpu_addr{cpu_addr}, host_ptr{host_ptr} {}
188
189CachedQuery::~CachedQuery() = default;
190
191void CachedQuery::Flush() {
192 const u64 value = counter->Query();
193 std::memcpy(host_ptr, &value, sizeof(value));
194}
195
196void CachedQuery::SetCounter(std::shared_ptr<HostCounter> counter_) {
197 counter = std::move(counter_);
198}
199
200QueryType CachedQuery::GetType() const {
201 return type;
57} 202}
58 203
59} // namespace OpenGL 204} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h
index 52c6546bf..91594b120 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.h
+++ b/src/video_core/renderer_opengl/gl_query_cache.h
@@ -4,38 +4,131 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
8#include <memory>
9#include <optional>
10#include <vector>
11
7#include <glad/glad.h> 12#include <glad/glad.h>
8 13
9#include "common/common_types.h" 14#include "common/common_types.h"
15#include "video_core/rasterizer_cache.h"
16#include "video_core/rasterizer_interface.h"
10#include "video_core/renderer_opengl/gl_resource_manager.h" 17#include "video_core/renderer_opengl/gl_resource_manager.h"
11 18
19namespace Core {
20class System;
21}
22
12namespace OpenGL { 23namespace OpenGL {
13 24
14class HostCounter final { 25class CachedQuery;
26class HostCounter;
27class RasterizerOpenGL;
28class QueryCache;
29
30class CounterStream final {
15public: 31public:
16 explicit HostCounter(GLenum target); 32 explicit CounterStream(QueryCache& cache, VideoCore::QueryType type);
17 ~HostCounter(); 33 ~CounterStream();
34
35 void Update(bool enabled, bool any_command_queued);
36
37 void Reset(bool any_command_queued);
38
39 std::shared_ptr<HostCounter> GetCurrent(bool any_command_queued);
40
41 bool IsEnabled() const {
42 return current != nullptr;
43 }
44
45private:
46 void EndQuery(bool any_command_queued);
47
48 QueryCache& cache;
49
50 std::shared_ptr<HostCounter> current;
51 std::shared_ptr<HostCounter> last;
52 VideoCore::QueryType type;
53 GLenum target;
54};
55
56class QueryCache final : public RasterizerCache<std::shared_ptr<CachedQuery>> {
57public:
58 explicit QueryCache(Core::System& system, RasterizerOpenGL& rasterizer);
59 ~QueryCache();
60
61 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type);
62
63 void UpdateCounters();
64
65 void ResetCounter(VideoCore::QueryType type);
18 66
19 /// Enables or disables the counter as required. 67 void Reserve(VideoCore::QueryType type, OGLQuery&& query);
20 void UpdateState(bool enabled);
21 68
22 /// Resets the counter disabling it if needed. 69 std::shared_ptr<HostCounter> GetHostCounter(std::shared_ptr<HostCounter> dependency,
23 void Reset(); 70 VideoCore::QueryType type);
71
72protected:
73 void FlushObjectInner(const std::shared_ptr<CachedQuery>& counter) override;
74
75private:
76 CounterStream& GetStream(VideoCore::QueryType type);
77
78 Core::System& system;
79 RasterizerOpenGL& rasterizer;
80
81 std::array<CounterStream, VideoCore::NumQueryTypes> streams;
82 std::array<std::vector<OGLQuery>, VideoCore::NumQueryTypes> reserved_queries;
83};
84
85class HostCounter final {
86public:
87 explicit HostCounter(QueryCache& cache, std::shared_ptr<HostCounter> dependency,
88 VideoCore::QueryType type);
89 explicit HostCounter(QueryCache& cache, std::shared_ptr<HostCounter> dependency,
90 VideoCore::QueryType type, OGLQuery&& query);
91 ~HostCounter();
24 92
25 /// Returns the current value of the query. 93 /// Returns the current value of the query.
26 /// @note It may harm precision of future queries if the counter is not disabled.
27 u64 Query(); 94 u64 Query();
28 95
29private: 96private:
30 /// Enables the counter when disabled. 97 QueryCache& cache;
31 void Enable(); 98 VideoCore::QueryType type;
32 99
33 /// Disables the counter when enabled. 100 std::shared_ptr<HostCounter> dependency; ///< Counter queued before this one.
34 void Disable(); 101 OGLQuery query; ///< OpenGL query.
102 u64 result; ///< Added values of the counter.
103};
104
105class CachedQuery final : public RasterizerCacheObject {
106public:
107 explicit CachedQuery(VideoCore::QueryType type, VAddr cpu_addr, u8* host_ptr);
108 ~CachedQuery();
109
110 /// Writes the counter value to host memory.
111 void Flush();
112
113 /// Updates the counter this cached query registered in guest memory will write when requested.
114 void SetCounter(std::shared_ptr<HostCounter> counter);
35 115
36 OGLQuery query; ///< OpenGL query. 116 /// Returns the query type.
37 u64 counter{}; ///< Added values of the counter. 117 VideoCore::QueryType GetType() const;
38 bool is_beginned{}; ///< True when the OpenGL query is beginned. 118
119 VAddr GetCpuAddr() const override {
120 return cpu_addr;
121 }
122
123 std::size_t GetSizeInBytes() const override {
124 return sizeof(u64);
125 }
126
127private:
128 VideoCore::QueryType type;
129 VAddr cpu_addr; ///< Guest CPU address.
130 u8* host_ptr; ///< Writable host pointer.
131 std::shared_ptr<HostCounter> counter; ///< Host counter to query, owns the dependency tree.
39}; 132};
40 133
41} // namespace OpenGL 134} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 652db705b..827f85884 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -25,6 +25,7 @@
25#include "video_core/engines/maxwell_3d.h" 25#include "video_core/engines/maxwell_3d.h"
26#include "video_core/engines/shader_type.h" 26#include "video_core/engines/shader_type.h"
27#include "video_core/memory_manager.h" 27#include "video_core/memory_manager.h"
28#include "video_core/renderer_opengl/gl_query_cache.h"
28#include "video_core/renderer_opengl/gl_rasterizer.h" 29#include "video_core/renderer_opengl/gl_rasterizer.h"
29#include "video_core/renderer_opengl/gl_shader_cache.h" 30#include "video_core/renderer_opengl/gl_shader_cache.h"
30#include "video_core/renderer_opengl/gl_shader_gen.h" 31#include "video_core/renderer_opengl/gl_shader_gen.h"
@@ -92,8 +93,8 @@ std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer,
92RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 93RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
93 ScreenInfo& info) 94 ScreenInfo& info)
94 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device}, 95 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
95 shader_cache{*this, system, emu_window, device}, system{system}, screen_info{info}, 96 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
96 buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { 97 screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
97 shader_program_manager = std::make_unique<GLShader::ProgramManager>(); 98 shader_program_manager = std::make_unique<GLShader::ProgramManager>();
98 state.draw.shader_program = 0; 99 state.draw.shader_program = 0;
99 state.Apply(); 100 state.Apply();
@@ -548,9 +549,9 @@ void RasterizerOpenGL::Clear() {
548void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { 549void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
549 MICROPROFILE_SCOPE(OpenGL_Drawing); 550 MICROPROFILE_SCOPE(OpenGL_Drawing);
550 auto& gpu = system.GPU().Maxwell3D(); 551 auto& gpu = system.GPU().Maxwell3D();
551
552 const auto& regs = gpu.regs; 552 const auto& regs = gpu.regs;
553 samples_passed.UpdateState(regs.samplecnt_enable); 553
554 query_cache.UpdateCounters();
554 555
555 SyncRasterizeEnable(state); 556 SyncRasterizeEnable(state);
556 SyncColorMask(); 557 SyncColorMask();
@@ -718,24 +719,11 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
718} 719}
719 720
720void RasterizerOpenGL::ResetCounter(VideoCore::QueryType type) { 721void RasterizerOpenGL::ResetCounter(VideoCore::QueryType type) {
721 switch (type) { 722 query_cache.ResetCounter(type);
722 case VideoCore::QueryType::SamplesPassed:
723 samples_passed.Reset();
724 break;
725 default:
726 UNIMPLEMENTED_MSG("type={}", static_cast<u32>(type));
727 break;
728 }
729} 723}
730 724
731u64 RasterizerOpenGL::Query(VideoCore::QueryType type) { 725void RasterizerOpenGL::Query(GPUVAddr gpu_addr, VideoCore::QueryType type) {
732 switch (type) { 726 query_cache.Query(gpu_addr, type);
733 case VideoCore::QueryType::SamplesPassed:
734 return samples_passed.Query();
735 default:
736 UNIMPLEMENTED_MSG("type={}", static_cast<u32>(type));
737 return 1;
738 }
739} 727}
740 728
741void RasterizerOpenGL::FlushAll() {} 729void RasterizerOpenGL::FlushAll() {}
@@ -747,6 +735,7 @@ void RasterizerOpenGL::FlushRegion(CacheAddr addr, u64 size) {
747 } 735 }
748 texture_cache.FlushRegion(addr, size); 736 texture_cache.FlushRegion(addr, size);
749 buffer_cache.FlushRegion(addr, size); 737 buffer_cache.FlushRegion(addr, size);
738 query_cache.FlushRegion(addr, size);
750} 739}
751 740
752void RasterizerOpenGL::InvalidateRegion(CacheAddr addr, u64 size) { 741void RasterizerOpenGL::InvalidateRegion(CacheAddr addr, u64 size) {
@@ -757,6 +746,7 @@ void RasterizerOpenGL::InvalidateRegion(CacheAddr addr, u64 size) {
757 texture_cache.InvalidateRegion(addr, size); 746 texture_cache.InvalidateRegion(addr, size);
758 shader_cache.InvalidateRegion(addr, size); 747 shader_cache.InvalidateRegion(addr, size);
759 buffer_cache.InvalidateRegion(addr, size); 748 buffer_cache.InvalidateRegion(addr, size);
749 query_cache.InvalidateRegion(addr, size);
760} 750}
761 751
762void RasterizerOpenGL::FlushAndInvalidateRegion(CacheAddr addr, u64 size) { 752void RasterizerOpenGL::FlushAndInvalidateRegion(CacheAddr addr, u64 size) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 857a6c073..4fb6811a7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -63,7 +63,7 @@ public:
63 void Clear() override; 63 void Clear() override;
64 void DispatchCompute(GPUVAddr code_addr) override; 64 void DispatchCompute(GPUVAddr code_addr) override;
65 void ResetCounter(VideoCore::QueryType type) override; 65 void ResetCounter(VideoCore::QueryType type) override;
66 u64 Query(VideoCore::QueryType type) override; 66 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type) override;
67 void FlushAll() override; 67 void FlushAll() override;
68 void FlushRegion(CacheAddr addr, u64 size) override; 68 void FlushRegion(CacheAddr addr, u64 size) override;
69 void InvalidateRegion(CacheAddr addr, u64 size) override; 69 void InvalidateRegion(CacheAddr addr, u64 size) override;
@@ -78,6 +78,11 @@ public:
78 void LoadDiskResources(const std::atomic_bool& stop_loading, 78 void LoadDiskResources(const std::atomic_bool& stop_loading,
79 const VideoCore::DiskResourceLoadCallback& callback) override; 79 const VideoCore::DiskResourceLoadCallback& callback) override;
80 80
81 /// Returns true when there are commands queued to the OpenGL server.
82 bool AnyCommandQueued() const {
83 return num_queued_commands > 0;
84 }
85
81private: 86private:
82 /// Configures the color and depth framebuffer states. 87 /// Configures the color and depth framebuffer states.
83 void ConfigureFramebuffers(); 88 void ConfigureFramebuffers();
@@ -207,6 +212,7 @@ private:
207 ShaderCacheOpenGL shader_cache; 212 ShaderCacheOpenGL shader_cache;
208 SamplerCacheOpenGL sampler_cache; 213 SamplerCacheOpenGL sampler_cache;
209 FramebufferCacheOpenGL framebuffer_cache; 214 FramebufferCacheOpenGL framebuffer_cache;
215 QueryCache query_cache;
210 216
211 Core::System& system; 217 Core::System& system;
212 ScreenInfo& screen_info; 218 ScreenInfo& screen_info;
@@ -224,8 +230,6 @@ private:
224 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; 230 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
225 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; 231 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
226 232
227 HostCounter samples_passed{GL_SAMPLES_PASSED};
228
229 /// Number of commands queued to the OpenGL driver. Reseted on flush. 233 /// Number of commands queued to the OpenGL driver. Reseted on flush.
230 std::size_t num_queued_commands = 0; 234 std::size_t num_queued_commands = 0;
231}; 235};