This commit is contained in:
xsl
2025-09-04 10:54:47 +08:00
commit 6bc8f61b18
1808 changed files with 208268 additions and 0 deletions
@@ -0,0 +1,41 @@
# Copyright (c) 2024-2025, 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_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 HPP Hello Triangle"
DESCRIPTION "An introduction into Vulkan using Vulkan 1.3 using Vulkan-Hpp"
SHADER_FILES_GLSL
"hello_triangle_1_3/glsl/triangle.vert"
"hello_triangle_1_3/glsl/triangle.frag"
SHADER_FILES_HLSL
"hello_triangle_1_3/hlsl/triangle.vert.hlsl"
"hello_triangle_1_3/hlsl/triangle.frag.hlsl"
SHADER_FILES_SLANG
"hello_triangle_1_3/slang/triangle.vert.slang"
"hello_triangle_1_3/slang/triangle.frag.slang")
if(${VKB_${FOLDER_NAME}})
target_compile_definitions(${FOLDER_NAME} PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1)
endif()
@@ -0,0 +1,212 @@
////
* Copyright (c) 2025, The Khronos Group
*
* 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 using Vulkan-Hpp
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/hpp_hello_triangle_1_3[Khronos Vulkan samples github repository].
endif::[]
NOTE: A transcoded version of the API sample https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/api/hello_triangle_1_3[Hello Triangle 1.3] that illustrates the usage of the C{pp} bindings of Vulkan provided by Vulkan-Hpp.
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 `vk::RenderPass` or `vk::Framebuffer` objects.
- **`vk::CommandBuffer::beginRendering()` and `vk::CommandBuffer::endRendering()`:** These functions are used to begin and end rendering operations dynamically.
- **Pipeline Creation:** Uses `vk::PipelineRenderingCreateInfo` 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:**
- **`vk::CommandBuffer::pipelineBarrier2()`:** Replaces the older `vk::CommandBuffer::pipelineBarrier()` for more detailed synchronization.
- **`vk::DependencyInfo` and `vk::ImageMemoryBarrier2`:** Used to specify precise memory dependencies and image layout transitions.
**Example Usage:**
```cpp
vk::ImageMemoryBarrier2 image_barrier = {
// ... members ...
};
vk::DependencyInfo dependency_info = {
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &image_barrier,
};
cmd.pipelineBarrier2(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::DynamicState::eCullMode`, `vk::DynamicState::eFrontFace`, and `vk::DynamicState::ePrimitiveTopology`.
- **Dynamic State Commands:** Uses `vk::CommandBuffer::setCullMode()`, `vk::CommandBuffer::setFrontFace()`, and `vk::CommandBuffer::setPrimitiveTopology()` to set these states dynamically.
**Example Usage:**
```cpp
cmd.setCullMode(vk::DynamicState::eCullMode);
cmd.setFrontFace(vk::FrontFace::eClockwise);
cmd.setPrimitiveTopology(vk::PrimitiveTopology::eTriangleList);
```
**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
vk::BufferCreateInfo buffer_info = { /* ... */ };
vertex_buffer = device.createBuffer(buffer_info);
vk::MemoryAllocateInfo alloc_info = { /* ... */ };
vertex_buffer_memory = device.allocateMemory(alloc_info);
```
- **Binding the Vertex Buffer:**
```cpp
cmd.bindVertexBuffers(0, 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 `vk::CommandBuffer::beginRendering()` 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 `vk::CommandBuffer::endRendering()` to finish rendering.
- **Image Layout Transition:** Transitions the swapchain image layout for presentation using `vk::CommandBuffer::pipelineBarrier2()`.
- **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.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,170 @@
/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#pragma once
#include "platform/application.h"
#include "platform/window.h"
#include <vulkan/vulkan.hpp>
/**
* @brief A self-contained (minimal use of framework) sample that illustrates
* the rendering of a triangle
*/
class HPPHelloTriangleV13 : public vkb::Application
{
// Define the Vertex structure
struct Vertex
{
glm::vec2 position;
glm::vec3 color;
};
// Define the vertex data
const std::vector<Vertex> vertices = {
{{0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, // Vertex 1: Red
{{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, // Vertex 2: Green
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} // Vertex 3: Blue
};
/**
* @brief Swapchain state
*/
struct SwapchainDimensions
{
/// Width of the swapchain.
uint32_t width = 0;
/// Height of the swapchain.
uint32_t height = 0;
/// Pixel format of the swapchain.
vk::Format format = vk::Format::eUndefined;
};
/**
* @brief Per-frame data
*/
struct PerFrame
{
vk::Fence queue_submit_fence = nullptr;
vk::CommandPool primary_command_pool = nullptr;
vk::CommandBuffer primary_command_buffer = nullptr;
vk::Semaphore swapchain_acquire_semaphore = nullptr;
vk::Semaphore swapchain_release_semaphore = nullptr;
};
/**
* @brief Vulkan objects and global state
*/
struct Context
{
/// The Vulkan instance.
vk::Instance instance = nullptr;
/// The Vulkan physical device.
vk::PhysicalDevice gpu = nullptr;
/// The Vulkan device.
vk::Device device = nullptr;
/// The Vulkan device queue.
vk::Queue queue = nullptr;
/// The swapchain.
vk::SwapchainKHR swapchain = nullptr;
/// The swapchain dimensions.
SwapchainDimensions swapchain_dimensions;
/// The surface we will render to.
vk::SurfaceKHR surface = nullptr;
/// The queue family index where graphics work will be submitted.
int32_t graphics_queue_index = -1;
/// The image view for each swapchain image.
std::vector<vk::ImageView> swapchain_image_views;
/// The handles to the images in the swapchain.
std::vector<vk::Image> swapchain_images;
/// The graphics pipeline.
vk::Pipeline pipeline = nullptr;
/**
* The pipeline layout for resources.
* Not used in this sample, but we still need to provide a dummy one.
*/
vk::PipelineLayout pipeline_layout = nullptr;
/// The debug utility messenger callback.
vk::DebugUtilsMessengerEXT debug_callback = nullptr;
/// A set of semaphores that can be reused.
std::vector<vk::Semaphore> recycled_semaphores;
/// A set of per-frame data.
std::vector<PerFrame> per_frame;
/// The Vulkan buffer object that holds the vertex data for the triangle.
vk::Buffer vertex_buffer = nullptr;
/// The device memory allocated for the vertex buffer.
vk::DeviceMemory vertex_buffer_memory = nullptr;
};
public:
HPPHelloTriangleV13() = default;
virtual ~HPPHelloTriangleV13();
private:
// from vkb::Application
virtual bool prepare(const vkb::ApplicationOptions &options) override;
virtual bool resize(const uint32_t width, const uint32_t height) override;
virtual void update(float delta_time) override;
vk::Result acquire_next_swapchain_image(uint32_t *image);
uint32_t find_memory_type(vk::PhysicalDevice physical_device, uint32_t type_filter, vk::MemoryPropertyFlags properties);
void init_device();
void init_instance();
void init_per_frame(PerFrame &per_frame);
void init_pipeline();
void init_swapchain();
void init_vertex_buffer();
vk::ShaderModule load_shader_module(const std::string &path, vk::ShaderStageFlagBits shader_stage);
vk::Result present_image(uint32_t index);
void render_triangle(uint32_t swapchain_index);
void select_physical_device_and_surface(vkb::Window *window);
void teardown_per_frame(PerFrame &per_frame);
void transition_image_layout(vk::CommandBuffer cmd,
vk::Image image,
vk::ImageLayout oldLayout,
vk::ImageLayout newLayout,
vk::AccessFlags2 srcAccessMask,
vk::AccessFlags2 dstAccessMask,
vk::PipelineStageFlags2 srcStage,
vk::PipelineStageFlags2 dstStage);
bool validate_extensions(const std::vector<const char *> &required, const std::vector<vk::ExtensionProperties> &available);
private:
Context context;
};
std::unique_ptr<vkb::Application> create_hpp_hello_triangle_1_3();