Vulkan 学习笔记:Command Buffers

单个command buffer代码

#include "Renderer.h"

int main() {
	Renderer r;
	// need to send command into command pool when creating a window
	auto device = r._device;
	auto queue = r._queue;

	// Fence
	// wait for the gpu to be ready on the cpu side?
	// cpu wait for gpu
	VkFence fence;
	VkFenceCreateInfo fence_create_info{};
	fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	vkCreateFence(device, &fence_create_info, nullptr, &fence);

	// Semaphore
	// semaphore tells gpu when other process completed
	VkSemaphore semaphore;
	VkSemaphoreCreateInfo semaphore_create_info{};
	semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	vkCreateSemaphore(device ,&semaphore_create_info, nullptr, &semaphore);
	//semaphore_create_info.flag
	
	// Command Pool
	// allocate command buffers in a pool
	// as destroy pool, also destroy all buffers
	VkCommandPool command_pool;
	VkCommandPoolCreateInfo pool_create_info{};
	pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	pool_create_info.queueFamilyIndex = r._graphics_family_index;// probably which queue to execute the commmand
	pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	std::cout << "Command Pool Created" << std::endl;
	ErrorCheck(vkCreateCommandPool(device, &pool_create_info, nullptr, &command_pool));

	// Command Buffer
	VkCommandBuffer command_buffer;
	VkCommandBufferAllocateInfo command_buffer_allocate_info{};
	command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	command_buffer_allocate_info.commandPool = command_pool;
	command_buffer_allocate_info.commandBufferCount = 1;// how many command buffer to allocate for the pool
	command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;//
	// initial state
	vkAllocateCommandBuffers(device, &command_buffer_allocate_info, &command_buffer);
	{
		
		VkCommandBufferBeginInfo begin_info{};
		begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
		//begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
		// recording state
		vkBeginCommandBuffer(command_buffer, &begin_info);

		// vkCmd...

		// need to set viewport per command buffer
		VkViewport viewport{};
		viewport.maxDepth = 1.0f;
		viewport.minDepth = 0.0f;
		viewport.width = 512;
		viewport.height = 512;
		viewport.x = 0;
		viewport.y = 0;
		vkCmdSetViewport(command_buffer, 0, 1, &viewport);

		// executable state, end recording compile the cb on gpu?? 
		vkEndCommandBuffer(command_buffer);
	}
	{
		// submit command buffer to gpu
		VkSubmitInfo submit_info{};
		submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
		submit_info.commandBufferCount = 1;
		submit_info.pCommandBuffers = &command_buffer;

		// submit command buffer to gpu
		vkQueueSubmit(queue, 1, &submit_info, fence);
	}
	// true: need to wait for all fence to complete before continue, false: wait only 1 fence
	vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);

	// gpu works concurrently with cpu, wait for the queue
	// wait for the submit to be done
	// if commented , error: Attempt to destroy command pool with VkCommandBuffer 0x2109f440ab0[] which is in use.
	// because command buffer wasn't complete on gpu when cpu tries to delete it,need to wait on cpu side
	vkQueueWaitIdle(queue);

	// destroy command pool
	vkDestroyCommandPool(device, command_pool, nullptr);
	vkDestroyFence(device, fence, nullptr);
}

多个command buffer,将如下部分替换(//***)
用semaphore做不同gpu command buffer间的同步

// Command Buffer
VkCommandBuffer command_buffer[2];//***
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
command_buffer_allocate_info.commandPool = command_pool;
command_buffer_allocate_info.commandBufferCount = 2;// ***
command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
// initial state
vkAllocateCommandBuffers(device, &command_buffer_allocate_info, command_buffer);// ***
{
	
	VkCommandBufferBeginInfo begin_info{};
	begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	//begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	// recording state
	vkBeginCommandBuffer(command_buffer[0], &begin_info);// ***

	// vkCmd...

	// need to set viewport per command buffer
	VkViewport viewport{};
	viewport.maxDepth = 1.0f;
	viewport.minDepth = 0.0f;
	viewport.width = 512;
	viewport.height = 512;
	viewport.x = 0;
	viewport.y = 0;
	vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);// ***

	// executable state, end recording compile the cb on gpu?? 
	vkEndCommandBuffer(command_buffer[0]);// ***
}
{

	VkCommandBufferBeginInfo begin_info{};
	begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	//begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	// recording state
	vkBeginCommandBuffer(command_buffer[1], &begin_info);// ***

	// vkCmd...

	// need to set viewport per command buffer
	VkViewport viewport{};
	viewport.maxDepth = 1.0f;
	viewport.minDepth = 0.0f;
	viewport.width = 512;
	viewport.height = 512;
	viewport.x = 0;
	viewport.y = 0;
	vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);// ***

	// executable state, end recording compile the cb on gpu?? 
	vkEndCommandBuffer(command_buffer[1]);// ***
}
{
	// submit command buffer to gpu
	VkSubmitInfo submit_info{};
	submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submit_info.commandBufferCount = 1;
	submit_info.pCommandBuffers = &command_buffer[0];// ***
	submit_info.signalSemaphoreCount = 1;// ***
	submit_info.pSignalSemaphores = &semaphore;// signal the semaphore// ***

	vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);// ***
}
{
	//VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT };
	VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };// all need to be done after signaled// ***
	// submit command buffer to gpu
	VkSubmitInfo submit_info{};
	submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submit_info.commandBufferCount = 1;
	submit_info.pCommandBuffers = &command_buffer[1];// ***
	submit_info.waitSemaphoreCount = 1;
	submit_info.pWaitSemaphores = &semaphore;// ***
	// where we are going to wait for semaphores, as signaled then access certain stage
	// as the command buffer reaches fragment shader stage, it wait for the semaphore
	submit_info.pWaitDstStageMask = flags;// pipeline stage mask// ***

	// submit command buffer to gpu
	vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);// ***
}

// true: need to wait for all fence to complete before continue, false: wait only 1 fence
//vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
vkQueueWaitIdle(queue);

// destroy command pool
vkDestroyCommandPool(device, command_pool, nullptr);
vkDestroyFence(device, fence, nullptr);
vkDestroySemaphore(device, semaphore, nullptr);

课程结束完整代码
main.cpp

#include "Renderer.h"

int main() {
	Renderer r;
	// need to send command into command pool when creating a window
	auto device = r._device;
	auto queue = r._queue;

	// Fence
	// wait for the gpu to be ready on the cpu side?
	// cpu wait for gpu
	VkFence fence;
	VkFenceCreateInfo fence_create_info{};
	fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	vkCreateFence(device, &fence_create_info, nullptr, &fence);

	// Semaphore
	// semaphore tells gpu when other process completed
	VkSemaphore semaphore;
	VkSemaphoreCreateInfo semaphore_create_info{};
	semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	vkCreateSemaphore(device ,&semaphore_create_info, nullptr, &semaphore);
	//semaphore_create_info.flag
	
	// Command Pool
	// allocate command buffers in a pool
	// as destroy pool, also destroy all buffers
	VkCommandPool command_pool;
	VkCommandPoolCreateInfo pool_create_info{};
	pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	pool_create_info.queueFamilyIndex = r._graphics_family_index;// probably which queue to execute the commmand
	pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	std::cout << "Command Pool Created" << std::endl;
	ErrorCheck(vkCreateCommandPool(device, &pool_create_info, nullptr, &command_pool));

	// Command Buffer
	VkCommandBuffer command_buffer[2];
	VkCommandBufferAllocateInfo command_buffer_allocate_info{};
	command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	command_buffer_allocate_info.commandPool = command_pool;
	command_buffer_allocate_info.commandBufferCount = 2;// how many command buffer to allocate for the pool
	command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;//
	// initial state
	vkAllocateCommandBuffers(device, &command_buffer_allocate_info, command_buffer);
	{
		
		VkCommandBufferBeginInfo begin_info{};
		begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
		//begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
		// recording state
		vkBeginCommandBuffer(command_buffer[0], &begin_info);

		// vkCmd...
		vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 0, nullptr);

		// need to set viewport per command buffer
		VkViewport viewport{};
		viewport.maxDepth = 1.0f;
		viewport.minDepth = 0.0f;
		viewport.width = 512;
		viewport.height = 512;
		viewport.x = 0;
		viewport.y = 0;
		vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);

		// executable state, end recording compile the cb on gpu?? 
		vkEndCommandBuffer(command_buffer[0]);
	}
	{

		VkCommandBufferBeginInfo begin_info{};
		begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
		//begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
		// recording state
		vkBeginCommandBuffer(command_buffer[1], &begin_info);

		// vkCmd...

		// need to set viewport per command buffer
		VkViewport viewport{};
		viewport.maxDepth = 1.0f;
		viewport.minDepth = 0.0f;
		viewport.width = 512;
		viewport.height = 512;
		viewport.x = 0;
		viewport.y = 0;
		vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);

		// executable state, end recording compile the cb on gpu?? 
		vkEndCommandBuffer(command_buffer[1]);
	}
	{
		// submit command buffer to gpu
		VkSubmitInfo submit_info{};
		submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
		submit_info.commandBufferCount = 1;
		submit_info.pCommandBuffers = &command_buffer[0];
		submit_info.signalSemaphoreCount = 1;
		submit_info.pSignalSemaphores = &semaphore;// signal the semaphore

		// submit command buffer to gpu
		//vkQueueSubmit(queue, 1, &submit_info, fence);
		vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
	}
	{
		//VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT };
		VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };// all need to be done after signaled
		// submit command buffer to gpu
		VkSubmitInfo submit_info{};
		submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
		submit_info.commandBufferCount = 1;
		submit_info.pCommandBuffers = &command_buffer[1];
		submit_info.waitSemaphoreCount = 1;
		submit_info.pWaitSemaphores = &semaphore;
		// where we are going to wait for semaphores, as signaled then access certain stage
		// as the command buffer reaches fragment shader stage, it wait for the semaphore
		submit_info.pWaitDstStageMask = flags;// pipeline stage mask

		// submit command buffer to gpu
		vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
	}

	// true: need to wait for all fence to complete before continue, false: wait only 1 fence
	//vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);

	// gpu works concurrently with cpu, wait for the queue
	// wait for the submit to be done
	// if commented , error: Attempt to destroy command pool with VkCommandBuffer 0x2109f440ab0[] which is in use.
	// because command buffer wasn't complete on gpu when cpu tries to delete it,need to wait on cpu side
	vkQueueWaitIdle(queue);

	// destroy command pool
	vkDestroyCommandPool(device, command_pool, nullptr);
	vkDestroyFence(device, fence, nullptr);
	vkDestroySemaphore(device, semaphore, nullptr);
}

Render.cpp

#include "Renderer.h"

Renderer::Renderer() {
	_SetupDebug();
	_InitInstance();
	_InitDebug();
	_InitDevice();
}

Renderer::~Renderer() {
	_DeInitDevice();
	_DeInitDebug();
	_DeInitInstance();
}

void Renderer::_InitInstance()
{
	VkApplicationInfo application_info{};
	application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	application_info.apiVersion = VK_API_VERSION_1_3;//tells driver api version
	application_info.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
	application_info.pApplicationName = "Vulkan_tutorial_1";

	VkInstanceCreateInfo instance_create_info{};
	instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	instance_create_info.pApplicationInfo = &application_info;
	instance_create_info.enabledLayerCount = _instance_layers.size();
	instance_create_info.ppEnabledLayerNames = _instance_layers.data();
	instance_create_info.enabledExtensionCount = _instance_extensions.size();
	instance_create_info.ppEnabledExtensionNames = _instance_extensions.data();
	//instance_create_info.pNext = &debug_callback_create_info;// add loader message

	//std::cout << "Vulkan Instance create error check" << std::endl;
	ErrorCheck(vkCreateInstance(&instance_create_info, nullptr, &_Instance));
}

void Renderer::_DeInitInstance() {
	vkDestroyInstance(_Instance, nullptr);
	_Instance = nullptr;

}

void Renderer::_InitDevice()
{
	// give the logical device used to render
	{
		uint32_t gpu_count = 0;
		// return gpu_count
		vkEnumeratePhysicalDevices(_Instance, &gpu_count, nullptr);
		std::vector<VkPhysicalDevice> gpu_list(gpu_count);
		// return the number of handles actually written to pPhysicalDevices
		vkEnumeratePhysicalDevices(_Instance, &gpu_count, gpu_list.data());
		_gpu = gpu_list[0];
		// properties are returned
		vkGetPhysicalDeviceProperties(_gpu, &_gpu_properties);
	}
	{
		// get _graphics_family_index
		// similarly query properties of queues available on a physical device
		uint32_t family_count = 0;
		vkGetPhysicalDeviceQueueFamilyProperties(_gpu, &family_count, nullptr);
		std::vector<VkQueueFamilyProperties> family_property_list{ family_count };
		vkGetPhysicalDeviceQueueFamilyProperties(_gpu, &family_count, family_property_list.data());

		bool found = false;
		for (uint32_t i = 0; i < family_count; ++i) {
			// VK_QUEUE_GRAPHICS_BIT specifies that queues in this queue family support graphics operations.
			if (family_property_list[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
				found = true;
				_graphics_family_index = i;
			}
		}
		if (!found) {
			assert(0 && "VULKAN ERROR: QUEUE FAMILY SUPPORT NOT FOUND");
			std::cout << "VULKAN ERROR: QUEUE FAMILY SUPPORT NOT FOUND " << std::endl;
			std::exit(-1);
		}
	}
	{
		// how many instance layers, instances
		uint32_t layer_count = 0;
		vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
		std::vector<VkLayerProperties> layer_property_list(layer_count);
		// gives the layer currently installed in the system
		vkEnumerateInstanceLayerProperties(&layer_count, layer_property_list.data());
		std::cout << "instance_layers " << std::endl;
		for (auto& i : layer_property_list) {
			std::cout << " " << i.layerName << "\t\t  | " << i.description << std::endl;
		}
		std::cout << std::endl;
		/*
		instance_layers
		 VK_LAYER_AMD_switchable_graphics                 | AMD switchable graphics layer
		 VK_LAYER_RENDERDOC_Capture               | Debugging capture layer for RenderDoc
		 VK_LAYER_LUNARG_api_dump                 | LunarG API dump layer
		 VK_LAYER_LUNARG_gfxreconstruct           | GFXReconstruct Capture Layer Version 0.9.15
		 VK_LAYER_KHRONOS_synchronization2                | Khronos Synchronization2 layer
		 VK_LAYER_KHRONOS_validation              | Khronos Validation Layer
		 VK_LAYER_LUNARG_monitor                  | Execution Monitoring Layer
		 VK_LAYER_LUNARG_screenshot               | LunarG image capture layer
		 VK_LAYER_KHRONOS_profiles                | Khronos Profiles layer
		*/
	}
	{
		// how many instance layers, instances
		uint32_t layer_count = 0;
		vkEnumerateDeviceLayerProperties(_gpu, &layer_count, nullptr);
		std::vector<VkLayerProperties> layer_property_list(layer_count);
		// gives the layer currently installed in the system
		vkEnumerateDeviceLayerProperties(_gpu, &layer_count, layer_property_list.data());
		std::cout << "device_layers " << std::endl;
		for (auto& i : layer_property_list) {
			std::cout << " " << i.layerName << "\t\t  | " << i.description << std::endl;
		}
		std::cout << std::endl;
	}

	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 = _device_layers.size();
	device_create_info.ppEnabledLayerNames = _device_layers.data();
	device_create_info.enabledExtensionCount = _device_extensions.size();
	device_create_info.ppEnabledExtensionNames = _device_extensions.data();

	// return device
	//std::cout << "VULKAN ERROR: QUEUE FAMILY SUPPORTING GRAPHICS NOT FOUND CHECK" << std::endl;
	ErrorCheck(vkCreateDevice(_gpu, &device_create_info, nullptr, &_device));

	// fetch the queue handle
	vkGetDeviceQueue(_device, _graphics_family_index, 0, &_queue);// 0 < queue_count_family = 1
}

void Renderer::_DeInitDevice() {
	vkDestroyDevice(_device, nullptr);
	_device = nullptr;
}

VKAPI_ATTR VkBool32  VKAPI_CALL
VulkanDebugCallBack(
	VkDebugReportFlagsEXT flags,// VkDebugReportCallbackCreateInfoEXT.flags
	VkDebugReportObjectTypeEXT obj_type,
	uint64_t src_obj,
	size_t location,
	int32_t msg_code,
	const char* layer_prefix,
	const char* msg,
	void* user_data

)
{
	// flags has bit on xxx
	if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
		std::cout << "DEBUG INFO: ";
	}
	if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
		std::cout << "DEBUG WARNING: ";
	}
	if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
		std::cout << "DEBUG PERFORMANCE_WARNING: ";
	}
	if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
		std::cout << "DEBUG ERROR: ";
	}
	if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
		std::cout << "DEBUG DEBUG: ";
	}
	std::cout << "@[ " << layer_prefix << " ]: ";
	std::cout << msg << std::endl;
	return false;
}

void Renderer::_SetupDebug()
{
	debug_callback_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
	debug_callback_create_info.pfnCallback = VulkanDebugCallBack;//  PFN_vkDebugReportCallbackEXT
	debug_callback_create_info.flags = 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 | \
		VK_DEBUG_REPORT_DEBUG_BIT_EXT;

	// layer needed to use is in the device, must be in the instance

	_instance_layers.push_back("VK_LAYER_KHRONOS_validation");
	_device_layers.push_back("VK_LAYER_KHRONOS_validation");

	//_instance_layers.push_back("VK_LAYER_AMD_switchable_graphics");
	//_device_layers.push_back("VK_LAYER_AMD_switchable_graphics");

	_instance_layers.push_back("VK_LAYER_RENDERDOC_Capture");
	_device_layers.push_back("VK_LAYER_RENDERDOC_Capture");

	// too much info
	//_instance_layers.push_back("VK_LAYER_LUNARG_api_dump");
	//_device_layers.push_back("VK_LAYER_LUNARG_api_dump");

	_instance_layers.push_back("VK_LAYER_LUNARG_gfxreconstruct");
	_device_layers.push_back("VK_LAYER_LUNARG_gfxreconstruct");

	// VK_ERROR_LAYER_NOT_PRESENT
	//_instance_layers.push_back(" VK_LAYER_KHRONOS_synchronization2");
	//_device_layers.push_back(" VK_LAYER_KHRONOS_synchronization2");

	//_instance_layers.push_back("VK_LAYER_LUNARG_monitor");
	//_device_layers.push_back("VK_LAYER_LUNARG_monitor");

	//_instance_layers.push_back("VK_LAYER_LUNARG_screenshot");
	//_device_layers.push_back("VK_LAYER_LUNARG_screenshot");

	//_instance_layers.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
	_instance_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
	//_device_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);

	// VK_ERROR_LAYER_NOT_PRESENT
	//_instance_layers.push_back(" VK_LAYER_KHRONOS_profiles");
	//_device_layers.push_back(" VK_LAYER_KHRONOS_profiles");



}

PFN_vkCreateDebugReportCallbackEXT fvkCreateDebugReportCallbackEXT = nullptr;
PFN_vkDestroyDebugReportCallbackEXT fvkDestroyDebugReportCallbackEXT = nullptr;

void Renderer::_InitDebug()
{
	// function pointer??
	fvkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(_Instance, "vkCreateDebugReportCallbackEXT");
	fvkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(_Instance, "vkDestroyDebugReportCallbackEXT");
	if (nullptr == fvkCreateDebugReportCallbackEXT || nullptr == fvkDestroyDebugReportCallbackEXT) {
		assert(0 && "Vulkan can't take debug function pointer");
		std::cout << "Vulkan can't take debug function pointer" << std::endl;
		std::exit(-1);
	}


	//std::cout << "Vulkan failed to set up a debug message check" << std::endl;
	ErrorCheck(fvkCreateDebugReportCallbackEXT(_Instance, &debug_callback_create_info, nullptr, &_debug_report));

	//fvkCreateDebugReportCallbackEXT(_Instance, nullptr, nullptr, nullptr);
}

void Renderer::_DeInitDebug()
{
	fvkDestroyDebugReportCallbackEXT(_Instance, _debug_report, nullptr);
	_debug_report = VK_NULL_HANDLE;
}

Render.h

#pragma once

#include <vulkan/vulkan.h>
#include "Shared.h"
#include <vector>
#include <iostream>
#include <cstdlib>
#include <assert.h>

class Renderer
{
public:
	Renderer();
	~Renderer();
//private:
	void _InitInstance();
	void _DeInitInstance();

	void _InitDevice();
	void _DeInitDevice();

	void _SetupDebug();
	void _InitDebug();
	void _DeInitDebug();

	VkInstance _Instance = VK_NULL_HANDLE;
	VkPhysicalDevice _gpu = VK_NULL_HANDLE;
	VkDevice _device = VK_NULL_HANDLE;
	VkPhysicalDeviceProperties _gpu_properties = {};
	VkQueue _queue = VK_NULL_HANDLE;

	uint32_t _graphics_family_index = 0;

	std::vector<const char*> _instance_layers;
	std::vector<const char*> _instance_extensions;
	std::vector<const char*> _device_layers;
	std::vector<const char*> _device_extensions;

	VkDebugReportCallbackEXT _debug_report = VK_NULL_HANDLE;

	VkDebugReportCallbackCreateInfoEXT debug_callback_create_info{};

};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值