From 2b58652f0897053d4da04deb586490220ab5a774 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 27 Jul 2019 19:40:10 -0300 Subject: maxwell_3d: Slow implementation of passed samples (query 21) Implements GL_SAMPLES_PASSED by waiting immediately for queries. --- src/video_core/renderer_opengl/gl_query_cache.cpp | 59 +++++++++++++++++++++++ src/video_core/renderer_opengl/gl_query_cache.h | 41 ++++++++++++++++ src/video_core/renderer_opengl/gl_rasterizer.cpp | 24 +++++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 5 ++ 4 files changed, 129 insertions(+) create mode 100644 src/video_core/renderer_opengl/gl_query_cache.cpp create mode 100644 src/video_core/renderer_opengl/gl_query_cache.h (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp new file mode 100644 index 000000000..1c7dc999a --- /dev/null +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp @@ -0,0 +1,59 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "video_core/renderer_opengl/gl_query_cache.h" + +namespace OpenGL { + +HostCounter::HostCounter(GLenum target) { + query.Create(target); +} + +HostCounter::~HostCounter() = default; + +void HostCounter::UpdateState(bool enabled) { + if (enabled) { + Enable(); + } else { + Disable(); + } +} + +void HostCounter::Reset() { + counter = 0; + Disable(); +} + +u64 HostCounter::Query() { + if (!is_beginned) { + return counter; + } + Disable(); + u64 value; + glGetQueryObjectui64v(query.handle, GL_QUERY_RESULT, &value); + Enable(); + + counter += value; + return counter; +} + +void HostCounter::Enable() { + if (is_beginned) { + return; + } + is_beginned = true; + glBeginQuery(GL_SAMPLES_PASSED, query.handle); +} + +void HostCounter::Disable() { + if (!is_beginned) { + return; + } + glEndQuery(GL_SAMPLES_PASSED); + is_beginned = false; +} + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h new file mode 100644 index 000000000..52c6546bf --- /dev/null +++ b/src/video_core/renderer_opengl/gl_query_cache.h @@ -0,0 +1,41 @@ +// 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 "video_core/renderer_opengl/gl_resource_manager.h" + +namespace OpenGL { + +class HostCounter final { +public: + explicit HostCounter(GLenum target); + ~HostCounter(); + + /// Enables or disables the counter as required. + void UpdateState(bool enabled); + + /// Resets the counter disabling it if needed. + void Reset(); + + /// Returns the current value of the query. + /// @note It may harm precision of future queries if the counter is not disabled. + u64 Query(); + +private: + /// Enables the counter when disabled. + void Enable(); + + /// Disables the counter when enabled. + void Disable(); + + OGLQuery query; ///< OpenGL query. + u64 counter{}; ///< Added values of the counter. + bool is_beginned{}; ///< True when the OpenGL query is beginned. +}; + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b0eb14c8b..8d132732a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -547,6 +547,9 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { MICROPROFILE_SCOPE(OpenGL_Drawing); auto& gpu = system.GPU().Maxwell3D(); + const auto& regs = gpu.regs; + samples_passed.UpdateState(regs.samplecnt_enable); + SyncRasterizeEnable(state); SyncColorMask(); SyncFragmentColorClampState(); @@ -709,6 +712,27 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); } +void RasterizerOpenGL::ResetCounter(VideoCore::QueryType type) { + switch (type) { + case VideoCore::QueryType::SamplesPassed: + samples_passed.Reset(); + break; + default: + UNIMPLEMENTED_MSG("type={}", static_cast(type)); + break; + } +} + +u64 RasterizerOpenGL::Query(VideoCore::QueryType type) { + switch (type) { + case VideoCore::QueryType::SamplesPassed: + return samples_passed.Query(); + default: + UNIMPLEMENTED_MSG("type={}", static_cast(type)); + return 1; + } +} + void RasterizerOpenGL::FlushAll() {} void RasterizerOpenGL::FlushRegion(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 0501f3828..32bcaf8c2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -24,6 +24,7 @@ #include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_framebuffer_cache.h" +#include "video_core/renderer_opengl/gl_query_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_sampler_cache.h" #include "video_core/renderer_opengl/gl_shader_cache.h" @@ -61,6 +62,8 @@ public: bool DrawMultiBatch(bool is_indexed) override; void Clear() override; void DispatchCompute(GPUVAddr code_addr) override; + void ResetCounter(VideoCore::QueryType type) override; + u64 Query(VideoCore::QueryType type) override; void FlushAll() override; void FlushRegion(CacheAddr addr, u64 size) override; void InvalidateRegion(CacheAddr addr, u64 size) override; @@ -221,6 +224,8 @@ private: GLintptr SetupIndexBuffer(); void SetupShaders(GLenum primitive_mode); + + HostCounter samples_passed{GL_SAMPLES_PASSED}; }; } // namespace OpenGL -- cgit v1.2.3