bool VulkanCommon::CheckPhysicalDeviceProperties( VkPhysicalDevice physical_device, uint32_t &selected_graphics_queue_family_index, uint32_t &selected_present_queue_family_index ) {
    uint32_t extensions_count = 0;
    if( (vkEnumerateDeviceExtensionProperties( physical_device, nullptr, &extensions_count, nullptr ) != VK_SUCCESS) ||
        (extensions_count == 0) ) {
      std::cout << "Error occurred during physical device " << physical_device << " extensions enumeration!" << std::endl;
      return false;
    }

    std::vector<VkExtensionProperties> available_extensions( extensions_count );
    if( vkEnumerateDeviceExtensionProperties( physical_device, nullptr, &extensions_count, &available_extensions[0] ) != VK_SUCCESS ) {
      std::cout << "Error occurred during physical device " << physical_device << " extensions enumeration!" << std::endl;
      return false;
    }

    std::vector<const char*> device_extensions = {
      VK_KHR_SWAPCHAIN_EXTENSION_NAME
    };

    for( size_t i = 0; i < device_extensions.size(); ++i ) {
      if( !CheckExtensionAvailability( device_extensions[i], available_extensions ) ) {
        std::cout << "Physical device " << physical_device << " doesn't support extension named \"" << device_extensions[i] << "\"!" << std::endl;
        return false;
      }
    }

    VkPhysicalDeviceProperties device_properties;
    VkPhysicalDeviceFeatures   device_features;

    vkGetPhysicalDeviceProperties( physical_device, &device_properties );
    vkGetPhysicalDeviceFeatures( physical_device, &device_features );

    uint32_t major_version = VK_VERSION_MAJOR( device_properties.apiVersion );

    if( (major_version < 1) &&
        (device_properties.limits.maxImageDimension2D < 4096) ) {
      std::cout << "Physical device " << physical_device << " doesn't support required parameters!" << std::endl;
      return false;
    }

    uint32_t queue_families_count = 0;
    vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_families_count, nullptr );
    if( queue_families_count == 0 ) {
      std::cout << "Physical device " << physical_device << " doesn't have any queue families!" << std::endl;
      return false;
    }

    std::vector<VkQueueFamilyProperties>  queue_family_properties( queue_families_count );
    std::vector<VkBool32>                 queue_present_support( queue_families_count );

    vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_families_count, &queue_family_properties[0] );

    uint32_t graphics_queue_family_index = UINT32_MAX;
    uint32_t present_queue_family_index = UINT32_MAX;

    for( uint32_t i = 0; i < queue_families_count; ++i ) {
      vkGetPhysicalDeviceSurfaceSupportKHR( physical_device, i, Vulkan.PresentationSurface, &queue_present_support[i] );

      if( (queue_family_properties[i].queueCount > 0) &&
          (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) ) {
        // Select first queue that supports graphics
        if( graphics_queue_family_index == UINT32_MAX ) {
          graphics_queue_family_index = i;
        }

        // If there is queue that supports both graphics and present - prefer it
        if( queue_present_support[i] ) {
          selected_graphics_queue_family_index = i;
          selected_present_queue_family_index = i;
          return true;
        }
      }
    }

    // We don't have queue that supports both graphics and present so we have to use separate queues
    for( uint32_t i = 0; i < queue_families_count; ++i ) {
      if( queue_present_support[i] ) {
        present_queue_family_index = i;
        break;
      }
    }

    // If this device doesn't support queues with graphics and present capabilities don't use it
    if( (graphics_queue_family_index == UINT32_MAX) ||
        (present_queue_family_index == UINT32_MAX) ) {
      std::cout << "Could not find queue families with required properties on physical device " << physical_device << "!" << std::endl;
      return false;
    }

    selected_graphics_queue_family_index = graphics_queue_family_index;
    selected_present_queue_family_index = present_queue_family_index;
    return true;
  }
예제 #2
0
int vk_init(){
	unsigned int i;
	unsigned int qi = 0;
	unsigned int qc = 0;
	VkResult res;
	VkApplicationInfo ainfo = {0};
	VkInstanceCreateInfo iinfo = {0};

	ainfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	ainfo.pApplicationName = "enaengine";
	ainfo.pEngineName = "enaengine";
	ainfo.apiVersion = VK_API_VERSION;


	iinfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	iinfo.pApplicationInfo = &ainfo;
	iinfo.enabledExtensionCount = NUMEXT;
	iinfo.ppEnabledExtensionNames = ext;
//	iinfo.enabledExtensionCount = glfw_extensions_count;
//	iinfo.ppEnabledExtensionNames = glfw_extensions;

	res = vkCreateInstance(&iinfo, NULL, &vkinstance);
	if(res){
		//TODO ERROR
		return FALSE;
	}


	res = vkEnumeratePhysicalDevices(vkinstance, &vkdevices_count, 0);
	if(vkdevices_count < 1 || res){
		//TODO ERROR
		return FALSE;
	}
	vkdevices = malloc(vkdevices_count * sizeof(VkPhysicalDevice));
	res = vkEnumeratePhysicalDevices(vkinstance, &vkdevices_count, vkdevices);
	if(res){
		//TODO ERROR
		return FALSE;
	}
	//find first dev with graphics capabilities
	for(i = 0; i < vkdevices_count; i++){
		vkactivedevice = vkdevices[i];
		qc = 0;
		vkGetPhysicalDeviceQueueFamilyProperties(vkactivedevice, &qc, NULL);
		if(!qc) continue;
		vkdevicesqp = malloc(qc * sizeof(VkQueueFamilyProperties));
		vkGetPhysicalDeviceQueueFamilyProperties(vkactivedevice, &qc, vkdevicesqp);
		for(qi = 0; qi < qc; qi++){
			if(vkdevicesqp[qi].queueFlags & VK_QUEUE_GRAPHICS_BIT) break;
		}
		if(qi != qc) break;

		if(vkdevicesqp) free(vkdevicesqp);
		vkdevicesqp = 0;
	}
	//didnt find one
	if(i == vkdevices_count){
		return FALSE;
	}
	//create dev (finally)
	float qp[] = {0.0f};
	VkDeviceQueueCreateInfo qci = {0};
	qci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	qci.queueFamilyIndex = qi;
	qci.queueCount = 1;
	qci.pQueuePriorities = qp;



	VkDeviceCreateInfo dci = {0};
	dci.queueCreateInfoCount = 1;
	dci.pQueueCreateInfos = &qci;
	dci.enabledExtensionCount = NUMEXT2;
	dci.ppEnabledExtensionNames = ext2;
	res = vkCreateDevice(vkactivedevice, &dci, 0, &vkdevice);
	if(res){
		//TODO error
		return FALSE;
	}


	vkGetPhysicalDeviceProperties(vkactivedevice, &vkdeviceprop);
	vkGetPhysicalDeviceFeatures(vkactivedevice, &vkdevicefeat);

	return TRUE;
}
예제 #3
0
VkPhysicalDeviceFeatures PhysicalDevice::features() const {
    VkPhysicalDeviceFeatures features;
    vkGetPhysicalDeviceFeatures(handle(), &features);
    return features;
}
예제 #4
0
Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
{
	// Create the instance
	//
	static Array<const char*, 8> LAYERS = {{"VK_LAYER_LUNARG_core_validation",
		"VK_LAYER_LUNARG_swapchain",
		"VK_LAYER_LUNARG_image",
		"VK_LAYER_GOOGLE_threading",
		"VK_LAYER_LUNARG_parameter_validation",
		"VK_LAYER_GOOGLE_unique_objects",
		"VK_LAYER_LUNARG_object_tracker",
		"VK_LAYER_LUNARG_standard_validation"}};

	static Array<const char*, 2> EXTENSIONS = {{VK_KHR_SURFACE_EXTENSION_NAME,
#if ANKI_OS == ANKI_OS_LINUX
		VK_KHR_XCB_SURFACE_EXTENSION_NAME
#elif ANKI_OS == ANKI_OS_WINDOWS
		VK_KHR_WIN32_SURFACE_EXTENSION_NAME
#else
#error TODO
#endif
	}};

	VkApplicationInfo app = {};
	app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	app.pApplicationName = "unamed";
	app.applicationVersion = 1;
	app.pEngineName = "AnKi 3D Engine";
	app.engineVersion = (ANKI_VERSION_MAJOR << 1) | ANKI_VERSION_MINOR;
	app.apiVersion = VK_MAKE_VERSION(1, 0, 3);

	VkInstanceCreateInfo ci = {};
	ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	ci.pApplicationInfo = &app;

	if(init.m_config->getNumber("debugContext"))
	{
		ANKI_LOGI("VK: Will enable debug layers");
		ci.enabledLayerCount = LAYERS.getSize();
		ci.ppEnabledLayerNames = &LAYERS[0];
	}

	ci.enabledExtensionCount = EXTENSIONS.getSize();
	ci.ppEnabledExtensionNames = &EXTENSIONS[0];

#if ANKI_GR_MANAGER_DEBUG_MEMMORY
	VkAllocationCallbacks allocCbs = {};
	VkAllocationCallbacks* pallocCbs = &allocCbs;
	allocCbs.pUserData = this;
	allocCbs.pfnAllocation = allocateCallback;
	allocCbs.pfnReallocation = reallocateCallback;
	allocCbs.pfnFree = freeCallback;
#else
	VkAllocationCallbacks* pallocCbs = nullptr;
#endif

	ANKI_VK_CHECK(vkCreateInstance(&ci, pallocCbs, &m_instance));

	// Create the physical device
	//
	uint32_t count = 0;
	ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, nullptr));
	ANKI_LOGI("VK: Number of physical devices: %u", count);
	if(count < 1)
	{
		ANKI_LOGE("Wrong number of physical devices");
		return ErrorCode::FUNCTION_FAILED;
	}

	count = 1;
	ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &m_physicalDevice));

	vkGetPhysicalDeviceProperties(m_physicalDevice, &m_devProps);

	// Find vendor
	switch(m_devProps.vendorID)
	{
	case 0x13B5:
		m_vendor = GpuVendor::ARM;
		break;
	case 0x10DE:
		m_vendor = GpuVendor::NVIDIA;
		break;
	case 0x1002:
	case 0x1022:
		m_vendor = GpuVendor::AMD;
		break;
	}
	ANKI_LOGI("GPU vendor is %s", &GPU_VENDOR_STR[m_vendor][0]);

	vkGetPhysicalDeviceFeatures(m_physicalDevice, &m_devFeatures);

	return ErrorCode::NONE;
}
예제 #5
-27
파일: vkUtilss.cpp 프로젝트: pac85/Engine
bool select_device(std::vector<VkPhysicalDevice> &devices, VkPhysicalDevice &chosen_device)
{
    bool suitable_dev_found = false;
    unsigned int best_score = 0;
    for (const auto& device : devices)
    {
        unsigned int score = 0;
        VkPhysicalDeviceProperties deviceProperties;
        VkPhysicalDeviceFeatures deviceFeatures;

        vkGetPhysicalDeviceProperties(device, &deviceProperties);
        vkGetPhysicalDeviceFeatures(device, &deviceFeatures);

        if(deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU){score+= 1000;}

        if(!deviceFeatures.geometryShader){score-= 1000000;}

        uint32_t queueFamilyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);

        std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
        vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());

        /*checks that all the needed queue families are supported */
        bool graphics_found = false, present_found = false;
        int i = 0;
        for(const auto& queueFamily : queueFamilies)
        {
            if (!graphics_found && queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
            {
                graphics_found = true;
                graphics_queue_family_index = i;
            }

            VkBool32 presentSupport = false;
            vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);

            if (!present_found && queueFamily.queueCount > 0 && presentSupport)
            {
                present_found = true;
                present_queue_family_index = i;
            }

            if(present_found && graphics_found){break;}//if it finds both there is no point in keeping looking for queue families

            i++;
        }
        if(!(graphics_found && present_found)){continue;}//if it didn't find both cues go to next device

        /*checking for device specific extnsions support*/
        uint32_t extensionCount;
        vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);

        std::vector<VkExtensionProperties> availableExtensions(extensionCount);
        vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());

        std::set<std::string> requiredExtensions(device_extensions.begin(), device_extensions.end());
        for (const auto& extension : availableExtensions)
        {
            requiredExtensions.erase(extension.extensionName);
        }

        if(!requiredExtensions.empty()){continue;}

        /*checks that swap chains are supported*/
        bool swapChainAdequate = false;

        SwapChainSupportDetails swapChainSupport = query_swap_chain_support(device);
        swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();


        if(score >= best_score)
        {
            chosen_device = device;
            suitable_dev_found = true;
            best_score = score;
        }

        if(!swapChainAdequate){continue;}

    }
    return suitable_dev_found;   //if no device is found
}