Blender  V2.93
gl_uniform_buffer.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) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "BKE_global.h"
25 
26 #include "BLI_string.h"
27 
28 #include "gpu_backend.hh"
29 #include "gpu_context_private.hh"
30 
31 #include "gl_backend.hh"
32 #include "gl_debug.hh"
33 #include "gl_uniform_buffer.hh"
34 
35 namespace blender::gpu {
36 
37 /* -------------------------------------------------------------------- */
41 GLUniformBuf::GLUniformBuf(size_t size, const char *name) : UniformBuf(size, name)
42 {
43  /* Do not create ubo GL buffer here to allow allocation from any thread. */
45 }
46 
48 {
49  GLContext::buf_free(ubo_id_);
50 }
51 
54 /* -------------------------------------------------------------------- */
58 void GLUniformBuf::init()
59 {
61 
62  glGenBuffers(1, &ubo_id_);
63  glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
64  glBufferData(GL_UNIFORM_BUFFER, size_in_bytes_, nullptr, GL_DYNAMIC_DRAW);
65 
66  debug::object_label(GL_UNIFORM_BUFFER, ubo_id_, name_);
67 }
68 
69 void GLUniformBuf::update(const void *data)
70 {
71  if (ubo_id_ == 0) {
72  this->init();
73  }
74  glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
75  glBufferSubData(GL_UNIFORM_BUFFER, 0, size_in_bytes_, data);
76  glBindBuffer(GL_UNIFORM_BUFFER, 0);
77 }
78 
81 /* -------------------------------------------------------------------- */
85 void GLUniformBuf::bind(int slot)
86 {
87  if (slot >= GLContext::max_ubo_binds) {
88  fprintf(stderr,
89  "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.",
90  name_,
91  slot,
93  return;
94  }
95 
96  if (ubo_id_ == 0) {
97  this->init();
98  }
99 
100  if (data_ != nullptr) {
101  this->update(data_);
103  }
104 
105  slot_ = slot;
106  glBindBufferBase(GL_UNIFORM_BUFFER, slot_, ubo_id_);
107 
108 #ifdef DEBUG
109  BLI_assert(slot < 16);
110  GLContext::get()->bound_ubo_slots |= 1 << slot;
111 #endif
112 }
113 
115 {
116 #ifdef DEBUG
117  /* NOTE: This only unbinds the last bound slot. */
118  glBindBufferBase(GL_UNIFORM_BUFFER, slot_, 0);
119  /* Hope that the context did not change. */
120  GLContext::get()->bound_ubo_slots &= ~(1 << slot_);
121 #endif
122  slot_ = 0;
123 }
124 
127 } // namespace blender::gpu
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define MEM_SAFE_FREE(v)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static void buf_free(GLuint buf_id)
Definition: gl_context.cc:257
static GLint max_ubo_binds
Definition: gl_context.hh:62
static GLint max_ubo_size
Definition: gl_context.hh:61
static GLContext * get()
Definition: gl_context.hh:118
GLUniformBuf(size_t size, const char *name)
void update(const void *data) override
void bind(int slot) override
void object_label(GLenum type, GLuint object, const char *name)
Definition: gl_debug.cc:335