Blender  V3.3
gpu_shader_interface.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 by Mike Erwin. All rights reserved. */
3 
13 #pragma once
14 
15 #include <cstring> /* required for STREQ later on. */
16 
17 #include "BLI_hash.h"
18 #include "BLI_utildefines.h"
19 
20 #include "GPU_shader.h"
22 
23 namespace blender::gpu {
24 
25 typedef struct ShaderInput {
32 
39  /* TODO(fclem): should be protected. */
40  public:
42  ShaderInput *inputs_ = nullptr;
44  char *name_buffer_ = nullptr;
59 
60  public:
63  virtual ~ShaderInterface();
64 
65  void debug_print();
66 
67  inline const ShaderInput *attr_get(const char *name) const
68  {
69  return input_lookup(inputs_, attr_len_, name);
70  }
71 
72  inline const ShaderInput *ubo_get(const char *name) const
73  {
74  return input_lookup(inputs_ + attr_len_, ubo_len_, name);
75  }
76  inline const ShaderInput *ubo_get(const int binding) const
77  {
78  return input_lookup(inputs_ + attr_len_, ubo_len_, binding);
79  }
80 
81  inline const ShaderInput *uniform_get(const char *name) const
82  {
83  return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
84  }
85 
86  inline const ShaderInput *texture_get(const int binding) const
87  {
88  return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
89  }
90 
91  inline const ShaderInput *ssbo_get(const char *name) const
92  {
93  return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, name);
94  }
95  inline const ShaderInput *ssbo_get(const int binding) const
96  {
97  return input_lookup(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_, binding);
98  }
99 
100  inline const char *input_name_get(const ShaderInput *input) const
101  {
102  return name_buffer_ + input->name_offset;
103  }
104 
105  /* Returns uniform location. */
106  inline int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
107  {
108  BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
109  return builtins_[builtin];
110  }
111 
112  /* Returns binding position. */
113  inline int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
114  {
115  BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
116  return builtin_blocks_[builtin];
117  }
118 
119  protected:
120  static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
121  static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
122 
123  inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
124  inline void copy_input_name(ShaderInput *input,
125  const StringRefNull &name,
126  char *name_buffer,
127  uint32_t &name_buffer_offset) const;
128 
132  void sort_inputs();
133 
134  private:
135  inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
136  uint inputs_len,
137  const char *name) const;
138 
139  inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
140  uint inputs_len,
141  int binding) const;
142 };
143 
145 {
146  switch (u) {
147  case GPU_UNIFORM_MODEL:
148  return "ModelMatrix";
149  case GPU_UNIFORM_VIEW:
150  return "ViewMatrix";
152  return "ModelViewMatrix";
154  return "ProjectionMatrix";
156  return "ViewProjectionMatrix";
157  case GPU_UNIFORM_MVP:
158  return "ModelViewProjectionMatrix";
159 
161  return "ModelMatrixInverse";
163  return "ViewMatrixInverse";
165  return "ModelViewMatrixInverse";
167  return "ProjectionMatrixInverse";
169  return "ViewProjectionMatrixInverse";
170 
171  case GPU_UNIFORM_NORMAL:
172  return "NormalMatrix";
173  case GPU_UNIFORM_ORCO:
174  return "OrcoTexCoFactors";
176  return "WorldClipPlanes";
177 
178  case GPU_UNIFORM_COLOR:
179  return "color";
181  return "gpu_BaseInstance";
183  return "drw_resourceChunk";
185  return "drw_ResourceID";
187  return "srgbTarget";
188 
189  default:
190  return nullptr;
191  }
192 }
193 
195 {
196  switch (u) {
198  return "viewBlock";
200  return "modelBlock";
202  return "infoBlock";
203 
205  return "drw_view";
207  return "drw_matrices";
209  return "drw_infos";
210  default:
211  return nullptr;
212  }
213 }
214 
215 /* Returns string length including '\0' terminator. */
217  char *name,
218  uint32_t name_len) const
219 {
220  /* remove "[0]" from array name */
221  if (name[name_len - 1] == ']') {
222  for (; name_len > 1; name_len--) {
223  if (name[name_len] == '[') {
224  name[name_len] = '\0';
225  break;
226  }
227  }
228  }
229 
230  input->name_offset = (uint32_t)(name - name_buffer_);
231  input->name_hash = BLI_hash_string(name);
232  return name_len + 1; /* include NULL terminator */
233 }
234 
236  const StringRefNull &name,
237  char *name_buffer,
238  uint32_t &name_buffer_offset) const
239 {
240  uint32_t name_len = name.size();
241  /* Copy include NULL terminator. */
242  memcpy(name_buffer + name_buffer_offset, name.c_str(), name_len + 1);
243  name_buffer_offset += set_input_name(input, name_buffer + name_buffer_offset, name_len);
244 }
245 
246 inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
247  const uint inputs_len,
248  const char *name) const
249 {
250  const uint name_hash = BLI_hash_string(name);
251  /* Simple linear search for now. */
252  for (int i = inputs_len - 1; i >= 0; i--) {
253  if (inputs[i].name_hash == name_hash) {
254  if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
255  /* Hash collision resolve. */
256  for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
257  if (STREQ(name, name_buffer_ + inputs[i].name_offset)) {
258  return inputs + i; /* not found */
259  }
260  }
261  return nullptr; /* not found */
262  }
263 
264  /* This is a bit dangerous since we could have a hash collision.
265  * where the asked uniform that does not exist has the same hash
266  * as a real uniform. */
267  BLI_assert(STREQ(name, name_buffer_ + inputs[i].name_offset));
268  return inputs + i;
269  }
270  }
271  return nullptr; /* not found */
272 }
273 
274 inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
275  const uint inputs_len,
276  const int binding) const
277 {
278  /* Simple linear search for now. */
279  for (int i = inputs_len - 1; i >= 0; i--) {
280  if (inputs[i].binding == binding) {
281  return inputs + i;
282  }
283  }
284  return nullptr; /* not found */
285 }
286 
287 } // 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:69
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNLIKELY(x)
#define STREQ(a, b)
GPUUniformBuiltin
Definition: GPU_shader.h:111
@ GPU_UNIFORM_VIEWPROJECTION_INV
Definition: GPU_shader.h:123
@ GPU_UNIFORM_PROJECTION
Definition: GPU_shader.h:115
@ GPU_UNIFORM_RESOURCE_ID
Definition: GPU_shader.h:132
@ GPU_UNIFORM_ORCO
Definition: GPU_shader.h:126
@ GPU_UNIFORM_VIEWPROJECTION
Definition: GPU_shader.h:116
@ GPU_UNIFORM_SRGB_TRANSFORM
Definition: GPU_shader.h:133
@ GPU_UNIFORM_VIEW
Definition: GPU_shader.h:113
@ GPU_UNIFORM_MODEL
Definition: GPU_shader.h:112
@ GPU_UNIFORM_MODELVIEW
Definition: GPU_shader.h:114
@ GPU_UNIFORM_BASE_INSTANCE
Definition: GPU_shader.h:130
@ GPU_UNIFORM_VIEW_INV
Definition: GPU_shader.h:120
@ GPU_UNIFORM_MODEL_INV
Definition: GPU_shader.h:119
@ GPU_UNIFORM_PROJECTION_INV
Definition: GPU_shader.h:122
@ GPU_UNIFORM_CLIPPLANES
Definition: GPU_shader.h:127
@ GPU_UNIFORM_COLOR
Definition: GPU_shader.h:129
@ GPU_UNIFORM_MODELVIEW_INV
Definition: GPU_shader.h:121
@ GPU_UNIFORM_NORMAL
Definition: GPU_shader.h:125
@ GPU_UNIFORM_RESOURCE_CHUNK
Definition: GPU_shader.h:131
@ GPU_NUM_UNIFORMS
Definition: GPU_shader.h:135
@ GPU_UNIFORM_MVP
Definition: GPU_shader.h:117
GPUUniformBlockBuiltin
Definition: GPU_shader.h:138
@ GPU_UNIFORM_BLOCK_DRW_VIEW
Definition: GPU_shader.h:144
@ GPU_UNIFORM_BLOCK_DRW_MODEL
Definition: GPU_shader.h:145
@ GPU_NUM_UNIFORM_BLOCKS
Definition: GPU_shader.h:148
@ GPU_UNIFORM_BLOCK_MODEL
Definition: GPU_shader.h:141
@ GPU_UNIFORM_BLOCK_VIEW
Definition: GPU_shader.h:140
@ GPU_UNIFORM_BLOCK_DRW_INFOS
Definition: GPU_shader.h:146
@ GPU_UNIFORM_BLOCK_INFO
Definition: GPU_shader.h:142
constexpr int64_t size() const
constexpr const char * c_str() const
const ShaderInput * ubo_get(const int binding) const
void copy_input_name(ShaderInput *input, const StringRefNull &name, char *name_buffer, uint32_t &name_buffer_offset) const
const ShaderInput * ubo_get(const char *name) const
int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
const ShaderInput * attr_get(const char *name) const
ShaderInterface(const shader::ShaderCreateInfo &info)
uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const
const ShaderInput * texture_get(const int binding) const
static const char * builtin_uniform_block_name(GPUUniformBlockBuiltin u)
int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
const ShaderInput * ssbo_get(const char *name) const
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
const char * input_name_get(const ShaderInput *input) const
const ShaderInput * ssbo_get(const int binding) const
const ShaderInput * uniform_get(const char *name) const
int32_t builtins_[GPU_NUM_UNIFORMS]
static const char * builtin_uniform_name(GPUUniformBuiltin u)
ccl_global KernelShaderEvalInput * input
struct blender::gpu::ShaderInput ShaderInput
static bNodeSocketTemplate inputs[]
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
signed int int32_t
Definition: stdint.h:77
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...