Blender  V2.93
gpu_shader_interface.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2016 by Mike Erwin.
17  * All rights reserved.
18  */
19 
29 #pragma once
30 
31 #include <cstring> /* required for STREQ later on. */
32 
33 #include "BLI_hash.h"
34 #include "BLI_utildefines.h"
35 
36 #include "GPU_shader.h"
37 
38 namespace blender::gpu {
39 
40 typedef struct ShaderInput {
47 
53  /* TODO(fclem): should be protected. */
54  public:
58  char *name_buffer_ = NULL;
71 
72  public:
74  virtual ~ShaderInterface();
75 
76  void debug_print(void);
77 
78  inline const ShaderInput *attr_get(const char *name) const
79  {
80  return input_lookup(inputs_, attr_len_, name);
81  }
82 
83  inline const ShaderInput *ubo_get(const char *name) const
84  {
85  return input_lookup(inputs_ + attr_len_, ubo_len_, name);
86  }
87  inline const ShaderInput *ubo_get(const int binding) const
88  {
89  return input_lookup(inputs_ + attr_len_, ubo_len_, binding);
90  }
91 
92  inline const ShaderInput *uniform_get(const char *name) const
93  {
94  return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
95  }
96 
97  inline const ShaderInput *texture_get(const int binding) const
98  {
99  return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
100  }
101 
102  inline const char *input_name_get(const ShaderInput *input) const
103  {
104  return name_buffer_ + input->name_offset;
105  }
106 
107  /* Returns uniform location. */
108  inline int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
109  {
110  BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
111  return builtins_[builtin];
112  }
113 
114  /* Returns binding position. */
115  inline int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
116  {
117  BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
118  return builtin_blocks_[builtin];
119  }
120 
121  protected:
122  static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
123  static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
124 
125  inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
126 
127  /* Finalize interface construction by sorting the ShaderInputs for faster lookups. */
128  void sort_inputs(void);
129 
130  private:
131  inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
132  const uint inputs_len,
133  const char *name) const;
134 
135  inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
136  const uint inputs_len,
137  const int binding) const;
138 };
139 
141 {
142  switch (u) {
143  case GPU_UNIFORM_MODEL:
144  return "ModelMatrix";
145  case GPU_UNIFORM_VIEW:
146  return "ViewMatrix";
148  return "ModelViewMatrix";
150  return "ProjectionMatrix";
152  return "ViewProjectionMatrix";
153  case GPU_UNIFORM_MVP:
154  return "ModelViewProjectionMatrix";
155 
157  return "ModelMatrixInverse";
159  return "ViewMatrixInverse";
161  return "ModelViewMatrixInverse";
163  return "ProjectionMatrixInverse";
165  return "ViewProjectionMatrixInverse";
166 
167  case GPU_UNIFORM_NORMAL:
168  return "NormalMatrix";
169  case GPU_UNIFORM_ORCO:
170  return "OrcoTexCoFactors";
172  return "WorldClipPlanes";
173 
174  case GPU_UNIFORM_COLOR:
175  return "color";
177  return "baseInstance";
179  return "resourceChunk";
181  return "resourceId";
183  return "srgbTarget";
184 
185  default:
186  return NULL;
187  }
188 }
189 
191 {
192  switch (u) {
194  return "viewBlock";
196  return "modelBlock";
198  return "infoBlock";
199  default:
200  return NULL;
201  }
202 }
203 
204 /* Returns string length including '\0' terminator. */
206  char *name,
207  uint32_t name_len) const
208 {
209  /* remove "[0]" from array name */
210  if (name[name_len - 1] == ']') {
211  name[name_len - 3] = '\0';
212  name_len -= 3;
213  }
214 
215  input->name_offset = (uint32_t)(name - name_buffer_);
216  input->name_hash = BLI_hash_string(name);
217  return name_len + 1; /* include NULL terminator */
218 }
219 
220 inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
221  const uint inputs_len,
222  const char *name) const
223 {
224  const uint name_hash = BLI_hash_string(name);
225  /* Simple linear search for now. */
226  for (int i = inputs_len - 1; i >= 0; i--) {
227  if (inputs[i].name_hash == name_hash) {
228  if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
229  /* Hash collision resolve. */
230  for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
231  if (STREQ(name, name_buffer_ + inputs[i].name_offset)) {
232  return inputs + i; /* not found */
233  }
234  }
235  return NULL; /* not found */
236  }
237 
238  /* This is a bit dangerous since we could have a hash collision.
239  * where the asked uniform that does not exist has the same hash
240  * as a real uniform. */
241  BLI_assert(STREQ(name, name_buffer_ + inputs[i].name_offset));
242  return inputs + i;
243  }
244  }
245  return NULL; /* not found */
246 }
247 
248 inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
249  const uint inputs_len,
250  const int binding) const
251 {
252  /* Simple linear search for now. */
253  for (int i = inputs_len - 1; i >= 0; i--) {
254  if (inputs[i].binding == binding) {
255  return inputs + i;
256  }
257  }
258  return NULL; /* not found */
259 }
260 
261 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition: BLI_hash.h:83
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNLIKELY(x)
#define STREQ(a, b)
GPUUniformBuiltin
Definition: GPU_shader.h:88
@ GPU_UNIFORM_VIEWPROJECTION_INV
Definition: GPU_shader.h:100
@ GPU_UNIFORM_PROJECTION
Definition: GPU_shader.h:92
@ GPU_UNIFORM_RESOURCE_ID
Definition: GPU_shader.h:109
@ GPU_UNIFORM_ORCO
Definition: GPU_shader.h:103
@ GPU_UNIFORM_VIEWPROJECTION
Definition: GPU_shader.h:93
@ GPU_UNIFORM_SRGB_TRANSFORM
Definition: GPU_shader.h:110
@ GPU_UNIFORM_VIEW
Definition: GPU_shader.h:90
@ GPU_UNIFORM_MODEL
Definition: GPU_shader.h:89
@ GPU_UNIFORM_MODELVIEW
Definition: GPU_shader.h:91
@ GPU_UNIFORM_BASE_INSTANCE
Definition: GPU_shader.h:107
@ GPU_UNIFORM_VIEW_INV
Definition: GPU_shader.h:97
@ GPU_UNIFORM_MODEL_INV
Definition: GPU_shader.h:96
@ GPU_UNIFORM_PROJECTION_INV
Definition: GPU_shader.h:99
@ GPU_UNIFORM_CLIPPLANES
Definition: GPU_shader.h:104
@ GPU_UNIFORM_COLOR
Definition: GPU_shader.h:106
@ GPU_UNIFORM_MODELVIEW_INV
Definition: GPU_shader.h:98
@ GPU_UNIFORM_NORMAL
Definition: GPU_shader.h:102
@ GPU_UNIFORM_RESOURCE_CHUNK
Definition: GPU_shader.h:108
@ GPU_NUM_UNIFORMS
Definition: GPU_shader.h:112
@ GPU_UNIFORM_MVP
Definition: GPU_shader.h:94
GPUUniformBlockBuiltin
Definition: GPU_shader.h:115
@ GPU_NUM_UNIFORM_BLOCKS
Definition: GPU_shader.h:120
@ GPU_UNIFORM_BLOCK_MODEL
Definition: GPU_shader.h:117
@ GPU_UNIFORM_BLOCK_VIEW
Definition: GPU_shader.h:116
@ GPU_UNIFORM_BLOCK_INFO
Definition: GPU_shader.h:118
const ShaderInput * ubo_get(const int binding) 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
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
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
const char * input_name_get(const ShaderInput *input) const
const ShaderInput * uniform_get(const char *name) const
int32_t builtins_[GPU_NUM_UNIFORMS]
static const char * builtin_uniform_name(GPUUniformBuiltin u)
struct blender::gpu::ShaderInput ShaderInput
static bNodeSocketTemplate inputs[]
unsigned short uint16_t
Definition: stdint.h:82
unsigned int uint32_t
Definition: stdint.h:83
signed int int32_t
Definition: stdint.h:80
unsigned char uint8_t
Definition: stdint.h:81
unsigned __int64 uint64_t
Definition: stdint.h:93