当前位置:网站首页>Vulkan practice first bullet
Vulkan practice first bullet
2022-07-03 00:43:00 【I haven't had quiet memories for a long time】
In the last article , We analyzed Vulkan For traditional graphics API The advantages of , Mainly in its performance and fine control GPU On , For details, please refer to Vulkan- Performance and refinement
Today we will use a simple example , Feel for yourself Vulkan Development of “ charm ”.
#include <iostream>
#include <chrono>
#include <cstring>
#include <glm/mat4x4.hpp>
#include <glm/gtx/transform.hpp>
#include "VK_UniformBuffer.h"
#include "VK_Context.h"
#include "VK_Pipeline.h"
#include "VK_DynamicState.h"
using namespace std;
const std::vector<uint32_t> indices = {
0, 1, 2
};
const std::vector<float> vertices = {
0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5
};
VK_Context *context = nullptr;
VK_Pipeline *pipeline = nullptr;
// When the window size changes, it passes onFrameSizeChanged Update window size
void onFrameSizeChanged(int width, int height)
{
pipeline->getDynamicState()->applyDynamicViewport({0, 0, (float)width, (float)height, 0, 1});
}
// Real time updates uniform value
uint32_t updateUniformBufferData(char *&data, uint32_t size)
{
static auto start = std::chrono::high_resolution_clock::now();
auto current = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>
(current - start).count();
glm::mat4 model = glm::rotate(glm::mat4(1.0f), time * glm::radians(30.0f), glm::vec3(0.0f, 0.0f,
1.0f));
memcpy(data, &model[0][0], size);
return sizeof(model);
}
int main()
{
VK_ContextConfig config;
config.debug = true;
config.name = "Uniform Demo";
context = createVkContext(config);
context->createWindow(640, 640, true);
context->setOnFrameSizeChanged(onFrameSizeChanged);
VK_Context::VK_Config vkConfig;
context->initVulkanDevice(vkConfig);
auto shaderSet = context->createShaderSet();
shaderSet->addShader("../jianghuxiuxing/shader/mvp/vertex.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addShader("../jianghuxiuxing/shader/mvp/fragmeng.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
shaderSet->appendAttributeDescription(0, sizeof (float) * 3, VK_FORMAT_R32G32B32_SFLOAT, 0);
shaderSet->appendAttributeDescription(1, sizeof (float) * 4, VK_FORMAT_R32G32B32A32_SFLOAT,
sizeof(float) * 3);
shaderSet->appendVertexInputBindingDescription(7 * sizeof(float), 0, VK_VERTEX_INPUT_RATE_VERTEX);
VkDescriptorSetLayoutBinding uniformBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT);
shaderSet->addDescriptorSetLayoutBinding(uniformBinding);
if (!shaderSet->isValid()) {
std::cerr << "invalid shaderSet" << std::endl;
shaderSet->release();
context->release();
return -1;
}
auto ubo = shaderSet->addUniformBuffer(0, sizeof(float) * 16);
ubo->setWriteDataCallback(updateUniformBufferData);
context->initVulkanContext();
pipeline = context->createPipeline(shaderSet);
pipeline->getDynamicState()->addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
pipeline->create();
pipeline->getDynamicState()->applyDynamicViewport({0, 0, 480, 480, 0, 1});
auto buffer = context->createVertexBuffer(vertices, 3 + 4, indices);
pipeline->addRenderBuffer(buffer);
context->createCommandBuffers();
context->run();
context->release();
return 0;
}Vertex Shader
#version 450
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
layout(location = 0) out vec4 fragColor;
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
} mvp;
void main() {
gl_Position = mvp.model * vec4(position, 1.0);
fragColor = color;
}Fragment Shader
#version 450
layout(location = 0) in vec4 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = fragColor;
}
effect :

From the above code implementation, we can see that Vulkan In the load spv Bytecode , According to specified shader All attributes are subject to more cumbersome restrictions , Developers need to pay more attention to program control and execution timing , This also confirms what we said in our last article Vulkan Instead of traditional graphics API Take care of everything , More checksums are delegated to the programmer .
Vulkan Rendering process of
- Create program window
- initialization Vulkan example - vulkan Initialization of the library
- Initialize the output surface - Indicates the render display destination
- Select the physical device that meets the requirements ( Usually more than one , For renderers , Physical devices are usually required to support graphics queues and surface rendering queues )
- Create logical devices - Logical devices can be created according to the specified physical devices ( Logical devices correspond to physical devices , But not the only )
- Create an instruction pool object - vulkan Instruction submission and transmission in require instruction buffering , For instruction buffering, you need to build an instruction pool object
- Create the exchange chain - vulkan There is no concept of default frame buffer in , You need a component that caches the rendering buffer , This is the exchange chain . The exchange chain is essentially a queue containing several images waiting to be presented
- Create an exchange queue image view - With the exchange chain is not enough , You need a set of graphics to save the rendering data
- Create render channels - Render channels are used to represent frame buffers , It is a collection of subchannels and subchannel relationships . Depth template attachment 、 Color accessories 、 Frame attachments are created at this stage
- Create descriptor layout - Descriptor is a special opaque shader variable , Shaders use it to access buffers and image resources indirectly . Descriptor set describes the descriptor set used by a pipeline . Descriptor layout is used to describe its layout .
- Create a route layout - The pipeline layout contains a list of descriptor set layouts
- Create frame buffer - The image as an attachment depends on the image returned when the exchange chain is used for rendering . This means that we must create a frame buffer for all images in the swap chain , And use the corresponding image when drawing . Its attachments must match those used in the render channel .
- Create descriptor pool - Descriptors need to be allocated from the pool , You can't create... Directly
- Create descriptor set - Descriptor pool is based on the number of exchange chain frames and Shader The number of descriptors and data in ,Shader Attribute types and the uninform、location Such information is transmitted at this stage
- Allocate and change row descriptor sets - Number of exchange chain frames 、uniform Data and graphical views are processed at this stage
- Create pipelines - according to Shader、 Pipeline layout 、 Render channels and other relevant information to construct pipelines ( You need to set various attribute associations Shader, Vertex input format , Viewport state , Rasterize , Multiple sampling is optional )
- Create command buffer - According to the command pool 、 Render channel 、 The number of exchange chain frames can be allocated and buffered with commands , Among them, the binding of pipelines 、 The binding of descriptor sets and the start and end rendering channels are completed in this stage .
- Render loop - Take the image from the exchange chain ( utilize vkAcquireNextImageKHR), to update uniform data - vkMapMemory、vkUnmapMemory, Commit instruction buffer ( utilize vkQueueSubmit), The image is sent back to the exchange chain for presentation .( It's a very complicated process , because Vulkan Multithreading needs to ensure synchronization, etc )
- Pipeline reconstruction - Pipelines are not always effective , If the rendering is lost or the window size changes or the pipeline configuration changes, the exchange chain and pipeline need to be reconstructed .( Related nodes also need to be rebuilt , For example, exchange chain , Render channel , Buffer pool, etc )
边栏推荐
- [Luogu p4320] road meets (round square tree)
- Multiprocess programming (I): basic concepts
- 2022中国3D视觉企业(引导定位、分拣场景)厂商名单
- Gan model architecture in mm
- 奥斯陆大学:Li Meng | 基于Swin-Transformer的深度强化学习
- NC24325 [USACO 2012 Mar S]Flowerpot
- 多进程编程(二):管道
- Automated defect analysis in electronic microscopic images
- antv x6节点拖拽到画布上后的回调事件(踩大坑记录)
- Shell 实现文件基本操作(sed-编辑、awk-匹配)
猜你喜欢
随机推荐
Rust字符串切片、结构体和枚举类
NC50528 滑动窗口
关于Unity屏幕相关Screen的练习题目,Unity内部环绕某点做运动
Nc17059 queue Q
1.12 - Instructions
Automated defect analysis in electronic microscopic images
详解用OpenCV的轮廓检测函数findContours()得到的轮廓拓扑结构(hiararchy)矩阵的意义、以及怎样用轮廓拓扑结构矩阵绘制轮廓拓扑结构图
微信小程序获取某个元素的信息(高、宽等),并将px转换为rpx。
Rust string slicing, structs, and enumeration classes
【Pulsar文档】概念和架构/Concepts and Architecture
在线预览Word文档
[golang syntax] map common errors golang panic: assignment to entry in nil map
免费自媒体必备工具分享
1.11 - bus
About qbytearray storage hexadecimal and hexadecimal conversion
为什么网站打开速度慢?
Markdown tutorial
University of Oslo: Li Meng | deep reinforcement learning based on swing transformer
[shutter] image component (load network pictures | load static pictures | load local pictures | path | provider plug-in)
Linux软件:如何安装Redis服务








