[Refactor] (MG_Backend/DirectVulkan): replace null-renderer guards with MOBILEGL_ASSERT

Drops the if (!pVulkanRenderer) { return; } / !MG_State::pGLContext early-return guards across DirectVulkan.cpp in favor of MOBILEGL_ASSERT, matching the pattern already used by the rest of the backend. Legitimate runtime conditions (index bounds, sync/query handle nullness, renderer-generation mismatch, timer-query support) are kept as real checks; only the null-pointer defenses are converted.
This commit is contained in:
2026-07-14 03:55:41 -04:00
parent 3445ab9304
commit 9c0d5517bd
@@ -230,7 +230,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} }
MG_State::GLState::ProgramObject* TryGetDirectVulkanProgram(GLuint program) { MG_State::GLState::ProgramObject* TryGetDirectVulkanProgram(GLuint program) {
if (!MG_State::pGLContext || !MG_State::pGLContext->ValidateProgramName(program)) { if (!MG_State::pGLContext->ValidateProgramName(program)) {
return nullptr; return nullptr;
} }
auto& programObject = MG_State::pGLContext->GetProgramObject(program); auto& programObject = MG_State::pGLContext->GetProgramObject(program);
@@ -383,33 +383,25 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} }
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferfi called with null VulkanRenderer");
return;
}
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferfi called with null GL context"); MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferfi called with null GL context");
pVulkanRenderer->ClearBufferfi(buffer, drawbuffer, depth, stencil); pVulkanRenderer->ClearBufferfi(buffer, drawbuffer, depth, stencil);
} }
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferfv called with null VulkanRenderer");
return;
}
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferfv called with null GL context"); MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferfv called with null GL context");
pVulkanRenderer->ClearBufferfv(buffer, drawbuffer, value); pVulkanRenderer->ClearBufferfv(buffer, drawbuffer, value);
} }
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferuiv called with null VulkanRenderer");
return;
}
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferuiv called with null GL context"); MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferuiv called with null GL context");
pVulkanRenderer->ClearBufferuiv(buffer, drawbuffer, value); pVulkanRenderer->ClearBufferuiv(buffer, drawbuffer, value);
} }
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferiv called with null VulkanRenderer");
return;
}
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferiv called with null GL context"); MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ClearBufferiv called with null GL context");
pVulkanRenderer->ClearBufferiv(buffer, drawbuffer, value); pVulkanRenderer->ClearBufferiv(buffer, drawbuffer, value);
} }
@@ -678,9 +670,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
srcWidth, srcHeight, srcDepth); srcWidth, srcHeight, srcDepth);
} }
void GenerateMipmap(GLenum target) { void GenerateMipmap(GLenum target) {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GenerateMipmap called with null VulkanRenderer");
return;
}
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::GenerateMipmap called with null GL context"); MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::GenerateMipmap called with null GL context");
pVulkanRenderer->GenerateMipmap(target); pVulkanRenderer->GenerateMipmap(target);
} }
@@ -720,9 +710,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void GetIntegeri_v(GLenum target, GLuint index, GLint* data) { void GetIntegeri_v(GLenum target, GLuint index, GLint* data) {
if (!data) return; if (!data) return;
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetIntegeri_v called with null VulkanRenderer");
switch (target) { switch (target) {
case GL_MAX_COMPUTE_WORK_GROUP_COUNT: case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
if (!pVulkanRenderer || index >= 3) { if (index >= 3) {
*data = 0; *data = 0;
return; return;
} }
@@ -730,7 +721,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
pVulkanRenderer->GetPhysicalDevice().properties.limits.maxComputeWorkGroupCount[index]); pVulkanRenderer->GetPhysicalDevice().properties.limits.maxComputeWorkGroupCount[index]);
return; return;
case GL_MAX_COMPUTE_WORK_GROUP_SIZE: case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
if (!pVulkanRenderer || index >= 3) { if (index >= 3) {
*data = 0; *data = 0;
return; return;
} }
@@ -1210,11 +1201,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
cache.storageBlocks[storageBlockIndex].binding = storageBlockBinding; cache.storageBlocks[storageBlockIndex].binding = storageBlockBinding;
} }
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
if (!pVulkanRenderer || !MG_State::pGLContext) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ReadPixels called with null VulkanRenderer");
// TODO: Route early/default-FBO readbacks through a real DirectVulkan read path instead of returning zeros. MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::ReadPixels called with null GL context");
ClearReadPixelsOutput(width, height, format, type, pixels);
return;
}
pVulkanRenderer->ReadPixels(x, y, width, height, format, type, pixels); pVulkanRenderer->ReadPixels(x, y, width, height, format, type, pixels);
} }
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) {
@@ -1230,10 +1218,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} }
void Clear(GLbitfield mask) { void Clear(GLbitfield mask) {
if (!pVulkanRenderer || !MG_State::pGLContext) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::Clear called with null VulkanRenderer");
// TODO: Preserve pending clears issued before the Vulkan renderer/context is fully attached. MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::Clear called with null GL context");
return;
}
pVulkanRenderer->Clear(mask); pVulkanRenderer->Clear(mask);
} }
@@ -1374,10 +1360,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
GLint dstY1, GLbitfield mask, GLenum filter) { GLint dstY1, GLbitfield mask, GLenum filter) {
if (!pVulkanRenderer || !MG_State::pGLContext) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::BlitFramebuffer called with null VulkanRenderer");
// TODO: Support pre-renderer/default-FBO blits instead of dropping them at the DirectVulkan boundary. MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::BlitFramebuffer called with null GL context");
return;
}
pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
} }
@@ -1409,15 +1393,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} // namespace } // namespace
BackendSyncHandle FenceSync() { BackendSyncHandle FenceSync() {
if (!pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::FenceSync called with null VulkanRenderer");
return nullptr;
}
return new VulkanSyncObject{pVulkanRenderer->GetSyncPointSubmitIndex(), GetRendererGeneration()}; return new VulkanSyncObject{pVulkanRenderer->GetSyncPointSubmitIndex(), GetRendererGeneration()};
} }
GLenum ClientWaitSync(BackendSyncHandle handle, GLbitfield flags, GLuint64 timeout) { GLenum ClientWaitSync(BackendSyncHandle handle, GLbitfield flags, GLuint64 timeout) {
const auto* sync = static_cast<VulkanSyncObject*>(handle); const auto* sync = static_cast<VulkanSyncObject*>(handle);
if (sync == nullptr || !pVulkanRenderer || sync->rendererGeneration != GetRendererGeneration()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClientWaitSync called with null VulkanRenderer");
if (sync == nullptr || sync->rendererGeneration != GetRendererGeneration()) {
return GL_ALREADY_SIGNALED; return GL_ALREADY_SIGNALED;
} }
if (pVulkanRenderer->IsSubmitIndexComplete(sync->submitIndex)) { if (pVulkanRenderer->IsSubmitIndexComplete(sync->submitIndex)) {
@@ -1459,7 +1442,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Bool GetSyncStatus(BackendSyncHandle handle) { Bool GetSyncStatus(BackendSyncHandle handle) {
const auto* sync = static_cast<VulkanSyncObject*>(handle); const auto* sync = static_cast<VulkanSyncObject*>(handle);
if (sync == nullptr || !pVulkanRenderer || sync->rendererGeneration != GetRendererGeneration()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetSyncStatus called with null VulkanRenderer");
if (sync == nullptr || sync->rendererGeneration != GetRendererGeneration()) {
return true; return true;
} }
// Pure status read (glGetSynciv must not flush). // Pure status read (glGetSynciv must not flush).
@@ -1486,11 +1470,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} // namespace } // namespace
Bool IsTimerQuerySupported() { Bool IsTimerQuerySupported() {
return pVulkanRenderer != nullptr && pVulkanRenderer->IsTimerQuerySupported(); MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::IsTimerQuerySupported called with null VulkanRenderer");
return pVulkanRenderer->IsTimerQuerySupported();
} }
BackendQueryHandle BeginTimeElapsedQuery() { BackendQueryHandle BeginTimeElapsedQuery() {
if (!pVulkanRenderer || !pVulkanRenderer->IsTimerQuerySupported()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::BeginTimeElapsedQuery called with null VulkanRenderer");
if (!pVulkanRenderer->IsTimerQuerySupported()) {
return nullptr; return nullptr;
} }
auto begin = pVulkanRenderer->WriteTimerQueryTimestamp(); auto begin = pVulkanRenderer->WriteTimerQueryTimestamp();
@@ -1506,7 +1492,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
void EndTimeElapsedQuery(BackendQueryHandle handle) { void EndTimeElapsedQuery(BackendQueryHandle handle) {
auto* query = static_cast<VulkanTimerQuery*>(handle); auto* query = static_cast<VulkanTimerQuery*>(handle);
if (query == nullptr || !pVulkanRenderer) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::EndTimeElapsedQuery called with null VulkanRenderer");
if (query == nullptr) {
return; return;
} }
if (query->rendererGeneration != GetRendererGeneration()) { if (query->rendererGeneration != GetRendererGeneration()) {
@@ -1520,7 +1507,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} }
BackendQueryHandle QueryCounterTimestamp() { BackendQueryHandle QueryCounterTimestamp() {
if (!pVulkanRenderer || !pVulkanRenderer->IsTimerQuerySupported()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::QueryCounterTimestamp called with null VulkanRenderer");
if (!pVulkanRenderer->IsTimerQuerySupported()) {
return nullptr; return nullptr;
} }
auto record = pVulkanRenderer->WriteTimerQueryTimestamp(); auto record = pVulkanRenderer->WriteTimerQueryTimestamp();
@@ -1537,7 +1525,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
auto* query = static_cast<VulkanTimerQuery*>(handle); auto* query = static_cast<VulkanTimerQuery*>(handle);
// Degraded/stale handles report available; GetQueryResult64 then // Degraded/stale handles report available; GetQueryResult64 then
// resolves them with a final zero result. // resolves them with a final zero result.
if (query == nullptr || !pVulkanRenderer || query->rendererGeneration != GetRendererGeneration()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::IsQueryResultAvailable called with null VulkanRenderer");
if (query == nullptr || query->rendererGeneration != GetRendererGeneration()) {
return true; return true;
} }
if (query->begin && !pVulkanRenderer->IsTimerQueryResultReady(*query->begin)) { if (query->begin && !pVulkanRenderer->IsTimerQueryResultReady(*query->begin)) {
@@ -1552,9 +1541,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Bool GetQueryResult64(BackendQueryHandle handle, Bool wait, Uint64* outNanoseconds) { Bool GetQueryResult64(BackendQueryHandle handle, Bool wait, Uint64* outNanoseconds) {
*outNanoseconds = 0; *outNanoseconds = 0;
auto* query = static_cast<VulkanTimerQuery*>(handle); auto* query = static_cast<VulkanTimerQuery*>(handle);
if (query == nullptr || !pVulkanRenderer || query->rendererGeneration != GetRendererGeneration()) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetQueryResult64 called with null VulkanRenderer");
// No renderer, or the records belong to a destroyed renderer: no if (query == nullptr || query->rendererGeneration != GetRendererGeneration()) {
// real value can ever be produced, so resolve with a final 0. // The records belong to a destroyed renderer: no real value can
// ever be produced, so resolve with a final 0.
return true; return true;
} }
// With wait, mirrors ClientWaitSync: a query ended this frame cannot // With wait, mirrors ClientWaitSync: a query ended this frame cannot