summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/renderer_vk.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/renderer_vk.cpp')
-rw-r--r--3rdparty/bgfx/src/renderer_vk.cpp135
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;