Beispiel #1
0
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();
      }
    }
  }
}
Beispiel #2
0
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;
}