summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-01-03 21:55:59 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-01-03 21:55:59 +0000
commit08274e2f167f07e70a1a25bcb5108ab4886d4e1f (patch)
tree265deb5a10ee24e0b6181a353cc42e79c66c4b91 /Graphics/GraphicsEngineOpenGL
parentRenamed QueryDataTimestamp::NumTicks to QueryDataTimestamp::Counter (diff)
downloadDiligentCore-08274e2f167f07e70a1a25bcb5108ab4886d4e1f.tar.gz
DiligentCore-08274e2f167f07e70a1a25bcb5108ab4886d4e1f.zip
Implemented queries in OpenGL
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h10
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.h9
-rw-r--r--Graphics/GraphicsEngineOpenGL/interface/QueryGL.h2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp53
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLObjectWrapper.cpp1
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp71
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