VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
vulkanUtils.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4
5#ifdef VISUTWIN_HAS_VULKAN
6
7#include "vulkanUtils.h"
9
10#include "spdlog/spdlog.h"
11
12namespace visutwin::canvas
13{
14 void vulkanImmediateSubmit(VulkanGraphicsDevice* device,
15 const std::function<void(VkCommandBuffer)>& func)
16 {
17 VkDevice vk = device->device();
18 VkCommandPool pool = device->uploadCommandPool();
19
20 VkCommandBufferAllocateInfo allocInfo{VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
21 allocInfo.commandPool = pool;
22 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
23 allocInfo.commandBufferCount = 1;
24
25 VkCommandBuffer cmd;
26 vkAllocateCommandBuffers(vk, &allocInfo, &cmd);
27
28 VkCommandBufferBeginInfo beginInfo{VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
29 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
30 vkBeginCommandBuffer(cmd, &beginInfo);
31
32 func(cmd);
33
34 vkEndCommandBuffer(cmd);
35
36 VkSubmitInfo submitInfo{VK_STRUCTURE_TYPE_SUBMIT_INFO};
37 submitInfo.commandBufferCount = 1;
38 submitInfo.pCommandBuffers = &cmd;
39
40 VkFence fence = device->uploadFence();
41 vkQueueSubmit(device->graphicsQueue(), 1, &submitInfo, fence);
42 vkWaitForFences(vk, 1, &fence, VK_TRUE, UINT64_MAX);
43 vkResetFences(vk, 1, &fence);
44
45 vkFreeCommandBuffers(vk, pool, 1, &cmd);
46 }
47
48 void vulkanTransitionImageLayout(VkCommandBuffer cmd, VkImage image,
49 VkImageLayout oldLayout, VkImageLayout newLayout, VkImageAspectFlags aspect)
50 {
51 VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
52 barrier.oldLayout = oldLayout;
53 barrier.newLayout = newLayout;
54 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
55 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
56 barrier.image = image;
57 barrier.subresourceRange.aspectMask = aspect;
58 barrier.subresourceRange.baseMipLevel = 0;
59 barrier.subresourceRange.levelCount = 1;
60 barrier.subresourceRange.baseArrayLayer = 0;
61 barrier.subresourceRange.layerCount = 1;
62
63 VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
64 VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
65
66 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
67 newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
68 barrier.srcAccessMask = 0;
69 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
70 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
71 dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
72 } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
73 newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
74 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
75 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
76 srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
77 dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
78 } else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
79 newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
80 barrier.srcAccessMask = 0;
81 barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
82 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
83 dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
84 } else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
85 newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
86 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
87 barrier.dstAccessMask = 0;
88 srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
89 dstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
90 } else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
91 newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
92 barrier.srcAccessMask = 0;
93 barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
94 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
95 dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
96 }
97
98 vkCmdPipelineBarrier(cmd, srcStage, dstStage, 0,
99 0, nullptr, 0, nullptr, 1, &barrier);
100 }
101
102 VkFormat vulkanMapPixelFormat(PixelFormat format)
103 {
104 switch (format) {
105 case PIXELFORMAT_RGB8: return VK_FORMAT_R8G8B8_UNORM;
106 case PIXELFORMAT_RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
107 case PIXELFORMAT_RGBA16F: return VK_FORMAT_R16G16B16A16_SFLOAT;
108 case PIXELFORMAT_RGBA32F: return VK_FORMAT_R32G32B32A32_SFLOAT;
109 case PIXELFORMAT_R32F: return VK_FORMAT_R32_SFLOAT;
110 case PIXELFORMAT_DEPTH: return VK_FORMAT_D32_SFLOAT;
111 case PIXELFORMAT_DEPTHSTENCIL: return VK_FORMAT_D24_UNORM_S8_UINT;
112 case PIXELFORMAT_R8: return VK_FORMAT_R8_UNORM;
113 case PIXELFORMAT_RG8: return VK_FORMAT_R8G8_UNORM;
114 default: return VK_FORMAT_R8G8B8A8_UNORM;
115 }
116 }
117
118 VkFilter vulkanMapFilterMode(FilterMode mode)
119 {
120 switch (mode) {
121 case FILTER_NEAREST:
124 return VK_FILTER_NEAREST;
125 default:
126 return VK_FILTER_LINEAR;
127 }
128 }
129
130 VkSamplerAddressMode vulkanMapAddressMode(AddressMode mode)
131 {
132 switch (mode) {
133 case ADDRESS_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
134 case ADDRESS_MIRRORED_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
135 default: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
136 }
137 }
138
139 VkCullModeFlags vulkanMapCullMode(CullMode mode)
140 {
141 switch (mode) {
142 case CullMode::CULLFACE_NONE: return VK_CULL_MODE_NONE;
143 case CullMode::CULLFACE_BACK: return VK_CULL_MODE_BACK_BIT;
144 case CullMode::CULLFACE_FRONT: return VK_CULL_MODE_FRONT_BIT;
145 case CullMode::CULLFACE_FRONTANDBACK: return VK_CULL_MODE_FRONT_AND_BACK;
146 default: return VK_CULL_MODE_BACK_BIT;
147 }
148 }
149
150 VkPrimitiveTopology vulkanMapPrimitiveType(PrimitiveType type)
151 {
152 switch (type) {
153 case PRIMITIVE_POINTS: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
154 case PRIMITIVE_LINES: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
155 case PRIMITIVE_LINESTRIP: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
156 case PRIMITIVE_TRIANGLES: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
157 case PRIMITIVE_TRISTRIP: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
158 case PRIMITIVE_TRIFAN: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
159 default: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
160 }
161 }
162
163 VkBlendFactor vulkanMapBlendFactor(int factor)
164 {
165 switch (factor) {
166 case BLENDMODE_ZERO: return VK_BLEND_FACTOR_ZERO;
167 case BLENDMODE_ONE: return VK_BLEND_FACTOR_ONE;
168 case BLENDMODE_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR;
169 case BLENDMODE_ONE_MINUS_SRC_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
170 case BLENDMODE_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR;
171 case BLENDMODE_ONE_MINUS_DST_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
172 case BLENDMODE_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA;
173 case BLENDMODE_SRC_ALPHA_SATURATE: return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
174 case BLENDMODE_ONE_MINUS_SRC_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
175 case BLENDMODE_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA;
176 case BLENDMODE_ONE_MINUS_DST_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
177 case BLENDMODE_CONSTANT: return VK_BLEND_FACTOR_CONSTANT_COLOR;
178 case BLENDMODE_ONE_MINUS_CONSTANT: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
179 default: return VK_BLEND_FACTOR_ONE;
180 }
181 }
182
183 VkBlendOp vulkanMapBlendOp(int op)
184 {
185 switch (op) {
186 case BLENDEQUATION_ADD: return VK_BLEND_OP_ADD;
187 case BLENDEQUATION_SUBTRACT: return VK_BLEND_OP_SUBTRACT;
188 case BLENDEQUATION_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
189 case BLENDEQUATION_MIN: return VK_BLEND_OP_MIN;
190 case BLENDEQUATION_MAX: return VK_BLEND_OP_MAX;
191 default: return VK_BLEND_OP_ADD;
192 }
193 }
194}
195
196#endif // VISUTWIN_HAS_VULKAN
constexpr int BLENDMODE_ONE_MINUS_SRC_ALPHA
Definition blendState.h:21
constexpr int BLENDMODE_ONE_MINUS_DST_ALPHA
Definition blendState.h:23
constexpr int BLENDEQUATION_MAX
Definition blendState.h:32
constexpr int BLENDMODE_DST_ALPHA
Definition blendState.h:22
constexpr int BLENDMODE_ONE_MINUS_CONSTANT
Definition blendState.h:25
constexpr int BLENDMODE_ONE_MINUS_SRC_COLOR
Definition blendState.h:16
constexpr int BLENDEQUATION_REVERSE_SUBTRACT
Definition blendState.h:30
constexpr int BLENDEQUATION_MIN
Definition blendState.h:31
constexpr int BLENDMODE_ONE
Definition blendState.h:14
constexpr int BLENDEQUATION_SUBTRACT
Definition blendState.h:29
@ PRIMITIVE_POINTS
Definition mesh.h:19
@ PRIMITIVE_LINES
Definition mesh.h:20
@ PRIMITIVE_LINESTRIP
Definition mesh.h:22
@ PRIMITIVE_TRISTRIP
Definition mesh.h:24
@ PRIMITIVE_TRIFAN
Definition mesh.h:25
@ PRIMITIVE_TRIANGLES
Definition mesh.h:23
constexpr int BLENDMODE_SRC_COLOR
Definition blendState.h:15
constexpr int BLENDMODE_CONSTANT
Definition blendState.h:24
constexpr int BLENDEQUATION_ADD
Definition blendState.h:28
constexpr int BLENDMODE_ZERO
Definition blendState.h:13
constexpr int BLENDMODE_SRC_ALPHA
Definition blendState.h:19
constexpr int BLENDMODE_SRC_ALPHA_SATURATE
Definition blendState.h:20
constexpr int BLENDMODE_ONE_MINUS_DST_COLOR
Definition blendState.h:18
constexpr int BLENDMODE_DST_COLOR
Definition blendState.h:17