init
@@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2020-2024, Sascha Willems
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
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 "Sascha Willems"
|
||||
NAME "VK_EXT_Debug_Utils"
|
||||
DESCRIPTION "Demonstrates the use of the debug utils extension for tagging and labeling Vulkan objects for debugging applications like RenderDoc"
|
||||
SHADER_FILES_GLSL
|
||||
"debug_utils/glsl/composition.vert"
|
||||
"debug_utils/glsl/composition.frag"
|
||||
"debug_utils/glsl/bloom.vert"
|
||||
"debug_utils/glsl/bloom.frag"
|
||||
"debug_utils/glsl/gbuffer.vert"
|
||||
"debug_utils/glsl/gbuffer.frag"
|
||||
SHADER_FILES_HLSL
|
||||
"debug_utils/hlsl/composition.vert.hlsl"
|
||||
"debug_utils/hlsl/composition.frag.hlsl"
|
||||
"debug_utils/hlsl/bloom.vert.hlsl"
|
||||
"debug_utils/hlsl/bloom.frag.hlsl"
|
||||
"debug_utils/hlsl/gbuffer.vert.hlsl"
|
||||
"debug_utils/hlsl/gbuffer.frag.hlsl")
|
||||
@@ -0,0 +1,294 @@
|
||||
////
|
||||
- Copyright (c) 2021-2025, Sascha Willems
|
||||
-
|
||||
- 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.
|
||||
-
|
||||
////
|
||||
= Vulkan Debug Utilities Extension
|
||||
|
||||
ifdef::site-gen-antora[]
|
||||
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/extensions/debug_utils[Khronos Vulkan samples github repository].
|
||||
endif::[]
|
||||
|
||||
|
||||
== Overview
|
||||
|
||||
This tutorial, along with the accompanying example code, demonstrates the use of the https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_EXT_debug_utils[VK_EXT_debug_utils] extension to setup a validation layer messenger callback and pass additional debugging information to debuggers like https://renderdoc.org/[RenderDoc].
|
||||
|
||||
`VK_EXT_debug_utils` has been introduced based on feedback for the initial Vulkan debugging extensions `VK_EXT_debug_report` and `VK_EXT_debug_marker`, combining these into a single instance extensions with some added functionality.
|
||||
|
||||
== Setup
|
||||
|
||||
NOTE: Enabling the extension is done inside the framework, see the `Instance` class in link:../../../framework/core/instance.cpp[instance.cpp] for details.
|
||||
|
||||
Enabling the functionality for the debug utilities is done by adding the extension to the list of extensions to enable at instance level.
|
||||
As with all extensions, this is optional and you should check if the extension is present before enabling it.
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
uint32_t instance_extension_count;
|
||||
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr));
|
||||
|
||||
std::vector<VkExtensionProperties> available_instance_extensions(instance_extension_count);
|
||||
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, available_instance_extensions.data()));
|
||||
|
||||
bool debug_utils = false;
|
||||
for (auto &available_extension : available_instance_extensions)
|
||||
{
|
||||
if (strcmp(available_extension.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0)
|
||||
{
|
||||
debug_utils = true;
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
== Validation
|
||||
|
||||
NOTE: Validation setup is done inside the framework, see the `Instance` class in `instance.cpp` for details.
|
||||
|
||||
After creating your instance with the `VK_EXT_debug_utils` extension enabled, you'll be able to use the debug functions that it provides.
|
||||
|
||||
=== Setting Up
|
||||
|
||||
NOTE: Depending on the implementation and loader you're using you may need to manually get the function pointers for these via `vkGetInstanceProcAddr` before you can use these.
|
||||
|
||||
`vkCreateDebugUtilsMessengerEXT` is used for setting up the debug messenger callback that is triggered by the validation layers:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_utils_create_info = {VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
|
||||
|
||||
debug_utils_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
||||
debug_utils_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
|
||||
debug_utils_create_info.pfnUserCallback = debug_utils_messenger_callback;
|
||||
----
|
||||
|
||||
We then pass this to the `pNext` member of our instance creation structure, enabling validation for instance creation and destruction:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
VkInstanceCreateInfo instance_create_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
|
||||
...
|
||||
instance_create_info.pNext = &debug_utils_create_info;
|
||||
----
|
||||
|
||||
After instance creation we can create the actual debug utils messenger callback that is invoked by the enabled validation layers:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
result = vkCreateDebugUtilsMessengerEXT(handle, &debug_utils_create_info, nullptr, &debug_utils_messenger);
|
||||
----
|
||||
|
||||
The `messageSeverity` member of the `VkDebugUtilsMessengerCreateInfoEXT` struct determines the kind of validation layer messages that are passed to the user callback:
|
||||
|
||||
* `VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT`: Verbose messages, including diagnostic messages from loaders, layers and drivers.
|
||||
* `VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT`: Informational message like resource details.
|
||||
* `VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT`: Warnings that may hint at application side bugs and undefined behavior.
|
||||
* `VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT`: Errors caused by application side violation of valid usage as specified by the spec.
|
||||
|
||||
In your typically validation setup you'd use `VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT` and `VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT` to catch bugs and errors in your application.
|
||||
|
||||
A basic debug messenger callback may then look like this:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL debug_utils_messenger_callback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT message_type,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
||||
void *user_data)
|
||||
{
|
||||
if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
||||
{
|
||||
LOGW("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage)
|
||||
}
|
||||
else if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
{
|
||||
LOGE("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage);
|
||||
}
|
||||
return VK_FALSE;
|
||||
}
|
||||
----
|
||||
|
||||
With the above setup, Vulkan spec violations of your application will now be reported to the standard output like this:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
Error: 0 - UNASSIGNED-CoreValidation-DrawState-InvalidRenderArea: Cannot execute a render pass with
|
||||
renderArea not within the bound of the framebuffer. RenderArea: x 0, y 0, width 1281, height 721.
|
||||
Framebuffer: width 1280, height 720.
|
||||
----
|
||||
|
||||
== Adding information for debugging tools
|
||||
|
||||
In this chapter we will take a look at how to pass additional information from our application to debugging tools.
|
||||
|
||||
The debug utilities adds several functions to add debugging information to your sample application's command buffers, queues, and all other Vulkan objects.
|
||||
|
||||
=== Inserting labels
|
||||
|
||||
The extension allows you to add colored labels to `command buffers` and `queues`, that work as markers inside the Vulkan Event chain.
|
||||
|
||||
This is esp.
|
||||
helpful in more complex applications with multiple command buffers in flight across different queues.
|
||||
|
||||
For comparison here is an unmarked event view from RenderDoc versus one viewed using debugging labels:
|
||||
|
||||
image::./images/renderdoc_no_labels.jpg[]
|
||||
image::./images/renderdoc_with_labels.jpg[]
|
||||
|
||||
Color choice aside, it's clear that the event tree with added debug labels is much easier to navigate.
|
||||
|
||||
There are two distinct concepts for adding labels to either a command buffer or a queue:
|
||||
|
||||
* Encapsulating labels: These are started with a `begin` command and closed with an `end` command.
|
||||
They encapsulate all submitted commands in between and can be *arbitrarily nested*.
|
||||
* Inserting labels: Those are inserted at the exact point where the commands are submitted.
|
||||
Think of these as *simple markers*.
|
||||
|
||||
The new functions to add such labels are:
|
||||
|
||||
* For command buffers
|
||||
** `vkCmdBeginDebugUtilsLabelEXT`
|
||||
** `vkCmdEndDebugUtilsLabelEXT`
|
||||
** `vkCmdInsertDebugUtilsLabelEXT`
|
||||
* For queues
|
||||
** `vkQueueBeginDebugUtilsLabelEXT`
|
||||
** `vkQueueEndDebugUtilsLabelEXT`
|
||||
** `vkQueueInsertDebugUtilsLabelEXT`
|
||||
|
||||
Once you start a new label via `vkCmd/QueueBeginDebugUtilsLabelEXT` all commands submitted to that command buffer or queue are encapsulated by that label until you end it via `vkCmd/QueueEndDebugUtilsLabelEXT` whereas a call to `vkCmd/QueueInsertDebugUtilsLabelEXT` simply inserts a marker at the current command buffer or queue command position;
|
||||
|
||||
For convenience, the sample wraps those functions into dedicated functions.
|
||||
|
||||
In this (simplified) code from our sample application we use encapsulating and nested labels to tag the whole separable bloom filter passes for the debugger, and also insert a marker before submitting the draw command for the bloom pass' full-screen quad:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
cmd_begin_label(draw_cmd_buffers[i], "Separable bloom filter", {0.5f, 0.76f, 0.34f, 1.0f});
|
||||
|
||||
cmd_begin_label(draw_cmd_buffers[i], "Vertical bloom pass", {0.4f, 0.61f, 0.27f, 1.0f});
|
||||
|
||||
vkCmdBeginRenderPass(draw_cmd_buffers[i], ...);
|
||||
vkCmdSetViewport(draw_cmd_buffers[i], ...);
|
||||
vkCmdSetScissor(draw_cmd_buffers[i], ...);
|
||||
vkCmdBindDescriptorSets(draw_cmd_buffers[i], ...);
|
||||
vkCmdBindPipeline(draw_cmd_buffers[i], ...);
|
||||
vkCmdDraw(draw_cmd_buffers[i], ...);
|
||||
vkCmdEndRenderPass(draw_cmd_buffers[i]);
|
||||
|
||||
cmd_end_label(draw_cmd_buffers[i]);
|
||||
|
||||
cmd_begin_label(draw_cmd_buffers[i], "Horizontal bloom pass and composition", {0.4f, 0.61f, 0.27f, 1.0f});
|
||||
|
||||
vkCmdBeginRenderPass(draw_cmd_buffers[i], ...);
|
||||
vkCmdSetViewport(draw_cmd_buffers[i], ...);
|
||||
vkCmdSetScissor(draw_cmd_buffers[i], ...);
|
||||
vkCmdBindDescriptorSets(draw_cmd_buffers[i], ...);
|
||||
vkCmdBindPipeline(draw_cmd_buffers[i], ...);
|
||||
vkCmdDraw(draw_cmd_buffers[i], ...);
|
||||
cmd_insert_label(draw_cmd_buffers[i], "Bloom full screen quad", {1.0f, 1.0f, 1.0f, 1.0f});
|
||||
vkCmdBindPipeline(draw_cmd_buffers[i], ...);
|
||||
vkCmdDraw(draw_cmd_buffers[i], ...);
|
||||
vkCmdEndRenderPass(draw_cmd_buffers[i]);
|
||||
|
||||
cmd_end_label(draw_cmd_buffers[i]);
|
||||
|
||||
cmd_end_label(draw_cmd_buffers[i]);
|
||||
----
|
||||
|
||||
Running this in RenderDoc will display the event browser with our colored debug labels:
|
||||
|
||||
image::./images/renderdoc_nested_cmd.jpg[]
|
||||
|
||||
=== Vulkan object naming and tagging
|
||||
|
||||
The other important functionality of this extension is the possibility to name (and tag) all Vulkan objects in your application.
|
||||
This makes object identification of the resources (inside the debugger) a lot easier and will help you understand your applications structure and aid you in finding bugs and problematic behavior.
|
||||
|
||||
Imagine you need to debug a problem with a shader module not properly working or seemingly the wrong shader used by a pipeline.
|
||||
Without adding names to your Vulkan objects, all your resources will have similar names auto-generated by the debugging application.
|
||||
In the case of RenderDoc it's the object's type with a continuous number:
|
||||
|
||||
image:./images/renderdoc_resource_inspector_no_names.jpg[]
|
||||
|
||||
Finding "Shader Module 257" or any of the "Graphics Pipeline 259/260" in your code will prove tricky to impossible.
|
||||
|
||||
But if you're using the new extension to add meaningful names to your Vulkan objects, connecting the resources and finding them in your application becomes straightforward:
|
||||
|
||||
image:./images/renderdoc_resource_inspector_names.jpg[]
|
||||
|
||||
Now you can clearly see what shader this actually is and what pipelines are using it.
|
||||
As an added bonus you also get named resources in the resource list, so searching for a specific resources is now also possible.
|
||||
|
||||
This is also evident in the pipeline state, where you can now e.g.
|
||||
see what pipeline, shader and buffer are bound at what stage:
|
||||
|
||||
image:./images/renderdoc_pipeline_state_names.jpg[]
|
||||
|
||||
This makes it very easy to see if the correct resources are used at that pipeline stage.
|
||||
(1) shows the pipeline and shader used at the vertex shader stage, and (2) lists the uniform buffer bound to set 0.
|
||||
|
||||
The new functions to set names and tags for Vulkan objects are:
|
||||
|
||||
* `vkSetDebugUtilsObjectNameEXT`
|
||||
* `vkSetDebugUtilsObjectTagEXT`
|
||||
|
||||
`vkSetDebugUtilsObjectNameEXT` lets you add a name to any Vulkan object via it's handle:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
VkDebugUtilsObjectNameInfoEXT name_info = {VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT};
|
||||
name_info.objectType = VK_OBJECT_TYPE_BUFFER;
|
||||
name_info.objectHandle = (uint64_t) uniform_buffers.matrices.handle;
|
||||
name_info.pObjectName = "Some uniform buffer";
|
||||
vkSetDebugUtilsObjectNameEXT(device, &name_info);
|
||||
----
|
||||
|
||||
`vkSetDebugUtilsObjectTagEXT` lets you add arbitrary data to any Vulkan object via it's handle.
|
||||
That data may be displayed by a debugging app or your own app inside the debug messenger callback:
|
||||
|
||||
[,cpp]
|
||||
----
|
||||
VkDebugUtilsObjectTagInfoEXT tag_info = {VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT};
|
||||
tag_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE;
|
||||
tag_info.objectHandle = (uint64_t) shader_stage.module;
|
||||
tag_info.tagName = 0;
|
||||
tag_info.tagSize = shader_source_glsl.data_size;
|
||||
tag_info.pTag = &shader_source_glsl.data;
|
||||
vkSetDebugUtilsObjectTagEXT(device, &info);
|
||||
----
|
||||
|
||||
For convenience, the sample wraps those functions into dedicated functions.
|
||||
|
||||
== Running the sample with a Vulkan debugger
|
||||
|
||||
To see this in action, you need to run the sample application from inside a Vulkan debugger.
|
||||
If you're unfamiliar with this, this is a sample setup for running our sample application from RenderDoc.
|
||||
The paths depend on where you have downloaded the source from this repository and the platform for which you are compiling:
|
||||
|
||||
image:./images/renderdoc_launch_settings.jpg[]
|
||||
|
||||
(1) is the binary you want to start, which depends on the platform you have compiled the samples for.
|
||||
(2) refers to the path that's passed as the working directory to the binary, which must be the root path of the repository so the asset's can be properly loaded.
|
||||
(3) tells the binary which sample to run.
|
||||
After setting these up press (4) to start the application from within RenderDoc.
|
||||
|
||||
Once the sample application is running, press F12 do capture the current frame, close the application and then select the capture in RenderDoc.
|
||||
|
||||
Once loaded you should be able to see a trace of a whole frame from that sample application along with labels and named Vulkan objects:
|
||||
|
||||
image:./images/renderdoc_final.jpg[]
|
||||
@@ -0,0 +1,158 @@
|
||||
/* Copyright (c) 2020-2024, Sascha Willems
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Debug Utils labeling
|
||||
* Note that you need to run this example inside a debugging tool like RenderDoc to see those labels
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "api_vulkan_sample.h"
|
||||
|
||||
class DebugUtils : public ApiVulkanSample
|
||||
{
|
||||
public:
|
||||
bool bloom = true;
|
||||
bool display_skysphere = true;
|
||||
bool debug_utils_supported = false;
|
||||
|
||||
struct
|
||||
{
|
||||
Texture skysphere;
|
||||
} textures;
|
||||
|
||||
struct
|
||||
{
|
||||
std::unique_ptr<vkb::sg::SubMesh> skysphere;
|
||||
std::unique_ptr<vkb::sg::SubMesh> scene;
|
||||
} models;
|
||||
|
||||
struct
|
||||
{
|
||||
std::unique_ptr<vkb::core::BufferC> matrices;
|
||||
} uniform_buffers;
|
||||
|
||||
struct UBOVS
|
||||
{
|
||||
glm::mat4 projection;
|
||||
glm::mat4 modelview;
|
||||
glm::mat4 skysphere_modelview;
|
||||
float modelscale = 0.05f;
|
||||
} ubo_vs;
|
||||
|
||||
struct
|
||||
{
|
||||
VkPipeline skysphere;
|
||||
VkPipeline sphere;
|
||||
VkPipeline composition;
|
||||
VkPipeline bloom[2];
|
||||
} pipelines;
|
||||
|
||||
struct
|
||||
{
|
||||
VkPipelineLayout models;
|
||||
VkPipelineLayout composition;
|
||||
VkPipelineLayout bloom_filter;
|
||||
} pipeline_layouts;
|
||||
|
||||
struct
|
||||
{
|
||||
VkDescriptorSet skysphere;
|
||||
VkDescriptorSet sphere;
|
||||
VkDescriptorSet composition;
|
||||
VkDescriptorSet bloom_filter;
|
||||
} descriptor_sets;
|
||||
|
||||
struct
|
||||
{
|
||||
VkDescriptorSetLayout models;
|
||||
VkDescriptorSetLayout composition;
|
||||
VkDescriptorSetLayout bloom_filter;
|
||||
} descriptor_set_layouts;
|
||||
|
||||
// Framebuffer for offscreen rendering
|
||||
struct FrameBufferAttachment
|
||||
{
|
||||
VkImage image;
|
||||
VkDeviceMemory mem;
|
||||
VkImageView view;
|
||||
VkFormat format;
|
||||
void destroy(VkDevice device)
|
||||
{
|
||||
vkDestroyImageView(device, view, nullptr);
|
||||
vkDestroyImage(device, image, nullptr);
|
||||
vkFreeMemory(device, mem, nullptr);
|
||||
}
|
||||
};
|
||||
struct FrameBuffer
|
||||
{
|
||||
int32_t width, height;
|
||||
VkFramebuffer framebuffer;
|
||||
FrameBufferAttachment color[2];
|
||||
FrameBufferAttachment depth;
|
||||
VkRenderPass render_pass;
|
||||
VkSampler sampler;
|
||||
} offscreen;
|
||||
|
||||
struct
|
||||
{
|
||||
int32_t width, height;
|
||||
VkFramebuffer framebuffer;
|
||||
FrameBufferAttachment color[1];
|
||||
VkRenderPass render_pass;
|
||||
VkSampler sampler;
|
||||
} filter_pass;
|
||||
|
||||
struct
|
||||
{
|
||||
glm::vec4 offset;
|
||||
glm::vec4 color;
|
||||
uint32_t object_type;
|
||||
} push_const_block;
|
||||
|
||||
DebugUtils();
|
||||
~DebugUtils();
|
||||
void debug_check_extension();
|
||||
void cmd_begin_label(VkCommandBuffer command_buffer, const char *label_name, std::vector<float> color);
|
||||
void cmd_insert_label(VkCommandBuffer command_buffer, const char *label_name, std::vector<float> color);
|
||||
void cmd_end_label(VkCommandBuffer command_buffer);
|
||||
void queue_begin_label(VkQueue queue, const char *label_name, std::vector<float> color);
|
||||
void queue_insert_label(VkQueue queue, const char *label_name, std::vector<float> color);
|
||||
void queue_end_label(VkQueue queue);
|
||||
void set_object_name(VkObjectType object_type, uint64_t object_handle, const char *object_name);
|
||||
VkPipelineShaderStageCreateInfo debug_load_shader(const std::string &file, VkShaderStageFlagBits stage);
|
||||
void debug_name_objects();
|
||||
virtual void request_gpu_features(vkb::PhysicalDevice &gpu) override;
|
||||
void build_command_buffers() override;
|
||||
void create_attachment(VkFormat format, VkImageUsageFlagBits usage, FrameBufferAttachment *attachment);
|
||||
void prepare_offscreen_buffer();
|
||||
void load_assets();
|
||||
void setup_descriptor_pool();
|
||||
void setup_descriptor_set_layout();
|
||||
void setup_descriptor_sets();
|
||||
void prepare_pipelines();
|
||||
void prepare_uniform_buffers();
|
||||
void update_uniform_buffers();
|
||||
void draw();
|
||||
bool prepare(const vkb::ApplicationOptions &options) override;
|
||||
virtual void render(float delta_time) override;
|
||||
virtual void on_update_ui_overlay(vkb::Drawer &drawer) override;
|
||||
virtual bool resize(const uint32_t width, const uint32_t height) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<vkb::Application> create_debug_utils();
|
||||
|
After Width: | Height: | Size: 259 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 93 KiB |