Blender V4.3
vk_push_constants.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "vk_backend.hh"
11#include "vk_context.hh"
12#include "vk_memory_layout.hh"
13#include "vk_shader.hh"
15#include "vk_storage_buffer.hh"
16#include "vk_uniform_buffer.hh"
17
18namespace blender::gpu {
19
20template<typename LayoutT>
23 const ShaderInput &shader_input,
24 uint32_t *r_offset)
25{
26 align<LayoutT>(push_constant.type, push_constant.array_size, r_offset);
27
29 layout.location = shader_input.location;
30 layout.type = push_constant.type;
31 layout.array_size = push_constant.array_size;
32 layout.offset = *r_offset;
33 layout.inner_row_padding = LayoutT::inner_row_padding(push_constant.type);
34
35 reserve<LayoutT>(push_constant.type, push_constant.array_size, r_offset);
36 return layout;
37}
38
39template<typename LayoutT>
41{
42 uint32_t offset = 0;
43 for (const shader::ShaderCreateInfo::PushConst &push_constant : push_constants) {
44 align<LayoutT>(push_constant.type, push_constant.array_size, &offset);
45 reserve<LayoutT>(push_constant.type, push_constant.array_size, &offset);
46 }
47
49 return offset;
50}
51
53 const shader::ShaderCreateInfo &info, const VKDevice &device)
54{
55 if (info.push_constants_.is_empty()) {
56 return StorageType::NONE;
57 }
58
59 uint32_t max_push_constants_size =
60 device.physical_device_properties_get().limits.maxPushConstantsSize;
62 return size <= max_push_constants_size ? STORAGE_TYPE_DEFAULT : STORAGE_TYPE_FALLBACK;
63}
64
65template<typename LayoutT>
67 const VKShaderInterface &interface,
69 uint32_t *r_offset)
70{
72 const ShaderInput *shader_input = interface.uniform_get(push_constant.name.c_str());
73 r_struct.append(init_constant<LayoutT>(push_constant, *shader_input, r_offset));
74 }
76}
77
79 const VKShaderInterface &interface,
80 const StorageType storage_type,
81 const VKDescriptorSet::Location location)
82{
83 BLI_assert(push_constants.is_empty());
84 storage_type_ = storage_type;
85
86 size_in_bytes_ = 0;
87 if (storage_type == StorageType::UNIFORM_BUFFER) {
88 descriptor_set_location_ = location;
89 init_struct<Std140>(info, interface, push_constants, &size_in_bytes_);
90 }
91 else {
92 init_struct<Std430>(info, interface, push_constants, &size_in_bytes_);
93 }
94}
95
97{
98 for (const PushConstant &push_constant : push_constants) {
99 if (push_constant.location == location) {
100 return &push_constant;
101 }
102 }
103 return nullptr;
104}
105
107{
108 std::ostream &stream = std::cout;
109 stream << "VKPushConstants::Layout::debug_print()\n";
110 for (const PushConstant &push_constant : push_constants) {
111 stream << " - location:" << push_constant.location;
112 stream << ", offset:" << push_constant.offset;
113 stream << ", array_size:" << push_constant.array_size;
114 stream << "\n";
115 }
116}
117
119VKPushConstants::VKPushConstants(const Layout *layout) : layout_(layout)
120{
121 data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
122}
123
124VKPushConstants::VKPushConstants(VKPushConstants &&other) : layout_(other.layout_)
125{
126 data_ = other.data_;
127 other.data_ = nullptr;
128}
129
131{
132 if (data_ != nullptr) {
133 MEM_freeN(data_);
134 data_ = nullptr;
135 }
136}
137
139{
140 layout_ = other.layout_;
141
142 data_ = other.data_;
143 other.data_ = nullptr;
144
145 return *this;
146}
147
149{
151 BLI_assert(data_ != nullptr);
152 VKContext &context = *VKContext::get();
153 std::unique_ptr<VKUniformBuffer> &uniform_buffer = tracked_resource_for(context, is_dirty_);
154 uniform_buffer->update(data_);
155 is_dirty_ = false;
156}
157
158std::unique_ptr<VKUniformBuffer> &VKPushConstants::uniform_buffer_get()
159{
161 return active_resource();
162}
163
164std::unique_ptr<VKUniformBuffer> VKPushConstants::create_resource(VKContext & /*context*/)
165{
166 return std::make_unique<VKUniformBuffer>(layout_->size_in_bytes(), __func__);
167}
168
169} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:50
void append(const T &value)
const ShaderInput * uniform_get(const char *name) const
static VKContext * get()
Definition vk_context.hh:97
const VkPhysicalDeviceProperties & physical_device_properties_get() const
Definition vk_device.hh:199
VKPushConstants & operator=(VKPushConstants &&other)
std::unique_ptr< VKUniformBuffer > create_resource(VKContext &context) override
std::unique_ptr< VKUniformBuffer > & uniform_buffer_get()
std::unique_ptr< VKUniformBuffer > & tracked_resource_for(VKContext &context, const bool is_dirty)
std::unique_ptr< VKUniformBuffer > & active_resource()
output_img push_constant(Type::FLOAT, "subtrahend") .define("TYPE"
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void init_struct(const shader::ShaderCreateInfo &info, const VKShaderInterface &interface, Vector< VKPushConstants::Layout::PushConstant > &r_struct, uint32_t *r_offset)
static void reserve(const shader::Type type, int32_t array_size, uint32_t *r_offset)
uint32_t struct_size(Span< shader::ShaderCreateInfo::PushConst > push_constants)
static VKPushConstants::Layout::PushConstant init_constant(const shader::ShaderCreateInfo::PushConst &push_constant, const ShaderInput &shader_input, uint32_t *r_offset)
static void align_end_of_struct(uint32_t *r_offset)
static void align(const shader::Type &type, const int32_t array_size, uint32_t *r_offset)
unsigned int uint32_t
Definition stdint.h:80
signed int int32_t
Definition stdint.h:77
static constexpr StorageType STORAGE_TYPE_DEFAULT
static constexpr StorageType STORAGE_TYPE_FALLBACK
static StorageType determine_storage_type(const shader::ShaderCreateInfo &info, const VKDevice &device)
const PushConstant * find(int32_t location) const
void init(const shader::ShaderCreateInfo &info, const VKShaderInterface &interface, StorageType storage_type, VKDescriptorSet::Location location)
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...