Blender V5.0
gl_uniform_buffer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_string.h"
10
11#include "GPU_capabilities.hh"
12
14
15#include "gl_debug.hh"
16#include "gl_texture.hh"
17#include "gl_uniform_buffer.hh"
18
19namespace blender::gpu {
20
21/* -------------------------------------------------------------------- */
24
26{
27 /* Do not create ubo GL buffer here to allow allocation from any thread. */
29}
30
35
37
38/* -------------------------------------------------------------------- */
41
42void GLUniformBuf::init()
43{
45
46 glGenBuffers(1, &ubo_id_);
47 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
48 glBufferData(GL_UNIFORM_BUFFER, size_in_bytes_, nullptr, GL_DYNAMIC_DRAW);
49
50 debug::object_label(GL_UNIFORM_BUFFER, ubo_id_, name_);
51}
52
53void GLUniformBuf::update(const void *data)
54{
55 if (ubo_id_ == 0) {
56 this->init();
57 }
58 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
59 glBufferSubData(GL_UNIFORM_BUFFER, 0, size_in_bytes_, data);
60 glBindBuffer(GL_UNIFORM_BUFFER, 0);
61}
62
64{
65 if (ubo_id_ == 0) {
66 this->init();
67 }
68
69 uint32_t data = 0;
70 TextureFormat internal_format = TextureFormat::UINT_32;
71 eGPUDataFormat data_format = GPU_DATA_UINT;
72
74 glClearNamedBufferData(ubo_id_,
75 to_gl_internal_format(internal_format),
76 to_gl_data_format(internal_format),
77 to_gl(data_format),
78 &data);
79 }
80 else {
81 /* WATCH(@fclem): This should be ok since we only use clear outside of drawing functions. */
82 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
83 glClearBufferData(GL_UNIFORM_BUFFER,
84 to_gl_internal_format(internal_format),
85 to_gl_data_format(internal_format),
86 to_gl(data_format),
87 &data);
88 glBindBuffer(GL_UNIFORM_BUFFER, 0);
89 }
90}
91
93
94/* -------------------------------------------------------------------- */
97
98void GLUniformBuf::bind(int slot)
99{
100 if (slot >= GLContext::max_ubo_binds) {
101 fprintf(
102 stderr,
103 "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.\n",
104 name_,
105 slot,
107 return;
108 }
109
110 if (ubo_id_ == 0) {
111 this->init();
112 }
113
114 if (data_ != nullptr) {
115 this->update(data_);
117 }
118
119 slot_ = slot;
120 glBindBufferBase(GL_UNIFORM_BUFFER, slot_, ubo_id_);
121
122#ifndef NDEBUG
123 BLI_assert(slot < 16);
124 GLContext::get()->bound_ubo_slots |= 1 << slot;
125#endif
126}
127
129{
130 if (ubo_id_ == 0) {
131 this->init();
132 }
133 if (data_ != nullptr) {
134 this->update(data_);
136 }
137
138 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, ubo_id_);
139#ifndef NDEBUG
140 BLI_assert(slot < 16);
141 GLContext::get()->bound_ssbo_slots |= 1 << slot;
142#endif
143}
144
146{
147#ifndef NDEBUG
148 /* NOTE: This only unbinds the last bound slot. */
149 glBindBufferBase(GL_UNIFORM_BUFFER, slot_, 0);
150 /* Hope that the context did not change. */
151 GLContext::get()->bound_ubo_slots &= ~(1 << slot_);
152#endif
153 slot_ = 0;
154}
155
157
158} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
size_t GPU_max_uniform_buffer_size()
eGPUDataFormat
@ GPU_DATA_UINT
#define MEM_SAFE_FREE(v)
BMesh const char void * data
void init()
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static void buffer_free(GLuint buf_id)
static GLint max_ubo_binds
Definition gl_context.hh:55
static bool direct_state_access_support
Definition gl_context.hh:61
static GLContext * get()
GLUniformBuf(size_t size, const char *name)
void update(const void *data) override
void bind(int slot) override
void bind_as_ssbo(int slot) override
UniformBuf(size_t size, const char *name)
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:329
GLenum to_gl_internal_format(TextureFormat format)
GLenum to_gl_data_format(TextureFormat format)
static GLenum to_gl(const GPUAttachmentType type)
const char * name