Blender V5.0
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_format.hh"
22#include "GPU_shader.hh"
23#include "GPU_vertex_format.hh" /* GPU_VERT_ATTR_MAX_LEN */
26
27namespace blender::gpu {
28
44
51 /* TODO(fclem): should be protected. */
52 public:
54 ShaderInput *inputs_ = nullptr;
56 char *name_buffer_ = nullptr;
64 uint16_t enabled_attr_mask_ = 0;
65 uint16_t enabled_ubo_mask_ = 0;
66 uint8_t enabled_ima_mask_ = 0;
68 uint16_t enabled_ssbo_mask_ = 0;
69 /* Bitmask to apply to enabled_ssbo_mask_ to get attributes that are sourced from SSBOs. */
70 uint16_t ssbo_attr_mask_ = 0;
74
81
82 /* Formats of all image units. */
83 std::array<TextureWriteFormat, GPU_MAX_IMAGE> image_formats_;
84
86 virtual ~ShaderInterface();
87
88 void debug_print() const;
89
91 {
92 return input_lookup(inputs_, attr_len_, name);
93 }
94 const ShaderInput *attr_get(const int binding) const
95 {
96 return input_lookup(inputs_, attr_len_, binding);
97 }
98
100 {
101 return input_lookup(inputs_ + attr_len_, ubo_len_, name);
102 }
103 const ShaderInput *ubo_get(const int binding) const
104 {
105 return input_lookup(inputs_ + attr_len_, ubo_len_, binding);
106 }
107
109 {
110 return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
111 }
112
113 const ShaderInput *texture_get(const int binding) const
114 {
115 return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
116 }
117
119 {
120 return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, name);
121 }
122 const ShaderInput *ssbo_get(const int binding) const
123 {
124 return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, binding);
125 }
126
128 {
129 return input_lookup(
131 }
132
133 const char *input_name_get(const ShaderInput *input) const
134 {
135 return name_buffer_ + input->name_offset;
136 }
137
138 /* Returns uniform location. */
140 {
141 BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
142 return builtins_[builtin];
143 }
144
145 /* Returns binding position. */
147 {
148 BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
149 return builtin_blocks_[builtin];
150 }
151
152 inline uint valid_bindings_get(const ShaderInput *const inputs, const uint inputs_len) const;
153
154 protected:
155 static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
156 static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
157
158 inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
159 inline void copy_input_name(ShaderInput *input,
160 const StringRefNull &name,
161 char *name_buffer,
162 uint32_t &name_buffer_offset) const;
163
167 void sort_inputs();
168
170
171 private:
172 inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
173 uint inputs_len,
174 StringRefNull name) const;
175
176 inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
177 uint inputs_len,
178 int binding) const;
179};
180
182{
183 switch (u) {
185 return "ModelMatrix";
186 case GPU_UNIFORM_VIEW:
187 return "ViewMatrix";
189 return "ModelViewMatrix";
191 return "ProjectionMatrix";
193 return "ViewProjectionMatrix";
194 case GPU_UNIFORM_MVP:
195 return "ModelViewProjectionMatrix";
196
198 return "ModelMatrixInverse";
200 return "ViewMatrixInverse";
202 return "ModelViewMatrixInverse";
204 return "ProjectionMatrixInverse";
206 return "ViewProjectionMatrixInverse";
207
209 return "NormalMatrix";
211 return "WorldClipPlanes";
212
214 return "color";
216 return "gpu_BaseInstance";
218 return "drw_resourceChunk";
220 return "drw_ResourceID";
222 return "srgbTarget";
224 return "gpu_scene_linear_to_rec709";
225
226 default:
227 return nullptr;
228 }
229}
230
232{
233 switch (u) {
235 return "viewBlock";
237 return "modelBlock";
239 return "infoBlock";
240
242 return "drw_view_";
244 return "drw_matrices";
246 return "drw_infos";
248 return "drw_clipping_";
249 default:
250 return nullptr;
251 }
252}
253
254/* Returns string length including '\0' terminator. */
256 char *name,
257 uint32_t name_len) const
258{
259 /* remove "[0]" from array name */
260 if (name[name_len - 1] == ']') {
261 for (; name_len > 1; name_len--) {
262 if (name[name_len] == '[') {
263 name[name_len] = '\0';
264 break;
265 }
266 }
267 }
268
269 input->name_offset = (uint32_t)(name - name_buffer_);
270 input->name_hash = BLI_hash_string(name);
271 return name_len + 1; /* include NULL terminator */
272}
273
275 const StringRefNull &name,
276 char *name_buffer,
277 uint32_t &name_buffer_offset) const
278{
279 uint32_t name_len = name.size();
280 /* Copy include NULL terminator. */
281 memcpy(name_buffer + name_buffer_offset, name.c_str(), name_len + 1);
282 name_buffer_offset += set_input_name(input, name_buffer + name_buffer_offset, name_len);
283}
284
285inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
286 const uint inputs_len,
287 const StringRefNull name) const
288{
289 const uint name_hash = BLI_hash_string(name.c_str());
290 /* Simple linear search for now. */
291 for (int i = inputs_len - 1; i >= 0; i--) {
292 if (inputs[i].name_hash == name_hash) {
293 if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
294 /* Hash collision resolve. */
295 for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
296 if (name == (name_buffer_ + inputs[i].name_offset)) {
297 return inputs + i; /* not found */
298 }
299 }
300 return nullptr; /* not found */
301 }
302
303 /* This is a bit dangerous since we could have a hash collision.
304 * where the asked uniform that does not exist has the same hash
305 * as a real uniform. */
306 BLI_assert(name == (name_buffer_ + inputs[i].name_offset));
307 return inputs + i;
308 }
309 }
310 return nullptr; /* not found */
311}
312
313inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
314 const uint inputs_len,
315 const int binding) const
316{
317 /* Simple linear search for now. */
318 for (int i = inputs_len - 1; i >= 0; i--) {
319 if (inputs[i].binding == binding) {
320 return inputs + i;
321 }
322 }
323 return nullptr; /* not found */
324}
325
327 const uint inputs_len) const
328{
329 /* Simple linear search for now. */
330 int valid_bindings = 0;
331 for (int i = inputs_len - 1; i >= 0; i--) {
332 if (inputs[i].binding > -1) {
333 valid_bindings++;
334 }
335 }
336 return valid_bindings;
337}
338
339} // 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_SCENE_LINEAR_XFORM
@ 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
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
void set_image_formats_from_info(const shader::ShaderCreateInfo &info)
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]
std::array< TextureWriteFormat, GPU_MAX_IMAGE > image_formats_
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[]
const char * name
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
i
Definition text_draw.cc:230