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; }
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; }
bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR( Serialiser* localSerialiser, VkDevice device, VkSwapchainKHR swapchain, uint32_t* pCount, VkImage* pSwapchainImages) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(ResourceId, swapId, GetResID(swapchain)); SERIALISE_ELEMENT(uint32_t, idx, *pCount); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapchainImages)); if(m_State == READING) { // use original ID because we don't create a live version of the swapchain auto &swapInfo = m_CreationInfo.m_SwapChain[swapId]; RDCASSERT(idx < swapInfo.images.size(), idx, swapInfo.images.size()); GetResourceManager()->AddLiveResource(id, swapInfo.images[idx].im); m_CreationInfo.m_Image[GetResID(swapInfo.images[idx].im)] = m_CreationInfo.m_Image[swapId]; } 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; }
vector<ResourceId> D3D12RenderState::GetRTVIDs() const { vector<ResourceId> ret; if(rtSingle) { if(!rts.empty()) { const D3D12Descriptor *descs = DescriptorFromPortableHandle(GetResourceManager(), rts[0]); for(UINT i = 0; i < rts.size(); i++) { RDCASSERT(descs[i].GetType() == D3D12Descriptor::TypeRTV); ret.push_back(GetResID(descs[i].nonsamp.resource)); } } } else { for(UINT i = 0; i < rts.size(); i++) { WrappedID3D12DescriptorHeap *heap = GetResourceManager()->GetLiveAs<WrappedID3D12DescriptorHeap>(rts[0].heap); const D3D12Descriptor &desc = heap->GetDescriptors()[rts[i].index]; RDCASSERT(desc.GetType() == D3D12Descriptor::TypeRTV); ret.push_back(GetResID(desc.nonsamp.resource)); } } return ret; }
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 D3D12Descriptor::GetRefIDs(ResourceId &id, ResourceId &id2, FrameRefType &ref) { id = ResourceId(); id2 = ResourceId(); ref = eFrameRef_Read; switch(GetType()) { case D3D12Descriptor::TypeUndefined: case D3D12Descriptor::TypeSampler: // nothing to do - no resource here break; case D3D12Descriptor::TypeCBV: id = WrappedID3D12Resource::GetResIDFromAddr(nonsamp.cbv.BufferLocation); break; case D3D12Descriptor::TypeSRV: id = GetResID(nonsamp.resource); break; case D3D12Descriptor::TypeUAV: id2 = GetResID(nonsamp.uav.counterResource); // deliberate fall-through case D3D12Descriptor::TypeRTV: case D3D12Descriptor::TypeDSV: ref = eFrameRef_Write; id = GetResID(nonsamp.resource); break; } }
VkResult WrappedVulkan::vkFlushMappedMemoryRanges( VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) { if(m_State >= WRITING) { bool capframe = false; { SCOPED_LOCK(m_CapTransitionLock); capframe = (m_State == WRITING_CAPFRAME); } for(uint32_t i = 0; i < memRangeCount; i++) { ResourceId memid = GetResID(pMemRanges[i].memory); MemMapState *state = GetRecord(pMemRanges[i].memory)->memMapState; state->mapFlushed = true; if(state->mappedPtr == NULL) { RDCERR("Flushing memory that isn't currently mapped"); continue; } if(capframe) { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(FLUSH_MEM); Serialise_vkFlushMappedMemoryRanges(localSerialiser, device, 1, pMemRanges + i); m_FrameCaptureRecord->AddChunk(scope.Get()); GetResourceManager()->MarkResourceFrameReferenced(GetResID(pMemRanges[i].memory), eFrameRef_Write); } else { GetResourceManager()->MarkDirtyResource(memid); } } } VkMappedMemoryRange *unwrapped = GetTempArray<VkMappedMemoryRange>(memRangeCount); for(uint32_t i=0; i < memRangeCount; i++) { unwrapped[i] = pMemRanges[i]; unwrapped[i].memory = Unwrap(unwrapped[i].memory); } VkResult ret = ObjDisp(device)->FlushMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped); return ret; }
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; }
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; }
void D3D12ResourceManager::ApplyBarriers(vector<D3D12_RESOURCE_BARRIER> &barriers, map<ResourceId, SubresourceStateVector> &states) { for(size_t b = 0; b < barriers.size(); b++) { D3D12_RESOURCE_TRANSITION_BARRIER &trans = barriers[b].Transition; ResourceId id = GetResID(trans.pResource); SubresourceStateVector &st = states[id]; // skip non-transitions, or begin-halves of transitions if(barriers[b].Type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION || (barriers[b].Flags & D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY)) continue; if(trans.Subresource == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) { for(size_t i = 0; i < st.size(); i++) { BARRIER_ASSERT("Mismatching before state", st[i] == trans.StateBefore, st[i], trans.StateBefore, i); st[i] = trans.StateAfter; } } else { BARRIER_ASSERT("Mismatching before state", st[trans.Subresource] == trans.StateBefore, st[trans.Subresource], trans.StateBefore, trans.Subresource); st[trans.Subresource] = trans.StateAfter; } } }
PortableHandle ToPortableHandle(D3D12Descriptor *desc) { if(desc == NULL) return PortableHandle(0); return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx); }
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); }
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_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 WrappedID3D12Device::Serialise_CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *pDesc, ID3D12RootSignature *pRootSignature, REFIID riid, void **ppvCommandSignature) { SERIALISE_ELEMENT(D3D12_COMMAND_SIGNATURE_DESC, desc, *pDesc); SERIALISE_ELEMENT(ResourceId, RootSig, GetResID(pRootSignature)); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, CommandSig, ((WrappedID3D12CommandSignature *)*ppvCommandSignature)->GetResourceID()); if(m_State == READING) { pRootSignature = NULL; if(RootSig != ResourceId()) pRootSignature = GetResourceManager()->GetLiveAs<ID3D12RootSignature>(RootSig); ID3D12CommandSignature *ret = NULL; HRESULT hr = m_pDevice->CreateCommandSignature(&desc, pRootSignature, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12CommandSignature(ret, this); GetResourceManager()->AddLiveResource(CommandSig, ret); } } return true; }
bool WrappedVulkan::Serialise_vkResetEvent( Serialiser* localSerialiser, VkDevice device, VkEvent event) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); Serialise_DebugMessages(localSerialiser, false); if(m_State < WRITING) { // see top of this file for current event/fence handling } return true; }
void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferViewCreateInfo *pCreateInfo) { buffer = GetResID(pCreateInfo->buffer); offset = pCreateInfo->offset; size = pCreateInfo->range; }
void VulkanResourceManager::MarkSparseMapReferenced(SparseMapping *sparse) { if(sparse == NULL) { RDCERR("Unexpected NULL sparse mapping"); return; } for(size_t i = 0; i < sparse->opaquemappings.size(); i++) MarkResourceFrameReferenced(GetResID(sparse->opaquemappings[i].memory), eFrameRef_Read); for(int a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) for(VkDeviceSize i = 0; sparse->pages[a] && i < VkDeviceSize(sparse->imgdim.width * sparse->imgdim.height * sparse->imgdim.depth); i++) MarkResourceFrameReferenced(GetResID(sparse->pages[a][i].first), eFrameRef_Read); }
bool WrappedVulkan::Serialise_vkGetEventStatus( Serialiser* localSerialiser, VkDevice device, VkEvent event) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); Serialise_DebugMessages(localSerialiser, false); if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(id); ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); } return true; }
// needs to be separate so we don't erase from m_ImageLayouts in other destroy functions void WrappedVulkan::vkDestroyImage(VkDevice device, VkImage obj, const VkAllocationCallbacks* pAllocator) { { SCOPED_LOCK(m_ImageLayoutsLock); m_ImageLayouts.erase(GetResID(obj)); } VkImage unwrappedObj = Unwrap(obj); GetResourceManager()->ReleaseWrappedResource(obj, true); return ObjDisp(device)->DestroyImage(Unwrap(device), unwrappedObj, pAllocator); }
bool WrappedID3D12Device::Serialise_CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, void **ppvResource) { SERIALISE_ELEMENT(ResourceId, Heap, GetResID(pHeap)); SERIALISE_ELEMENT(UINT64, Offset, HeapOffset); SERIALISE_ELEMENT(D3D12_RESOURCE_DESC, desc, *pDesc); SERIALISE_ELEMENT(D3D12_RESOURCE_STATES, state, InitialState); SERIALISE_ELEMENT(bool, HasClearValue, pOptimizedClearValue != NULL); SERIALISE_ELEMENT_OPT(D3D12_CLEAR_VALUE, clearVal, *pOptimizedClearValue, HasClearValue); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()); if(m_State == READING) { pHeap = GetResourceManager()->GetLiveAs<ID3D12Heap>(Heap); pOptimizedClearValue = HasClearValue ? &clearVal : NULL; ID3D12Resource *ret = NULL; HRESULT hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), Offset, &desc, state, pOptimizedClearValue, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12Resource(ret, this); GetResourceManager()->AddLiveResource(Res, ret); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; states.resize(GetNumSubresources(&desc), state); } } return true; }
VkResult WrappedVulkan::vkMapMemory( VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) { void *realData = NULL; VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), offset, size, flags, &realData); if(ret == VK_SUCCESS && realData) { ResourceId id = GetResID(mem); if(m_State >= WRITING) { VkResourceRecord *memrecord = GetRecord(mem); // must have map state, only non host visible memories have no map // state, and they can't be mapped! RDCASSERT(memrecord->memMapState); MemMapState &state = *memrecord->memMapState; // ensure size is valid RDCASSERT(size == VK_WHOLE_SIZE || (size > 0 && size <= memrecord->Length)); state.mappedPtr = (byte *)realData; state.refData = NULL; state.mapOffset = offset; state.mapSize = size == VK_WHOLE_SIZE ? memrecord->Length : size; state.mapFlushed = false; *ppData = realData; if(state.mapCoherent) { SCOPED_LOCK(m_CoherentMapsLock); m_CoherentMaps.push_back(memrecord); } } else { *ppData = realData; } } else { *ppData = NULL; } return ret; }
bool WrappedVulkan::Serialise_vkDeviceWaitIdle(Serialiser* localSerialiser, VkDevice device) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(id); ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); } return true; }
bool WrappedVulkan::Serialise_vkCreateBuffer( Serialiser* localSerialiser, VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkBufferCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pBuffer)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkBuffer buf = VK_NULL_HANDLE; VkBufferUsageFlags origusage = info.usage; // ensure we can always readback from buffers info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &info, NULL, &buf); info.usage = origusage; if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf); GetResourceManager()->AddLiveResource(id, buf); m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &info); } } return true; }
bool WrappedVulkan::Serialise_vkUnmapMemory( Serialiser* localSerialiser, VkDevice device, VkDeviceMemory mem) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(ResourceId, id, GetResID(mem)); MemMapState *state; if(m_State >= WRITING) state = GetRecord(mem)->memMapState; SERIALISE_ELEMENT(uint64_t, memOffset, state->mapOffset); SERIALISE_ELEMENT(uint64_t, memSize, state->mapSize); SERIALISE_ELEMENT_BUF(byte*, data, (byte *)state->mappedPtr + state->mapOffset, (size_t)memSize); if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); mem = GetResourceManager()->GetLiveHandle<VkDeviceMemory>(id); void *mapPtr = NULL; VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); if(ret != VK_SUCCESS) { RDCERR("Error mapping memory on replay: 0x%08x", ret); } else { memcpy((byte *)mapPtr, data, (size_t)memSize); ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); } SAFE_DELETE_ARRAY(data); } return true; }
HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::Signal(ID3D12Fence *pFence, UINT64 Value) { if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(SIGNAL); Serialise_Signal(pFence, Value); m_QueueRecord->AddChunk(scope.Get()); GetResourceManager()->MarkResourceFrameReferenced(GetResID(pFence), eFrameRef_Read); } return m_pReal->Signal(Unwrap(pFence), Value); }
ResourceId D3D12RenderState::GetDSVID() const { if(dsv.heap != ResourceId()) { const D3D12Descriptor *desc = DescriptorFromPortableHandle(GetResourceManager(), dsv); RDCASSERT(desc->GetType() == D3D12Descriptor::TypeDSV); return GetResID(desc->nonsamp.resource); } return ResourceId(); }
bool WrappedVulkan::Serialise_vkResetFences( Serialiser* localSerialiser, VkDevice device, uint32_t fenceCount, const VkFence* pFences) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); SERIALISE_ELEMENT(uint32_t, count, fenceCount); Serialise_DebugMessages(localSerialiser, false); vector<VkFence> fences; for(uint32_t i=0; i < count; i++) { ResourceId fence; if(m_State >= WRITING) fence = GetResID(pFences[i]); localSerialiser->Serialise("pFences[]", fence); if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle<VkFence>(fence))); } if(m_State < WRITING && !fences.empty()) { // we don't care about fence states ourselves as we cannot record them perfectly and just // do full waitidle flushes. device = GetResourceManager()->GetLiveHandle<VkDevice>(id); // since we don't have anything signalling or waiting on fences, don't bother to reset them // either //ObjDisp(device)->ResetFences(Unwrap(device), (uint32_t)fences.size(), &fences[0]); } return true; }
bool WrappedVulkan::Serialise_vkWaitForFences( Serialiser* localSerialiser, VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); SERIALISE_ELEMENT(VkBool32, wait, waitAll); SERIALISE_ELEMENT(uint64_t, tmout, timeout); SERIALISE_ELEMENT(uint32_t, count, fenceCount); Serialise_DebugMessages(localSerialiser, false); vector<VkFence> fences; for(uint32_t i=0; i < count; i++) { ResourceId fence; if(m_State >= WRITING) fence = GetResID(pFences[i]); localSerialiser->Serialise("pFences[]", fence); if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle<VkFence>(fence))); } if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(id); ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); } return true; }