HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gfx_pipeline_override_vulkan_impl.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "gfx_pipeline_override_vulkan_intf.hpp"
8#include "gfx_device_vulkan_impl.hpp"
9#include "../macros.hpp"
10#include <vulkan/vulkan.hpp>
11
12hi_export_module(hikogui.GFX : gfx_pipeline_override_impl);
13
14hi_export namespace hi { inline namespace v1 {
15
16/* Do not blend, simply use just the alpha channel and overwrite the pixels in the color attachment directly.
17 */
18inline std::vector<vk::PipelineColorBlendAttachmentState> gfx_pipeline_override::getPipelineColorBlendAttachmentStates() const
19{
20 bool has_dual_source_blend = false;
21 if (auto device_ = device()) {
22 has_dual_source_blend = device_->device_features.dualSrcBlend;
23 }
24
25 return {
26 {VK_TRUE, // blendEnable
27 has_dual_source_blend ? vk::BlendFactor::eSrc1Color : vk::BlendFactor::eOne, // srcColorBlendFactor
28 has_dual_source_blend ? vk::BlendFactor::eOneMinusSrc1Color : vk::BlendFactor::eZero, // dstColorBlendFactor
29 vk::BlendOp::eAdd, // colorBlendOp
30 has_dual_source_blend ? vk::BlendFactor::eSrc1Alpha : vk::BlendFactor::eOne, // srcAlphaBlendFactor
31 has_dual_source_blend ? vk::BlendFactor::eOneMinusSrc1Alpha : vk::BlendFactor::eZero, // dstAlphaBlendFactor
32 vk::BlendOp::eAdd, // alphaBlendOp
33 vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB |
34 vk::ColorComponentFlagBits::eA}};
35}
36
37inline void gfx_pipeline_override::draw_in_command_buffer(vk::CommandBuffer commandBuffer, draw_context const& context)
38{
39 gfx_pipeline::draw_in_command_buffer(commandBuffer, context);
40
41 hi_axiom_not_null(device());
42 device()->flushAllocation(vertexBufferAllocation, 0, vertexBufferData.size() * sizeof(vertex));
43
44 std::vector<vk::Buffer> tmpvertexBuffers = {vertexBuffer};
45 std::vector<vk::DeviceSize> tmpOffsets = {0};
46 hi_assert(tmpvertexBuffers.size() == tmpOffsets.size());
47
48 device()->override_pipeline->drawInCommandBuffer(commandBuffer);
49
50 commandBuffer.bindVertexBuffers(0, tmpvertexBuffers, tmpOffsets);
51
52 pushConstants.windowExtent = extent2{narrow_cast<float>(extent.width), narrow_cast<float>(extent.height)};
53 pushConstants.viewportScale = scale2{2.0f / extent.width, 2.0f / extent.height};
54 commandBuffer.pushConstants(
55 pipelineLayout,
56 vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
57 0,
58 sizeof(push_constants),
59 &pushConstants);
60
61 auto const numberOfRectangles = vertexBufferData.size() / 4;
62 auto const numberOfTriangles = numberOfRectangles * 2;
63
64 device()->cmdBeginDebugUtilsLabelEXT(commandBuffer, "draw alpha overlays");
65 commandBuffer.drawIndexed(narrow_cast<uint32_t>(numberOfTriangles * 3), 1, 0, 0, 0);
66 device()->cmdEndDebugUtilsLabelEXT(commandBuffer);
67}
68
69inline std::vector<vk::PipelineShaderStageCreateInfo> gfx_pipeline_override::createShaderStages() const
70{
71 hi_axiom_not_null(device());
72 return device()->override_pipeline->shaderStages;
73}
74
75inline std::vector<vk::DescriptorSetLayoutBinding> gfx_pipeline_override::createDescriptorSetLayoutBindings() const
76{
77 return {};
78}
79
80inline std::vector<vk::WriteDescriptorSet> gfx_pipeline_override::createWriteDescriptorSet() const
81{
82 return {};
83}
84
85inline size_t gfx_pipeline_override::getDescriptorSetVersion() const
86{
87 return 0;
88}
89
90inline std::vector<vk::PushConstantRange> gfx_pipeline_override::createPushConstantRanges() const
91{
92 return push_constants::pushConstantRanges();
93}
94
95inline vk::VertexInputBindingDescription gfx_pipeline_override::createVertexInputBindingDescription() const
96{
97 return vertex::inputBindingDescription();
98}
99
100inline std::vector<vk::VertexInputAttributeDescription> gfx_pipeline_override::createVertexInputAttributeDescriptions() const
101{
102 return vertex::inputAttributeDescriptions();
103}
104
105inline void gfx_pipeline_override::build_vertex_buffers()
106{
107 using vertexIndexType = uint16_t;
108 constexpr ssize_t numberOfVertices = 1 << (sizeof(vertexIndexType) * CHAR_BIT);
109
110 vk::BufferCreateInfo const bufferCreateInfo = {
111 vk::BufferCreateFlags(),
112 sizeof(vertex) * numberOfVertices,
113 vk::BufferUsageFlagBits::eVertexBuffer,
114 vk::SharingMode::eExclusive};
115 VmaAllocationCreateInfo allocationCreateInfo = {};
116 allocationCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
117 allocationCreateInfo.pUserData = const_cast<char *>("alpha-pipeline vertex buffer");
118 allocationCreateInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
119
120 hi_axiom_not_null(device());
121 std::tie(vertexBuffer, vertexBufferAllocation) = device()->createBuffer(bufferCreateInfo, allocationCreateInfo);
122 device()->setDebugUtilsObjectNameEXT(vertexBuffer, "alpha-pipeline vertex buffer");
123 vertexBufferData = device()->mapMemory<vertex>(vertexBufferAllocation);
124}
125
126inline void gfx_pipeline_override::teardown_vertex_buffers()
127{
128 hi_axiom_not_null(device());
129 device()->unmapMemory(vertexBufferAllocation);
130 device()->destroyBuffer(vertexBuffer, vertexBufferAllocation);
131}
132
133inline gfx_pipeline_override::device_shared::device_shared(gfx_device const& device) : device(device)
134{
135 buildShaders();
136}
137
138inline gfx_pipeline_override::device_shared::~device_shared() {}
139
140inline void gfx_pipeline_override::device_shared::destroy(gfx_device const*vulkanDevice)
141{
142 hi_assert_not_null(vulkanDevice);
143 teardownShaders(vulkanDevice);
144}
145
146inline void gfx_pipeline_override::device_shared::drawInCommandBuffer(vk::CommandBuffer const& commandBuffer)
147{
148 commandBuffer.bindIndexBuffer(device.quadIndexBuffer, 0, vk::IndexType::eUint16);
149}
150
151inline void gfx_pipeline_override::device_shared::place_vertices(vector_span<vertex>& vertices, aarectangle clipping_rectangle, quad box, quad_color color, quad_color blend_factor)
152{
153 auto const clipping_rectangle_ = sfloat_rgba32{clipping_rectangle};
154
155 vertices.emplace_back(box.p0, clipping_rectangle_, color.p0, blend_factor.p0);
156 vertices.emplace_back(box.p1, clipping_rectangle_, color.p1, blend_factor.p1);
157 vertices.emplace_back(box.p2, clipping_rectangle_, color.p2, blend_factor.p2);
158 vertices.emplace_back(box.p3, clipping_rectangle_, color.p3, blend_factor.p3);
159}
160
161inline void gfx_pipeline_override::device_shared::buildShaders()
162{
163 vertexShaderModule = device.loadShader(URL("resource:override_vulkan.vert.spv"));
164 device.setDebugUtilsObjectNameEXT(vertexShaderModule, "alpha-pipeline vertex shader");
165
166 fragmentShaderModule = device.loadShader(URL("resource:override_vulkan.frag.spv"));
167 device.setDebugUtilsObjectNameEXT(vertexShaderModule, "alpha-pipeline fragment shader");
168
169 shaderStages = {
170 {vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vertexShaderModule, "main"},
171 {vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fragmentShaderModule, "main"}};
172}
173
174inline void gfx_pipeline_override::device_shared::teardownShaders(gfx_device const*vulkanDevice)
175{
176 hi_assert_not_null(vulkanDevice);
177 vulkanDevice->destroy(vertexShaderModule);
178 vulkanDevice->destroy(fragmentShaderModule);
179}
180
181}} // namespace hi::v1
The HikoGUI namespace.
Definition array_generic.hpp:20
std::ptrdiff_t ssize_t
Signed size/index into an array.
Definition misc.hpp:32
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
This is a RGBA floating point color.
Definition color_intf.hpp:49
A color for each corner of a quad.
Definition quad_color.hpp:22
color p0
left-bottom
Definition quad_color.hpp:24
color p2
left-top
Definition quad_color.hpp:26
color p3
right-top
Definition quad_color.hpp:27
color p1
right-bottom
Definition quad_color.hpp:25
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:33
T size(T... args)
T tie(T... args)