Blender V5.0
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
8
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>
22 const shader::ShaderCreateInfo::PushConst &push_constant,
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>
69 uint32_t *r_offset)
70{
71 for (const shader::ShaderCreateInfo::PushConst &push_constant : info.push_constants_) {
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
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{
150 BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
151 BLI_assert(data_ != nullptr);
152 if (!uniform_buffer_) {
153 uniform_buffer_ = std::make_unique<VKUniformBuffer>(layout_->size_in_bytes(),
154 "push constants buffer");
155 }
156
157 uniform_buffer_->reset_data_uploaded();
158 uniform_buffer_->update(data_);
159}
160
161std::unique_ptr<VKUniformBuffer> &VKPushConstants::uniform_buffer_get()
162{
163 BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
164 BLI_assert(uniform_buffer_);
165 return uniform_buffer_;
166}
167
168} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr const char * c_str() const
void append(const T &value)
const VkPhysicalDeviceProperties & physical_device_properties_get() const
Definition vk_device.hh:269
VKPushConstants & operator=(VKPushConstants &&other)
std::unique_ptr< VKUniformBuffer > & uniform_buffer_get()
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
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)
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...