diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-01-03 21:55:59 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-01-03 21:55:59 +0000 |
| commit | 08274e2f167f07e70a1a25bcb5108ab4886d4e1f (patch) | |
| tree | 265deb5a10ee24e0b6181a353cc42e79c66c4b91 /Graphics/GraphicsEngineOpenGL | |
| parent | Renamed QueryDataTimestamp::NumTicks to QueryDataTimestamp::Counter (diff) | |
| download | DiligentCore-08274e2f167f07e70a1a25bcb5108ab4886d4e1f.tar.gz DiligentCore-08274e2f167f07e70a1a25bcb5108ab4886d4e1f.zip | |
Implemented queries in OpenGL
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
6 files changed, 144 insertions, 2 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h index 80694be8..5e963b61 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -330,4 +330,14 @@ private: GLsync SyncHandle = {}; }; +class GLQueryCreateReleaseHelper +{ +public: + void Create(GLuint& Query) { glGenQueries(1, &Query); } + void Release(GLuint Query) { glDeleteQueries(1, &Query); } + + static const char* Name; +}; +typedef GLObjWrapper<GLQueryCreateReleaseHelper> GLQueryObj; + } // namespace GLObjectWrappers diff --git a/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.h index 08b2ed74..71379b66 100644 --- a/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.h @@ -54,9 +54,18 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryGL, TQueryBase); + /// Implementation of IQuery::GetData() in OpenGL backend. virtual bool GetData(void* pData, Uint32 DataSize) override final; + + /// Implementation of IQueryGL::GetGlQueryHandle(). + virtual GLuint GetGlQueryHandle() const override final + { + return m_GlQuery; + } + private: + GLObjectWrappers::GLQueryObj m_GlQuery; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/interface/QueryGL.h b/Graphics/GraphicsEngineOpenGL/interface/QueryGL.h index 9339626a..dc11eb86 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/QueryGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/QueryGL.h @@ -43,6 +43,8 @@ static constexpr INTERFACE_ID IID_QueryGL = /// Exposes OpenGL-specific functionality of a Query object. class IQueryGL : public IQuery { + /// Returns OpenGL handle of an internal query object. + virtual GLuint GetGlQueryHandle() const = 0; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index beb549f8..6726eb6d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -1067,6 +1067,29 @@ void DeviceContextGLImpl::BeginQuery(IQuery* pQuery) return; auto* pQueryGLImpl = ValidatedCast<QueryGLImpl>(pQuery); + auto QueryType = pQueryGLImpl->GetDesc().Type; + auto glQuery = pQueryGLImpl->GetGlQueryHandle(); + + switch (QueryType) + { + case QUERY_TYPE_OCCLUSION: + glBeginQuery(GL_SAMPLES_PASSED, glQuery); + CHECK_GL_ERROR("Failed to begin GL_SAMPLES_PASSED query"); + break; + + case QUERY_TYPE_BINARY_OCCLUSION: + glBeginQuery(GL_ANY_SAMPLES_PASSED, glQuery); + CHECK_GL_ERROR("Failed to begin GL_ANY_SAMPLES_PASSED query"); + break; + + case QUERY_TYPE_PIPELINE_STATISTICS: + glBeginQuery(GL_PRIMITIVES_GENERATED, glQuery); + CHECK_GL_ERROR("Failed to begin GL_PRIMITIVES_GENERATED query"); + break; + + default: + UNEXPECTED("Unexpected query type"); + } } void DeviceContextGLImpl::EndQuery(IQuery* pQuery) @@ -1075,6 +1098,36 @@ void DeviceContextGLImpl::EndQuery(IQuery* pQuery) return; auto* pQueryGLImpl = ValidatedCast<QueryGLImpl>(pQuery); + auto QueryType = pQueryGLImpl->GetDesc().Type; + switch (QueryType) + { + case QUERY_TYPE_OCCLUSION: + glEndQuery(GL_SAMPLES_PASSED); + CHECK_GL_ERROR("Failed to end GL_SAMPLES_PASSED query"); + break; + + case QUERY_TYPE_BINARY_OCCLUSION: + glEndQuery(GL_ANY_SAMPLES_PASSED); + CHECK_GL_ERROR("Failed to end GL_ANY_SAMPLES_PASSED query"); + break; + + case QUERY_TYPE_PIPELINE_STATISTICS: + glEndQuery(GL_PRIMITIVES_GENERATED); + CHECK_GL_ERROR("Failed to end GL_PRIMITIVES_GENERATED query"); + break; + + case QUERY_TYPE_TIMESTAMP: +#if GL_ARB_timer_query + glQueryCounter(pQueryGLImpl->GetGlQueryHandle(), GL_TIMESTAMP); + CHECK_GL_ERROR("glQueryCounter failed"); +#else + LOG_WARNING_MESSAGE_ONCE("Timer queries are not supported by this device"); +#endif + break; + + default: + UNEXPECTED("Unexpected query type"); + } } bool DeviceContextGLImpl::UpdateCurrentGLContext() diff --git a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp index 6b8fa93a..c894d340 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp @@ -41,6 +41,7 @@ const char *GLTextureCreateReleaseHelper :: Name = "texture"; const char *GLSamplerCreateReleaseHelper :: Name = "sampler"; const char *GLFBOCreateReleaseHelper :: Name = "framebuffer"; const char *GLRBOCreateReleaseHelper :: Name = "renderbuffer"; +const char *GLQueryCreateReleaseHelper :: Name = "query"; // clang-format on } // namespace GLObjectWrappers diff --git a/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp index f65f8809..f2601f4a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp @@ -42,7 +42,8 @@ QueryGLImpl::QueryGLImpl(IReferenceCounters* pRefCounters, pRefCounters, pDevice, Desc - } + }, + m_GlQuery{true} // clang-format on { } @@ -53,7 +54,73 @@ QueryGLImpl::~QueryGLImpl() bool QueryGLImpl::GetData(void* pData, Uint32 DataSize) { - return false; + GLint ResultAvailable = 0; +#if !GL_ARB_timer_query + if (m_Desc.Type != QUERY_TYPE_TIMESTAMP) +#endif + { + glGetQueryObjectiv(m_GlQuery, GL_QUERY_RESULT_AVAILABLE, &ResultAvailable); + CHECK_GL_ERROR("Failed to get query result"); + } + + if (ResultAvailable) + { + switch (m_Desc.Type) + { + case QUERY_TYPE_OCCLUSION: + { + auto& QueryData = *reinterpret_cast<QueryDataOcclusion*>(pData); + + GLuint SamplesPassed = 0; + glGetQueryObjectuiv(m_GlQuery, GL_QUERY_RESULT, &SamplesPassed); + CHECK_GL_ERROR("Failed to get query result"); + QueryData.NumSamples = SamplesPassed; + } + break; + + case QUERY_TYPE_BINARY_OCCLUSION: + { + auto& QueryData = *reinterpret_cast<QueryDataBinaryOcclusion*>(pData); + + GLuint AnySamplePassed = 0; + glGetQueryObjectuiv(m_GlQuery, GL_QUERY_RESULT, &AnySamplePassed); + CHECK_GL_ERROR("Failed to get query result"); + QueryData.AnySamplePassed = AnySamplePassed != 0; + } + break; + + case QUERY_TYPE_PIPELINE_STATISTICS: + { + auto& QueryData = *reinterpret_cast<QueryDataPipelineStatistics*>(pData); + + GLuint PrimitivesGenerated = 0; + glGetQueryObjectuiv(m_GlQuery, GL_QUERY_RESULT, &PrimitivesGenerated); + CHECK_GL_ERROR("Failed to get query result"); + QueryData.ClippingInvocations = PrimitivesGenerated; + } + break; + + case QUERY_TYPE_TIMESTAMP: + { +#if GL_ARB_timer_query + auto& QueryData = *reinterpret_cast<QueryDataTimestamp*>(pData); + GLuint64 Counter = 0; + glGetQueryObjectui64v(m_GlQuery, GL_QUERY_RESULT, &Counter); + CHECK_GL_ERROR("Failed to get query result"); + QueryData.Counter = Counter; + // Counter is always measured in nanoseconds (10^-9 seconds) + QueryData.Frequency = 1000000000; +#endif + } + break; + + default: + UNEXPECTED("Unexpected query type"); + return false; + } + } + + return ResultAvailable != 0; } } // namespace Diligent |
