bool WrappedVulkan::Serialise_vkCmdSetDepthBias(Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, float depthBias, float depthBiasClamp, float slopeScaledDepthBias) { SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); SERIALISE_ELEMENT(float, bias, depthBias); SERIALISE_ELEMENT(float, biasclamp, depthBiasClamp); SERIALISE_ELEMENT(float, slope, slopeScaledDepthBias); Serialise_DebugMessages(localSerialiser, false); if(m_State < WRITING) m_LastCmdBufferID = cmdid; if(m_State == EXECUTING) { if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) { cmdBuffer = RerecordCmdBuf(cmdid); ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); m_RenderState.bias.depth = bias; m_RenderState.bias.biasclamp = biasclamp; m_RenderState.bias.slope = slope; } } else if(m_State == READING) { cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid); ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); } return true; }
bool WrappedVulkan::Serialise_vkAllocateMemory( Serialiser* localSerialiser, VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkMemoryAllocateInfo, info, *pAllocateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pMemory)); if(m_State == READING) { VkDeviceMemory mem = VK_NULL_HANDLE; device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); // serialised memory type index is non-remapped, so we remap now. // PORTABILITY may need to re-write info to change memory type index to the // appropriate index on replay info.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[info.memoryTypeIndex]; VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, NULL, &mem); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), mem); GetResourceManager()->AddLiveResource(id, mem); m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &info); // create a buffer with the whole memory range bound, for copying to and from // conveniently (for initial state data) VkBuffer buf = VK_NULL_HANDLE; VkBufferCreateInfo bufInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, }; ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); RDCASSERTEQUAL(ret, VK_SUCCESS); ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0); // register as a live-only resource, so it is cleaned up properly GetResourceManager()->AddLiveResource(bufid, buf); m_CreationInfo.m_Memory[live].wholeMemBuf = buf; } } return true; }
// needs to be separate because it releases internal resources void WrappedVulkan::vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR obj, const VkAllocationCallbacks* pAllocator) { // release internal rendering objects we created for rendering the overlay { SwapchainInfo &info = *GetRecord(obj)->swapInfo; RenderDoc::Inst().RemoveFrameCapturer(LayerDisp(m_Instance), info.wndHandle); VkRenderPass unwrappedRP = Unwrap(info.rp); GetResourceManager()->ReleaseWrappedResource(info.rp, true); ObjDisp(device)->DestroyRenderPass(Unwrap(device), unwrappedRP, NULL); for(size_t i=0; i < info.images.size(); i++) { VkFramebuffer unwrappedFB = Unwrap(info.images[i].fb); VkImageView unwrappedView = Unwrap(info.images[i].view); GetResourceManager()->ReleaseWrappedResource(info.images[i].fb, true); // note, image doesn't have to be destroyed, just untracked GetResourceManager()->ReleaseWrappedResource(info.images[i].im, true); GetResourceManager()->ReleaseWrappedResource(info.images[i].view, true); ObjDisp(device)->DestroyFramebuffer(Unwrap(device), unwrappedFB, NULL); ObjDisp(device)->DestroyImageView(Unwrap(device), unwrappedView, NULL); } } VkSwapchainKHR unwrappedObj = Unwrap(obj); GetResourceManager()->ReleaseWrappedResource(obj, true); ObjDisp(device)->DestroySwapchainKHR(Unwrap(device), unwrappedObj, pAllocator); }
bool WrappedVulkan::Serialise_vkCmdSetDepthBounds(Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, float minDepthBounds, float maxDepthBounds) { SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); SERIALISE_ELEMENT(float, mind, minDepthBounds); SERIALISE_ELEMENT(float, maxd, maxDepthBounds); Serialise_DebugMessages(localSerialiser, false); if(m_State < WRITING) m_LastCmdBufferID = cmdid; if(m_State == EXECUTING) { if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) { cmdBuffer = RerecordCmdBuf(cmdid); ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); m_RenderState.mindepth = mind; m_RenderState.maxdepth = maxd; } } else if(m_State == READING) { cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid); ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); } return true; }
bool WrappedVulkan::Serialise_vkCreateEvent( Serialiser* localSerialiser, VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkEventCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pEvent)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkEvent ev = VK_NULL_HANDLE; VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), &info, NULL, &ev); // see top of this file for current event/fence handling ObjDisp(device)->SetEvent(Unwrap(device), ev); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev); GetResourceManager()->AddLiveResource(id, ev); } } return true; }
void PreDraw(uint32_t eid, VkCommandBuffer cmd) { if(m_OcclusionQueryPool != VK_NULL_HANDLE) ObjDisp(cmd)->CmdBeginQuery(Unwrap(cmd), m_OcclusionQueryPool, (uint32_t)m_Results.size(), VK_QUERY_CONTROL_PRECISE_BIT); if(m_PipeStatsQueryPool != VK_NULL_HANDLE) ObjDisp(cmd)->CmdBeginQuery(Unwrap(cmd), m_PipeStatsQueryPool, (uint32_t)m_Results.size(), 0); ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_TimeStampQueryPool, (uint32_t)(m_Results.size() * 2 + 0)); }
bool PostDraw(uint32_t eid, VkCommandBuffer cmd) { ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_TimeStampQueryPool, (uint32_t)(m_Results.size() * 2 + 1)); if(m_OcclusionQueryPool != VK_NULL_HANDLE) ObjDisp(cmd)->CmdEndQuery(Unwrap(cmd), m_OcclusionQueryPool, (uint32_t)m_Results.size()); if(m_PipeStatsQueryPool != VK_NULL_HANDLE) ObjDisp(cmd)->CmdEndQuery(Unwrap(cmd), m_PipeStatsQueryPool, (uint32_t)m_Results.size()); m_Results.push_back(eid); return false; }
bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines( Serialiser *localSerialiser, VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache)); SERIALISE_ELEMENT(VkGraphicsPipelineCreateInfo, info, *pCreateInfos); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines)); if(m_State == READING) { VkPipeline pipe = VK_NULL_HANDLE; device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); // don't use pipeline caches on replay pipelineCache = VK_NULL_HANDLE; // GetResourceManager()->GetLiveHandle<VkPipelineCache>(cacheId); VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), 1, &info, NULL, &pipe); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live; if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe))) { live = GetResourceManager()->GetNonDispWrapper(pipe)->id; // destroy this instance of the duplicate, as we must have matching create/destroy // calls and there won't be a wrapped resource hanging around to destroy this one. ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL); // whenever the new ID is requested, return the old ID, via replacements. GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); } else { live = GetResourceManager()->WrapResource(Unwrap(device), pipe); GetResourceManager()->AddLiveResource(id, pipe); m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info); } } } return true; }
void WrappedVulkan::vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { // flush out any pending commands/semaphores SubmitCmds(); SubmitSemaphores(); FlushQ(); // MULTIDEVICE this function will need to check if the device is the one we // used for debugmanager/cmd pool etc, and only remove child queues and // resources (instead of doing full resource manager shutdown). // Or will we have a debug manager per-device? RDCASSERT(m_Device == device); // delete all debug manager objects SAFE_DELETE(m_DebugManager); // since we didn't create proper registered resources for our command buffers, // they won't be taken down properly with the pool. So we release them (just our // data) here. for(size_t i=0; i < m_InternalCmds.freecmds.size(); i++) GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]); // destroy our command pool if(m_InternalCmds.cmdpool != VK_NULL_HANDLE) { ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL); GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool); } for(size_t i=0; i < m_InternalCmds.freesems.size(); i++) { ObjDisp(m_Device)->DestroySemaphore(Unwrap(m_Device), Unwrap(m_InternalCmds.freesems[i]), NULL); GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freesems[i]); } m_InternalCmds.Reset(); m_QueueFamilyIdx = ~0U; m_Queue = VK_NULL_HANDLE; // destroy the API device immediately. There should be no more // resources left in the resource manager device/physical device/instance. // Anything we created should be gone and anything the application created // should be deleted by now. // If there were any leaks, we will leak them ourselves in vkDestroyInstance // rather than try to delete API objects after the device has gone ObjDisp(m_Device)->DestroyDevice(Unwrap(m_Device), pAllocator); GetResourceManager()->ReleaseWrappedResource(m_Device); m_Device = VK_NULL_HANDLE; m_PhysicalDevice = VK_NULL_HANDLE; }
VkResult WrappedVulkan::vkDbgSetObjectTag( VkDevice device, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t tagSize, const void* pTag) { if(ObjDisp(device)->DbgSetObjectTag) ObjDisp(device)->DbgSetObjectTag(device, objType, object, tagSize, pTag); // don't do anything with the tags return VK_SUCCESS; }
bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout( Serialiser* localSerialiser, VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkDescriptorSetLayoutCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSetLayout)); if(m_State == READING) { VkDescriptorSetLayout layout = VK_NULL_HANDLE; device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &info, NULL, &layout); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live; if(GetResourceManager()->HasWrapper(ToTypedHandle(layout))) { live = GetResourceManager()->GetNonDispWrapper(layout)->id; // destroy this instance of the duplicate, as we must have matching create/destroy // calls and there won't be a wrapped resource hanging around to destroy this one. ObjDisp(device)->DestroyDescriptorSetLayout(Unwrap(device), layout, NULL); // whenever the new ID is requested, return the old ID, via replacements. GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); } else { live = GetResourceManager()->WrapResource(Unwrap(device), layout); GetResourceManager()->AddLiveResource(id, layout); m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &info); } } } return true; }
VkResult WrappedVulkan::vkWaitForFences( VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout) { SCOPED_DBG_SINK(); VkFence *unwrapped = GetTempArray<VkFence>(fenceCount); for (uint32_t i = 0; i < fenceCount; i++) unwrapped[i] = Unwrap(pFences[i]); VkResult ret = ObjDisp(device)->WaitForFences(Unwrap(device), fenceCount, unwrapped, waitAll, timeout); if(m_State >= WRITING_CAPFRAME) { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(WAIT_FENCES); Serialise_vkWaitForFences(localSerialiser, device, fenceCount, pFences, waitAll, timeout); m_FrameCaptureRecord->AddChunk(scope.Get()); } return ret; }
VkBool32 WrappedVulkan::vkGetPhysicalDeviceXlibPresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID) { return ObjDisp(physicalDevice) ->GetPhysicalDeviceXlibPresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, dpy, visualID); }
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); WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); // we don't have an actual OS handle to identify this window. Instead construct something // that should be unique and hopefully not clashing/overlapping with other window handles // in use. uintptr_t fakeWindowHandle; fakeWindowHandle = (uintptr_t)NON_DISP_TO_UINT64(pCreateInfo->displayMode); fakeWindowHandle += pCreateInfo->planeIndex; fakeWindowHandle += pCreateInfo->planeStackIndex << 4; // since there's no point in allocating a full resource record and storing the window // handle under there somewhere, we just cast. We won't use the resource record for anything wrapped->record = (VkResourceRecord *)fakeWindowHandle; } return ret; }
VkResult WrappedVulkan::vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { // should not come in here at all on replay RDCASSERT(m_State >= WRITING); VkResult ret = ObjDisp(instance)->CreateWin32SurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); if(ret == VK_SUCCESS) { GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); // since there's no point in allocating a full resource record and storing the window // handle under there somewhere, we just cast. We won't use the resource record for anything wrapped->record = (VkResourceRecord *)pCreateInfo->hwnd; Keyboard::AddInputWindow((void *)pCreateInfo->hwnd); } return ret; }
bool WrappedVulkan::Serialise_vkGetDeviceQueue(Serialiser *localSerialiser, VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(uint32_t, familyIdx, m_SupportedQueueFamily); SERIALISE_ELEMENT(uint32_t, idx, queueIndex); SERIALISE_ELEMENT(ResourceId, queueId, GetResID(*pQueue)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkQueue queue; ObjDisp(device)->GetDeviceQueue(Unwrap(device), familyIdx, idx, &queue); GetResourceManager()->WrapResource(Unwrap(device), queue); GetResourceManager()->AddLiveResource(queueId, queue); if(familyIdx == m_QueueFamilyIdx) { m_Queue = queue; // we can now submit any cmds that were queued (e.g. from creating debug // manager on vkCreateDevice) SubmitCmds(); } } return true; }
VkResult WrappedVulkan::vkGetSwapchainCounterEXT(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t *pCounterValue) { return ObjDisp(device)->GetSwapchainCounterEXT(Unwrap(device), Unwrap(swapchain), counter, pCounterValue); }
VkResult WrappedVulkan::vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties) { return ObjDisp(physicalDevice) ->GetPhysicalDeviceDisplayPropertiesKHR(Unwrap(physicalDevice), pPropertyCount, pProperties); }
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, and render to it for the text overlay unwrapped[i].imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_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; }
void WrappedVulkan::vkDestroyDebugReportCallbackEXT( VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) { return ObjDisp(instance)->DestroyDebugReportCallbackEXT(Unwrap(instance), callback, pAllocator); }
VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) { return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfaceCapabilitiesKHR(Unwrap(physicalDevice), Unwrap(surface), pSurfaceCapabilities); }
bool WrappedVulkan::Serialise_vkCreateFence( Serialiser* localSerialiser, VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkFenceCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFence)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkFence fence = VK_NULL_HANDLE; VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, NULL, &fence); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence); GetResourceManager()->AddLiveResource(id, fence); } } return true; }
void WrappedVulkan::vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) { ObjDisp(physicalDevice) ->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), format, pFormatProperties); }
void WrappedVulkan::vkGetImageSparseMemoryRequirements( VkDevice device, VkImage image, uint32_t *pNumRequirements, VkSparseImageMemoryRequirements *pSparseMemoryRequirements) { ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(image), pNumRequirements, pSparseMemoryRequirements); }
VkResult WrappedVulkan::vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { return ObjDisp(device)->AcquireNextImageKHR(Unwrap(device), Unwrap(swapchain), timeout, Unwrap(semaphore), Unwrap(fence), pImageIndex); }
VkResult WrappedVulkan::vkBindBufferMemory( VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset) { VkResourceRecord *record = GetRecord(buffer); if(m_State >= WRITING) { Chunk *chunk = NULL; { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_MEM); Serialise_vkBindBufferMemory(localSerialiser, device, buffer, mem, memOffset); chunk = scope.Get(); } // memory object bindings are immutable and must happen before creation or use, // so this can always go into the record, even if a resource is created and bound // to memory mid-frame record->AddChunk(chunk); record->AddParent(GetRecord(mem)); record->baseResource = GetResID(mem); } return ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), memOffset); }
void WrappedVulkan::vkFreeMemory( VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator) { // we just need to clean up after ourselves on replay WrappedVkNonDispRes *wrapped = (WrappedVkNonDispRes *)GetWrapped(memory); VkDeviceMemory unwrappedMem = wrapped->real.As<VkDeviceMemory>(); if(m_State >= WRITING) { // there is an implicit unmap on free, so make sure to tidy up if(wrapped->record->memMapState && wrapped->record->memMapState->refData) Serialiser::FreeAlignedBuffer(wrapped->record->memMapState->refData); { SCOPED_LOCK(m_CoherentMapsLock); auto it = std::find(m_CoherentMaps.begin(), m_CoherentMaps.end(), wrapped->record); if(it != m_CoherentMaps.end()) m_CoherentMaps.erase(it); } } GetResourceManager()->ReleaseWrappedResource(memory); ObjDisp(device)->FreeMemory(Unwrap(device), unwrappedMem, pAllocator); }
VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats) { return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(physicalDevice), Unwrap(surface), pSurfaceFormatCount, pSurfaceFormats); }
VkResult WrappedVulkan::vkGetPhysicalDeviceSurfacePresentModesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes) { return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(physicalDevice), Unwrap(surface), pPresentModeCount, pPresentModes); }
void WrappedVulkan::vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) { RDCASSERT(m_Instance == instance); if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE) ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL); // the device should already have been destroyed, assuming that the // application is well behaved. If not, we just leak. ObjDisp(m_Instance)->DestroyInstance(Unwrap(m_Instance), NULL); GetResourceManager()->ReleaseWrappedResource(m_Instance); RenderDoc::Inst().RemoveDeviceFrameCapturer(LayerDisp(m_Instance)); m_Instance = VK_NULL_HANDLE; }