Blind (untested) implementation of wrapping/handling for VK_KHR_display

This commit is contained in:
baldurk
2016-08-23 17:18:42 +02:00
parent 872fbe017b
commit 5826777dfe
5 changed files with 390 additions and 188 deletions
@@ -162,6 +162,7 @@ typedef struct VkLayerDispatchTable_ {
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR AcquireNextImageKHR;
PFN_vkQueuePresentKHR QueuePresentKHR;
PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
} VkLayerDispatchTable;
typedef struct VkLayerInstanceDispatchTable_ {
+39
View File
@@ -317,6 +317,9 @@ private:
vector<uint32_t *> m_MemIdxMaps;
void RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProps, uint32_t **memIdxMap);
void WrapAndProcessCreatedSwapchain(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
VkSwapchainKHR *pSwapChain);
struct
{
void Reset()
@@ -1334,4 +1337,40 @@ public:
uint32_t queueFamilyIndex, Display *dpy,
VisualID visualID);
#endif
// VK_KHR_display and VK_KHR_display_swapchain. These have no library or include dependencies so
// wecan just compile them in on all platforms to reduce platform-specific code. They are mostly
// only actually used though on *nix.
VkResult vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkDisplayPropertiesKHR *pProperties);
VkResult vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkDisplayPlanePropertiesKHR *pProperties);
VkResult vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
uint32_t *pDisplayCount, VkDisplayKHR *pDisplays);
VkResult vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
uint32_t *pPropertyCount,
VkDisplayModePropertiesKHR *pProperties);
VkResult vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode);
VkResult vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
uint32_t planeIndex,
VkDisplayPlaneCapabilitiesKHR *pCapabilities);
VkResult vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VkResult vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
const VkSwapchainCreateInfoKHR *pCreateInfos,
const VkAllocationCallbacks *pAllocator,
VkSwapchainKHR *pSwapchains);
};
+53 -14
View File
@@ -32,6 +32,8 @@
#undef VK_KHR_android_surface
#undef VK_KHR_surface
#undef VK_KHR_swapchain
#undef VK_KHR_display
#undef VK_KHR_display_swapchain
#undef VK_EXT_debug_report
#undef VK_EXT_debug_marker
@@ -243,23 +245,37 @@
HookInit(CmdExecuteCommands); \
HookInit(CmdEndRenderPass);
// We can always build in VK_KHR_display and VK_KHR_display_swapchain support
// because they don't need any libraries or headers.
// They're not really used or relevant on win32/android but for platform simplicity
// we just include it always, it does no harm to include.
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
#define CheckInstanceExts() \
CheckExt(VK_KHR_xlib_surface) CheckExt(VK_KHR_xcb_surface) CheckExt(VK_KHR_win32_surface) \
CheckExt(VK_KHR_android_surface) CheckExt(VK_KHR_surface) CheckExt(VK_EXT_debug_report)
#define CheckInstanceExts() \
CheckExt(VK_KHR_xlib_surface) CheckExt(VK_KHR_xcb_surface) CheckExt(VK_KHR_win32_surface) \
CheckExt(VK_KHR_android_surface) CheckExt(VK_KHR_surface) CheckExt(VK_EXT_debug_report) \
CheckExt(VK_KHR_display)
#define CheckDeviceExts() CheckExt(VK_EXT_debug_marker) CheckExt(VK_KHR_swapchain)
#define CheckDeviceExts() \
CheckExt(VK_EXT_debug_marker) CheckExt(VK_KHR_swapchain) CheckExt(VK_KHR_display_swapchain)
#define HookInitVulkanInstanceExts() \
HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceCapabilitiesKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceFormatsKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfacePresentModesKHR); \
HookInitExtension(VK_EXT_debug_report, CreateDebugReportCallbackEXT); \
HookInitExtension(VK_EXT_debug_report, DestroyDebugReportCallbackEXT); \
HookInitExtension(VK_EXT_debug_report, DebugReportMessageEXT); \
#define HookInitVulkanInstanceExts() \
HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceCapabilitiesKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceFormatsKHR); \
HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfacePresentModesKHR); \
HookInitExtension(VK_EXT_debug_report, CreateDebugReportCallbackEXT); \
HookInitExtension(VK_EXT_debug_report, DestroyDebugReportCallbackEXT); \
HookInitExtension(VK_EXT_debug_report, DebugReportMessageEXT); \
HookInitExtension(VK_KHR_display, GetPhysicalDeviceDisplayPropertiesKHR); \
HookInitExtension(VK_KHR_display, GetPhysicalDeviceDisplayPlanePropertiesKHR); \
HookInitExtension(VK_KHR_display, GetDisplayPlaneSupportedDisplaysKHR); \
HookInitExtension(VK_KHR_display, GetDisplayModePropertiesKHR); \
HookInitExtension(VK_KHR_display, CreateDisplayModeKHR); \
HookInitExtension(VK_KHR_display, GetDisplayPlaneCapabilitiesKHR); \
HookInitExtension(VK_KHR_display, CreateDisplayPlaneSurfaceKHR); \
HookInitInstance_PlatformSpecific()
#define HookInitVulkanDeviceExts() \
@@ -272,7 +288,8 @@
HookInitExtension(VK_KHR_swapchain, DestroySwapchainKHR); \
HookInitExtension(VK_KHR_swapchain, GetSwapchainImagesKHR); \
HookInitExtension(VK_KHR_swapchain, AcquireNextImageKHR); \
HookInitExtension(VK_KHR_swapchain, QueuePresentKHR);
HookInitExtension(VK_KHR_swapchain, QueuePresentKHR); \
HookInitExtension(VK_KHR_display_swapchain, CreateSharedSwapchainsKHR);
#define DefineHooks() \
HookDefine3(VkResult, vkEnumeratePhysicalDevices, VkInstance, instance, uint32_t *, \
@@ -597,6 +614,28 @@
HookDefine2(VkResult, vkQueuePresentKHR, VkQueue, queue, VkPresentInfoKHR *, pPresentInfo); \
HookDefine3(void, vkDestroySurfaceKHR, VkInstance, instance, VkSurfaceKHR, surface, \
const VkAllocationCallbacks *, pAllocator); \
HookDefine3(VkResult, vkGetPhysicalDeviceDisplayPropertiesKHR, VkPhysicalDevice, physicalDevice, \
uint32_t *, pPropertyCount, VkDisplayPropertiesKHR *, pProperties); \
HookDefine3(VkResult, vkGetPhysicalDeviceDisplayPlanePropertiesKHR, VkPhysicalDevice, \
physicalDevice, uint32_t *, pPropertyCount, VkDisplayPlanePropertiesKHR *, \
pProperties); \
HookDefine4(VkResult, vkGetDisplayPlaneSupportedDisplaysKHR, VkPhysicalDevice, physicalDevice, \
uint32_t, planeIndex, uint32_t *, pDisplayCount, VkDisplayKHR *, pDisplays); \
HookDefine4(VkResult, vkGetDisplayModePropertiesKHR, VkPhysicalDevice, physicalDevice, \
VkDisplayKHR, display, uint32_t *, pPropertyCount, VkDisplayModePropertiesKHR *, \
pProperties); \
HookDefine5(VkResult, vkCreateDisplayModeKHR, VkPhysicalDevice, physicalDevice, VkDisplayKHR, \
display, const VkDisplayModeCreateInfoKHR *, pCreateInfo, \
const VkAllocationCallbacks *, pAllocator, VkDisplayModeKHR *, pMode); \
HookDefine4(VkResult, vkGetDisplayPlaneCapabilitiesKHR, VkPhysicalDevice, physicalDevice, \
VkDisplayModeKHR, mode, uint32_t, planeIndex, VkDisplayPlaneCapabilitiesKHR *, \
pCapabilities); \
HookDefine4(VkResult, vkCreateDisplayPlaneSurfaceKHR, VkInstance, instance, \
const VkDisplaySurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \
pAllocator, VkSurfaceKHR *, pSurface); \
HookDefine5(VkResult, vkCreateSharedSwapchainsKHR, VkDevice, device, uint32_t, swapchainCount, \
const VkSwapchainCreateInfoKHR *, pCreateInfos, const VkAllocationCallbacks *, \
pAllocator, VkSwapchainKHR *, pSwapchains); \
HookDefine_PlatformSpecific()
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
+9
View File
@@ -72,6 +72,9 @@ enum VkResourceType
eResSurface
};
// VkDisplayKHR and VkDisplayModeKHR are both UNWRAPPED because there's no need to wrap them.
// The only thing we need to wrap VkSurfaceKHR for is to get back the window from it later.
// dummy standin for a typeless real resource
// stored in a uint64_t, with function to cast back
// if we know what type it is
@@ -544,6 +547,9 @@ struct WrappedVkSurfaceKHR : WrappedVkNonDispRes
};
};
// VkDisplayKHR and VkDisplayModeKHR are both UNWRAPPED because there's no need to wrap them.
// The only thing we need to wrap VkSurfaceKHR for is to get back the window from it later.
// Note: we assume only the following resources can return duplicate handles (and so
// on replay we need to handle two distinct ids with the same handle.
// Other resources are discounted because they have 'state' or otherwise wouldn't make
@@ -630,6 +636,9 @@ UNWRAP_NONDISP_HELPER(VkCommandPool)
UNWRAP_NONDISP_HELPER(VkSwapchainKHR)
UNWRAP_NONDISP_HELPER(VkSurfaceKHR)
// VkDisplayKHR and VkDisplayModeKHR are both UNWRAPPED because there's no need to wrap them.
// The only thing we need to wrap VkSurfaceKHR for is to get back the window from it later.
#define WRAPPING_DEBUG 0
template <typename RealType>
+288 -174
View File
@@ -295,6 +295,183 @@ bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(Serialiser *localSerialiser,
return true;
}
void WrappedVulkan::WrapAndProcessCreatedSwapchain(VkDevice device,
const VkSwapchainCreateInfoKHR *pCreateInfo,
VkSwapchainKHR *pSwapChain)
{
ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSwapChain);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER);
Serialise_vkCreateSwapchainKHR(localSerialiser, device, pCreateInfo, NULL, pSwapChain);
chunk = scope.Get();
}
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSwapChain);
record->AddChunk(chunk);
record->swapInfo = new SwapchainInfo();
SwapchainInfo &swapInfo = *record->swapInfo;
// sneaky casting of window handle into record
swapInfo.wndHandle = (RENDERDOC_WindowHandle)GetRecord(pCreateInfo->surface);
{
SCOPED_LOCK(m_SwapLookupLock);
m_SwapLookup[swapInfo.wndHandle] = *pSwapChain;
}
RenderDoc::Inst().AddFrameCapturer(LayerDisp(m_Instance), swapInfo.wndHandle, this);
swapInfo.format = pCreateInfo->imageFormat;
swapInfo.extent = pCreateInfo->imageExtent;
swapInfo.arraySize = pCreateInfo->imageArrayLayers;
VkResult vkr = VK_SUCCESS;
const VkLayerDispatchTable *vt = ObjDisp(device);
{
VkAttachmentDescription attDesc = {
0,
pCreateInfo->imageFormat,
VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
VkSubpassDescription sub = {
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
0, NULL, // inputs
1, &attRef, // color
NULL, // resolve
NULL, // depth-stencil
0, NULL, // preserve
};
VkRenderPassCreateInfo rpinfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
NULL,
0,
1,
&attDesc,
1,
&sub,
0,
NULL, // dependencies
};
vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &swapInfo.rp);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapInfo.rp);
}
// serialise out the swap chain images
{
uint32_t numSwapImages;
vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numSwapImages, NULL);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
swapInfo.lastPresent = 0;
swapInfo.images.resize(numSwapImages);
for(uint32_t i = 0; i < numSwapImages; i++)
{
swapInfo.images[i].im = VK_NULL_HANDLE;
swapInfo.images[i].view = VK_NULL_HANDLE;
swapInfo.images[i].fb = VK_NULL_HANDLE;
}
VkImage *images = new VkImage[numSwapImages];
// go through our own function so we assign these images IDs
vkr = vkGetSwapchainImagesKHR(device, *pSwapChain, &numSwapImages, images);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
for(uint32_t i = 0; i < numSwapImages; i++)
{
SwapchainInfo::SwapImage &swapImInfo = swapInfo.images[i];
// memory doesn't exist for genuine WSI created images
swapImInfo.im = images[i];
ResourceId imid = GetResID(images[i]);
VkImageSubresourceRange range;
range.baseMipLevel = range.baseArrayLayer = 0;
range.levelCount = 1;
range.layerCount = pCreateInfo->imageArrayLayers;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
// fill out image info so we track resource state barriers
{
SCOPED_LOCK(m_ImageLayoutsLock);
m_ImageLayouts[imid].subresourceStates.clear();
m_ImageLayouts[imid].subresourceStates.push_back(
ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
}
{
VkImageViewCreateInfo info = {
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
NULL,
0,
Unwrap(images[i]),
VK_IMAGE_VIEW_TYPE_2D,
pCreateInfo->imageFormat,
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
};
vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &swapImInfo.view);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.view);
VkFramebufferCreateInfo fbinfo = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
NULL,
0,
Unwrap(swapInfo.rp),
1,
UnwrapPtr(swapImInfo.view),
(uint32_t)pCreateInfo->imageExtent.width,
(uint32_t)pCreateInfo->imageExtent.height,
1,
};
vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &swapImInfo.fb);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.fb);
}
}
SAFE_DELETE_ARRAY(images);
}
FirstFrame(*pSwapChain);
}
else
{
GetResourceManager()->AddLiveResource(id, *pSwapChain);
}
}
VkResult WrappedVulkan::vkCreateSwapchainKHR(VkDevice device,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
@@ -311,179 +488,7 @@ VkResult WrappedVulkan::vkCreateSwapchainKHR(VkDevice device,
ObjDisp(device)->CreateSwapchainKHR(Unwrap(device), &createInfo, pAllocator, pSwapChain);
if(ret == VK_SUCCESS)
{
ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSwapChain);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER);
Serialise_vkCreateSwapchainKHR(localSerialiser, device, pCreateInfo, NULL, pSwapChain);
chunk = scope.Get();
}
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSwapChain);
record->AddChunk(chunk);
record->swapInfo = new SwapchainInfo();
SwapchainInfo &swapInfo = *record->swapInfo;
// sneaky casting of window handle into record
swapInfo.wndHandle = (RENDERDOC_WindowHandle)GetRecord(pCreateInfo->surface);
{
SCOPED_LOCK(m_SwapLookupLock);
m_SwapLookup[swapInfo.wndHandle] = *pSwapChain;
}
RenderDoc::Inst().AddFrameCapturer(LayerDisp(m_Instance), swapInfo.wndHandle, this);
swapInfo.format = pCreateInfo->imageFormat;
swapInfo.extent = pCreateInfo->imageExtent;
swapInfo.arraySize = pCreateInfo->imageArrayLayers;
VkResult vkr = VK_SUCCESS;
const VkLayerDispatchTable *vt = ObjDisp(device);
{
VkAttachmentDescription attDesc = {
0,
pCreateInfo->imageFormat,
VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
VkSubpassDescription sub = {
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
0, NULL, // inputs
1, &attRef, // color
NULL, // resolve
NULL, // depth-stencil
0, NULL, // preserve
};
VkRenderPassCreateInfo rpinfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
NULL,
0,
1,
&attDesc,
1,
&sub,
0,
NULL, // dependencies
};
vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &swapInfo.rp);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapInfo.rp);
}
// serialise out the swap chain images
{
uint32_t numSwapImages;
vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numSwapImages, NULL);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
swapInfo.lastPresent = 0;
swapInfo.images.resize(numSwapImages);
for(uint32_t i = 0; i < numSwapImages; i++)
{
swapInfo.images[i].im = VK_NULL_HANDLE;
swapInfo.images[i].view = VK_NULL_HANDLE;
swapInfo.images[i].fb = VK_NULL_HANDLE;
}
VkImage *images = new VkImage[numSwapImages];
// go through our own function so we assign these images IDs
vkr = vkGetSwapchainImagesKHR(device, *pSwapChain, &numSwapImages, images);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
for(uint32_t i = 0; i < numSwapImages; i++)
{
SwapchainInfo::SwapImage &swapImInfo = swapInfo.images[i];
// memory doesn't exist for genuine WSI created images
swapImInfo.im = images[i];
ResourceId imid = GetResID(images[i]);
VkImageSubresourceRange range;
range.baseMipLevel = range.baseArrayLayer = 0;
range.levelCount = 1;
range.layerCount = pCreateInfo->imageArrayLayers;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
// fill out image info so we track resource state barriers
{
SCOPED_LOCK(m_ImageLayoutsLock);
m_ImageLayouts[imid].subresourceStates.clear();
m_ImageLayouts[imid].subresourceStates.push_back(
ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
}
{
VkImageViewCreateInfo info = {
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
NULL,
0,
Unwrap(images[i]),
VK_IMAGE_VIEW_TYPE_2D,
pCreateInfo->imageFormat,
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
};
vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &swapImInfo.view);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.view);
VkFramebufferCreateInfo fbinfo = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
NULL,
0,
Unwrap(swapInfo.rp),
1,
UnwrapPtr(swapImInfo.view),
(uint32_t)pCreateInfo->imageExtent.width,
(uint32_t)pCreateInfo->imageExtent.height,
1,
};
vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &swapImInfo.fb);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.fb);
}
}
SAFE_DELETE_ARRAY(images);
}
FirstFrame(*pSwapChain);
}
else
{
GetResourceManager()->AddLiveResource(id, *pSwapChain);
}
}
WrapAndProcessCreatedSwapchain(device, pCreateInfo, pSwapChain);
return ret;
}
@@ -744,7 +749,8 @@ void WrappedVulkan::vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surfac
WrappedVkSurfaceKHR *wrapper = GetWrapped(surface);
// record pointer has window handle packed in
Keyboard::RemoveInputWindow((void *)wrapper->record);
if(wrapper->record)
Keyboard::RemoveInputWindow((void *)wrapper->record);
// now set record pointer back to NULL so no-one tries to delete it
wrapper->record = NULL;
@@ -754,3 +760,111 @@ void WrappedVulkan::vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surfac
GetResourceManager()->ReleaseWrappedResource(surface, true);
ObjDisp(instance)->DestroySurfaceKHR(Unwrap(instance), unwrappedObj, pAllocator);
}
// VK_KHR_display and VK_KHR_display_swapchain. These have no library or include dependencies so
// wecan just compile them in on all platforms to reduce platform-specific code. They are mostly
// only actually used though on *nix.
VkResult WrappedVulkan::vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkDisplayPropertiesKHR *pProperties)
{
return ObjDisp(physicalDevice)
->GetPhysicalDeviceDisplayPropertiesKHR(Unwrap(physicalDevice), pPropertyCount, pProperties);
}
VkResult WrappedVulkan::vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
VkDisplayPlanePropertiesKHR *pProperties)
{
return ObjDisp(physicalDevice)
->GetPhysicalDeviceDisplayPlanePropertiesKHR(Unwrap(physicalDevice), pPropertyCount,
pProperties);
}
VkResult WrappedVulkan::vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
uint32_t planeIndex,
uint32_t *pDisplayCount,
VkDisplayKHR *pDisplays)
{
// we don't wrap the resulting displays since there's no data we need for them
return ObjDisp(physicalDevice)
->GetDisplayPlaneSupportedDisplaysKHR(Unwrap(physicalDevice), planeIndex, pDisplayCount,
pDisplays);
}
VkResult WrappedVulkan::vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
VkDisplayKHR display, uint32_t *pPropertyCount,
VkDisplayModePropertiesKHR *pProperties)
{
// display is not wrapped since we have no need of any data associated with it
return ObjDisp(physicalDevice)
->GetDisplayModePropertiesKHR(Unwrap(physicalDevice), display, pPropertyCount, pProperties);
}
VkResult WrappedVulkan::vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDisplayModeKHR *pMode)
{
// we don't wrap the resulting mode since there's no data we need for it
return ObjDisp(physicalDevice)
->CreateDisplayModeKHR(Unwrap(physicalDevice), display, pCreateInfo, pAllocator, pMode);
}
VkResult WrappedVulkan::vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
VkDisplayModeKHR mode, uint32_t planeIndex,
VkDisplayPlaneCapabilitiesKHR *pCapabilities)
{
// mode is not wrapped since we have no need of any data associated with it
return ObjDisp(physicalDevice)
->GetDisplayPlaneCapabilitiesKHR(Unwrap(physicalDevice), mode, planeIndex, pCapabilities);
}
VkResult WrappedVulkan::vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface)
{
// should not come in here at all on replay
RDCASSERT(m_State >= WRITING);
VkResult ret = ObjDisp(instance)->CreateDisplayPlaneSurfaceKHR(Unwrap(instance), pCreateInfo,
pAllocator, pSurface);
if(ret == VK_SUCCESS)
{
// we must wrap surfaces to be consistent with the rest of the code and surface handling,
// but there's nothing actually to do here - no meaningful data we care about here.
GetResourceManager()->WrapResource(Unwrap(instance), *pSurface);
}
return ret;
}
VkResult WrappedVulkan::vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
const VkSwapchainCreateInfoKHR *pCreateInfos,
const VkAllocationCallbacks *pAllocator,
VkSwapchainKHR *pSwapchains)
{
VkSwapchainCreateInfoKHR *unwrapped = GetTempArray<VkSwapchainCreateInfoKHR>(swapchainCount);
for(uint32_t i = 0; i < swapchainCount; i++)
{
unwrapped[i] = pCreateInfos[i];
// make sure we can readback to get the screenshot
unwrapped[i].imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
unwrapped[i].surface = Unwrap(unwrapped[i].surface);
unwrapped[i].oldSwapchain = Unwrap(unwrapped[i].oldSwapchain);
}
VkResult ret = ObjDisp(device)->CreateSharedSwapchainsKHR(Unwrap(device), swapchainCount,
unwrapped, pAllocator, pSwapchains);
if(ret == VK_SUCCESS)
{
for(uint32_t i = 0; i < swapchainCount; i++)
WrapAndProcessCreatedSwapchain(device, pCreateInfos + i, pSwapchains + i);
}
return ret;
}