Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions filament/backend/src/opengl/OpenGLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
#endif
#endif

#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)
if (ext.EXT_disjoint_timer_query) {
// timer queries are available
if (bugs.dont_use_timer_query && platform.canCreateFence()) {
mGpuTimerType = TimerQueryFactory::Type::Fence;
} else {
mGpuTimerType = TimerQueryFactory::Type::Native;
}
} else
#endif
if (platform.canCreateFence()) {
mGpuTimerType = TimerQueryFactory::Type::Fence;
} else {
mGpuTimerType = TimerQueryFactory::Type::Fallback;
}

// in practice KHR_Debug has never been useful, and actually is confusing. We keep this
// only for our own debugging, in case we need it some day.
#if false && !defined(NDEBUG) && defined(GL_KHR_debug)
Expand Down
8 changes: 8 additions & 0 deletions filament/backend/src/opengl/OpenGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ class OpenGLContext final : public TimerQueryFactoryInterface {

ShaderModel getShaderModel() const noexcept { return mShaderModel; }

TimerQueryFactory::Type getGpuTimerType() const noexcept { return mGpuTimerType; }

bool isGpuTimeSupported() const noexcept {
return getGpuTimerType() != TimerQueryFactory::Type::Fallback;
}

void resetState() noexcept;

inline void useProgram(GLuint program) noexcept;
Expand Down Expand Up @@ -542,6 +548,8 @@ class OpenGLContext final : public TimerQueryFactoryInterface {

Platform::DriverConfig const mDriverConfig;

TimerQueryFactory::Type mGpuTimerType{ TimerQueryFactory::Type::Fallback };

void bindFramebufferResolved(GLenum target, GLuint buffer) noexcept;

const std::array<std::tuple<bool const&, char const*, char const*>, sizeof(bugs)> mBugDatabase{{
Expand Down
2 changes: 1 addition & 1 deletion filament/backend/src/opengl/OpenGLDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2859,7 +2859,7 @@ bool OpenGLDriver::isFrameBufferFetchMultiSampleSupported() {
}

bool OpenGLDriver::isFrameTimeSupported() {
return TimerQueryFactory::isGpuTimeSupported();
return mContext.isGpuTimeSupported();
}

bool OpenGLDriver::isAutoDepthResolveSupported() {
Expand Down
35 changes: 11 additions & 24 deletions filament/backend/src/opengl/OpenGLTimerQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,34 +48,25 @@ class OpenGLDriver;

// ------------------------------------------------------------------------------------------------

bool TimerQueryFactory::mGpuTimeSupported = false;

TimerQueryFactoryInterface* TimerQueryFactory::init(
OpenGLPlatform& platform, OpenGLContext& context) {
(void)context;

TimerQueryFactoryInterface* impl = nullptr;

#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)
if (context.ext.EXT_disjoint_timer_query) {
// timer queries are available
if (context.bugs.dont_use_timer_query && platform.canCreateFence()) {
// however, they don't work well, revert to using fences if we can.
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
} else {
switch (context.getGpuTimerType()) {
case Type::Fallback: {
impl = new(std::nothrow) TimerQueryFallbackFactory();
break;
}
case Type::Native: {
impl = new(std::nothrow) TimerQueryNativeFactory(context);
break;
}
case Type::Fence: {
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
break;
}
mGpuTimeSupported = true;
} else
#endif
if (platform.canCreateFence()) {
// no timer queries, but we can use fences
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
mGpuTimeSupported = true;
} else {
// no queries, no fences -- that's a problem
impl = new(std::nothrow) TimerQueryFallbackFactory();
mGpuTimeSupported = false;
}
assert_invariant(impl);
return impl;
Expand All @@ -100,8 +91,6 @@ TimerQueryResult TimerQueryFactoryInterface::getTimerQueryValue(

// ------------------------------------------------------------------------------------------------

#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)

TimerQueryNativeFactory::TimerQueryNativeFactory(OpenGLContext& context)
: mContext(context) {
}
Expand Down Expand Up @@ -165,8 +154,6 @@ void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQ
});
}

#endif

// ------------------------------------------------------------------------------------------------

TimerQueryFenceFactory::TimerQueryFenceFactory(OpenGLPlatform& platform)
Expand Down
15 changes: 6 additions & 9 deletions filament/backend/src/opengl/OpenGLTimerQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ struct GLTimerQuery : public HwTimerQuery {
*/

class TimerQueryFactory {
static bool mGpuTimeSupported;
public:
enum class Type {
Fallback = 0,
Native,
Fence,
};

static TimerQueryFactoryInterface* init(
OpenGLPlatform& platform, OpenGLContext& context);

static bool isGpuTimeSupported() noexcept {
return mGpuTimeSupported;
}
};

class TimerQueryFactoryInterface {
Expand All @@ -86,8 +87,6 @@ class TimerQueryFactoryInterface {
static TimerQueryResult getTimerQueryValue(GLTimerQuery* tq, uint64_t* elapsedTime) noexcept;
};

#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)

class TimerQueryNativeFactory final : public TimerQueryFactoryInterface {
public:
explicit TimerQueryNativeFactory(OpenGLContext& context);
Expand All @@ -100,8 +99,6 @@ class TimerQueryNativeFactory final : public TimerQueryFactoryInterface {
OpenGLContext& mContext;
};

#endif

class TimerQueryFenceFactory final : public TimerQueryFactoryInterface {
public:
explicit TimerQueryFenceFactory(OpenGLPlatform& platform);
Expand Down
Loading