예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
bool WrappedVulkan::Serialise_vkCreateRenderPass(
			Serialiser*                                 localSerialiser,
			VkDevice                                    device,
			const VkRenderPassCreateInfo*               pCreateInfo,
			const VkAllocationCallbacks*                pAllocator,
			VkRenderPass*                               pRenderPass)
{
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
	SERIALISE_ELEMENT(VkRenderPassCreateInfo, info, *pCreateInfo);
	SERIALISE_ELEMENT(ResourceId, id, GetResID(*pRenderPass));

	if(m_State == READING)
	{
		device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
		VkRenderPass rp = VK_NULL_HANDLE;

		VulkanCreationInfo::RenderPass rpinfo;
		rpinfo.Init(GetResourceManager(), m_CreationInfo, &info);

		// we want to store off the data so we can display it after the pass.
		// override any user-specified DONT_CARE.
		VkAttachmentDescription *att = (VkAttachmentDescription *)info.pAttachments;
		for(uint32_t i=0; i < info.attachmentCount; i++)
		{
			att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
			att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;

			// renderpass can't start or end in presentable layout on replay
			ReplacePresentableImageLayout(att[i].initialLayout);
			ReplacePresentableImageLayout(att[i].finalLayout);
		}

		VkResult ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rp);

		if(ret != VK_SUCCESS)
		{
			RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret);
		}
		else
		{
			ResourceId live;

			if(GetResourceManager()->HasWrapper(ToTypedHandle(rp)))
			{
				live = GetResourceManager()->GetNonDispWrapper(rp)->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)->DestroyRenderPass(Unwrap(device), rp, 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), rp);
				GetResourceManager()->AddLiveResource(id, rp);

				// make a version of the render pass that loads from its attachments,
				// so it can be used for replaying a single draw after a render pass
				// without doing a clear or a DONT_CARE load.
				for(uint32_t i=0; i < info.attachmentCount; i++)
				{
					att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
					att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
				}

				ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRP);
				RDCASSERTEQUAL(ret, VK_SUCCESS);
				
				// handle the loadRP being a duplicate
				if(GetResourceManager()->HasWrapper(ToTypedHandle(rpinfo.loadRP)))
				{
					// just fetch the existing wrapped object
					rpinfo.loadRP = (VkRenderPass)(uint64_t)GetResourceManager()->GetNonDispWrapper(rpinfo.loadRP);

					// 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)->DestroyRenderPass(Unwrap(device), rpinfo.loadRP, NULL);

					// don't need to ReplaceResource as no IDs are involved
				}
				else
				{
					ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRP);

					// register as a live-only resource, so it is cleaned up properly
					GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRP);
				}
				
				m_CreationInfo.m_RenderPass[live] = rpinfo;
			}
		}
	}

	return true;
}
예제 #4
0
bool WrappedVulkan::ReleaseResource(WrappedVkRes *res)
{
	if(res == NULL) return true;

	// MULTIDEVICE need to get the actual device that created this object
	VkDevice dev = GetDev();
	const VkLayerDispatchTable *vt = ObjDisp(dev);

	WrappedVkNonDispRes *nondisp = (WrappedVkNonDispRes *)res;
	WrappedVkDispRes *disp = (WrappedVkDispRes *)res;
	uint64_t handle = (uint64_t)nondisp;

	switch(IdentifyTypeByPtr(res))
	{
		case eResSurface:
		case eResSwapchain:
			if(m_State >= WRITING)
				RDCERR("Swapchain/swapchain object is leaking");
			else
				RDCERR("Should be no swapchain/surface objects created on replay");
			break;

		case eResUnknown:
			RDCERR("Unknown resource type!");
			break;
			
		case eResCommandBuffer:
			// special case here, on replay we don't have the tracking
			// to remove these with the parent object so do it here.
			// This ensures we clean up after ourselves with a well-
			// behaved application.
			if(m_State < WRITING)
				GetResourceManager()->ReleaseWrappedResource((VkCommandBuffer)res);
			break;
		case eResDescriptorSet:
			if(m_State < WRITING)
				GetResourceManager()->ReleaseWrappedResource(VkDescriptorSet(handle));
			break;
		case eResPhysicalDevice:
			if(m_State < WRITING)
				GetResourceManager()->ReleaseWrappedResource((VkPhysicalDevice)disp);
			break;
		case eResQueue:
			if(m_State < WRITING)
				GetResourceManager()->ReleaseWrappedResource((VkQueue)disp);
			break;
			
		case eResDevice:
			// these are explicitly released elsewhere, do not need to destroy
			// any API objects.
			// On replay though we do need to tidy up book-keeping for these.
			if(m_State < WRITING)
			{
				GetResourceManager()->ReleaseCurrentResource(disp->id);
				GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As<VkDevice>()));
			}
			break;
		case eResInstance:
			if(m_State < WRITING)
			{
				GetResourceManager()->ReleaseCurrentResource(disp->id);
				GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As<VkInstance>()));
			}
			break;

		case eResDeviceMemory:
		{
			VkDeviceMemory real = nondisp->real.As<VkDeviceMemory>();
			GetResourceManager()->ReleaseWrappedResource(VkDeviceMemory(handle));
			vt->FreeMemory(Unwrap(dev), real, NULL);
			break;
		}
		case eResBuffer:
		{
			VkBuffer real = nondisp->real.As<VkBuffer>();
			GetResourceManager()->ReleaseWrappedResource(VkBuffer(handle));
			vt->DestroyBuffer(Unwrap(dev), real, NULL);
			break;
		}
		case eResBufferView:
		{
			VkBufferView real = nondisp->real.As<VkBufferView>();
			GetResourceManager()->ReleaseWrappedResource(VkBufferView(handle));
			vt->DestroyBufferView(Unwrap(dev), real, NULL);
			break;
		}
		case eResImage:
		{
			VkImage real = nondisp->real.As<VkImage>();
			GetResourceManager()->ReleaseWrappedResource(VkImage(handle));
			vt->DestroyImage(Unwrap(dev), real, NULL);
			break;
		}
		case eResImageView:
		{
			VkImageView real = nondisp->real.As<VkImageView>();
			GetResourceManager()->ReleaseWrappedResource(VkImageView(handle));
			vt->DestroyImageView(Unwrap(dev), real, NULL);
			break;
		}
		case eResFramebuffer:
		{
			VkFramebuffer real = nondisp->real.As<VkFramebuffer>();
			GetResourceManager()->ReleaseWrappedResource(VkFramebuffer(handle));
			vt->DestroyFramebuffer(Unwrap(dev), real, NULL);
			break;
		}
		case eResRenderPass:
		{
			VkRenderPass real = nondisp->real.As<VkRenderPass>();
			GetResourceManager()->ReleaseWrappedResource(VkRenderPass(handle));
			vt->DestroyRenderPass(Unwrap(dev), real, NULL);
			break;
		}
		case eResShaderModule:
		{
			VkShaderModule real = nondisp->real.As<VkShaderModule>();
			GetResourceManager()->ReleaseWrappedResource(VkShaderModule(handle));
			vt->DestroyShaderModule(Unwrap(dev), real, NULL);
			break;
		}
		case eResPipelineCache:
		{
			VkPipelineCache real = nondisp->real.As<VkPipelineCache>();
			GetResourceManager()->ReleaseWrappedResource(VkPipelineCache(handle));
			vt->DestroyPipelineCache(Unwrap(dev), real, NULL);
			break;
		}
		case eResPipelineLayout:
		{
			VkPipelineLayout real = nondisp->real.As<VkPipelineLayout>();
			GetResourceManager()->ReleaseWrappedResource(VkPipelineLayout(handle));
			vt->DestroyPipelineLayout(Unwrap(dev), real, NULL);
			break;
		}
		case eResPipeline:
		{
			VkPipeline real = nondisp->real.As<VkPipeline>();
			GetResourceManager()->ReleaseWrappedResource(VkPipeline(handle));
			vt->DestroyPipeline(Unwrap(dev), real, NULL);
			break;
		}
		case eResSampler:
		{
			VkSampler real = nondisp->real.As<VkSampler>();
			GetResourceManager()->ReleaseWrappedResource(VkSampler(handle));
			vt->DestroySampler(Unwrap(dev), real, NULL);
			break;
		}
		case eResDescriptorPool:
		{
			VkDescriptorPool real = nondisp->real.As<VkDescriptorPool>();
			GetResourceManager()->ReleaseWrappedResource(VkDescriptorPool(handle));
			vt->DestroyDescriptorPool(Unwrap(dev), real, NULL);
			break;
		}
		case eResDescriptorSetLayout:
		{
			VkDescriptorSetLayout real = nondisp->real.As<VkDescriptorSetLayout>();
			GetResourceManager()->ReleaseWrappedResource(VkDescriptorSetLayout(handle));
			vt->DestroyDescriptorSetLayout(Unwrap(dev), real, NULL);
			break;
		}
		case eResCommandPool:
		{
			VkCommandPool real = nondisp->real.As<VkCommandPool>();
			GetResourceManager()->ReleaseWrappedResource(VkCommandPool(handle));
			vt->DestroyCommandPool(Unwrap(dev), real, NULL);
			break;
		}
		case eResFence:
		{
			VkFence real = nondisp->real.As<VkFence>();
			GetResourceManager()->ReleaseWrappedResource(VkFence(handle));
			vt->DestroyFence(Unwrap(dev), real, NULL);
			break;
		}
		case eResEvent:
		{
			VkEvent real = nondisp->real.As<VkEvent>();
			GetResourceManager()->ReleaseWrappedResource(VkEvent(handle));
			vt->DestroyEvent(Unwrap(dev), real, NULL);
			break;
		}
		case eResQueryPool:
		{
			VkQueryPool real = nondisp->real.As<VkQueryPool>();
			GetResourceManager()->ReleaseWrappedResource(VkQueryPool(handle));
			vt->DestroyQueryPool(Unwrap(dev), real, NULL);
			break;
		}
		case eResSemaphore:
		{
			VkSemaphore real = nondisp->real.As<VkSemaphore>();
			GetResourceManager()->ReleaseWrappedResource(VkSemaphore(handle));
			vt->DestroySemaphore(Unwrap(dev), real, NULL);
			break;
		}
	}

	return true;
}