diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 66c95be25..4968ff76b 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -51,6 +51,18 @@ enum nzFaceFilling nzFaceFilling_Max = nzFaceFilling_Fill }; +enum nzGpuQueryMode +{ + nzGpuQueryMode_AnySamplesPassed, + nzGpuQueryMode_AnySamplesPassedConservative, + nzGpuQueryMode_PrimitiveGenerated, + nzGpuQueryMode_SamplesPassed, + nzGpuQueryMode_TimeElapsed, + nzGpuQueryMode_TransformFeedbackPrimitivesWritten, + + nzGpuQueryMode_Max = nzGpuQueryMode_TransformFeedbackPrimitivesWritten +}; + enum nzMatrixType { // Matrices de base diff --git a/include/Nazara/Renderer/OcclusionQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp similarity index 60% rename from include/Nazara/Renderer/OcclusionQuery.hpp rename to include/Nazara/Renderer/GpuQuery.hpp index 601b63f3a..16558236d 100644 --- a/include/Nazara/Renderer/OcclusionQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -4,29 +4,31 @@ #pragma once -#ifndef NAZARA_OCCLUSIONQUERY_HPP -#define NAZARA_OCCLUSIONQUERY_HPP +#ifndef NAZARA_GPUQUERY_HPP +#define NAZARA_GPUQUERY_HPP #include #include +#include -class NAZARA_API NzOcclusionQuery : NzNonCopyable +class NAZARA_API NzGpuQuery : NzNonCopyable { public: - NzOcclusionQuery(); - ~NzOcclusionQuery(); + NzGpuQuery(); + ~NzGpuQuery(); - void Begin(); + void Begin(nzGpuQueryMode mode); void End(); unsigned int GetResult() const; bool IsResultAvailable() const; + static bool IsModeSupported(nzGpuQueryMode mode); static bool IsSupported(); private: unsigned int m_id; }; -#endif // NAZARA_OCCLUSIONQUERY_HPP +#endif // NAZARA_GPUQUERY_HPP diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 270a037be..e184f024d 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -135,6 +135,7 @@ class NAZARA_API NzOpenGL static GLenum FaceCulling[nzFaceCulling_Max+1]; static GLenum FaceFilling[nzFaceFilling_Max+1]; static GLenum PrimitiveMode[nzPrimitiveMode_Max+1]; + static GLenum QueryMode[nzGpuQueryMode_Max+1]; static GLenum RendererComparison[nzRendererComparison_Max+1]; static GLenum RendererParameter[nzRendererParameter_Max+1]; static GLenum SamplerWrapMode[nzSamplerWrap_Max+1]; diff --git a/src/Nazara/Renderer/OcclusionQuery.cpp b/src/Nazara/Renderer/GpuQuery.cpp similarity index 59% rename from src/Nazara/Renderer/OcclusionQuery.cpp rename to src/Nazara/Renderer/GpuQuery.cpp index f514daa4d..cb8c80d12 100644 --- a/src/Nazara/Renderer/OcclusionQuery.cpp +++ b/src/Nazara/Renderer/GpuQuery.cpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include @@ -11,7 +11,7 @@ #include #include -NzOcclusionQuery::NzOcclusionQuery() : +NzGpuQuery::NzGpuQuery() : m_id(0) { if (IsSupported()) @@ -35,7 +35,7 @@ m_id(0) #endif } -NzOcclusionQuery::~NzOcclusionQuery() +NzGpuQuery::~NzGpuQuery() { if (m_id) { @@ -46,7 +46,7 @@ NzOcclusionQuery::~NzOcclusionQuery() } } -void NzOcclusionQuery::Begin() +void NzGpuQuery::Begin(nzGpuQueryMode mode) { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -56,10 +56,18 @@ void NzOcclusionQuery::Begin() } #endif - glBeginQuery(GL_SAMPLES_PASSED, m_id); + #if NAZARA_RENDERER_SAFE + if (!IsModeSupported(mode)) + { + NazaraError("Mode (0x" + NzString::Number(mode, 16) + ") not supported"); + return; + } + #endif + + glBeginQuery(NzOpenGL::QueryMode[mode], m_id); } -void NzOcclusionQuery::End() +void NzGpuQuery::End() { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -72,7 +80,7 @@ void NzOcclusionQuery::End() glEndQuery(GL_SAMPLES_PASSED); } -unsigned int NzOcclusionQuery::GetResult() const +unsigned int NzGpuQuery::GetResult() const { NzContext::EnsureContext(); @@ -82,7 +90,7 @@ unsigned int NzOcclusionQuery::GetResult() const return result; } -bool NzOcclusionQuery::IsResultAvailable() const +bool NzGpuQuery::IsResultAvailable() const { NzContext::EnsureContext(); @@ -92,7 +100,28 @@ bool NzOcclusionQuery::IsResultAvailable() const return available == GL_TRUE; } -bool NzOcclusionQuery::IsSupported() +bool NzGpuQuery::IsModeSupported(nzGpuQueryMode mode) +{ + switch (mode) + { + case nzGpuQueryMode_AnySamplesPassed: + case nzGpuQueryMode_TimeElapsed: + return NzOpenGL::GetVersion() >= 330; + + case nzGpuQueryMode_AnySamplesPassedConservative: + return NzOpenGL::GetVersion() >= 430; + + case nzGpuQueryMode_PrimitiveGenerated: + case nzGpuQueryMode_SamplesPassed: + case nzGpuQueryMode_TransformFeedbackPrimitivesWritten: + return true; + } + + NazaraError("Gpu Query mode not handled (0x" + NzString::Number(mode, 16) + ')'); + return false; +} + +bool NzGpuQuery::IsSupported() { return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery); } diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 72a43eb07..989328fec 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1707,6 +1707,18 @@ GLenum NzOpenGL::PrimitiveMode[nzPrimitiveMode_Max+1] = static_assert(sizeof(NzOpenGL::PrimitiveMode)/sizeof(GLenum) == nzPrimitiveMode_Max+1, "Primitive mode array is incomplete"); +GLenum NzOpenGL::QueryMode[nzGpuQueryMode_Max+1] = +{ + GL_ANY_SAMPLES_PASSED, // nzGpuQueryMode_AnySamplesPassed + GL_ANY_SAMPLES_PASSED_CONSERVATIVE, // nzGpuQueryMode_AnySamplesPassedConservative + GL_PRIMITIVES_GENERATED, // nzGpuQueryMode_PrimitiveGenerated + GL_SAMPLES_PASSED, // nzGpuQueryMode_SamplesPassed + GL_TIME_ELAPSED, // nzGpuQueryMode_TimeElapsed + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN // nzGpuQueryMode_TransformFeedbackPrimitivesWritten +}; + +static_assert(sizeof(NzOpenGL::QueryMode)/sizeof(GLenum) == nzGpuQueryMode_Max+1, "Query mode array is incomplete"); + GLenum NzOpenGL::RendererComparison[nzRendererComparison_Max+1] = { GL_ALWAYS, // nzRendererComparison_Always