Blender  V2.93
gl_shader_interface.cc
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 
26 #include "BLI_bitmap.h"
27 
28 #include "gl_batch.hh"
29 
30 #include "gl_shader_interface.hh"
31 
32 namespace blender::gpu {
33 
34 /* -------------------------------------------------------------------- */
41 static inline int block_binding(int32_t program, uint32_t block_index)
42 {
43  /* For now just assign a consecutive index. In the future, we should set it in
44  * the shader using layout(binding = i) and query its value. */
45  glUniformBlockBinding(program, block_index, block_index);
46  return block_index;
47 }
48 
49 static inline int sampler_binding(int32_t program,
50  uint32_t uniform_index,
51  int32_t uniform_location,
52  int *sampler_len)
53 {
54  /* Identify sampler uniforms and assign sampler units to them. */
55  GLint type;
56  glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
57 
58  switch (type) {
59  case GL_SAMPLER_1D:
60  case GL_SAMPLER_2D:
61  case GL_SAMPLER_3D:
62  case GL_SAMPLER_CUBE:
63  case GL_SAMPLER_CUBE_MAP_ARRAY_ARB: /* OpenGL 4.0 */
64  case GL_SAMPLER_1D_SHADOW:
65  case GL_SAMPLER_2D_SHADOW:
66  case GL_SAMPLER_1D_ARRAY:
67  case GL_SAMPLER_2D_ARRAY:
68  case GL_SAMPLER_1D_ARRAY_SHADOW:
69  case GL_SAMPLER_2D_ARRAY_SHADOW:
70  case GL_SAMPLER_2D_MULTISAMPLE:
71  case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
72  case GL_SAMPLER_CUBE_SHADOW:
73  case GL_SAMPLER_BUFFER:
74  case GL_INT_SAMPLER_1D:
75  case GL_INT_SAMPLER_2D:
76  case GL_INT_SAMPLER_3D:
77  case GL_INT_SAMPLER_CUBE:
78  case GL_INT_SAMPLER_1D_ARRAY:
79  case GL_INT_SAMPLER_2D_ARRAY:
80  case GL_INT_SAMPLER_2D_MULTISAMPLE:
81  case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
82  case GL_INT_SAMPLER_BUFFER:
83  case GL_UNSIGNED_INT_SAMPLER_1D:
84  case GL_UNSIGNED_INT_SAMPLER_2D:
85  case GL_UNSIGNED_INT_SAMPLER_3D:
86  case GL_UNSIGNED_INT_SAMPLER_CUBE:
87  case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
88  case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
89  case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
90  case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
91  case GL_UNSIGNED_INT_SAMPLER_BUFFER: {
92  /* For now just assign a consecutive index. In the future, we should set it in
93  * the shader using layout(binding = i) and query its value. */
94  int binding = *sampler_len;
95  glUniform1i(uniform_location, binding);
96  (*sampler_len)++;
97  return binding;
98  }
99  default:
100  return -1;
101  }
102 }
103 
104 static inline int image_binding(int32_t program,
105  uint32_t uniform_index,
106  int32_t uniform_location,
107  int *image_len)
108 {
109  /* Identify image uniforms and assign image units to them. */
110  GLint type;
111  glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
112 
113  switch (type) {
114  case GL_IMAGE_1D:
115  case GL_IMAGE_2D:
116  case GL_IMAGE_3D: {
117  /* For now just assign a consecutive index. In the future, we should set it in
118  * the shader using layout(binding = i) and query its value. */
119  int binding = *image_len;
120  glUniform1i(uniform_location, binding);
121  (*image_len)++;
122  return binding;
123  }
124  default:
125  return -1;
126  }
127 }
130 /* -------------------------------------------------------------------- */
135 {
136  /* Necessary to make #glUniform works. */
137  glUseProgram(program);
138 
139  GLint max_attr_name_len = 0, attr_len = 0;
140  glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_len);
141  glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len);
142 
143  GLint max_ubo_name_len = 0, ubo_len = 0;
144  glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len);
145  glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len);
146 
147  GLint max_uniform_name_len = 0, active_uniform_len = 0, uniform_len = 0;
148  glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_len);
149  glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniform_len);
150  uniform_len = active_uniform_len;
151 
152  BLI_assert(ubo_len <= 16 && "enabled_ubo_mask_ is uint16_t");
153 
154  /* Work around driver bug with Intel HD 4600 on Windows 7/8, where
155  * GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH does not work. */
156  if (attr_len > 0 && max_attr_name_len == 0) {
157  max_attr_name_len = 256;
158  }
159  if (ubo_len > 0 && max_ubo_name_len == 0) {
160  max_ubo_name_len = 256;
161  }
162  if (uniform_len > 0 && max_uniform_name_len == 0) {
163  max_uniform_name_len = 256;
164  }
165 
166  /* GL_ACTIVE_UNIFORMS lied to us! Remove the UBO uniforms from the total before
167  * allocating the uniform array. */
168  GLint max_ubo_uni_len = 0;
169  for (int i = 0; i < ubo_len; i++) {
170  GLint ubo_uni_len;
171  glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
172  max_ubo_uni_len = max_ii(max_ubo_uni_len, ubo_uni_len);
173  uniform_len -= ubo_uni_len;
174  }
175  /* Bit set to true if uniform comes from a uniform block. */
176  BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__);
177  /* Set uniforms from block for exclusion. */
178  GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
179  for (int i = 0; i < ubo_len; i++) {
180  GLint ubo_uni_len;
181  glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
182  glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, ubo_uni_ids);
183  for (int u = 0; u < ubo_uni_len; u++) {
184  BLI_BITMAP_ENABLE(uniforms_from_blocks, ubo_uni_ids[u]);
185  }
186  }
187  MEM_freeN(ubo_uni_ids);
188 
189  int input_tot_len = attr_len + ubo_len + uniform_len;
190  inputs_ = (ShaderInput *)MEM_callocN(sizeof(ShaderInput) * input_tot_len, __func__);
191 
192  const uint32_t name_buffer_len = attr_len * max_attr_name_len + ubo_len * max_ubo_name_len +
193  uniform_len * max_uniform_name_len;
194  name_buffer_ = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
195  uint32_t name_buffer_offset = 0;
196 
197  /* Attributes */
198  enabled_attr_mask_ = 0;
199  for (int i = 0; i < attr_len; i++) {
200  char *name = name_buffer_ + name_buffer_offset;
201  GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
202  GLsizei name_len = 0;
203  GLenum type;
204  GLint size;
205 
206  glGetActiveAttrib(program, i, remaining_buffer, &name_len, &size, &type, name);
207  GLint location = glGetAttribLocation(program, name);
208  /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
209  if (location == -1) {
210  continue;
211  }
212 
213  ShaderInput *input = &inputs_[attr_len_++];
214  input->location = input->binding = location;
215 
216  name_buffer_offset += set_input_name(input, name, name_len);
217  enabled_attr_mask_ |= (1 << input->location);
218  }
219 
220  /* Uniform Blocks */
221  for (int i = 0; i < ubo_len; i++) {
222  char *name = name_buffer_ + name_buffer_offset;
223  GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
224  GLsizei name_len = 0;
225 
226  glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name);
227 
228  ShaderInput *input = &inputs_[attr_len_ + ubo_len_++];
229  input->binding = input->location = block_binding(program, i);
230 
231  name_buffer_offset += this->set_input_name(input, name, name_len);
232  enabled_ubo_mask_ |= (1 << input->binding);
233  }
234 
235  /* Uniforms & samplers & images */
236  for (int i = 0, sampler = 0, image = 0; i < active_uniform_len; i++) {
237  if (BLI_BITMAP_TEST(uniforms_from_blocks, i)) {
238  continue;
239  }
240  char *name = name_buffer_ + name_buffer_offset;
241  GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
242  GLsizei name_len = 0;
243 
244  glGetActiveUniformName(program, i, remaining_buffer, &name_len, name);
245 
247  input->location = glGetUniformLocation(program, name);
248  input->binding = sampler_binding(program, i, input->location, &sampler);
249 
250  name_buffer_offset += this->set_input_name(input, name, name_len);
251  enabled_tex_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
252 
253  if (input->binding == -1) {
254  input->binding = image_binding(program, i, input->location, &image);
255 
256  enabled_ima_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
257  }
258  }
259 
260  /* Builtin Uniforms */
261  for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
262  GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
263  builtins_[u] = glGetUniformLocation(program, builtin_uniform_name(u));
264  }
265 
266  /* Builtin Uniforms Blocks */
267  for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) {
268  GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int);
269  const ShaderInput *block = this->ubo_get(builtin_uniform_block_name(u));
270  builtin_blocks_[u] = (block != nullptr) ? block->binding : -1;
271  }
272 
273  MEM_freeN(uniforms_from_blocks);
274 
275  /* Resize name buffer to save some memory. */
276  if (name_buffer_offset < name_buffer_len) {
277  name_buffer_ = (char *)MEM_reallocN(name_buffer_, name_buffer_offset);
278  }
279 
280  // this->debug_print();
281 
282  this->sort_inputs();
283 }
284 
286 {
287  for (auto *ref : refs_) {
288  if (ref != nullptr) {
289  ref->remove(this);
290  }
291  }
292 }
293 
296 /* -------------------------------------------------------------------- */
301 {
302  for (int i = 0; i < refs_.size(); i++) {
303  if (refs_[i] == NULL) {
304  refs_[i] = ref;
305  return;
306  }
307  }
308  refs_.append(ref);
309 }
310 
312 {
313  for (int i = 0; i < refs_.size(); i++) {
314  if (refs_[i] == ref) {
315  refs_[i] = NULL;
316  break; /* cannot have duplicates */
317  }
318  }
319 }
320 
323 /* -------------------------------------------------------------------- */
330 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:63
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:78
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
MINLINE int max_ii(int a, int b)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
GPUUniformBuiltin
Definition: GPU_shader.h:88
@ GPU_NUM_UNIFORMS
Definition: GPU_shader.h:112
GPUUniformBlockBuiltin
Definition: GPU_shader.h:115
@ GPU_NUM_UNIFORM_BLOCKS
Definition: GPU_shader.h:120
#define MEM_reallocN(vmemh, len)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
const ShaderInput * ubo_get(const char *name) const
uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const
static const char * builtin_uniform_block_name(GPUUniformBlockBuiltin u)
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
int32_t builtins_[GPU_NUM_UNIFORMS]
static const char * builtin_uniform_name(GPUUniformBuiltin u)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static int block_binding(int32_t program, uint32_t block_index)
static int sampler_binding(int32_t program, uint32_t uniform_index, int32_t uniform_location, int *sampler_len)
static int image_binding(int32_t program, uint32_t uniform_index, int32_t uniform_location, int *image_len)
unsigned int uint32_t
Definition: stdint.h:83
signed int int32_t
Definition: stdint.h:80