Blender V4.5
gpu_shader_interface.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13
14#pragma once
15
16#include <cstring> /* required for STREQ later on. */
17
18#include "BLI_hash.h"
19#include "BLI_sys_types.h"
20
21#include "GPU_shader.hh"
22#include "GPU_vertex_format.hh" /* GPU_VERT_ATTR_MAX_LEN */
24
25namespace blender::gpu {
26
42
49 /* TODO(fclem): should be protected. */
50 public:
52 ShaderInput *inputs_ = nullptr;
54 char *name_buffer_ = nullptr;
62 uint16_t enabled_attr_mask_ = 0;
63 uint16_t enabled_ubo_mask_ = 0;
64 uint8_t enabled_ima_mask_ = 0;
66 uint16_t enabled_ssbo_mask_ = 0;
67 /* Bitmask to apply to enabled_ssbo_mask_ to get attributes that are sourced from SSBOs. */
68 uint16_t ssbo_attr_mask_ = 0;
72
79
81 virtual ~ShaderInterface();
82
83 void debug_print() const;
84
85 const ShaderInput *attr_get(const StringRefNull name) const
86 {
87 return input_lookup(inputs_, attr_len_, name);
88 }
89 const ShaderInput *attr_get(const int binding) const
90 {
91 return input_lookup(inputs_, attr_len_, binding);
92 }
93
94 const ShaderInput *ubo_get(const StringRefNull name) const
95 {
96 return input_lookup(inputs_ + attr_len_, ubo_len_, name);
97 }
98 const ShaderInput *ubo_get(const int binding) const
99 {
100 return input_lookup(inputs_ + attr_len_, ubo_len_, binding);
101 }
102
103 const ShaderInput *uniform_get(const StringRefNull name) const
104 {
105 return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
106 }
107
108 const ShaderInput *texture_get(const int binding) const
109 {
110 return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
111 }
112
113 const ShaderInput *ssbo_get(const StringRefNull name) const
114 {
115 return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, name);
116 }
117 const ShaderInput *ssbo_get(const int binding) const
118 {
119 return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, binding);
120 }
121
122 const ShaderInput *constant_get(const StringRefNull name) const
123 {
124 return input_lookup(
126 }
127
128 const char *input_name_get(const ShaderInput *input) const
129 {
130 return name_buffer_ + input->name_offset;
131 }
132
133 /* Returns uniform location. */
135 {
136 BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
137 return builtins_[builtin];
138 }
139
140 /* Returns binding position. */
142 {
143 BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
144 return builtin_blocks_[builtin];
145 }
146
147 inline uint valid_bindings_get(const ShaderInput *const inputs, const uint inputs_len) const;
148
149 protected:
150 static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
151 static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
152
153 inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
154 inline void copy_input_name(ShaderInput *input,
155 const StringRefNull &name,
156 char *name_buffer,
157 uint32_t &name_buffer_offset) const;
158
162 void sort_inputs();
163
164 private:
165 inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
166 uint inputs_len,
167 StringRefNull name) const;
168
169 inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
170 uint inputs_len,
171 int binding) const;
172};
173
175{
176 switch (u) {
178 return "ModelMatrix";
179 case GPU_UNIFORM_VIEW:
180 return "ViewMatrix";
182 return "ModelViewMatrix";
184 return "ProjectionMatrix";
186 return "ViewProjectionMatrix";
187 case GPU_UNIFORM_MVP:
188 return "ModelViewProjectionMatrix";
189
191 return "ModelMatrixInverse";
193 return "ViewMatrixInverse";
195 return "ModelViewMatrixInverse";
197 return "ProjectionMatrixInverse";
199 return "ViewProjectionMatrixInverse";
200
202 return "NormalMatrix";
204 return "WorldClipPlanes";
205
207 return "color";
209 return "gpu_BaseInstance";
211 return "drw_resourceChunk";
213 return "drw_ResourceID";
215 return "srgbTarget";
216
217 default:
218 return nullptr;
219 }
220}
221
223{
224 switch (u) {
226 return "viewBlock";
228 return "modelBlock";
230 return "infoBlock";
231
233 return "drw_view_";
235 return "drw_matrices";
237 return "drw_infos";
239 return "drw_clipping_";
240 default:
241 return nullptr;
242 }
243}
244
245/* Returns string length including '\0' terminator. */
247 char *name,
248 uint32_t name_len) const
249{
250 /* remove "[0]" from array name */
251 if (name[name_len - 1] == ']') {
252 for (; name_len > 1; name_len--) {
253 if (name[name_len] == '[') {
254 name[name_len] = '\0';
255 break;
256 }
257 }
258 }
259
260 input->name_offset = (uint32_t)(name - name_buffer_);
261 input->name_hash = BLI_hash_string(name);
262 return name_len + 1; /* include NULL terminator */
263}
264
266 const StringRefNull &name,
267 char *name_buffer,
268 uint32_t &name_buffer_offset) const
269{
270 uint32_t name_len = name.size();
271 /* Copy include NULL terminator. */
272 memcpy(name_buffer + name_buffer_offset, name.c_str(), name_len + 1);
273 name_buffer_offset += set_input_name(input, name_buffer + name_buffer_offset, name_len);
274}
275
276inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
277 const uint inputs_len,
278 const StringRefNull name) const
279{
280 const uint name_hash = BLI_hash_string(name.c_str());
281 /* Simple linear search for now. */
282 for (int i = inputs_len - 1; i >= 0; i--) {
283 if (inputs[i].name_hash == name_hash) {
284 if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
285 /* Hash collision resolve. */
286 for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
287 if (name == (name_buffer_ + inputs[i].name_offset)) {
288 return inputs + i; /* not found */
289 }
290 }
291 return nullptr; /* not found */
292 }
293
294 /* This is a bit dangerous since we could have a hash collision.
295 * where the asked uniform that does not exist has the same hash
296 * as a real uniform. */
297 BLI_assert(name == (name_buffer_ + inputs[i].name_offset));
298 return inputs + i;
299 }
300 }
301 return nullptr; /* not found */
302}
303
304inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
305 const uint inputs_len,
306 const int binding) const
307{
308 /* Simple linear search for now. */
309 for (int i = inputs_len - 1; i >= 0; i--) {
310 if (inputs[i].binding == binding) {
311 return inputs + i;
312 }
313 }
314 return nullptr; /* not found */
315}
316
318 const uint inputs_len) const
319{
320 /* Simple linear search for now. */
321 int valid_bindings = 0;
322 for (int i = inputs_len - 1; i >= 0; i--) {
323 if (inputs[i].binding > -1) {
324 valid_bindings++;
325 }
326 }
327 return valid_bindings;
328}
329
330} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition BLI_hash.h:67
unsigned int uint
#define UNLIKELY(x)
#define GPU_NUM_UNIFORMS
GPUUniformBuiltin
@ GPU_UNIFORM_VIEWPROJECTION_INV
@ GPU_UNIFORM_PROJECTION
@ GPU_UNIFORM_RESOURCE_ID
@ GPU_UNIFORM_VIEWPROJECTION
@ GPU_UNIFORM_SRGB_TRANSFORM
@ GPU_UNIFORM_VIEW
@ GPU_UNIFORM_MODEL
@ GPU_UNIFORM_MODELVIEW
@ GPU_UNIFORM_BASE_INSTANCE
@ GPU_UNIFORM_VIEW_INV
@ GPU_UNIFORM_MODEL_INV
@ GPU_UNIFORM_PROJECTION_INV
@ GPU_UNIFORM_CLIPPLANES
@ GPU_UNIFORM_COLOR
@ GPU_UNIFORM_MODELVIEW_INV
@ GPU_UNIFORM_NORMAL
@ GPU_UNIFORM_RESOURCE_CHUNK
@ GPU_UNIFORM_MVP
GPUUniformBlockBuiltin
@ GPU_UNIFORM_BLOCK_DRW_VIEW
@ GPU_UNIFORM_BLOCK_DRW_MODEL
@ GPU_NUM_UNIFORM_BLOCKS
@ GPU_UNIFORM_BLOCK_MODEL
@ GPU_UNIFORM_BLOCK_VIEW
@ GPU_UNIFORM_BLOCK_DRW_CLIPPING
@ GPU_UNIFORM_BLOCK_DRW_INFOS
@ GPU_UNIFORM_BLOCK_INFO
static constexpr int GPU_VERT_ATTR_MAX_LEN
unsigned long long int uint64_t
constexpr int64_t size() const
constexpr const char * c_str() const
void copy_input_name(ShaderInput *input, const StringRefNull &name, char *name_buffer, uint32_t &name_buffer_offset) const
int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
const ShaderInput * attr_get(const StringRefNull name) const
const ShaderInput * uniform_get(const StringRefNull name) const
uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const
const ShaderInput * texture_get(const int binding) const
const ShaderInput * ubo_get(const int binding) const
const char * input_name_get(const ShaderInput *input) const
static const char * builtin_uniform_block_name(GPUUniformBlockBuiltin u)
int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
const ShaderInput * ubo_get(const StringRefNull name) const
const ShaderInput * ssbo_get(const StringRefNull name) const
uint valid_bindings_get(const ShaderInput *const inputs, const uint inputs_len) const
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
const ShaderInput * attr_get(const int binding) const
int32_t builtins_[GPU_NUM_UNIFORMS]
uint8_t attr_types_[GPU_VERT_ATTR_MAX_LEN]
const ShaderInput * constant_get(const StringRefNull name) const
const ShaderInput * ssbo_get(const int binding) const
static const char * builtin_uniform_name(GPUUniformBuiltin u)
#define input
static blender::bke::bNodeSocketTemplate inputs[]
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
i
Definition text_draw.cc:230