diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_vk.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_vk.cpp | 135 |
1 files changed, 102 insertions, 33 deletions
diff --git a/3rdparty/bgfx/src/renderer_vk.cpp b/3rdparty/bgfx/src/renderer_vk.cpp index aba25e78512..8b2c6cd001e 100644 --- a/3rdparty/bgfx/src/renderer_vk.cpp +++ b/3rdparty/bgfx/src/renderer_vk.cpp @@ -17,10 +17,6 @@ # import <Metal/Metal.h> #endif // BX_PLATFORM_OSX -#if defined(WL_EGL_PLATFORM) -# include <wayland-egl-backend.h> -#endif // defined(WL_EGL_PLATFORM) - namespace bgfx { namespace vk { static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; @@ -346,6 +342,18 @@ VK_IMPORT_DEVICE EXT_shader_viewport_index_layer, EXT_custom_border_color, KHR_draw_indirect_count, + +# if BX_PLATFORM_ANDROID + KHR_android_surface, +# elif BX_PLATFORM_LINUX + KHR_wayland_surface, + KHR_xlib_surface, + KHR_xcb_surface, +# elif BX_PLATFORM_WINDOWS + KHR_win32_surface, +# elif BX_PLATFORM_OSX + MVK_macos_surface, +# endif Count }; @@ -371,6 +379,17 @@ VK_IMPORT_DEVICE { "VK_EXT_shader_viewport_index_layer", 1, false, false, true , Layer::Count }, { "VK_EXT_custom_border_color", 1, false, false, true , Layer::Count }, { "VK_KHR_draw_indirect_count", 1, false, false, true , Layer::Count }, +# if BX_PLATFORM_ANDROID + { VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_LINUX + { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, + { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, + { VK_KHR_XCB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_WINDOWS + { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_OSX + { VK_MVK_MACOS_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# endif }; BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); @@ -1159,7 +1178,7 @@ VK_IMPORT_DEVICE #else "libvulkan.so.1" #endif // BX_PLATFORM_* - ); + ); if (NULL == m_vulkan1Dll) { @@ -1229,13 +1248,12 @@ VK_IMPORT const char* enabledExtension[Extension::Count + 3] = #else - uint32_t numEnabledExtensions = headless ? 0 : 2; + uint32_t numEnabledExtensions = headless ? 0 : 1; - const char* enabledExtension[Extension::Count + 2] = + const char* enabledExtension[Extension::Count + 1] = #endif { VK_KHR_SURFACE_EXTENSION_NAME, - KHR_SURFACE_EXTENSION_NAME, #if BX_PLATFORM_OSX VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, #endif @@ -2664,6 +2682,7 @@ VK_IMPORT_DEVICE m_indexBuffers[_blitter.m_ib->handle.idx].update(m_commandBuffer, 0, _numIndices*2, _blitter.m_ib->data); m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandBuffer, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); + VkRenderPassBeginInfo rpbi; rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rpbi.pNext = NULL; @@ -2757,6 +2776,13 @@ VK_IMPORT_DEVICE { return suspended; } + + //BX_TRACE("updateResolution(%d, %d) m_resolution=(%d, %d)" + // , _resolution.width + // , _resolution.height + // , m_resolution.width + // , m_resolution.height + // ); uint32_t flags = _resolution.reset & ~(0 | BGFX_RESET_SUSPEND @@ -2764,19 +2790,13 @@ VK_IMPORT_DEVICE | BGFX_RESET_DEPTH_CLAMP ); - // Note: m_needToRefreshSwapchain is deliberately ignored when deciding whether to recreate the swapchain - // because it can happen several frames before submit is called with the new resolution. - // Instead, vkAcquireNextImageKHR and all draws to the backbuffer are skipped until the window size is updated. - // That also fixes a related issue where VK_ERROR_OUT_OF_DATE_KHR is returned from - // vkQueuePresentKHR when the window doesn't exist anymore, and vkGetPhysicalDeviceSurfaceCapabilitiesKHR - // fails with VK_ERROR_SURFACE_LOST_KHR. - if (false || m_resolution.format != _resolution.format || m_resolution.width != _resolution.width || m_resolution.height != _resolution.height || m_resolution.reset != flags - || m_backBuffer.m_swapChain.m_needToRecreateSurface) + || m_backBuffer.m_swapChain.m_needToRecreateSurface + || m_backBuffer.m_swapChain.m_needToRecreateSwapchain) { flags &= ~BGFX_RESET_INTERNAL_FORCE; @@ -2794,6 +2814,10 @@ VK_IMPORT_DEVICE preReset(); m_backBuffer.update(m_commandBuffer, m_resolution); + // Update the resolution again here, as the actual width and height + // is now final (as it was potentially clamped by the Vulkan driver). + m_resolution.width = m_backBuffer.m_width; + m_resolution.height = m_backBuffer.m_height; postReset(); } @@ -4131,10 +4155,10 @@ VK_IMPORT_DEVICE { case UniformType::Mat3: case UniformType::Mat3|kUniformFragmentBit: - { + { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) - { + { Matrix4 mtx; mtx.un.val[ 0] = value[0]; mtx.un.val[ 1] = value[1]; @@ -6658,6 +6682,7 @@ VK_DESTROY ; const bool recreateSwapchain = false + || m_needToRecreateSwapchain || m_resolution.format != _resolution.format || m_resolution.width != _resolution.width || m_resolution.height != _resolution.height @@ -6763,22 +6788,25 @@ VK_DESTROY } #elif BX_PLATFORM_LINUX { -#if defined(WL_EGL_PLATFORM) if (g_platformData.type == bgfx::NativeWindowHandleType::Wayland) { + BGFX_FATAL(s_extension[Extension::KHR_wayland_surface].m_supported, Fatal::UnableToInitialize, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME " not supported"); + BGFX_FATAL(NULL != vkCreateWaylandSurfaceKHR, Fatal::UnableToInitialize, "vkCreateWaylandSurfaceKHR == 0"); + BX_TRACE("Attempting Wayland surface creation."); VkWaylandSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; sci.flags = 0; sci.display = (wl_display*)g_platformData.ndt; - sci.surface = (wl_surface*)((wl_egl_window*)m_nwh)->surface; + sci.surface = (wl_surface*)m_nwh; result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface); } else -#endif // defined(WL_EGL_PLATFORM) { - if (NULL != vkCreateXlibSurfaceKHR) + if (s_extension[Extension::KHR_xlib_surface].m_supported) { + BGFX_FATAL(NULL != vkCreateXlibSurfaceKHR, Fatal::UnableToInitialize, "vkCreateXlibSurfaceKHR == 0") + BX_TRACE("Attempting Xlib surface creation."); VkXlibSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6788,7 +6816,7 @@ VK_DESTROY result = vkCreateXlibSurfaceKHR(instance, &sci, allocatorCb, &m_surface); } - if (VK_SUCCESS != result) + if (VK_SUCCESS != result && s_extension[Extension::KHR_xcb_surface].m_supported) { void* xcbdll = bx::dlopen("libX11-xcb.so.1"); @@ -6800,6 +6828,8 @@ VK_DESTROY union { void* ptr; xcb_window_t window; } cast = { m_nwh }; + BGFX_FATAL(NULL != vkCreateXcbSurfaceKHR, Fatal::UnableToInitialize, "vkCreateXcbSurfaceKHR == 0") + VkXcbSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6932,6 +6962,15 @@ VK_DESTROY , surfaceCapabilities.minImageExtent.height , surfaceCapabilities.maxImageExtent.height ); + if (width != m_resolution.width || height != m_resolution.height) + { + BX_TRACE("Clamped swapchain resolution from %dx%d to %dx%d" + , m_resolution.width + , m_resolution.height + , width + , height + ); + } VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; @@ -7052,6 +7091,8 @@ VK_DESTROY m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED; } + BX_TRACE("Succesfully created swapchain (%dx%d) with %d images.", width, height, m_numSwapChainImages); + VkSemaphoreCreateInfo sci; sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; sci.pNext = NULL; @@ -7071,7 +7112,7 @@ VK_DESTROY m_currentSemaphore = 0; m_needPresent = false; - m_needToRefreshSwapchain = false; + m_needToRecreateSwapchain = false; return result; } @@ -7373,7 +7414,7 @@ VK_DESTROY bool SwapChainVK::acquire(VkCommandBuffer _commandBuffer) { if (VK_NULL_HANDLE == m_swapchain - || m_needToRefreshSwapchain) + || m_needToRecreateSwapchain) { return false; } @@ -7395,6 +7436,11 @@ VK_DESTROY , &m_backBufferColorIdx ); + if (result != VK_SUCCESS) + { + BX_TRACE("vkAcquireNextImageKHR(...): result = %s", getName(result)); + } + switch (result) { case VK_SUCCESS: @@ -7402,11 +7448,12 @@ VK_DESTROY case VK_ERROR_SURFACE_LOST_KHR: m_needToRecreateSurface = true; - BX_FALLTHROUGH; + m_needToRecreateSwapchain = true; + return false; case VK_ERROR_OUT_OF_DATE_KHR: case VK_SUBOPTIMAL_KHR: - m_needToRefreshSwapchain = true; + m_needToRecreateSwapchain = true; return false; default: @@ -7448,16 +7495,22 @@ VK_DESTROY pi.pImageIndices = &m_backBufferColorIdx; pi.pResults = NULL; VkResult result = vkQueuePresentKHR(m_queue, &pi); + + if (result != VK_SUCCESS) + { + BX_TRACE("vkQueuePresentKHR(...): result = %s", getName(result)); + } switch (result) { case VK_ERROR_SURFACE_LOST_KHR: m_needToRecreateSurface = true; - BX_FALLTHROUGH; + m_needToRecreateSwapchain = true; + break; case VK_ERROR_OUT_OF_DATE_KHR: case VK_SUBOPTIMAL_KHR: - m_needToRefreshSwapchain = true; + m_needToRecreateSwapchain = true; break; default: @@ -7615,8 +7668,10 @@ VK_DESTROY { m_swapChain.update(_commandBuffer, m_nwh, _resolution); VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &m_renderPass) ); - m_width = _resolution.width; - m_height = _resolution.height; + // Don't believe the passed Resolution, as the Vulkan driver might have + // specified another resolution, which we had to obey. + m_width = m_swapChain.m_sci.imageExtent.width; + m_height = m_swapChain.m_sci.imageExtent.height; m_sampler = m_swapChain.m_sampler; } @@ -8275,12 +8330,26 @@ VK_DESTROY if (isFrameBufferValid) { viewState.m_rect = _render->m_view[view].m_rect; - const Rect& rect = _render->m_view[view].m_rect; - const Rect& scissorRect = _render->m_view[view].m_scissor; + Rect rect = _render->m_view[view].m_rect; + Rect scissorRect = _render->m_view[view].m_scissor; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : rect; restoreScissor = false; + // Clamp the rect to what's valid according to Vulkan. + rect.m_width = bx::min(rect.m_width, fb.m_width - rect.m_x); + rect.m_height = bx::min(rect.m_height, fb.m_height - rect.m_y); + if (_render->m_view[view].m_rect.m_width != rect.m_width + || _render->m_view[view].m_rect.m_height != rect.m_height) + { + BX_TRACE("Clamp render pass from %dx%d to %dx%d" + , _render->m_view[view].m_rect.m_width + , _render->m_view[view].m_rect.m_height + , rect.m_width + , rect.m_height + ); + } + rpbi.framebuffer = fb.m_currentFramebuffer; rpbi.renderPass = fb.m_renderPass; rpbi.renderArea.offset.x = rect.m_x; |