Skip to content

Commit

Permalink
Vulkan 1 3 hello triangle sample (#1230)
Browse files Browse the repository at this point in the history
* Hello Triangle using Vulkan 1.3

1: It is using vertex buffer to load vertices compared to hardcoded in shader in hello_triangle 1.0
2: It is using dynamic rendering so frame buffers and Render passes removed
3: Used Synchronization2 in image layout transition.
3: Updated the code to use VK_DEBUG_UTILS (new) instead VK_DEBUG_REPORT(old)
4: Update the code to use Dynamic pipeline status
5: Removed unused parameters from functions
6: Used C++20 initializers
Signed-off-by: aliasifhuawei <[email protected]>

* Updated Antora requirement

* Updated Api README

* updated wait_stage with correct bit

* Updated Samples CMakeLists

* Removed portability related code

* run clang format

* Fixed alignment

* Fixed VkBufferCreateInfo flags

* Added topology for VkPipelineInputAssemblyStateCreateInfo

* Added missing VKB_DEBUG

* removed unnecessary shader stage code

* Remove unnecessary access to the old swapchain

* Moved tear down code to destructor as this is called once.

* Add missing Doxygen param

* tabifying cmake

* adjust define

* do a resize check

* updated with designated initialization

* simplified API check

* let default initialize component

* run clang-format

* Spacing

* Added a check of required feature

Re worked the structs to enable only the required features

* Update readme with what sample does and how it works

* Fixed shader path

* added comment for wait_stage

* indent fix

* Removed duplicate code comment
  • Loading branch information
alihuawei authored Dec 16, 2024
1 parent 646c3e4 commit 3792764
Show file tree
Hide file tree
Showing 9 changed files with 1,799 additions and 0 deletions.
1 change: 1 addition & 0 deletions antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
** xref:samples/api/hdr/README.adoc[HDR]
*** xref:samples/api/hpp_hdr/README.adoc[HDR (Vulkan-Hpp)]
** xref:samples/api/hello_triangle/README.adoc[Hello Triangle]
** xref:samples/api/hello_triangle_1_3/README.adoc[Hello Triangle 1.3]
*** xref:samples/api/hpp_hello_triangle/README.adoc[Hello Triangle (Vulkan-Hpp)]
** xref:samples/api/hlsl_shaders/README.adoc[HLSL Shaders]
*** xref:samples/api/hpp_hlsl_shaders/README.adoc[HLSL Shaders (Vulkan-Hpp)]
Expand Down
1 change: 1 addition & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ endforeach ()
set(ORDER_LIST
#API Samples
"hello_triangle"
"hello_triangle_1_3"
"dynamic_uniform_buffers"
"texture_loading"
"hdr"
Expand Down
4 changes: 4 additions & 0 deletions samples/api/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Implements a high dynamic range rendering pipeline using 16/32 bit floating poin

A self-contained (minimal use of framework) sample that illustrates the rendering of a triangle.

=== xref:./{api_samplespath}hello_triangle/README.adoc[Hello Triangle 1.3]

A self-contained (minimal use of framework) sample that illustrates the rendering of a triangle using Vulkan 1.3 features.

=== xref:./{api_samplespath}hpp_compute_nbody/README.adoc[HPP Compute shader N-Body simulation]

A transcoded version of the API sample xref:./{api_samplespath}compute_nbody/README.adoc[Compute N-Body] that illustrates the usage of the C{pp} bindings of Vulkan provided by vulkan.hpp.
Expand Down
33 changes: 33 additions & 0 deletions samples/api/hello_triangle_1_3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) 2024, Huawei Technologies Co., Ltd.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 the "License";
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

get_filename_component(FOLDER_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_LIST_DIR} PATH)
get_filename_component(CATEGORY_NAME ${PARENT_DIR} NAME)

add_sample(
ID ${FOLDER_NAME}
CATEGORY ${CATEGORY_NAME}
AUTHOR "Huawei Technologies Co., Ltd."
NAME "Vulkan 1.3 Hello Triangle"
DESCRIPTION "An introduction into Vulkan using Vulkan 1.3"
SHADER_FILES_GLSL
"hello_triangle_1_3/triangle.vert"
"hello_triangle_1_3/triangle.frag")
213 changes: 213 additions & 0 deletions samples/api/hello_triangle_1_3/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
////
* Copyright (c) 2024, Huawei Technologies Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
////
= Hello Triangle with Vulkan 1.3 Features
ifdef::site-gen-antora[]
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/api/hello_triangle_1_3[Khronos Vulkan samples github repository].
endif::[]
This sample demonstrates how to render a simple triangle using Vulkan 1.3 core features. It modernizes the traditional "Hello Triangle" Vulkan sample by incorporating:
- **Dynamic Rendering**
- **Synchronization2**
- **Extended Dynamic State**
- **Vertex Buffers**
## Overview
The sample renders a colored triangle to the screen using Vulkan 1.3. It showcases how to:
- Initialize Vulkan with Vulkan 1.3 features enabled.
- Use dynamic rendering to simplify the rendering pipeline.
- Employ the Synchronization2 API for improved synchronization.
- Utilize extended dynamic states to reduce pipeline complexity.
- Manage vertex data using vertex buffers instead of hard-coded vertices.
## Key Features
### 1. Dynamic Rendering
**What is Dynamic Rendering?**
Dynamic Rendering is a feature introduced in Vulkan 1.3 that allows rendering without pre-defined render passes and framebuffers. It simplifies the rendering process by enabling you to specify rendering states directly during command buffer recording.
**How It's Used in the Sample:**
- **No Render Passes or Framebuffers:** The sample does not create `VkRenderPass` or `VkFramebuffer` objects.
- **`vkCmdBeginRendering()` and `vkCmdEndRendering()`:** These functions are used to begin and end rendering operations dynamically.
- **Pipeline Creation:** Uses `VkPipelineRenderingCreateInfo` during pipeline creation to specify rendering details.
**Benefits:**
- Simplifies code by reducing boilerplate associated with render passes and framebuffers.
- Increases flexibility by allowing rendering to different attachments without recreating render passes.
### 2. Synchronization2
**What is Synchronization2?**
Synchronization2 is an improved synchronization API introduced in Vulkan 1.3. It provides more granular control over synchronization primitives and simplifies the synchronization process.
**How It's Used in the Sample:**
- **`vkCmdPipelineBarrier2()`:** Replaces the older `vkCmdPipelineBarrier()` for more detailed synchronization.
- **`VkDependencyInfo` and `VkImageMemoryBarrier2`:** Used to specify precise memory dependencies and image layout transitions.
**Example Usage:**
```cpp
VkImageMemoryBarrier2 image_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
// ... other members ...
};
VkDependencyInfo dependency_info = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &image_barrier,
};
vkCmdPipelineBarrier2(cmd, &dependency_info);
```
**Benefits:**
- Provides more expressive and flexible synchronization.
- Reduces the potential for synchronization errors.
- Simplifies the specification of pipeline stages and access masks.
### 3. Extended Dynamic State
**What is Extended Dynamic State?**
Extended Dynamic State allows more pipeline states to be set dynamically at command buffer recording time rather than during pipeline creation. This reduces the number of pipeline objects needed.
**How It's Used in the Sample:**
- **Dynamic States Enabled:** The sample enables dynamic states like `VK_DYNAMIC_STATE_CULL_MODE`, `VK_DYNAMIC_STATE_FRONT_FACE`, and `VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY`.
- **Dynamic State Commands:** Uses `vkCmdSetCullMode()`, `vkCmdSetFrontFace()`, and `vkCmdSetPrimitiveTopology()` to set these states dynamically.
**Example Usage:**
```cpp
vkCmdSetCullMode(cmd, VK_CULL_MODE_NONE);
vkCmdSetFrontFace(cmd, VK_FRONT_FACE_CLOCKWISE);
vkCmdSetPrimitiveTopology(cmd, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
```
**Benefits:**
- Reduces the need to create multiple pipelines for different state configurations.
- Enhances flexibility by allowing state changes without pipeline recreation.
### 4. Vertex Buffers
**What Changed?**
Unlike the original sample, which used hard-coded vertices in the shader, this sample uses a vertex buffer to store vertex data.
**How It's Used in the Sample:**
- **Vertex Structure Defined:**
```cpp
struct Vertex {
glm::vec2 position;
glm::vec3 color;
};
```
- **Vertex Data Stored in a Buffer:**
```cpp
std::vector<Vertex> vertices = {
{{0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, // Red Vertex
// ... other vertices ...
};
```
- **Buffer Creation and Memory Allocation:**
```cpp
VkBufferCreateInfo buffer_info = { /* ... */ };
vkCreateBuffer(device, &buffer_info, nullptr, &vertex_buffer);
VkMemoryAllocateInfo alloc_info = { /* ... */ };
vkAllocateMemory(device, &alloc_info, nullptr, &vertex_buffer_memory);
```
- **Binding the Vertex Buffer:**
```cpp
vkCmdBindVertexBuffers(cmd, 0, 1, &vertex_buffer, &offset);
```
**Benefits:**
- **Flexibility:** Easier to modify vertex data without changing shaders.
- **Performance:** Potentially better performance due to efficient memory usage.
- **Scalability:** Simplifies rendering more complex geometries.
## How the Sample Works
1. **Initialization:**
- **Instance Creation:** Initializes a Vulkan instance with Vulkan 1.3 API version and required extensions.
- **Device Selection:** Chooses a physical device that supports Vulkan 1.3 and required features.
- **Logical Device Creation:** Creates a logical device with enabled Vulkan 1.3 features like dynamic rendering, synchronization2, and extended dynamic state.
- **Surface and Swapchain Creation:** Sets up the window surface and initializes the swapchain for presenting images.
2. **Vertex Buffer Setup:**
- **Vertex Data Definition:** Defines vertices with positions and colors.
- **Buffer Creation:** Creates a buffer to store vertex data.
- **Memory Allocation:** Allocates memory for the buffer and maps the vertex data into it.
3. **Pipeline Setup:**
- **Shader Modules:** Loads and compiles vertex and fragment shaders.
- **Pipeline Layout:** Creates a pipeline layout (empty in this case as no descriptors are used).
- **Dynamic States Specification:** Specifies which states will be dynamic.
- **Graphics Pipeline Creation:** Creates the graphics pipeline with dynamic rendering info and dynamic states enabled.
4. **Rendering Loop:**
- **Acquire Swapchain Image:** Gets the next available image from the swapchain.
- **Command Buffer Recording:**
- **Begin Rendering:** Uses `vkCmdBeginRendering()` with dynamic rendering info.
- **Set Dynamic States:** Sets viewport, scissor, cull mode, front face, and primitive topology dynamically.
- **Bind Pipeline and Vertex Buffer:** Binds the graphics pipeline and the vertex buffer.
- **Draw Call:** Issues a draw call to render the triangle.
- **End Rendering:** Uses `vkCmdEndRendering()` to finish rendering.
- **Image Layout Transition:** Transitions the swapchain image layout for presentation using `vkCmdPipelineBarrier2()`.
- **Queue Submission:** Submits the command buffer to the graphics queue.
- **Present Image:** Presents the rendered image to the screen.
5. **Cleanup:**
- **Resource Destruction:** Cleans up Vulkan resources like pipelines, buffers, and swapchain images upon application exit.
## Dependencies and Requirements
- **Vulkan SDK 1.3 or Later:** Ensure you have the Vulkan SDK that supports Vulkan 1.3.
- **Hardware Support:** A GPU that supports Vulkan 1.3 features, including dynamic rendering, synchronization2, and extended dynamic state.
- **GLM Library:** Used for vector and matrix operations.
- **Shader Compiler:** GLSL shaders are compiled at runtime using a GLSL compiler.
Loading

0 comments on commit 3792764

Please sign in to comment.