summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorGravatar Ameer J2023-12-19 17:32:31 -0500
committerGravatar Ameer J2023-12-19 17:32:31 -0500
commitdb8a601cf82cd4797c32931f13a585c64527780d (patch)
treeec0f8a7f5355c9ecb01b03580b65d01671ac3359 /src/video_core/renderer_opengl
parentMerge pull request #12382 from liamwhite/image-limit (diff)
downloadyuzu-db8a601cf82cd4797c32931f13a585c64527780d.tar.gz
yuzu-db8a601cf82cd4797c32931f13a585c64527780d.tar.xz
yuzu-db8a601cf82cd4797c32931f13a585c64527780d.zip
OpenGL: Add GL_PRIMITIVES_GENERATED and GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp49
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
3 files changed, 54 insertions, 21 deletions
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp
index ec142d48e..fef7360ed 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_query_cache.cpp
@@ -18,16 +18,27 @@ namespace OpenGL {
18 18
19namespace { 19namespace {
20 20
21constexpr std::array<GLenum, VideoCore::NumQueryTypes> QueryTargets = {GL_SAMPLES_PASSED};
22
23constexpr GLenum GetTarget(VideoCore::QueryType type) { 21constexpr GLenum GetTarget(VideoCore::QueryType type) {
24 return QueryTargets[static_cast<std::size_t>(type)]; 22 switch (type) {
23 case VideoCore::QueryType::SamplesPassed:
24 return GL_SAMPLES_PASSED;
25 case VideoCore::QueryType::PrimitivesGenerated:
26 return GL_PRIMITIVES_GENERATED;
27 case VideoCore::QueryType::TfbPrimitivesWritten:
28 return GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
29 default:
30 break;
31 }
32 UNIMPLEMENTED_MSG("Query type {}", type);
33 return 0;
25} 34}
26 35
27} // Anonymous namespace 36} // Anonymous namespace
28 37
29QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_) 38QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_)
30 : QueryCacheLegacy(rasterizer_, cpu_memory_), gl_rasterizer{rasterizer_} {} 39 : QueryCacheLegacy(rasterizer_, cpu_memory_), gl_rasterizer{rasterizer_} {
40 EnableCounters();
41}
31 42
32QueryCache::~QueryCache() = default; 43QueryCache::~QueryCache() = default;
33 44
@@ -103,13 +114,13 @@ u64 CachedQuery::Flush([[maybe_unused]] bool async) {
103 auto& stream = cache->Stream(type); 114 auto& stream = cache->Stream(type);
104 const bool slice_counter = WaitPending() && stream.IsEnabled(); 115 const bool slice_counter = WaitPending() && stream.IsEnabled();
105 if (slice_counter) { 116 if (slice_counter) {
106 stream.Update(false); 117 stream.Disable();
107 } 118 }
108 119
109 auto result = VideoCommon::CachedQueryBase<HostCounter>::Flush(); 120 auto result = VideoCommon::CachedQueryBase<HostCounter>::Flush();
110 121
111 if (slice_counter) { 122 if (slice_counter) {
112 stream.Update(true); 123 stream.Enable();
113 } 124 }
114 125
115 return result; 126 return result;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 279e5a4e0..0545e33c5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -51,6 +51,22 @@ constexpr size_t NUM_SUPPORTED_VERTEX_ATTRIBUTES = 16;
51void oglEnable(GLenum cap, bool state) { 51void oglEnable(GLenum cap, bool state) {
52 (state ? glEnable : glDisable)(cap); 52 (state ? glEnable : glDisable)(cap);
53} 53}
54
55std::optional<VideoCore::QueryType> MaxwellToVideoCoreQuery(VideoCommon::QueryType type) {
56 switch (type) {
57 case VideoCommon::QueryType::PrimitivesGenerated:
58 case VideoCommon::QueryType::VtgPrimitivesOut:
59 return VideoCore::QueryType::PrimitivesGenerated;
60 case VideoCommon::QueryType::ZPassPixelCount64:
61 return VideoCore::QueryType::SamplesPassed;
62 case VideoCommon::QueryType::StreamingPrimitivesSucceeded:
63 // case VideoCommon::QueryType::StreamingByteCount:
64 // TODO: StreamingByteCount = StreamingPrimitivesSucceeded * num_verts * vert_stride
65 return VideoCore::QueryType::TfbPrimitivesWritten;
66 default:
67 return std::nullopt;
68 }
69}
54} // Anonymous namespace 70} // Anonymous namespace
55 71
56RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 72RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
@@ -212,7 +228,6 @@ void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) {
212 228
213 SCOPE_EXIT({ gpu.TickWork(); }); 229 SCOPE_EXIT({ gpu.TickWork(); });
214 gpu_memory->FlushCaching(); 230 gpu_memory->FlushCaching();
215 query_cache.UpdateCounters();
216 231
217 GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; 232 GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
218 if (!pipeline) { 233 if (!pipeline) {
@@ -330,7 +345,6 @@ void RasterizerOpenGL::DrawTexture() {
330 MICROPROFILE_SCOPE(OpenGL_Drawing); 345 MICROPROFILE_SCOPE(OpenGL_Drawing);
331 346
332 SCOPE_EXIT({ gpu.TickWork(); }); 347 SCOPE_EXIT({ gpu.TickWork(); });
333 query_cache.UpdateCounters();
334 348
335 texture_cache.SynchronizeGraphicsDescriptors(); 349 texture_cache.SynchronizeGraphicsDescriptors();
336 texture_cache.UpdateRenderTargets(false); 350 texture_cache.UpdateRenderTargets(false);
@@ -397,21 +411,28 @@ void RasterizerOpenGL::DispatchCompute() {
397} 411}
398 412
399void RasterizerOpenGL::ResetCounter(VideoCommon::QueryType type) { 413void RasterizerOpenGL::ResetCounter(VideoCommon::QueryType type) {
400 if (type == VideoCommon::QueryType::ZPassPixelCount64) { 414 const auto query_cache_type = MaxwellToVideoCoreQuery(type);
401 query_cache.ResetCounter(VideoCore::QueryType::SamplesPassed); 415 if (!query_cache_type.has_value()) {
416 UNIMPLEMENTED_MSG("Reset query type: {}", type);
417 return;
402 } 418 }
419 query_cache.ResetCounter(*query_cache_type);
403} 420}
404 421
405void RasterizerOpenGL::Query(GPUVAddr gpu_addr, VideoCommon::QueryType type, 422void RasterizerOpenGL::Query(GPUVAddr gpu_addr, VideoCommon::QueryType type,
406 VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport) { 423 VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport) {
407 if (type == VideoCommon::QueryType::ZPassPixelCount64) { 424 const auto query_cache_type = MaxwellToVideoCoreQuery(type);
408 if (True(flags & VideoCommon::QueryPropertiesFlags::HasTimeout)) { 425 if (!query_cache_type.has_value()) {
409 query_cache.Query(gpu_addr, VideoCore::QueryType::SamplesPassed, {gpu.GetTicks()}); 426 return QueryFallback(gpu_addr, type, flags, payload, subreport);
410 } else {
411 query_cache.Query(gpu_addr, VideoCore::QueryType::SamplesPassed, std::nullopt);
412 }
413 return;
414 } 427 }
428 const bool has_timeout = True(flags & VideoCommon::QueryPropertiesFlags::HasTimeout);
429 const auto timestamp = has_timeout ? std::optional<u64>{gpu.GetTicks()} : std::nullopt;
430 query_cache.Query(gpu_addr, *query_cache_type, timestamp);
431}
432
433void RasterizerOpenGL::QueryFallback(GPUVAddr gpu_addr, VideoCommon::QueryType type,
434 VideoCommon::QueryPropertiesFlags flags, u32 payload,
435 u32 subreport) {
415 if (type != VideoCommon::QueryType::Payload) { 436 if (type != VideoCommon::QueryType::Payload) {
416 payload = 1u; 437 payload = 1u;
417 } 438 }
@@ -1294,15 +1315,13 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum
1294 program->ConfigureTransformFeedback(); 1315 program->ConfigureTransformFeedback();
1295 1316
1296 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || 1317 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
1297 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) || 1318 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation));
1298 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
1299 UNIMPLEMENTED_IF(primitive_mode != GL_POINTS);
1300 1319
1301 // We may have to call BeginTransformFeedbackNV here since they seem to call different 1320 // We may have to call BeginTransformFeedbackNV here since they seem to call different
1302 // implementations on Nvidia's driver (the pointer is different) but we are using 1321 // implementations on Nvidia's driver (the pointer is different) but we are using
1303 // ARB_transform_feedback3 features with NV_transform_feedback interactions and the ARB 1322 // ARB_transform_feedback3 features with NV_transform_feedback interactions and the ARB
1304 // extension doesn't define BeginTransformFeedback (without NV) interactions. It just works. 1323 // extension doesn't define BeginTransformFeedback (without NV) interactions. It just works.
1305 glBeginTransformFeedback(GL_POINTS); 1324 glBeginTransformFeedback(primitive_mode);
1306} 1325}
1307 1326
1308void RasterizerOpenGL::EndTransformFeedback() { 1327void RasterizerOpenGL::EndTransformFeedback() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ceffe1f1e..b79d7a70c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -225,6 +225,9 @@ private:
225 /// End a transform feedback 225 /// End a transform feedback
226 void EndTransformFeedback(); 226 void EndTransformFeedback();
227 227
228 void QueryFallback(GPUVAddr gpu_addr, VideoCommon::QueryType type,
229 VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport);
230
228 Tegra::GPU& gpu; 231 Tegra::GPU& gpu;
229 232
230 const Device& device; 233 const Device& device;