bool VulkanWrapper::VWGraphicInstance::CheckValidationLayerSupport()
{
	uint32_t layerCount;
	vkEnumerateInstanceLayerProperties(&layerCount, nullptr);

	std::vector<VkLayerProperties> availableLayers(layerCount);
	vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());

	for (const char* layerName : validationLayers) {
		bool layerFound = false;

		for (const auto& layerProperties : availableLayers) {
			if (strcmp(layerName, layerProperties.layerName) == 0) {
				layerFound = true;
				break;
			}
		}

		if (!layerFound) {
			return false;
		}
	}

	return true;
}
Exemple #2
0
Instance::Instance() {
    // Get layers
    uint32_t layerCount;
    vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
    layersProperties.resize(layerCount);
    vkEnumerateInstanceLayerProperties(&layerCount, layersProperties.data());

    // Get extensions
    uint32_t extensionCount;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
    extensionProperties.resize(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionProperties.data());

#if defined(_WIN32)
    enabledExtensions = {
        "VK_KHR_surface",
        "VK_KHR_win32_surface",
    };
#elif defined(__linux__)
    enabledExtensions = {
        "VK_KHR_surface",
        "VK_KHR_xcb_surface",
    };
#endif

    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pApplicationName = "Application";
    applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    applicationInfo.apiVersion = VK_API_VERSION_1_0;

    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pApplicationInfo = &applicationInfo;
}
Exemple #3
0
bool VulkanContext::CheckValidationLayerAvailablility()
{
  u32 extension_count = 0;
  VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
  if (res != VK_SUCCESS)
  {
    LOG_VULKAN_ERROR(res, "vkEnumerateInstanceExtensionProperties failed: ");
    return false;
  }

  std::vector<VkExtensionProperties> extension_list(extension_count);
  res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_list.data());
  ASSERT(res == VK_SUCCESS);

  u32 layer_count = 0;
  res = vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
  if (res != VK_SUCCESS)
  {
    LOG_VULKAN_ERROR(res, "vkEnumerateInstanceExtensionProperties failed: ");
    return false;
  }

  std::vector<VkLayerProperties> layer_list(layer_count);
  res = vkEnumerateInstanceLayerProperties(&layer_count, layer_list.data());
  ASSERT(res == VK_SUCCESS);

  // Check for both VK_EXT_debug_report and VK_LAYER_LUNARG_standard_validation
  return (std::find_if(extension_list.begin(), extension_list.end(),
                       [](const auto& it) {
                         return strcmp(it.extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0;
                       }) != extension_list.end() &&
          std::find_if(layer_list.begin(), layer_list.end(), [](const auto& it) {
            return strcmp(it.layerName, "VK_LAYER_LUNARG_standard_validation") == 0;
          }) != layer_list.end());
}
Exemple #4
0
void RHIRoot::EnumLayers()
{
	uint32 layerCount = 0;
	K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, nullptr));
	if(layerCount>0)
	{
		s_LayerProps.resize(layerCount);
		K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, s_LayerProps.data()));
	}
	VKLOG(Info, "layerCount = %d. ", layerCount);
}
Exemple #5
0
void checkGlobalLayerPresent(const char* layerName) {
    uint32_t layerCount = 0;
    std::vector<VkLayerProperties> layers;
    vkEnumerateInstanceLayerProperties(&layerCount, NULL);
    layers.resize(layerCount);
    vkEnumerateInstanceLayerProperties(&layerCount, layers.data());
    for (auto& layer : layers) {
        if (!strcmp(layerName, layer.layerName)) {
            return;
        }
    }
    cerr << "ERROR: cannot find layer: " << layerName << endl;
    exit(1);
}
Exemple #6
0
bool hasLayer(const char * name) {
	uint32_t count = 0;
	std::vector<VkLayerProperties> layerprops;
	vkEnumerateInstanceLayerProperties(&count, nullptr);
	if (count != 0) {
		layerprops = std::vector<VkLayerProperties>(count);
		vkEnumerateInstanceLayerProperties(&count, layerprops.data());
		for (auto prop : layerprops) {
			if (strcmp(name, prop.layerName) == 0) {
				std::cout << "found layer: " << prop.layerName << std::endl;
				return true;
			}
		}
	} 
	return false;
}
TEST_F(EnumerateInstanceLayerProperties, OnePass)
{
    // Count required for this test.
    if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
    {
        return;
    }

    uint32_t count = std::stoul(arguments[2]);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].layerName
                << ' ' << properties[p].specVersion
                << ' ' << properties[p].implementationVersion
                << ' ' << properties[p].description << '\n';
        }
    }
}
TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    // We need atleast two for the test to be relevant.
    if(count < 2u)
    {
        return;
    }

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    count = 1;
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_INCOMPLETE);
}
TEST_F(EnumerateInstanceLayerProperties, Count)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
    {
        std::cout << "count=" << count << '\n';
    }
}
Exemple #10
0
void vulkan_instance_check_layers(const std::vector<const char*>& layers)
{
    uint32_t layers_count = 0;
    Assert(vkEnumerateInstanceLayerProperties(&layers_count, nullptr) == VK_SUCCESS);
    Assert(layers_count > 0);

    std::vector<VkLayerProperties> available_layers(layers_count);
    Assert(vkEnumerateInstanceLayerProperties(&layers_count, &available_layers[0]) == VK_SUCCESS);

    for (size_t i = 0; i < layers.size(); ++i)
    {
        bool found = false;
        for (size_t j = 0; j < available_layers.size(); ++j)
        {
            if (std::strcmp(available_layers[j].layerName, layers[i]) == 0)
                found = true;
        }
        Assert(found, fmt::format("vulkan: layer '{}' not supported by the instance", layers[i]));
    }
}
/*
 * Return list of Global layers available
 */
std::vector<VkLayerProperties> GetGlobalLayers() {
    VkResult err;
    std::vector<VkLayerProperties> layers;
    uint32_t layer_count;

    do {
        layer_count = 0;
        err = vkEnumerateInstanceLayerProperties(&layer_count, NULL);

        if (err == VK_SUCCESS) {
            layers.reserve(layer_count);
            err =
                vkEnumerateInstanceLayerProperties(&layer_count, layers.data());
        }
    } while (err == VK_INCOMPLETE);

    assert(err == VK_SUCCESS);

    return layers;
}
TEST_F(EnumerateInstanceLayerProperties, TwoPass)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].layerName
                << ' ' << properties[p].specVersion
                << ' ' << properties[p].implementationVersion
                << ' ' << properties[p].description << '\n';
        }
    }
}
    // Check for the availabilty of some validation layers
    bool checkValidationLayerSupport()
    {
        uint32_t layerCount;
        vkEnumerateInstanceLayerProperties(&layerCount, nullptr);

        // Get the available validation layers
        std::vector<VkLayerProperties>  availableLayers(layerCount);
        vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());

        // Convert to a set
        std::unordered_set<std::string> availableLayersSet;
        std::for_each(availableLayers.begin(), availableLayers.end(), [&availableLayersSet] (VkLayerProperties& p) {
            availableLayersSet.emplace(p.layerName);
        });

        // Construct other set
        std::unordered_set<std::string> validationLayersSet(validationLayers.begin(), validationLayers.end());

        // Ensure selected validation layers is a subset of available layers
        return std::includes(availableLayersSet.begin(), availableLayersSet.end(), 
                             validationLayersSet.begin(), validationLayersSet.end());
    }
Exemple #14
0
VkResult VulkanContext::GetInstanceLayerProperties() {
	/*
	 * It's possible, though very rare, that the number of
	 * instance layers could change. For example, installing something
	 * could include new layers that the loader would pick up
	 * between the initial query for the count and the
	 * request for VkLayerProperties. The loader indicates that
	 * by returning a VK_INCOMPLETE status and will update the
	 * the count parameter.
	 * The count parameter will be updated with the number of
	 * entries loaded into the data pointer - in case the number
	 * of layers went down or is smaller than the size given.
	 */
	uint32_t instance_layer_count;
	std::vector<VkLayerProperties> vk_props;
	VkResult res;
	do {
		res = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
		if (res != VK_SUCCESS)
			return res;
		if (!instance_layer_count)
			return VK_SUCCESS;
		vk_props.resize(instance_layer_count);
		res = vkEnumerateInstanceLayerProperties(&instance_layer_count, vk_props.data());
	} while (res == VK_INCOMPLETE);

	// Now gather the extension list for each instance layer.
	for (uint32_t i = 0; i < instance_layer_count; i++) {
		LayerProperties layer_props;
		layer_props.properties = vk_props[i];
		res = GetInstanceLayerExtensionList(layer_props.properties.layerName, layer_props.extensions);
		if (res != VK_SUCCESS)
			return res;
		instance_layer_properties_.push_back(layer_props);
	}
	return res;
}
Exemple #15
0
/** Enumerates and caches all layers supported by the Vulkan Instance. */
void Anvil::Instance::enumerate_instance_layers()
{
    std::vector<VkLayerProperties> layer_props;
    uint32_t                       n_layers    = 0;
    VkResult                       result      = VK_ERROR_INITIALIZATION_FAILED;

    ANVIL_REDUNDANT_VARIABLE(result);

    /* Retrieve layer data */
    result = vkEnumerateInstanceLayerProperties(&n_layers,
                                                nullptr); /* pProperties */
    anvil_assert_vk_call_succeeded(result);

    layer_props.resize(n_layers + 1 /* global layer */);

    result = vkEnumerateInstanceLayerProperties(&n_layers,
                                               &layer_props[0]);

    anvil_assert_vk_call_succeeded(result);

    /* Convert raw layer props data to internal descriptors */
    for (uint32_t n_layer = 0;
                  n_layer < n_layers + 1;
                ++n_layer)
    {
        Anvil::Layer* layer_ptr = nullptr;

        if (n_layer < n_layers)
        {
            m_supported_layers.push_back(Anvil::Layer(layer_props[n_layer]) );

            layer_ptr = &m_supported_layers[n_layer];
        }

        enumerate_layer_extensions(layer_ptr);
    }
}
Exemple #16
0
C9::C9()
	: mGpuCount(0), 
	mPhysicalDevices(nullptr),
	mReferenceCount(0),
	mInstance(VK_NULL_HANDLE),
	mLayerProperties(nullptr),
	mLayerPropertyCount(0),
	mValidationPresent(false),
	mResult(VK_SUCCESS),
	mOptionDescriptions("Allowed options")
{
	//Setup configuration & logging.

	mOptionDescriptions.add_options()
		("LogFile", boost::program_options::value<std::string>(), "The location of the log file.");

	boost::program_options::store(boost::program_options::parse_config_file<char>("SchaeferGL.conf", mOptionDescriptions), mOptions);
	boost::program_options::notify(mOptions);

	if (mOptions.count("LogFile"))
	{
		boost::log::add_file_log(mOptions["LogFile"].as<std::string>());
	}
	else
	{
		boost::log::add_file_log("SchaeferGL.log");
	}


	//Continue instance setup.
	mResult = vkEnumerateInstanceLayerProperties(&mLayerPropertyCount, nullptr);
	if (mResult != VK_SUCCESS)
	{
		BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumerateInstanceLayerProperties failed with return code of " << mResult;
		return;
	}
	else
	{
		BOOST_LOG_TRIVIAL(info) << "C9::C9 vkEnumerateInstanceLayerProperties found " << mLayerPropertyCount << " layers.";
	}
	mLayerProperties = new VkLayerProperties[mLayerPropertyCount];
	mResult = vkEnumerateInstanceLayerProperties(&mLayerPropertyCount, mLayerProperties);
	if (mResult == VK_SUCCESS)
	{
		for (size_t i = 0; i < mLayerPropertyCount; i++)
		{
			if (strcmp(mLayerProperties[i].layerName,"VK_LAYER_LUNARG_standard_validation")==0)
			{
				mValidationPresent = true;
			}
			BOOST_LOG_TRIVIAL(info) << "C9::C9 vkEnumerateInstanceLayerProperties - layerName: " << mLayerProperties[i].layerName;
		}		
	}

	mExtensionNames.push_back("VK_KHR_surface");
	mExtensionNames.push_back("VK_KHR_win32_surface");
#ifdef _DEBUG
	mExtensionNames.push_back("VK_EXT_debug_report");
	mLayerExtensionNames.push_back("VK_LAYER_LUNARG_standard_validation");
#endif // _DEBUG

	// initialize the VkApplicationInfo structure
	VkApplicationInfo app_info = {};
	app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	app_info.pNext = nullptr;
	app_info.pApplicationName = APP_SHORT_NAME;
	app_info.applicationVersion = 1;
	app_info.pEngineName = APP_SHORT_NAME;
	app_info.engineVersion = 1;
	app_info.apiVersion = 0; // VK_API_VERSION;

	// initialize the VkInstanceCreateInfo structure
	VkInstanceCreateInfo inst_info =
	{
		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,								  // VkStructureType sType;
		NULL,																  // const void* pNext;
		0,																	  // VkInstanceCreateFlags flags;
		&app_info,															  // const VkApplicationInfo* pApplicationInfo;
		mLayerExtensionNames.size(),										  // uint32_t enabledLayerNameCount;
		mLayerExtensionNames.size()>0 ? mLayerExtensionNames.data() : nullptr,// const char* const* ppEnabledLayerNames;
		mExtensionNames.size(),											      // uint32_t enabledExtensionNameCount;
		mExtensionNames.size()>0 ? mExtensionNames.data() : nullptr,		  // const char* const* ppEnabledExtensionNames;
	};

	//Get an instance handle.
	if (VK_SUCCESS == vkCreateInstance(&inst_info, NULL, &mInstance))
	{
#ifdef _DEBUG
		/* Load VK_EXT_debug_report entry points in debug builds */
		vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT"));
		vkDebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(vkGetInstanceProcAddr(mInstance, "vkDebugReportMessageEXT"));
		vkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT"));

		VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = {};
		callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
		callbackCreateInfo.pNext = nullptr;
		callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
		callbackCreateInfo.pfnCallback = &DebugReportCallback;
		callbackCreateInfo.pUserData = nullptr;

		/* Register the callback */
		mResult = vkCreateDebugReportCallbackEXT(mInstance, &callbackCreateInfo, nullptr, &mCallback);
		if (mResult != VK_SUCCESS)
		{
			BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkCreateDebugReportCallbackEXT failed with return code of " << mResult;
			return;
		}
		else
		{
			BOOST_LOG_TRIVIAL(info) << "C9::C9 vkCreateDebugReportCallbackEXT succeeded.";
		}
#endif

		//Fetch an array of available physical devices.
		mResult = vkEnumeratePhysicalDevices(mInstance, &mGpuCount, NULL);
		if (mResult != VK_SUCCESS)
		{
			BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumeratePhysicalDevices failed with return code of " << mResult;
			return;
		}
		else
		{
			BOOST_LOG_TRIVIAL(info) << "There were " << mGpuCount << " physical devices found.";
		}

		if (mGpuCount > 0)
		{
			mPhysicalDevices = new VkPhysicalDevice[mGpuCount]();
			mResult = vkEnumeratePhysicalDevices(mInstance, &mGpuCount, mPhysicalDevices);
			if (mResult != VK_SUCCESS)
			{
				BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumeratePhysicalDevices failed with return code of " << mResult;
				return;
			}
		}
		else
		{
			BOOST_LOG_TRIVIAL(fatal) << "No phyuscial devices were found.";
		}
	}
	else
	{
		BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkCreateInstance failed.";
		return;
	}
}
int sample_main(int argc, char *argv[]) {
    VkResult res;
    struct sample_info info;
    uint32_t instance_layer_count;
    VkLayerProperties *vk_props = NULL;

    init_global_layer_properties(info);

    /* VULKAN_KEY_START */

    /*
     * It's possible, though very rare, that the number of
     * instance layers could change. For example, installing something
     * could include new layers that the loader would pick up
     * between the initial query for the count and the
     * request for VkLayerProperties. The loader indicates that
     * by returning a VK_INCOMPLETE status and will update the
     * the count parameter.
     * The count parameter will be updated with the number of
     * entries loaded into the data pointer - in case the number
     * of layers went down or is smaller than the size given.
     */
    do {
        res = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
        if (res)
            break;

        if (instance_layer_count == 0) {
            break;
        }

        vk_props = (VkLayerProperties *)realloc(
            vk_props, instance_layer_count * sizeof(VkLayerProperties));

        res =
            vkEnumerateInstanceLayerProperties(&instance_layer_count, vk_props);
    } while (res == VK_INCOMPLETE);

    std::cout << "Instance Layers:" << std::endl;
    for (uint32_t i = 0; i < instance_layer_count; i++) {
        VkLayerProperties *props = &vk_props[i];
        uint32_t major, minor, patch;
        std::cout << props->layerName << ":" << std::endl;
        extract_version(props->specVersion, major, minor, patch);
        std::cout << "\tVersion: " << props->implementationVersion << std::endl;
        std::cout << "\tAPI Version: "
                  << "(" << major << "." << minor << "." << patch << ")"
                  << std::endl;
        std::cout << "\tDescription: " << props->description << std::endl;
        std::cout << std::endl
                  << std::endl;
    }

    std::cout << std::endl;

    free(vk_props);

    /* VULKAN_KEY_END */

    return 0;
}
// Devices
void Renderer::_InitDevice() {
	{
		uint32_t gpu_count = 0;
		
		// Read number of GPU's
		vkEnumeratePhysicalDevices(_instance, &gpu_count, nullptr);
		
		std::vector<VkPhysicalDevice> gpu_list(gpu_count);

		// Populate list
		vkEnumeratePhysicalDevices(_instance, &gpu_count, gpu_list.data());

		_gpu = gpu_list[0]; // Get the first available list
		vkGetPhysicalDeviceProperties(_gpu, &_gpu_properties);
		vkGetPhysicalDeviceMemoryProperties(_gpu, &_gpu_memory_properties);
	}
	
	{
		uint32_t family_count = 0;

		// Read number of GPU queue family properties
		vkGetPhysicalDeviceQueueFamilyProperties(_gpu, &family_count, nullptr);

		std::vector<VkQueueFamilyProperties> family_property_list(family_count);

		// Populate list
		vkGetPhysicalDeviceQueueFamilyProperties(_gpu, &family_count, family_property_list.data());
		
		// Find the graphics family
		bool found = false;
		for (uint32_t i = 0; i < family_count; ++i) {
			if (family_property_list[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
				found = true;
				_graphics_family_index = i;
			}
		}

		if (!found) {
			assert(0 && "Vulkan ERROR: Queue family supporting graphics not found.");
			std::exit(-1);
		}
	}

	// Instance Layers
	{
		uint32_t layer_count = 0;

		// Read the number of layers
		vkEnumerateInstanceLayerProperties(&layer_count, nullptr);

		std::vector<VkLayerProperties> layer_property_list(layer_count);

		// Populate list
		vkEnumerateInstanceLayerProperties(&layer_count, layer_property_list.data());

#if BUILD_ENABLE_VULKAN_RUNTIME_DEBUG
		std::cout << "Instance layers: \n";
		for (auto &i : layer_property_list) {
			std::cout << " " << i.layerName << "\t\t | " << i.description << std::endl;
		}
		std::cout << std::endl;
#endif
	}

	// Instance Extensions
	{
		uint32_t extension_count = 0;

		// Read the number of extensions
		vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);

		std::vector<VkExtensionProperties> extension_property_list(extension_count);

		// Populate list
		vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_property_list.data());

#if BUILD_ENABLE_VULKAN_RUNTIME_DEBUG
		std::cout << "Instance extensions: \n";
		for (auto &i : extension_property_list) {
			std::cout << " " << i.extensionName << "\t\t | " << i.specVersion << std::endl;
		}
		std::cout << std::endl;
#endif
	}

	// Device Layers
	{
		uint32_t layer_count = 0;

		// Read the number of layers
		vkEnumerateDeviceLayerProperties(_gpu, &layer_count, nullptr);

		std::vector<VkLayerProperties> layer_property_list(layer_count);

		// Populate list
		vkEnumerateDeviceLayerProperties(_gpu, &layer_count, layer_property_list.data());

#if BUILD_ENABLE_VULKAN_RUNTIME_DEBUG
		std::cout << "Device layers: \n";
		for (auto &i : layer_property_list) {
			std::cout << " " << i.layerName << "\t\t | " << i.description << std::endl;
		}
		std::cout << std::endl;
#endif
	}

	// Device Extensions
	{
		uint32_t extension_count = 0;

		// Read the number of extensions
		vkEnumerateDeviceExtensionProperties(_gpu, nullptr, &extension_count, nullptr);

		std::vector<VkExtensionProperties> extension_property_list(extension_count);

		// Populate list
		vkEnumerateDeviceExtensionProperties(_gpu, nullptr, &extension_count, extension_property_list.data());

#if BUILD_ENABLE_VULKAN_RUNTIME_DEBUG
		std::cout << "Device extensions: \n";
		for (auto &i : extension_property_list) {
			std::cout << " " << i.extensionName << "\t\t | " << i.specVersion << std::endl;
		}
		std::cout << std::endl;
#endif
	}

	float queue_priorities[] {1.0f};

	VkDeviceQueueCreateInfo device_queue_create_info {};
	device_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	device_queue_create_info.queueFamilyIndex = _graphics_family_index;
	device_queue_create_info.queueCount = 1;
	device_queue_create_info.pQueuePriorities = queue_priorities;

	VkDeviceCreateInfo device_create_info = {};
	device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	device_create_info.queueCreateInfoCount = 1;
	device_create_info.pQueueCreateInfos = &device_queue_create_info;
	device_create_info.enabledLayerCount = (uint32_t) _device_layer_list.size();
	device_create_info.ppEnabledLayerNames = _device_layer_list.data();
	device_create_info.enabledExtensionCount = (uint32_t) _device_extension_list.size();
	device_create_info.ppEnabledExtensionNames = _device_extension_list.data();

	ErrorCheck(vkCreateDevice(_gpu, &device_create_info, nullptr, &_device));

	vkGetDeviceQueue(_device, _graphics_family_index, 0, &_queue);
}
Exemple #19
0
int main(int argc, char** argv) {
	
	g_validationLayers = std::vector<const char*> {
		"VK_LAYER_LUNARG_mem_tracker",
		"VK_LAYER_GOOGLE_unique_objects",
	};

	// Init GLFW
	{
		// Handle GLFW errors
		glfwSetErrorCallback([](int error, const char* description) {
			std::cout << "GLFW error: " << error << " - " << description << std::endl;
		});
		
		// Initialize GLFW
		if (!glfwInit())
			error("Cannot initialize GLFW.");

		// Check Vulkan support
		if (!glfwVulkanSupported())
			error("Cannot find compatible Vulkan client driver.");
	}

	// Get Validation layers
	{
		uint32_t numInstanceLayers = 0;

		// Get numInstanceLayers
		if (vkEnumerateInstanceLayerProperties(&numInstanceLayers, nullptr))
			error("Vulkan: Could not enumerate instance layer properties.");

		if (numInstanceLayers > 0) {
			std::vector<VkLayerProperties> instanceLayers(numInstanceLayers);
			if (vkEnumerateInstanceLayerProperties(&numInstanceLayers, instanceLayers.data()))
				error("Vulkan: Could not enumerate instance layer properties.");

			// Print layers:
			std::cout << "Validation layers: " << std::endl;
			for (int i = 0; i < numInstanceLayers; ++i) {
				std::cout << "\t" << instanceLayers[i].layerName << std::endl;
				std::cout << "\t\t" << instanceLayers[i].description << std::endl;
				std::cout << std::endl;
			}
			std::cout << std::endl;
		}
		else
			std::cout << "No validation layers found!" << std::endl;

		// TODO: Check Layers
	}

	// Check instance extensions
	{
		int numRequiredExtensions;
		const char** requiredExtensions;

		// Get required extensions from GLFW
		{
			requiredExtensions = glfwGetRequiredInstanceExtensions((int*)&numRequiredExtensions);

			if (numRequiredExtensions > 0) {
				// Write to global g_extensions
				for (int i = 0; i < numRequiredExtensions; ++i)
					g_extensions.push_back(requiredExtensions[i]);

				// Print
				std::cout << "Required Instance Extensions(GLFW):" << std::endl;
				for (int i = 0; i < numRequiredExtensions; ++i) {
					std::cout << "\t" << requiredExtensions[i] << std::endl;
				}
				std::cout << std::endl;
			}
			// TODO: Check extensions
		}

		// Get Instance extensions
		{
			VkResult err;
			uint32_t numInstanceExtensions;
			err = vkEnumerateInstanceExtensionProperties(nullptr, &numInstanceExtensions, nullptr);

			if (numInstanceExtensions > 0) {
				std::vector<VkExtensionProperties> instanceExtensions(numInstanceExtensions);
				err = vkEnumerateInstanceExtensionProperties(NULL, &numInstanceExtensions, instanceExtensions.data());

				// Print
				std::cout << "Instance Extensions: " << std::endl;
				for (int i = 0; i < numInstanceExtensions; ++i) {
					std::cout << "\t" <<instanceExtensions[i].extensionName << std::endl;
					std::cout << "\t\t" << instanceExtensions[i].specVersion << std::endl;
					std::cout << std::endl;
				}
				std::cout << std::endl;
			}
			// TODO: Check instance extensions(with required instance extensions)
		}
	}

	// Create Vulkan Instance
	{
		VkApplicationInfo app;
		{
			app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
			app.pNext = nullptr;
			app.pApplicationName = "Vulkan test 1";
			app.applicationVersion = 0;
			app.pEngineName = "Vulkan test 1";
			app.engineVersion = 0;
			app.apiVersion = VK_API_VERSION;
		}

		VkInstanceCreateInfo instanceInfo;
		{
			instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
			instanceInfo.pNext = nullptr;
			instanceInfo.pApplicationInfo = &app;
			instanceInfo.enabledLayerCount = g_validationLayers.size();
			instanceInfo.ppEnabledLayerNames = g_validationLayers.data();
			instanceInfo.enabledExtensionCount = g_extensions.size();
			instanceInfo.ppEnabledExtensionNames = g_extensions.data();
		}

		// TODO: Aligned allocators
		VkAllocationCallbacks allocator;
		{
			allocator.pUserData = nullptr;
			allocator.pfnAllocation = [](void* pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)->void* {
				return malloc(size);
			};
			allocator.pfnFree = [](void* pUserData, void* pMemory) {
				free(pMemory);
			};
			allocator.pfnReallocation = [](void* pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) {
				free(pOriginal);
				return malloc(size);
			};
			allocator.pfnInternalAllocation = nullptr;
			allocator.pfnInternalFree = nullptr;
			allocator.pfnReallocation = nullptr;
		}
		
		// Create vulkan instance
		VkResult vkError = vkCreateInstance(&instanceInfo, &allocator, &g_vkInstance);

		// Handle errors
		switch (vkError) {
		case VK_ERROR_INCOMPATIBLE_DRIVER:
			error("Drivers do not support vulkan. Drivers could be outdated.");
			break;
		case VK_ERROR_EXTENSION_NOT_PRESENT:
			error("Cannot find specified extension.");
			break;
		case VK_SUCCESS:
			// Succes! (prevent default from catching success as error)
			std::cout << "Vulkan instance created!" << std::endl;
			break;
		default:
			error("Could not create vulkan Instance. Drivers could be outdated.");
			break;
		}

	}

	// Look for GPU device
	{
		uint32_t numGPUs;
		VkResult vkError = vkEnumeratePhysicalDevices(g_vkInstance, &numGPUs, nullptr);
		
		if (numGPUs < 0)
			error("vkEnumeratePhysicalDevices could not find any GPU devices.");

		if (vkError)
			error("vkEnumeratePhysicalDevices could not enumerate GPU devices.");

		if (numGPUs > 0) {
			std::vector<VkPhysicalDevice> physicalDevices(numGPUs);
			if (vkEnumeratePhysicalDevices(g_vkInstance, &numGPUs, physicalDevices.data()))
				error("vkEnumeratePhysicalDevices could not enumerate GPU devices.");

			g_vkGPU = physicalDevices[0];

			std::cout << numGPUs << " GPUs found!" << std::endl;
		}
	}

	// Get queue properties
	{
		uint32_t numQueues;
		vkGetPhysicalDeviceProperties(g_vkGPU, &g_vkGPUProperties);

		vkGetPhysicalDeviceQueueFamilyProperties(g_vkGPU, &numQueues, nullptr);
		if (numQueues == 0)
			error("vkGetPhysicalDeviceQueueFamilyProperties could not find any queues.");

		g_vkQueueProperties = std::vector<VkQueueFamilyProperties>(numQueues);
		vkGetPhysicalDeviceQueueFamilyProperties(g_vkGPU, &numQueues, g_vkQueueProperties.data());
	}

	// Look for device layers (Unecessary code that does nothing)
	{
		uint32_t numDeviceLayers;

		if (vkEnumerateDeviceLayerProperties(g_vkGPU, &numDeviceLayers, nullptr))
			error("vkEnumerateDeviceLayerProperties failed!");

		if (numDeviceLayers > 0) {
			std::vector<VkLayerProperties> deviceLayers(numDeviceLayers);

			if (vkEnumerateDeviceLayerProperties(g_vkGPU, &numDeviceLayers, deviceLayers.data()))
				error("vkEnumerateDeviceLayerProperties failed!");

			// TODO: Check device layers.
		}
	}

	// Look for device extensions (swapchain extension)
	{
		uint32_t numDeviceExtensions;
		bool extensionSwapChainFound = false;

		if (vkEnumerateDeviceExtensionProperties(g_vkGPU, nullptr, &numDeviceExtensions, nullptr))
			error("vkEnumerateDeviceExtensionProperties failed!");

		if (numDeviceExtensions > 0) {
			std::vector<VkExtensionProperties> deviceExtensions(numDeviceExtensions);
			
			if (vkEnumerateDeviceExtensionProperties(g_vkGPU, nullptr, &numDeviceExtensions, deviceExtensions.data()))
				error("vkEnumerateDeviceExtensionProperties failed!");

			// Search for swapchain extension
			for (VkExtensionProperties extension : deviceExtensions) {
				if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
					extensionSwapChainFound = true;
			}
			
			// Print
			std::cout << std::endl << "Extensions:" << std::endl;
			for (VkExtensionProperties extension : deviceExtensions) {
				std::cout << extension.extensionName << "(" << extension.specVersion << ")" << std::endl;
			}
			std::cout << std::endl;
		}

		if (!extensionSwapChainFound)
			error("Failed to find the " VK_KHR_SWAPCHAIN_EXTENSION_NAME " extension!");
	}

	// TODO: Validate

	// Get instance function adresses
	{
		GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceFormatsKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfacePresentModesKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, GetPhysicalDeviceSurfaceSupportKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, CreateSwapchainKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, DestroySwapchainKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, GetSwapchainImagesKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, AcquireNextImageKHR);
		GET_INSTANCE_PROC_ADDR(g_vkInstance, QueuePresentKHR);
	}

	// Create window
	{
		glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

		g_window = glfwCreateWindow(g_width, g_height, "Vulkan test", NULL, NULL);

		if (!g_window)
			error("Could not create window!");

		glfwSetWindowRefreshCallback(g_window, [](GLFWwindow* window) {
			// TODO: draw();
		});
		glfwSetFramebufferSizeCallback(g_window, [](GLFWwindow* window, int width, int height) {
			g_width = width;
			g_height = height;
			// TODO: resize();
		});


	}

	// Init swapchain
	{
		glfwCreateWindowSurface(g_vkInstance, g_window, nullptr, &g_vkSurface);

		std::vector<VkBool32> supportsPresent(g_vkQueueProperties.size());

		for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i)
			g_vkFPGetPhysicalDeviceSurfaceSupportKHR(g_vkGPU, i, g_vkSurface, &supportsPresent[i]);

		uint32_t graphicsQueueNodeIndex = UINT32_MAX;
		uint32_t presentQueueNodeIndex = UINT32_MAX;

		for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i) {
			if (graphicsQueueNodeIndex == UINT32_MAX) {
				graphicsQueueNodeIndex = i;
			}

			if (supportsPresent[i] == VK_TRUE) {
				graphicsQueueNodeIndex = i;
				presentQueueNodeIndex = i;
				break;
			}
		}

		//if (presentQueueNodeIndex == UINT32_MAX) {
		//	for (uint32_t i = 0; i < g_vkQueueProperties.size(); ++i) {
		//		if (supportsPresent[i] == VK_TRUE) {
		//			presentQueueNodeIndex = i;
		//		}
		//	}
		//}

		if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX)
			error("Could not find a graphics and a present queue.");

		if (graphicsQueueNodeIndex != presentQueueNodeIndex)
			error("Could not find a common graphics and present queue.");

		g_vkGraphicsQueueNodeIndex = graphicsQueueNodeIndex;

		//TODO: init device
		{
			float queuePriotities = 0.f;
			VkDeviceQueueCreateInfo queue;
			{
				queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
				queue.pNext = NULL;
				queue.queueFamilyIndex = g_vkGraphicsQueueNodeIndex;
				queue.queueCount = 1;
				queue.pQueuePriorities = &queuePriotities;
			}

		}

		//vkGetDeviceQueue(g_vkDevice, g_vkGraphicsQueueNodeIndex, 0, g_vkQueue);

	}

	std::cin.get();

	return 0;
}
Exemple #20
0
Context::Context()
{
    if(!loadVulkanLibrary())
    {
        CV_Error(Error::StsError, "loadVulkanLibrary failed");
        return;
    }
    else if (!loadVulkanEntry())
    {
        CV_Error(Error::StsError, "loadVulkanEntry failed");
        return;
    }
    else if (!loadVulkanGlobalFunctions())
    {
        CV_Error(Error::StsError, "loadVulkanGlobalFunctions failed");
        return;
    }

    // create VkInstance, VkPhysicalDevice
    std::vector<const char *> enabledExtensions;
    if (enableValidationLayers)
    {
        uint32_t layerCount;
        vkEnumerateInstanceLayerProperties(&layerCount, NULL);

        std::vector<VkLayerProperties> layerProperties(layerCount);
        vkEnumerateInstanceLayerProperties(&layerCount, layerProperties.data());

        bool foundLayer = false;
        for (VkLayerProperties prop : layerProperties)
        {
            if (strcmp("VK_LAYER_LUNARG_standard_validation", prop.layerName) == 0)
            {
                foundLayer = true;
                break;
            }
        }

        if (!foundLayer)
        {
            throw std::runtime_error("Layer VK_LAYER_LUNARG_standard_validation not supported\n");
        }
        kEnabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");

        uint32_t extensionCount;

        vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, NULL);
        std::vector<VkExtensionProperties> extensionProperties(extensionCount);
        vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionProperties.data());

        bool foundExtension = false;
        for (VkExtensionProperties prop : extensionProperties)
        {
            if (strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, prop.extensionName) == 0)
            {
                foundExtension = true;
                break;
            }
        }

        if (!foundExtension) {
            throw std::runtime_error("Extension VK_EXT_DEBUG_REPORT_EXTENSION_NAME not supported\n");
        }
        enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
    }

    VkApplicationInfo applicationInfo = {};
    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pApplicationName = "VkCom Library";
    applicationInfo.applicationVersion = 0;
    applicationInfo.pEngineName = "vkcom";
    applicationInfo.engineVersion = 0;
    applicationInfo.apiVersion = VK_API_VERSION_1_0;;

    VkInstanceCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.flags = 0;
    createInfo.pApplicationInfo = &applicationInfo;

    // Give our desired layers and extensions to vulkan.
    createInfo.enabledLayerCount = kEnabledLayers.size();
    createInfo.ppEnabledLayerNames = kEnabledLayers.data();
    createInfo.enabledExtensionCount = enabledExtensions.size();
    createInfo.ppEnabledExtensionNames = enabledExtensions.data();

    VK_CHECK_RESULT(vkCreateInstance(&createInfo, NULL, &kInstance));

    if (!loadVulkanFunctions(kInstance))
    {
        CV_Error(Error::StsError, "loadVulkanFunctions failed");
        return;
    }

    if (enableValidationLayers && vkCreateDebugReportCallbackEXT)
    {
        VkDebugReportCallbackCreateInfoEXT createInfo = {};
        createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
        createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
                           VK_DEBUG_REPORT_WARNING_BIT_EXT |
                           VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
        createInfo.pfnCallback = &debugReportCallbackFn;

        // Create and register callback.
        VK_CHECK_RESULT(vkCreateDebugReportCallbackEXT(kInstance, &createInfo,
                                                       NULL, &kDebugReportCallback));
    }

    // find physical device
    uint32_t deviceCount;
    vkEnumeratePhysicalDevices(kInstance, &deviceCount, NULL);
    if (deviceCount == 0)
    {
        throw std::runtime_error("could not find a device with vulkan support");
    }

    std::vector<VkPhysicalDevice> devices(deviceCount);
    vkEnumeratePhysicalDevices(kInstance, &deviceCount, devices.data());

    for (VkPhysicalDevice device : devices)
    {
        if (true)
        {
            kPhysicalDevice = device;
            break;
        }
    }

    kQueueFamilyIndex = getComputeQueueFamilyIndex();

    // create device, queue, command pool
    VkDeviceQueueCreateInfo queueCreateInfo = {};
    queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    queueCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
    queueCreateInfo.queueCount = 1; // create one queue in this family. We don't need more.
    float queuePriorities = 1.0;  // we only have one queue, so this is not that imporant.
    queueCreateInfo.pQueuePriorities = &queuePriorities;

    VkDeviceCreateInfo deviceCreateInfo = {};

    // Specify any desired device features here. We do not need any for this application, though.
    VkPhysicalDeviceFeatures deviceFeatures = {};

    deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    deviceCreateInfo.enabledLayerCount = kEnabledLayers.size();
    deviceCreateInfo.ppEnabledLayerNames = kEnabledLayers.data();
    deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
    deviceCreateInfo.queueCreateInfoCount = 1;
    deviceCreateInfo.pEnabledFeatures = &deviceFeatures;

    VK_CHECK_RESULT(vkCreateDevice(kPhysicalDevice, &deviceCreateInfo, NULL, &kDevice));

    // Get a handle to the only member of the queue family.
    vkGetDeviceQueue(kDevice, kQueueFamilyIndex, 0, &kQueue);

    // create command pool
    VkCommandPoolCreateInfo commandPoolCreateInfo = {};
    commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
    commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
    // the queue family of this command pool. All command buffers allocated from this command pool,
    // must be submitted to queues of this family ONLY.
    commandPoolCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
    VK_CHECK_RESULT(vkCreateCommandPool(kDevice, &commandPoolCreateInfo, NULL, &kCmdPool));
}
gboolean
gst_vulkan_instance_open (GstVulkanInstance * instance, GError ** error)
{
  VkExtensionProperties *instance_extensions;
  char *extension_names[64];    /* FIXME: make dynamic */
  VkLayerProperties *instance_layers;
  uint32_t instance_extension_count = 0;
  uint32_t enabled_extension_count = 0;
  uint32_t instance_layer_count = 0;
  uint32_t enabled_layer_count = 0;
  gchar **enabled_layers;
  VkResult err;

  GST_OBJECT_LOCK (instance);
  if (instance->priv->opened) {
    GST_OBJECT_UNLOCK (instance);
    return TRUE;
  }

  /* Look for validation layers */
  err = vkEnumerateInstanceLayerProperties (&instance_layer_count, NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vKEnumerateInstanceLayerProperties") < 0)
    goto error;

  instance_layers = g_new0 (VkLayerProperties, instance_layer_count);
  err =
      vkEnumerateInstanceLayerProperties (&instance_layer_count,
      instance_layers);
  if (gst_vulkan_error_to_g_error (err, error,
          "vKEnumerateInstanceLayerProperties") < 0) {
    g_free (instance_layers);
    goto error;
  }

  /* TODO: allow outside selection */
  _check_for_all_layers (G_N_ELEMENTS (instance_validation_layers),
      instance_validation_layers, instance_layer_count, instance_layers,
      &enabled_layer_count, &enabled_layers);

  g_free (instance_layers);

  err =
      vkEnumerateInstanceExtensionProperties (NULL, &instance_extension_count,
      NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumerateInstanceExtensionProperties") < 0) {
    g_strfreev (enabled_layers);
    goto error;
  }
  GST_DEBUG_OBJECT (instance, "Found %u extensions", instance_extension_count);

  memset (extension_names, 0, sizeof (extension_names));
  instance_extensions =
      g_new0 (VkExtensionProperties, instance_extension_count);
  err =
      vkEnumerateInstanceExtensionProperties (NULL, &instance_extension_count,
      instance_extensions);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumerateInstanceExtensionProperties") < 0) {
    g_strfreev (enabled_layers);
    g_free (instance_extensions);
    goto error;
  }

  {
    GstVulkanDisplayType display_type;
    gboolean swapchain_ext_found = FALSE;
    gboolean winsys_ext_found = FALSE;
    const gchar *winsys_ext_name;

    display_type = gst_vulkan_display_choose_type (instance);

    winsys_ext_name =
        gst_vulkan_display_type_to_extension_string (display_type);
    if (!winsys_ext_name) {
      GST_WARNING_OBJECT (instance, "No window system extension enabled");
      winsys_ext_found = TRUE;  /* Don't error out completely */
    }

    /* TODO: allow outside selection */
    for (uint32_t i = 0; i < instance_extension_count; i++) {
      GST_TRACE_OBJECT (instance, "checking instance extension %s",
          instance_extensions[i].extensionName);

      if (!g_strcmp0 (VK_KHR_SURFACE_EXTENSION_NAME,
              instance_extensions[i].extensionName)) {
        swapchain_ext_found = TRUE;
        extension_names[enabled_extension_count++] =
            (gchar *) VK_KHR_SURFACE_EXTENSION_NAME;
      }
      if (!g_strcmp0 (VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
              instance_extensions[i].extensionName)) {
        extension_names[enabled_extension_count++] =
            (gchar *) VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
      }
      if (!g_strcmp0 (winsys_ext_name, instance_extensions[i].extensionName)) {
        winsys_ext_found = TRUE;
        extension_names[enabled_extension_count++] = (gchar *) winsys_ext_name;
      }
      g_assert (enabled_extension_count < 64);
    }
    if (!swapchain_ext_found) {
      g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
          "vkEnumerateInstanceExtensionProperties failed to find the required "
          "\"" VK_KHR_SURFACE_EXTENSION_NAME "\" extension");
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
    if (!winsys_ext_found) {
      g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
          "vkEnumerateInstanceExtensionProperties failed to find the required "
          "\"%s\" window system extension", winsys_ext_name);
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
  }

  {
    VkApplicationInfo app = { 0, };
    VkInstanceCreateInfo inst_info = { 0, };

    app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    app.pNext = NULL;
    app.pApplicationName = APP_SHORT_NAME;
    app.applicationVersion = 0;
    app.pEngineName = APP_SHORT_NAME;
    app.engineVersion = 0;
    app.apiVersion = VK_API_VERSION_1_0;

    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pNext = NULL;
    inst_info.pApplicationInfo = &app;
#if 0
    inst_info.enabledLayerCount = enabled_layer_count;
    inst_info.ppEnabledLayerNames = (const char *const *) enabled_layers;
#else
    inst_info.enabledLayerCount = 0;
    inst_info.ppEnabledLayerNames = NULL;
#endif
    inst_info.enabledExtensionCount = enabled_extension_count;
    inst_info.ppEnabledExtensionNames = (const char *const *) extension_names;

    err = vkCreateInstance (&inst_info, NULL, &instance->instance);
    if (gst_vulkan_error_to_g_error (err, error, "vkCreateInstance") < 0) {
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
  }

  g_free (instance_extensions);
  g_strfreev (enabled_layers);

  err =
      vkEnumeratePhysicalDevices (instance->instance,
      &instance->n_physical_devices, NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumeratePhysicalDevices") < 0)
    goto error;
  g_assert (instance->n_physical_devices > 0);
  instance->physical_devices =
      g_new0 (VkPhysicalDevice, instance->n_physical_devices);
  err =
      vkEnumeratePhysicalDevices (instance->instance,
      &instance->n_physical_devices, instance->physical_devices);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumeratePhysicalDevices") < 0)
    goto error;

  instance->dbgCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkCreateDebugReportCallbackEXT");
  if (!instance->dbgCreateDebugReportCallback) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkCreateDebugReportCallback");
    goto error;
  }
  instance->dbgDestroyDebugReportCallback =
      (PFN_vkDestroyDebugReportCallbackEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkDestroyDebugReportCallbackEXT");
  if (!instance->dbgDestroyDebugReportCallback) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkDestroyDebugReportCallback");
    goto error;
  }
  instance->dbgReportMessage = (PFN_vkDebugReportMessageEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkDebugReportMessageEXT");
  if (!instance->dbgReportMessage) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkDebugReportMessage");
    goto error;
  }

  {
    VkDebugReportCallbackCreateInfoEXT info = { 0, };

    info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
    info.pNext = NULL;
    info.flags =
        VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
        VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT |
        VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
    info.pfnCallback = (PFN_vkDebugReportCallbackEXT) _gst_vk_debug_callback;
    info.pUserData = NULL;

    err =
        instance->dbgCreateDebugReportCallback (instance->instance, &info, NULL,
        &instance->msg_callback);
    if (gst_vulkan_error_to_g_error (err, error,
            "vkCreateDebugReportCallback") < 0)
      goto error;
  }

  instance->priv->opened = TRUE;
  GST_OBJECT_UNLOCK (instance);

  return TRUE;

error:
  {
    GST_OBJECT_UNLOCK (instance);
    return FALSE;
  }
}
Exemple #22
0
bool Renderer::CreateInstance()
{
	//Get Layer count and layer properties
	uint32_t layerPropertiesCount;
	
	auto err = vkEnumerateInstanceLayerProperties(&layerPropertiesCount, nullptr);

	if (err != VK_SUCCESS)
	{
		//TODO output an error 
		return false;
	}

	if (layerPropertiesCount == 0)
	{
		return true;
	}

	std::unique_ptr<VkLayerProperties[]> layerPropertiesArray(new VkLayerProperties[layerPropertiesCount]);	

	err = vkEnumerateInstanceLayerProperties(&layerPropertiesCount, layerPropertiesArray.get());
	if (err != VK_SUCCESS)
	{
		//TODO output debug error
		return false;
	}

	// Get extension count and properties
	uint32_t extensionCount;
	err = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
	if (err != VK_SUCCESS)
	{
		//TODO output an error 
		return false;
	}

	std::unique_ptr<VkExtensionProperties[]> extensionsArray( new VkExtensionProperties[extensionCount] );

	err = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionsArray.get());
	if (err != VK_SUCCESS)
	{
		//TODO output an error 
		return false;
	}

	//Get layer names
	char ** layerNames = new char*[layerPropertiesCount];

	for (uint32_t i = 0; i < layerPropertiesCount; ++i)
	{
		size_t nameLength = strlen(layerPropertiesArray[i].layerName) + 1;
		layerNames[i] = new char[nameLength];
		strcpy_s(layerNames[i], nameLength, layerPropertiesArray[i].layerName);
	}


	//Get extension names
	char** extensionNames = new char*[extensionCount];

	for (uint32_t i = 0; i < extensionCount; ++i)
	{
		size_t nameLength = strlen(extensionsArray[i].extensionName) + 1;
		extensionNames[i] = new char[nameLength];
		strcpy_s(extensionNames[i], nameLength, extensionsArray[i].extensionName);
	}
	
	//Create instance

	VkApplicationInfo appInfo {};
	appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	appInfo.pApplicationName = "Test";
	appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 8); // VK_API_VERSION; is deprecated

	VkInstanceCreateInfo createInfo {};
	createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	createInfo.pApplicationInfo = &appInfo;
	createInfo.enabledLayerCount = layerPropertiesCount;
	createInfo.ppEnabledLayerNames = layerNames;
	createInfo.enabledExtensionCount = extensionCount;
	createInfo.ppEnabledExtensionNames = extensionNames;

	err = vkCreateInstance(&createInfo, nullptr, &instance);
	if (err != VK_SUCCESS)
	{
		//TODO output an error 
		return false;
	}

	//Create device

	return true;
}
Exemple #23
0
int main()
{
	//Настроем вывод.
	setlocale(LC_ALL, "Russian");
	//Подготовим данные приложения
	VkApplicationInfo app_info;
	memset(&app_info, 0, sizeof(app_info));
	app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	app_info.pApplicationName = app_name;
	#ifdef VK_API_VERSION_1_0
	app_info.apiVersion = VK_API_VERSION_1_0;
	#else
	app_info.apiVersion = VK_API_VERSION;
	#endif
	app_info.applicationVersion = VK_MAKE_VERSION(0, 1, 25);

	VkResult res; //заранее подготовим переменную для результата, она нам понадобится несколько раз.

	//Данные экземпляра
	VkInstanceCreateInfo instance_info;
	memset(&instance_info, 0, sizeof(instance_info));
	instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	instance_info.pApplicationInfo = &app_info;
	uint32_t available_instance_layer_count = 0;
	//узнаём кол-во установленных слоёв.
	res = vkEnumerateInstanceLayerProperties(&available_instance_layer_count, nullptr);
	if (res != VK_SUCCESS)
	{
		std::wcout << "Не удалось получить кол-во слоёв.\n";
		return -1;
	}
	//настраиваем массив
	std::vector<VkLayerProperties> available_instance_layers(available_instance_layer_count);
	//Получаем слои
	res = vkEnumerateInstanceLayerProperties(&available_instance_layer_count, available_instance_layers.data());
	if (available_instance_layer_count)
	{
		//А теперь выводим на экран.
		std::wcout << L"\n\nСлои экземпляра:\n";
		for (uint32_t i = 0; i < available_instance_layer_count; i++)
		{
			VkLayerProperties &properties = available_instance_layers[i];
			std::cout << properties.layerName << (strlen(properties.layerName) < 24 ? "\t" : "")
			<< (strlen(properties.layerName) < 32 ? "\t" : "")
			<< "\t|" << properties.description << "\n";
		}
	}
	std::cout << "\n\n";

	std::vector<const char *> instance_layers;
	instance_layers.push_back("VK_LAYER_LUNARG_standard_validation");


	//И затем отправим их в стурктуру с информацией.
	instance_info.enabledLayerCount = instance_layers.size();
	instance_info.ppEnabledLayerNames = instance_layers.data();

	//Кол-во расширений.
	uint32_t available_instance_extension_count = 0;
	//Забираем кол-во расширений.
	res = vkEnumerateInstanceExtensionProperties(NULL, &available_instance_extension_count, nullptr);
	if (res != VK_SUCCESS) //Проверка
	{
		std::wcout << "Не удалось получить кол-во расширений.\n";
		return -1;
	}

	//настраиваем массив
	std::vector<VkExtensionProperties> available_instance_extensions(available_instance_extension_count);
	//Получаем расширения
	res = vkEnumerateInstanceExtensionProperties(NULL, &available_instance_extension_count, available_instance_extensions.data());
	if (available_instance_extension_count)
	{
		//Вывод на экран.
		std::wcout << L"\n\nРасширения экземпляра:\n";
		for (uint32_t i = 0; i < available_instance_extensions.size(); i++)
		{
			VkExtensionProperties &properties = available_instance_extensions[i];
			std::cout << properties.extensionName << "\n";
		}
		std::cout << "\n\n";
	}

	//Настройка расширений
	std::vector<const char *> instance_extensions;

	instance_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);

	instance_info.enabledExtensionCount = instance_extensions.size();
	instance_info.ppEnabledExtensionNames = instance_extensions.data();

	VkInstance instance = VK_NULL_HANDLE;
	res = vkCreateInstance(&instance_info, NULL, &instance);
	if (res != VK_SUCCESS) //С проверками особо заморачиваться не будем.
	{
		std::wcerr << L"Что-то не так...\n";
		return -1;
	}
	else
		std::wcout << L"Экземпляр Vulkan создан.\n";

	//Создадим указатели на функции таким образом.
	PFN_vkCreateDebugReportCallbackEXT fvkCreateDebugReportCallbackEXT = NULL;
	PFN_vkDestroyDebugReportCallbackEXT fvkDestroyDebugReportCallbackEXT = NULL;

	//И получим их.
	fvkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)
		vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
	fvkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)
		vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");

	/* Отлично, мы получили эти функции! Теперь, нам нужно подготовить информацию для callback'ов, а также
	 * оставить хэндл, который мы конечно же потом уничтожим.
	*/

	//Структура, которую мы должны заполнить
	VkDebugReportCallbackCreateInfoEXT debug_report_callback_info;
	memset(&debug_report_callback_info, 0, sizeof(debug_report_callback_info));
	debug_report_callback_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
	debug_report_callback_info.flags = VK_DEBUG_REPORT_DEBUG_BIT_EXT |
		VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
		VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;
	// Настало время прикрепить наш прототип здесь:
	debug_report_callback_info.pfnCallback = DebugReportCallback;

	VkDebugReportCallbackEXT debug_report_callback = VK_NULL_HANDLE;
	//И наконец-таки привзяываем наш Callback:
	res = fvkCreateDebugReportCallbackEXT(instance, &debug_report_callback_info, NULL, &debug_report_callback);
	if (res != VK_SUCCESS)
	{
		std::wcerr << L"Не удалось создать debug-report callback.\n";
		return -1;
	}

	std::vector<VkPhysicalDevice> gpu_list; //здесь будем хранить физические устройства.
	uint32_t gpu_count; //кол-во девайсов
	//получаем колв-о девайсов и сразу проверяем на удачу.
	if (vkEnumeratePhysicalDevices(instance, &gpu_count, VK_NULL_HANDLE) != VK_SUCCESS)
	{
		std::wcerr << L"Посчитать физические устройства не удалось :(\n";
		return -1;
	}
	gpu_list.resize(gpu_count); //заранее изменим размер под самый оптимальный.
	//Забираем физические девайсы
	if (vkEnumeratePhysicalDevices(instance, &gpu_count, gpu_list.data()) != VK_SUCCESS)
	{
		std::wcerr << L"Заполучить твои физические устройства не удалось, но я приду за ними в следующий раз!\n";
		return -1;
	}
	//Выбираем видеокарту
	VkPhysicalDevice gpu = gpu_list[0];
	//Теперь, семейства.
	uint32_t family_count = 0; //кол-во семейтсв
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, nullptr);
	std::vector<VkQueueFamilyProperties> family_properties_list(family_count);
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, family_properties_list.data());
	//Листаем семейтсва и получаем нужное.
	uint32_t valid_family_index = (uint32_t) -1; //значение -1 будем использовать как "не найдено, 404".
	for (uint32_t i = 0; i < family_count; i++) //листаем все семейства.
	{
		VkQueueFamilyProperties &properties = family_properties_list[i];
		if (properties.queueFlags & VK_QUEUE_GRAPHICS_BIT)
		{
			if (valid_family_index == (uint32_t) -1)
				valid_family_index = i;
		}
	}
	//И если наш индекс всё ещё не перезаписан, то..
	if (valid_family_index == (uint32_t) -1)
		return -1;

	//Описываем очереди.
	VkDeviceQueueCreateInfo device_queue_info;
    memset(&device_queue_info, 0, sizeof(device_queue_info));
	device_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;

	float device_queue_priority[] = {1.0f};
	device_queue_info.queueCount = 1;
	device_queue_info.queueFamilyIndex = valid_family_index;
	device_queue_info.pQueuePriorities = device_queue_priority;

	VkDeviceCreateInfo device_info;
    memset(&device_info, 0, sizeof(device_info));
	device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	device_info.queueCreateInfoCount = 1;
	device_info.pQueueCreateInfos = &device_queue_info;

	uint32_t available_device_layer_count = 0;
	res = vkEnumerateDeviceLayerProperties(gpu, &available_device_layer_count, VK_NULL_HANDLE);
	if (res != VK_SUCCESS)
	{
		std::wcout << "Не удалось получить кол-во слоёв.\n";
		return -1;
	}
	//настраиваем массив
	std::vector<VkLayerProperties> available_device_layers(available_device_layer_count);
	res = vkEnumerateDeviceLayerProperties(gpu, &available_device_layer_count, available_device_layers.data());
	if (res != VK_SUCCESS)
	{
		std::wcout << "Не удалось получить слои.\n";
		return -1;
	}
	if (available_device_layer_count)
	{
		//А теперь выводим на экран.
		std::wcout << L"\n\nСлои устройства:\n";
		for (uint32_t i = 0; i < available_device_layer_count; i++)
		{
			//Сделаем красивый вывод для имени и описания слоя.
			VkLayerProperties &properties = available_device_layers[i];
			std::cout << properties.layerName << (strlen(properties.layerName) < 24 ? "\t" : "")
			<< (strlen(properties.layerName) < 32 ? "\t" : "")
			<< "\t|" << properties.description << "\n";
		}
	}
	std::cout << "\n\n";

	//Кол-во расширений.
	uint32_t available_device_extension_count = 0;
	//Забираем кол-во расширений.
	res = vkEnumerateDeviceExtensionProperties(gpu, NULL, &available_device_extension_count, VK_NULL_HANDLE);
	if (res != VK_SUCCESS) //Проверка
	{
		std::wcout << "Не удалось получить кол-во расширений.\n";
		return -1;
	}

	//настраиваем массив
	std::vector<VkExtensionProperties> available_device_extensions(available_device_extension_count);
	//Получаем расширения
	res = vkEnumerateDeviceExtensionProperties(gpu, NULL, &available_device_extension_count, available_device_extensions.data());
	if (available_device_extension_count)
	{
		//Вывод на экран.
		std::wcout << L"\n\nРасширения устройства:\n";
		for (uint32_t i = 0; i < available_device_extensions.size(); i++)
		{
			VkExtensionProperties &properties = available_device_extensions[i];
			std::cout << properties.extensionName << "\n";
		}
		std::cout << "\n\n";
	}

	std::vector<const char *> device_layers = instance_layers;

	//Расширения и слои
	device_info.enabledLayerCount = device_layers.size();
	device_info.ppEnabledLayerNames = device_layers.data();

	//А расширения устройства оставим и на сей раз пустым.
	std::vector<const char *> device_extensions;

	device_info.enabledExtensionCount = device_extensions.size();
	device_info.ppEnabledExtensionNames = device_extensions.data();
	VkDevice device = VK_NULL_HANDLE;
	if (vkCreateDevice(gpu, &device_info, NULL, &device) != VK_SUCCESS)
		return -1;

	vkDestroyDevice(device, NULL);
	fvkDestroyDebugReportCallbackEXT(instance, debug_report_callback, NULL);
	vkDestroyInstance(instance, NULL);
	std::wcout << L"Пожарено!\n";
	return 0;
}