Vulkan & OpenGL Differences (Shaded Triangle)
1. Explicit Control
2. Command Buffers
3. Multiple Queues
4. Pipeline Creation
5. Synchronization
6. Resource Binding
7. Shader Modules
8. Render Passes
Summary
Shaded Triangle Steps
OpenGL Steps
+--------------------------------------+
| OpenGL Application |
| (Setup and Initialization) |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Shader Program |
| GLuint shaderProgram = glCreateProgram(); |
| glAttachShader(shaderProgram, vertexShader); |
| glAttachShader(shaderProgram, fragmentShader); |
| glLinkProgram(shaderProgram); |
+--------------------------------------+
|
v
+--------------------------------------+
| Setup Vertex Array Object |
| GLuint VAO; |
| glGenVertexArrays(1, &VAO); |
| glBindVertexArray(VAO); |
| glGenBuffers(1, &VBO); |
| glBindBuffer(GL_ARRAY_BUFFER, VBO); |
| glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); |
| glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); |
| glEnableVertexAttribArray(0); |
+--------------------------------------+
|
v
+--------------------------------------+
| Draw Call |
| glUseProgram(shaderProgram); |
| glBindVertexArray(VAO); |
| glDrawArrays(GL_TRIANGLES, 0, 3);|
+--------------------------------------+
|
v
+--------------------------------------+
| Framebuffer |
| SwapBuffers(window); |
+--------------------------------------+
Vulkan Steps
+--------------------------------------+
| Vulkan Application |
| (Setup and Initialization) |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Instance |
| vkCreateInstance(&instanceInfo, &instance); |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Device |
| vkCreateDevice(instance, &deviceCreateInfo, &device); |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Shader Modules |
| vkCreateShaderModule(device, &vertShaderInfo, &vertShaderModule); |
| vkCreateShaderModule(device, &fragShaderInfo, &fragShaderModule); |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Graphics Pipeline |
| vkCreateGraphicsPipelines(device, &pipelineInfo, &pipeline); |
+--------------------------------------+
|
v
+--------------------------------------+
| Create Vertex Buffer |
| vkCreateBuffer(device, &bufferCreateInfo, &vertexBuffer); |
| vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory); |
+--------------------------------------+
|
v
+--------------------------------------+
| Allocate Command Buffer |
| vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer); |
+--------------------------------------+
|
v
+--------------------------------------+
| Record Command Buffer |
| vkBeginCommandBuffer(commandBuffer, &beginInfo); |
| vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); |
| vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer, offsets); |
| vkCmdDraw(commandBuffer, 3, 1, 0, 0); |
| vkEndCommandBuffer(commandBuffer); |
+--------------------------------------+
|
v
+--------------------------------------+
| Submit Command Buffer |
| vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); |
+--------------------------------------+
|
v
+--------------------------------------+
| Render Pass |
| vkBeginRenderPass(commandBuffer, &renderPassInfo); |
+--------------------------------------+
|
v
+--------------------------------------+
| Framebuffer |
| vkEndRenderPass(commandBuffer); |
| vkQueuePresentKHR(presentQueue, &presentInfo); |
+--------------------------------------+
1. Initialize Vulkan
- Create a Vulkan Instance:
- This is the starting point for any Vulkan application and contains information about the application and the Vulkan API version.
- Use
vkCreateInstance
to create a Vulkan instance.
- Use
- This is the starting point for any Vulkan application and contains information about the application and the Vulkan API version.
2. Select a Physical Device
- Enumerate Physical Devices:
- Find available physical devices (GPUs) on the system.
- Use
vkEnumeratePhysicalDevices
- Use
- Find available physical devices (GPUs) on the system.
- Select a Suitable Device:
- Choose a physical device that supports the features and queues you need (like graphics, compute, etc.).
3. Create a Logical Device
- Create Logical Device:
- Create a logical device that allows your application to interact with the physical device. Specify the queue types needed, such as a graphics queue.
- Use
vkCreateDevice
- Use
- Create a logical device that allows your application to interact with the physical device. Specify the queue types needed, such as a graphics queue.
4. Create a Swap Chain
- Choose Swap Chain Parameters:
- Determine the swap chain's surface format, presentation mode, and extent.
- Create Swap Chain:
- Create the swap chain, which handles presenting images to the screen.
- Use
vkCreateSwapchainKHR
- Use
- Create the swap chain, which handles presenting images to the screen.
5. Create Image Views
- Create Image Views:
- For each image in the swap chain, create an image view using
vkCreateImageView
. This allows Vulkan to access the images in the swap chain.
- For each image in the swap chain, create an image view using
6. Create Render Pass
- Define Render Pass:
- Create a render pass that defines how framebuffer attachments (color, depth, etc.) are used during rendering.
- Use
vkCreateRenderPass
- Use
- Create a render pass that defines how framebuffer attachments (color, depth, etc.) are used during rendering.
7. Create Framebuffers
- Create Framebuffers:
- For each image view in the swap chain, create a framebuffer using
vkCreateFramebuffer
. This links the image views with the render pass.
- For each image view in the swap chain, create a framebuffer using
8. Create Shaders
- Load Shader Code:
- Load the vertex and fragment shader code, typically written in GLSL or HLSL.
- Create Shader Modules:
- Create shader modules for both the vertex and fragment shaders.
- Use
vkCreateShaderModule
- Use
- Create shader modules for both the vertex and fragment shaders.
9. Create Graphics Pipeline
- Define Graphics Pipeline:
- Use
vkCreateGraphicsPipelines
to create the graphics pipeline. - This involves specifying the shader stages, fixed-function state (like viewport, rasterization, blending), and the render pass.
- Use
10. Create Vertex Buffer
- Create Buffer:
- Create a vertex buffer that holds the triangle's vertex data (positions, colors, etc.).
- Use
vkCreateBuffer
- Use
- Create a vertex buffer that holds the triangle's vertex data (positions, colors, etc.).
- Allocate Memory:
- Allocate memory for the vertex buffer using
vkAllocateMemory
and bind it usingvkBindBufferMemory
.
- Allocate memory for the vertex buffer using
- Copy Data:
- Map the memory, copy the vertex data into it, and unmap the memory.
11. Create Command Buffers
- Allocate Command Buffers:
- Allocate command buffers for recording commands.
- Use
vkAllocateCommandBuffers
- Use
- Allocate command buffers for recording commands.
12. Record Commands
- Begin Command Buffer:
- Start recording commands in the command buffer.
- Use
vkBeginCommandBuffer
- Use
- Start recording commands in the command buffer.
- Begin Render Pass:
-
- Use
vkCmdBeginRenderPass
- Use
-
- Bind Graphics Pipeline:
-
- Use
vkCmdBindPipeline
- Use
-
- Bind Vertex Buffer:
-
- Use
vkCmdBindVertexBuffers
- Use
-
- Draw Command:
- Use
vkCmdDraw
to issue the draw command for the triangle.
- Use
- End Render Pass:
- Use
vkCmdEndRenderPass
to finish the render pass.
- Use
- End Command Buffer:
- Use
vkEndCommandBuffer
to finalize the command buffer.
- Use
13. Submit Command Buffer
- Submit to Queue:
- Submit the recorded command buffer to the graphics queue for execution.
- Use
vkQueueSubmit
- Use
- Submit the recorded command buffer to the graphics queue for execution.
14. Presenting the Image
- Present the Frame:
- Present the rendered image from the swap chain to the screen.
- Use
vkQueuePresentKHR
- Use
- Present the rendered image from the swap chain to the screen.
15. Cleanup
- Cleanup Resources:
- Destroy resources in the reverse order of their creation, such as pipelines, framebuffers, swap chains, and the Vulkan instance.
RESOURCES
https://edw.is/learning-vulkan/#what-i-gained-from-switching-to-vulkan
No Comments