void WrappedVulkan::vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { ObjDisp(device)->GetDeviceQueue(Unwrap(device), queueFamilyIndex, queueIndex, pQueue); if(m_SetDeviceLoaderData) m_SetDeviceLoaderData(m_Device, *pQueue); else SetDispatchTableOverMagicNumber(device, *pQueue); RDCASSERT(m_State >= WRITING); { // it's perfectly valid for enumerate type functions to return the same handle // each time. If that happens, we will already have a wrapper created so just // return the wrapped object to the user and do nothing else if(m_QueueFamilies[queueFamilyIndex][queueIndex] != VK_NULL_HANDLE) { *pQueue = m_QueueFamilies[queueFamilyIndex][queueIndex]; } else { ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pQueue); { Chunk *chunk = NULL; { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(GET_DEVICE_QUEUE); Serialise_vkGetDeviceQueue(localSerialiser, device, queueFamilyIndex, queueIndex, pQueue); chunk = scope.Get(); } VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pQueue); RDCASSERT(record); VkResourceRecord *instrecord = GetRecord(m_Instance); // treat queues as pool members of the instance (ie. freed when the instance dies) { instrecord->LockChunks(); instrecord->pooledChildren.push_back(record); instrecord->UnlockChunks(); } record->AddChunk(chunk); } m_QueueFamilies[queueFamilyIndex][queueIndex] = *pQueue; if(queueFamilyIndex == m_QueueFamilyIdx) { m_Queue = *pQueue; // we can now submit any cmds that were queued (e.g. from creating debug // manager on vkCreateDevice) SubmitCmds(); } } } }
VkResult WrappedVulkan::vkEnumeratePhysicalDevices( VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) { uint32_t count; VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL); if(vkr != VK_SUCCESS) return vkr; VkPhysicalDevice *devices = new VkPhysicalDevice[count]; vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices); RDCASSERTEQUAL(vkr, VK_SUCCESS); m_PhysicalDevices.resize(count); for(uint32_t i=0; i < count; i++) { // it's perfectly valid for enumerate type functions to return the same handle // each time. If that happens, we will already have a wrapper created so just // return the wrapped object to the user and do nothing else if(m_PhysicalDevices[i] != VK_NULL_HANDLE) { GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]); devices[i] = m_PhysicalDevices[i]; } else { GetResourceManager()->WrapResource(instance, devices[i]); if(m_State >= WRITING) { // add the record first since it's used in the serialise function below to fetch // the memory indices VkResourceRecord *record = GetResourceManager()->AddResourceRecord(devices[i]); RDCASSERT(record); record->memProps = new VkPhysicalDeviceMemoryProperties(); ObjDisp(devices[i])->GetPhysicalDeviceMemoryProperties(Unwrap(devices[i]), record->memProps); m_PhysicalDevices[i] = devices[i]; // we remap memory indices to discourage coherent maps as much as possible RemapMemoryIndices(record->memProps, &record->memIdxMap); { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(ENUM_PHYSICALS); Serialise_vkEnumeratePhysicalDevices(localSerialiser, instance, &i, &devices[i]); record->AddChunk(scope.Get()); } VkResourceRecord *instrecord = GetRecord(instance); instrecord->AddParent(record); // treat physical devices as pool members of the instance (ie. freed when the instance dies) { instrecord->LockChunks(); instrecord->pooledChildren.push_back(record); instrecord->UnlockChunks(); } } } } if(pPhysicalDeviceCount) *pPhysicalDeviceCount = count; if(pPhysicalDevices) memcpy(pPhysicalDevices, devices, count*sizeof(VkPhysicalDevice)); SAFE_DELETE_ARRAY(devices); return VK_SUCCESS; }
VkResult WrappedVulkan::vkAllocateDescriptorSets( VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets) { size_t tempmemSize = sizeof(VkDescriptorSetAllocateInfo) + sizeof(VkDescriptorSetLayout)*pAllocateInfo->descriptorSetCount; byte *memory = GetTempMemory(tempmemSize); VkDescriptorSetAllocateInfo *unwrapped = (VkDescriptorSetAllocateInfo *)memory; VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)(unwrapped + 1); *unwrapped = *pAllocateInfo; unwrapped->pSetLayouts = layouts; unwrapped->descriptorPool = Unwrap(unwrapped->descriptorPool); for(uint32_t i=0; i < pAllocateInfo->descriptorSetCount; i++) layouts[i] = Unwrap(pAllocateInfo->pSetLayouts[i]); VkResult ret = ObjDisp(device)->AllocateDescriptorSets(Unwrap(device), unwrapped, pDescriptorSets); if(ret != VK_SUCCESS) return ret; for(uint32_t i=0; i < pAllocateInfo->descriptorSetCount; i++) { ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pDescriptorSets[i]); if(m_State >= WRITING) { Chunk *chunk = NULL; { CACHE_THREAD_SERIALISER(); VkDescriptorSetAllocateInfo info = *pAllocateInfo; info.descriptorSetCount = 1; info.pSetLayouts += i; SCOPED_SERIALISE_CONTEXT(ALLOC_DESC_SET); Serialise_vkAllocateDescriptorSets(localSerialiser, device, &info, &pDescriptorSets[i]); chunk = scope.Get(); } VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pDescriptorSets[i]); record->AddChunk(chunk); ResourceId layoutID = GetResID(pAllocateInfo->pSetLayouts[i]); VkResourceRecord *layoutRecord = GetRecord(pAllocateInfo->pSetLayouts[i]); VkResourceRecord *poolrecord = GetRecord(pAllocateInfo->descriptorPool); { poolrecord->LockChunks(); poolrecord->pooledChildren.push_back(record); poolrecord->UnlockChunks(); } record->pool = poolrecord; record->AddParent(poolrecord); record->AddParent(GetResourceManager()->GetResourceRecord(layoutID)); // just always treat descriptor sets as dirty { SCOPED_LOCK(m_CapTransitionLock); if(m_State != WRITING_CAPFRAME) GetResourceManager()->MarkDirtyResource(id); else GetResourceManager()->MarkPendingDirty(id); } record->descInfo = new DescriptorSetData(); record->descInfo->layout = layoutRecord->descInfo->layout; record->descInfo->layout->CreateBindingsArray(record->descInfo->descBindings); } else { GetResourceManager()->AddLiveResource(id, pDescriptorSets[i]); } } return ret; }