Exemple #1
0
VkFormat VkHelper::findSupportedFormat(VkPhysicalDevice physicalDevice, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
{
	for (auto format : candidates)
	{
		VkFormatProperties props;
		vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
		if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features)
			return format;
		else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features)
			return format;
	}

	throw std::runtime_error("ERROR: Failed to find supported format.");

	return VkFormat();
}
bool WrappedVulkan::Serialise_vkCreateDevice(
		Serialiser*                                 localSerialiser,
		VkPhysicalDevice                            physicalDevice,
		const VkDeviceCreateInfo*                   pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
		VkDevice*                                   pDevice)
{
	SERIALISE_ELEMENT(ResourceId, physId, GetResID(physicalDevice));
	SERIALISE_ELEMENT(VkDeviceCreateInfo, serCreateInfo, *pCreateInfo);
	SERIALISE_ELEMENT(ResourceId, devId, GetResID(*pDevice));

	if(m_State == READING)
	{
		// we must make any modifications locally, so the free of pointers
		// in the serialised VkDeviceCreateInfo don't double-free
		VkDeviceCreateInfo createInfo = serCreateInfo;
		
		std::vector<string> Extensions;
		for(uint32_t i=0; i < createInfo.enabledExtensionCount; i++)
		{
			// don't include the debug marker extension
			if(strcmp(createInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME))
				Extensions.push_back(createInfo.ppEnabledExtensionNames[i]);
		}

		std::vector<string> Layers;
		for(uint32_t i=0; i < createInfo.enabledLayerCount; i++)
			Layers.push_back(createInfo.ppEnabledLayerNames[i]);

		StripUnwantedLayers(Layers);

		AddRequiredExtensions(false, Extensions);
		
#if defined(FORCE_VALIDATION_LAYERS)
		Layers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif

		createInfo.enabledLayerCount = (uint32_t)Layers.size();

		const char **layerArray = NULL;
		if(!Layers.empty())
		{
			layerArray = new const char *[createInfo.enabledLayerCount];
			
			for(uint32_t i=0; i < createInfo.enabledLayerCount; i++)
				layerArray[i] = Layers[i].c_str();

			createInfo.ppEnabledLayerNames = layerArray;
		}

		createInfo.enabledExtensionCount = (uint32_t)Extensions.size();

		const char **extArray = NULL;
		if(!Extensions.empty())
		{
			extArray = new const char *[createInfo.enabledExtensionCount];
			
			for(uint32_t i=0; i < createInfo.enabledExtensionCount; i++)
				extArray[i] = Extensions[i].c_str();

			createInfo.ppEnabledExtensionNames = extArray;
		}

		physicalDevice = GetResourceManager()->GetLiveHandle<VkPhysicalDevice>(physId);

		VkDevice device;

		uint32_t qCount = 0;
		ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL);

		VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount];
		ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props);

		bool found = false;
		uint32_t qFamilyIdx = 0;
		VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT);

		// for queue priorities, if we need it
		float one = 1.0f;

		// if we need to change the requested queues, it will point to this
		VkDeviceQueueCreateInfo *modQueues = NULL;

		for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++)
		{
			uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex;
			RDCASSERT(idx < qCount);

			// this requested queue is one we can use too
			if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0)
			{
				qFamilyIdx = idx;
				found = true;
				break;
			}
		}

		// if we didn't find it, search for which queue family we should add a request for
		if(!found)
		{
			RDCDEBUG("App didn't request a queue family we can use - adding our own");

			for(uint32_t i=0; i < qCount; i++)
			{
				if((props[i].queueFlags & search) == search)
				{
					qFamilyIdx = i;
					found = true;
					break;
				}
			}

			if(!found)
			{
				SAFE_DELETE_ARRAY(props);
				RDCERR("Can't add a queue with required properties for RenderDoc! Unsupported configuration");
			}
			else
			{
				// we found the queue family, add it
				modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1];
				for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++)
					modQueues[i] = createInfo.pQueueCreateInfos[i];

				modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx;
				modQueues[createInfo.queueCreateInfoCount].queueCount = 1;
				modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one;

				createInfo.pQueueCreateInfos = modQueues;
				createInfo.queueCreateInfoCount++;
			}
		}
		
		SAFE_DELETE_ARRAY(props);

		VkPhysicalDeviceFeatures enabledFeatures = {0};
		if(createInfo.pEnabledFeatures != NULL) enabledFeatures = *createInfo.pEnabledFeatures;
		createInfo.pEnabledFeatures = &enabledFeatures;

		VkPhysicalDeviceFeatures availFeatures = {0};
		ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &availFeatures);

		if(availFeatures.fillModeNonSolid)
			enabledFeatures.fillModeNonSolid = true;
		else
			RDCWARN("fillModeNonSolid = false, wireframe overlay will be solid");
		
		if(availFeatures.robustBufferAccess)
			enabledFeatures.robustBufferAccess = true;
		else
			RDCWARN("robustBufferAccess = false, out of bounds access due to bugs in application or RenderDoc may cause crashes");

		if(availFeatures.vertexPipelineStoresAndAtomics)
			enabledFeatures.vertexPipelineStoresAndAtomics = true;
		else
			RDCWARN("vertexPipelineStoresAndAtomics = false, output mesh data will not be available");

		uint32_t numExts = 0;

		VkResult vkr = ObjDisp(physicalDevice)->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, NULL);
		RDCASSERTEQUAL(vkr, VK_SUCCESS);

		VkExtensionProperties *exts = new VkExtensionProperties[numExts];

		vkr = ObjDisp(physicalDevice)->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, exts);
		RDCASSERTEQUAL(vkr, VK_SUCCESS);

		for(uint32_t i=0; i < numExts; i++)
			RDCLOG("Ext %u: %s (%u)", i, exts[i].extensionName, exts[i].specVersion);

		SAFE_DELETE_ARRAY(exts);

		// PORTABILITY check that extensions and layers supported in capture (from createInfo) are supported in replay

		vkr = GetDeviceDispatchTable(NULL)->CreateDevice(Unwrap(physicalDevice), &createInfo, NULL, &device);
		RDCASSERTEQUAL(vkr, VK_SUCCESS);

		GetResourceManager()->WrapResource(device, device);
		GetResourceManager()->AddLiveResource(devId, device);
		
		InitDeviceReplayTables(Unwrap(device));

		RDCASSERT(m_Device == VK_NULL_HANDLE); // MULTIDEVICE
		
		m_PhysicalDevice = physicalDevice;
		m_Device = device;

		m_QueueFamilyIdx = qFamilyIdx;

		if(m_InternalCmds.cmdpool == VK_NULL_HANDLE)
		{
			VkCommandPoolCreateInfo poolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, qFamilyIdx };
			vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL, &m_InternalCmds.cmdpool);
			RDCASSERTEQUAL(vkr, VK_SUCCESS);

			GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool);
		}
		
		ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props);
		
		ObjDisp(physicalDevice)->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);

		ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);

		for(int i=VK_FORMAT_BEGIN_RANGE+1; i < VK_FORMAT_END_RANGE; i++)
			ObjDisp(physicalDevice)->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i), &m_PhysicalDeviceData.fmtprops[i]);

		m_PhysicalDeviceData.readbackMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
		m_PhysicalDeviceData.uploadMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
		m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);

		for(size_t i=0; i < m_PhysicalDevices.size(); i++)
		{
			if(physicalDevice == m_PhysicalDevices[i])
			{
				m_PhysicalDeviceData.memIdxMap = m_MemIdxMaps[i];
				break;
			}
		}

		m_DebugManager = new VulkanDebugManager(this, device);

		SAFE_DELETE_ARRAY(modQueues);
		SAFE_DELETE_ARRAY(layerArray);
		SAFE_DELETE_ARRAY(extArray);
	}

	return true;
}