Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various gfx backend tweaks #3540

Merged
merged 5 commits into from
Nov 28, 2023
Merged
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
2 changes: 2 additions & 0 deletions lib/ivis_opengl/3rdparty/vk_mem_alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# pragma clang diagnostic ignored "-Wunused-private-field"
# pragma clang diagnostic ignored "-Wcast-align"
# pragma clang diagnostic ignored "-Wunused-function"
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# if defined(__APPLE__)
# pragma clang diagnostic ignored "-Wnullability-completeness" // Warning triggered on newer Xcode
# endif
Expand All @@ -47,6 +48,7 @@
# pragma GCC diagnostic ignored "-Wmissing-noreturn"
# pragma GCC diagnostic ignored "-Wcast-align"
# pragma GCC diagnostic ignored "-Wunused-function"
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(_MSC_VER)
# pragma warning( push )
# pragma warning( disable : 4189 ) // warning C4189: 'identifier' : local variable is initialized but not referenced
Expand Down
86 changes: 66 additions & 20 deletions lib/ivis_opengl/gfx_api_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3234,12 +3234,21 @@ bool gl_context::_initialize(const gfx_api::backend_Impl_Factory& impl, int32_t
int width, height = 0;
backend_impl->getDrawableSize(&width, &height);
debug(LOG_WZ, "Drawable Size: %d x %d", width, height);
width = std::max<int>(width, 0);
height = std::max<int>(height, 0);

wzGLClearErrors();

glViewport(0, 0, width, height);
wzGLCheckErrors();
viewportWidth = static_cast<uint32_t>(width);
viewportHeight = static_cast<uint32_t>(height);
glCullFace(GL_FRONT);
// glEnable(GL_CULL_FACE);
wzGLCheckErrors();

sceneFramebufferWidth = std::max<uint32_t>(viewportWidth, 2);
sceneFramebufferHeight = std::max<uint32_t>(viewportHeight, 2);

// initialize default (0) textures
if (!createDefaultTextures())
Expand Down Expand Up @@ -3410,13 +3419,13 @@ bool gl_context::initGLContext()
/* Dump general information about OpenGL implementation to the console and the dump file */
ssprintf(opengl.vendor, "OpenGL Vendor: %s", wzSafeGlGetString(GL_VENDOR));
addDumpInfo(opengl.vendor);
debug(LOG_3D, "%s", opengl.vendor);
debug(LOG_INFO, "%s", opengl.vendor);
ssprintf(opengl.renderer, "OpenGL Renderer: %s", wzSafeGlGetString(GL_RENDERER));
addDumpInfo(opengl.renderer);
debug(LOG_3D, "%s", opengl.renderer);
debug(LOG_INFO, "%s", opengl.renderer);
ssprintf(opengl.version, "OpenGL Version: %s", wzSafeGlGetString(GL_VERSION));
addDumpInfo(opengl.version);
debug(LOG_3D, "%s", opengl.version);
debug(LOG_INFO, "%s", opengl.version);

formattedRendererInfoString = calculateFormattedRendererInfoString();

Expand Down Expand Up @@ -3537,13 +3546,13 @@ bool gl_context::initGLContext()
}

std::pair<int, int> glslVersion(0, 0);
sscanf((char const *)glGetString(GL_SHADING_LANGUAGE_VERSION), "%d.%d", &glslVersion.first, &glslVersion.second);
sscanf((char const *)wzSafeGlGetString(GL_SHADING_LANGUAGE_VERSION), "%d.%d", &glslVersion.first, &glslVersion.second);

/* Dump information about OpenGL 2.0+ implementation to the console and the dump file */
GLint glMaxTIUs = 0, glMaxTIUAs = 0, glmaxSamples = 0, glmaxSamplesbuf = 0, glmaxVertexAttribs = 0, glMaxArrayTextureLayers = 0;

debug(LOG_3D, " * OpenGL GLSL Version : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
ssprintf(opengl.GLSLversion, "OpenGL GLSL Version : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
debug(LOG_3D, " * OpenGL GLSL Version : %s", wzSafeGlGetString(GL_SHADING_LANGUAGE_VERSION));
ssprintf(opengl.GLSLversion, "OpenGL GLSL Version : %s", wzSafeGlGetString(GL_SHADING_LANGUAGE_VERSION));
addDumpInfo(opengl.GLSLversion);

glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &glMaxTIUs);
Expand Down Expand Up @@ -3574,14 +3583,19 @@ bool gl_context::initGLContext()
}
enabledVertexAttribIndexes.resize(static_cast<size_t>(glmaxVertexAttribs), false);

wzGLClearErrors();

if (khr_debug)
{
if (glDebugMessageCallback && glDebugMessageControl)
{
glDebugMessageCallback(khr_callback, nullptr);
wzGLCheckErrors();
glEnable(GL_DEBUG_OUTPUT);
wzGLCheckErrors();
// Do not want to output notifications. Some drivers spam them too much.
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
wzGLCheckErrors();
debug(LOG_3D, "Enabling KHR_debug message callback");
}
else
Expand All @@ -3600,23 +3614,31 @@ bool gl_context::initGLContext()
return false;
}
glGenVertexArrays(1, &vaoId);
wzGLCheckErrors();
glBindVertexArray(vaoId);
wzGLCheckErrors();
}

if (GLAD_GL_ARB_timer_query)
{
glGenQueries(PERF_COUNT, perfpos);
wzGLCheckErrors();
}

if (GLAD_GL_EXT_texture_filter_anisotropic)
{
maxTextureAnisotropy = 0.f;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxTextureAnisotropy);
wzGLCheckErrors();
}

glGenBuffers(1, &scratchbuffer);
wzGLCheckErrors();

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
wzGLCheckErrors();

debug(LOG_INFO, "Success");

return true;
}
Expand Down Expand Up @@ -4063,14 +4085,34 @@ void gl_context::handleWindowSizeChange(unsigned int oldWidth, unsigned int oldH
backend_impl->getDrawableSize(&drawableWidth, &drawableHeight);
debug(LOG_WZ, "Logical Size: %d x %d; Drawable Size: %d x %d", screenWidth, screenHeight, drawableWidth, drawableHeight);

glViewport(0, 0, drawableWidth, drawableHeight);
viewportWidth = static_cast<uint32_t>(drawableWidth);
viewportHeight = static_cast<uint32_t>(drawableHeight);
int width = std::max<int>(drawableWidth, 0);
int height = std::max<int>(drawableHeight, 0);

glViewport(0, 0, width, height);
viewportWidth = static_cast<uint32_t>(width);
viewportHeight = static_cast<uint32_t>(height);
glCullFace(GL_FRONT);
// glEnable(GL_CULL_FACE);

// Re-create scene FBOs using new size
createSceneRenderpass();
// Re-create scene FBOs using new size (if drawable size is of reasonable dimensions)
if (viewportWidth > 0 && viewportHeight > 0)
{
uint32_t newSceneFramebufferWidth = std::max<uint32_t>(viewportWidth, 2);
uint32_t newSceneFramebufferHeight = std::max<uint32_t>(viewportHeight, 2);

if (sceneFramebufferWidth != newSceneFramebufferWidth || sceneFramebufferHeight != newSceneFramebufferHeight)
{
sceneFramebufferWidth = newSceneFramebufferWidth;
sceneFramebufferHeight = newSceneFramebufferHeight;
createSceneRenderpass();
}
}
else
{
// Some drivers seem to like to occasionally return a drawableSize that has a 0 dimension (ex. when minimized?)
// In this case, don't bother recreating the scene framebuffer (until it changes to something sensible)
debug(LOG_INFO, "Delaying scene framebuffer recreation (current Drawable Size: %d x %d)", drawableWidth, drawableHeight);
}
}

std::pair<uint32_t, uint32_t> gl_context::getDrawableDimensions()
Expand Down Expand Up @@ -4402,7 +4444,7 @@ bool gl_context::createSceneRenderpass()
ASSERT_GL_NOERRORS_OR_RETURN(false);
glBindRenderbuffer(GL_RENDERBUFFER, sceneMsaaRBO);
ASSERT_GL_NOERRORS_OR_RETURN(false);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, multiSampledBufferInternalFormat, viewportWidth, viewportHeight); // OpenGL 3.0+, OpenGL ES 3.0+
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, multiSampledBufferInternalFormat, sceneFramebufferWidth, sceneFramebufferHeight); // OpenGL 3.0+, OpenGL ES 3.0+
ASSERT_GL_NOERRORS_OR_RETURN(false);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
ASSERT_GL_NOERRORS_OR_RETURN(false);
Expand All @@ -4413,11 +4455,11 @@ bool gl_context::createSceneRenderpass()
// - OpenGL ES: color texture format must *MATCH* the format used for the multisampled color render buffer
GLenum colorInternalFormat = (samples > 0 && gles) ? multiSampledBufferInternalFormat : GL_RGB8;
GLenum colorBaseFormat = (samples > 0 && gles) ? multiSampledBufferBaseFormat : GL_RGB;
auto pNewSceneTexture = create_framebuffer_color_texture(colorInternalFormat, colorBaseFormat, GL_UNSIGNED_BYTE, viewportWidth, viewportHeight, "<scene texture>");
auto pNewSceneTexture = create_framebuffer_color_texture(colorInternalFormat, colorBaseFormat, GL_UNSIGNED_BYTE, sceneFramebufferWidth, sceneFramebufferHeight, "<scene texture>");
ASSERT_GL_NOERRORS_OR_RETURN(false);
if (!pNewSceneTexture)
{
debug(LOG_ERROR, "Failed to create scene color texture (%" PRIu32 " x %" PRIu32 ")", viewportWidth, viewportHeight);
debug(LOG_ERROR, "Failed to create scene color texture (%" PRIu32 " x %" PRIu32 ")", sceneFramebufferWidth, sceneFramebufferHeight);
return false;
}
sceneTexture = pNewSceneTexture;
Expand All @@ -4436,7 +4478,7 @@ bool gl_context::createSceneRenderpass()
ASSERT_GL_NOERRORS_OR_RETURN(false);
glBindRenderbuffer(GL_RENDERBUFFER, sceneDepthStencilRBO);
ASSERT_GL_NOERRORS_OR_RETURN(false);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, viewportWidth, viewportHeight); // OpenGL 3.0+, OpenGL ES 3.0+
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, sceneFramebufferWidth, sceneFramebufferHeight); // OpenGL 3.0+, OpenGL ES 3.0+
ASSERT_GL_NOERRORS_OR_RETURN(false);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
ASSERT_GL_NOERRORS_OR_RETURN(false);
Expand Down Expand Up @@ -4469,7 +4511,7 @@ bool gl_context::createSceneRenderpass()
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
debug(LOG_ERROR, "Failed to create scene framebuffer[%d] (%" PRIu32 " x %" PRIu32 ", samples: %d) with error: %s", i, viewportWidth, viewportHeight, static_cast<int>(samples), cbframebuffererror(status));
debug(LOG_ERROR, "Failed to create scene framebuffer[%d] (%" PRIu32 " x %" PRIu32 ", samples: %d) with error: %s", i, sceneFramebufferWidth, sceneFramebufferHeight, static_cast<int>(samples), cbframebuffererror(status));
encounteredError = true;
}
ASSERT_GL_NOERRORS_OR_RETURN(false);
Expand All @@ -4494,7 +4536,7 @@ bool gl_context::createSceneRenderpass()
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
debug(LOG_ERROR, "Failed to create scene resolve framebuffer[%d] (%" PRIu32 " x %" PRIu32 ", samples: %d) with error: %s", i, viewportWidth, viewportHeight, static_cast<int>(samples), cbframebuffererror(status));
debug(LOG_ERROR, "Failed to create scene resolve framebuffer[%d] (%" PRIu32 " x %" PRIu32 ", samples: %d) with error: %s", i, sceneFramebufferWidth, sceneFramebufferHeight, static_cast<int>(samples), cbframebuffererror(status));
encounteredError = true;
}
ASSERT_GL_NOERRORS_OR_RETURN(false);
Expand All @@ -4512,7 +4554,7 @@ bool gl_context::createSceneRenderpass()
void gl_context::beginSceneRenderPass()
{
glBindFramebuffer(GL_FRAMEBUFFER, sceneFBO[sceneFBOIdx]);
glViewport(0, 0, viewportWidth, viewportHeight);
glViewport(0, 0, sceneFramebufferWidth, sceneFramebufferHeight);
GLbitfield clearFlags = 0;
glDepthMask(GL_TRUE);
clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
Expand Down Expand Up @@ -4565,8 +4607,8 @@ void gl_context::endSceneRenderPass()
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, sceneFBO[sceneFBOIdx]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sceneResolveFBO[sceneFBOIdx]);
glBlitFramebuffer(0,0, viewportWidth, viewportHeight,
0,0, viewportWidth, viewportHeight,
glBlitFramebuffer(0,0, sceneFramebufferWidth, sceneFramebufferHeight,
0,0, sceneFramebufferWidth, sceneFramebufferHeight,
GL_COLOR_BUFFER_BIT,
GL_LINEAR);
}
Expand Down Expand Up @@ -4605,6 +4647,10 @@ void gl_context::endSceneRenderPass()
// switch back to default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Because the scene uses the same viewport, a call to glViewport should not be needed (NOTE: viewport is *not* part of the framebuffer state)
if (sceneFramebufferWidth != viewportWidth || sceneFramebufferHeight != viewportHeight)
{
glViewport(0, 0, viewportWidth, viewportHeight);
}
}

gfx_api::abstract_texture* gl_context::getSceneTexture()
Expand Down
2 changes: 2 additions & 0 deletions lib/ivis_opengl/gfx_api_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ struct gl_context final : public gfx_api::context
size_t depthBufferResolution = 4096;
size_t depthPassCount = WZ_MAX_SHADOW_CASCADES;

uint32_t sceneFramebufferWidth = 0;
uint32_t sceneFramebufferHeight = 0;
GLenum multiSampledBufferInternalFormat = GL_INVALID_ENUM;
GLenum multiSampledBufferBaseFormat = GL_INVALID_ENUM;
GLint maxMultiSampleBufferFormatSamples = 0;
Expand Down
18 changes: 16 additions & 2 deletions lib/ivis_opengl/gfx_api_vk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3855,7 +3855,7 @@ bool VkRoot::handleSurfaceLost()
}

bool result = false;
if (createSwapchain())
if (createSwapchain(false))
{
rebuildPipelinesIfNecessary();
result = true;
Expand Down Expand Up @@ -4071,7 +4071,7 @@ T clamp(const T& n, const T& lower, const T& upper) {
return std::max(lower, std::min(n, upper));
}

bool VkRoot::createSwapchain()
bool VkRoot::createSwapchain(bool allowHandleSurfaceLost)
{
ASSERT(backend_impl, "Backend implementation is null");
ASSERT(physicalDevice, "Physical device is null");
Expand All @@ -4089,6 +4089,20 @@ bool VkRoot::createSwapchain()
try {
swapChainSupport = querySwapChainSupport(physicalDevice, surface, vkDynLoader);
}
catch (const vk::SurfaceLostKHRError &e)
{
if (allowHandleSurfaceLost)
{
debug(LOG_INFO, "Querying swapchain support failed with ErrorSurfaceLostKHR - must recreate surface + swapchain: %s", e.what());
// recreate surface + swapchain
return handleSurfaceLost();
}
else
{
debug(LOG_ERROR, "Querying swapchain support failed with error: %s", e.what());
return false;
}
}
catch (const vk::SystemError &e)
{
debug(LOG_ERROR, "Querying swapchain support failed with error: %s", e.what());
Expand Down
2 changes: 1 addition & 1 deletion lib/ivis_opengl/gfx_api_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ struct VkRoot final : gfx_api::context
bool createLogicalDevice();
bool createAllocator();
void getQueues();
bool createSwapchain();
bool createSwapchain(bool allowHandleSurfaceLost = true);
void rebuildPipelinesIfNecessary();

void createDefaultRenderpass(vk::Format swapchainFormat, vk::Format depthFormat);
Expand Down
2 changes: 1 addition & 1 deletion lib/sdl/gfx_api_gl_sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ bool sdl_OpenGL_Impl::createGLContext()
// Although context creation eventually succeeded, log the attempts that failed
debug_multiline(LOG_3D, glContextErrors);
}
debug(LOG_3D, "Requested %s context", to_string(contextRequest).c_str());
debug(LOG_INFO, "Requested %s context", to_string(contextRequest).c_str());

int value = 0;
if (SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &value) == 0)
Expand Down
Loading