Vulkan流程图

参照vulkan指南中的示例程序,感觉Vulkan的对象太多了,很难记住,结合Triangle的代码和网上的一些资料,自己画了一下关系图,完成之后终于有了一个完整的印象。

Vulkan绘制一个三角形的伪代码 

#include <vulkan/vulkan.h>
// Pseudocode of what an application looks like. I've omitted most creation structures,
// almost all synchronisation and all error checking. This is not a copy‐paste guide!
void DoVulkanRendering()
{
	const char *extensionNames[] = { "VK_KHR_surface", "VK_KHR_win32_surface" };
	// future structs will not be detailed, but this one is for illustration.
	// Application info is optional (you can specify application/engine name and version)
	// Note we activate the WSI instance extensions, provided by the ICD to
	// allow us to create a surface (win32 is an example, there's also xcb/xlib/etc)
	VkInstanceCreateInfo instanceCreateInfo = {
		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType;
		NULL, // const void* pNext;
		0, // VkInstanceCreateFlags flags;
		NULL, // const VkApplicationInfo* pApplicationInfo;
		0, // uint32_t enabledLayerNameCount;
		NULL, // const char* const* ppEnabledLayerNames;
		2, // uint32_t enabledExtensionNameCount;
		extensionNames, // const char* const* ppEnabledExtensionNames;
	};
	VkInstance inst;
	vkCreateInstance(&instanceCreateInfo, NULL, &inst);
	// The enumeration pattern SHOULD be to call with last parameter NULL to
	// get the count, then call again to get the handles. For brevity, omitted
	VkPhysicalDevice phys[4]; uint32_t physCount = 4;
	vkEnumeratePhysicalDevices(inst, &physCount, phys);
	VkDeviceCreateInfo deviceCreateInfo = {
		// I said I was going to start omitting things!
	};
	VkDevice dev;
	vkCreateDevice(phys[0], &deviceCreateInfo, NULL, &dev);
	// fetch vkCreateWin32SurfaceKHR extension function pointer via vkGetInstanceProcAddr
	VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = {
		// HINSTANCE, HWND, etc
	};
	VkSurfaceKHR surf;
	vkCreateWin32SurfaceKHR(inst, &surfaceCreateInfo, NULL, &surf);
	VkSwapchainCreateInfoKHR swapCreateInfo = {
		// surf goes in here
	};
	VkSwapchainKHR swap;
	vkCreateSwapchainKHR(dev, &swapCreateInfo, NULL, &swap);
	// Again this should be properly enumerated
	VkImage images[4]; uint32_t swapCount;
	vkGetSwapchainImagesKHR(dev, swap, &swapCount, images);
	// Synchronisation is needed here!
	uint32_t currentSwapImage;
	vkAcquireNextImageKHR(dev, swap, UINT64_MAX, presentCompleteSemaphore, NULL, &currentSwapImage);
	// pass appropriate creation info to create view of image
	VkImageView backbufferView;
	vkCreateImageView(dev, &backbufferViewCreateInfo, NULL, &backbufferView);
	VkQueue queue;
	vkGetDeviceQueue(dev, 0, 0, &queue);
	VkRenderPassCreateInfo renderpassCreateInfo = {
		// here you will specify the total list of attachments
		// (which in this case is just one, that's e.g. R8G8B8A8_UNORM)
		// as well as describe a single subpass, using that attachment
		// for color and with no depth‐stencil attachment
	};
	VkRenderPass renderpass;
	vkCreateRenderPass(dev, &renderpassCreateInfo, NULL, &renderpass);
	VkFramebufferCreateInfo framebufferCreateInfo = {
		// include backbufferView here to render to, and renderpass to be
		// compatible with.
	};
	VkFramebuffer framebuffer;
	vkCreateFramebuffer(dev, &framebufferCreateInfo, NULL, &framebuffer);
	VkDescriptorSetLayoutCreateInfo descSetLayoutCreateInfo = {
		// whatever we want to match our shader. e.g. Binding 0 = UBO for a simple
		// case with just a vertex shader UBO with transform data.
	};
	VkDescriptorSetLayout descSetLayout;
	vkCreateDescriptorSetLayout(dev, &descSetLayoutCreateInfo, NULL, &descSetLayout);
	VkPipelineCreateInfo pipeLayoutCreateInfo = {
		// one descriptor set, with layout descSetLayout
	};
	VkPipelineLayout pipeLayout;
	vkCreatePipelineLayout(dev, &pipeLayoutCreateInfo, NULL, &pipeLayout);
	// upload the SPIR‐V shaders
	VkShaderModule vertModule, fragModule;
	vkCreateShaderModule(dev, &vertModuleInfoWithSPIRV, NULL, &vertModule);
	vkCreateShaderModule(dev, &fragModuleInfoWithSPIRV, NULL, &fragModule);
	VkGraphicsPipelineCreateInfo pipeCreateInfo = {
		// there are a LOT of sub‐structures under here to fully specify
		// the PSO state. It will reference vertModule, fragModule and pipeLayout
		// as well as renderpass for compatibility
	};
	VkPipeline pipeline;
	vkCreateGraphicsPipelines(dev, NULL, 1, &pipeCreateInfo, NULL, &pipeline);
	VkDescriptorPoolCreateInfo descPoolCreateInfo = {
		// the creation info states how many descriptor sets are in this pool
	};
	VkDescriptorPool descPool;
	vkCreateDescriptorPool(dev, &descPoolCreateInfo, NULL, &descPool);
	VkDescriptorSetAllocateInfo descAllocInfo = {
		// from pool descPool, with layout descSetLayout
	};
	VkDescriptorSet descSet;
	vkAllocateDescriptorSets(dev, &descAllocInfo, &descSet);
	VkBufferCreateInfo bufferCreateInfo = {
		// buffer for uniform usage, of appropriate size
	};
	VkMemoryAllocateInfo memAllocInfo = {
		// skipping querying for memory requirements. Let's assume the buffer
		// can be placed in host visible memory.
	};
	VkBuffer buffer;
	VkDeviceMemory memory;
	vkCreateBuffer(dev, &bufferCreateInfo, NULL, &buffer);
	vkAllocateMemory(dev, &memAllocInfo, NULL, &memory);
	vkBindBufferMemory(dev, buffer, memory, 0);
	void *data = NULL;
	vkMapMemory(dev, memory, 0, VK_WHOLE_SIZE, 0, &data);
	// fill data pointer with lovely transform goodness
	vkUnmapMemory(dev, memory);
	VkWriteDescriptorSet descriptorWrite = {
		// write the details of our UBO buffer into binding 0
	};
	vkUpdateDescriptorSets(dev, 1, &descriptorWrite, 0, NULL);
	// finally we can render something!
	// ...
	// Almost.
	VkCommandPoolCreateInfo commandPoolCreateInfo = {
		// nothing interesting
	};
	VkCommandPool commandPool;
	vkCreateCommandPool(dev, &commandPoolCreateInfo, NULL, &commandPool);
	VkCommandBufferAllocateInfo commandAllocInfo = {
		// allocate from commandPool
	};
	VkCommandBuffer cmd;
	vkAllocateCommandBuffers(dev, &commandAllocInfo, &cmd);
	// Now we can render!
	vkBeginCommandBuffer(cmd, &cmdBeginInfo);
	vkCmdBeginRenderPass(cmd, &renderpassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
	// bind the pipeline
	vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
	// bind the descriptor set
	vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
	descSetLayout, 1, &descSet, 0, NULL);
	// set the viewport
	vkCmdSetViewport(cmd, 1, &viewport);
	// draw the triangle
	vkCmdDraw(cmd, 3, 1, 0, 0);
	vkCmdEndRenderPass(cmd);
	vkEndCommandBuffer(cmd);
	VkSubmitInfo submitInfo = {
		// this contains a reference to the above cmd to submit
	};
	vkQueueSubmit(queue, 1, &submitInfo, NULL);
	// now we can present
	VkPresentInfoKHR presentInfo = {
		// swap and currentSwapImage are used here
	};
	vkQueuePresentKHR(queue, &presentInfo);
	// Wait for everything to be done, and destroy objects
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值