Blender V4.3
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
9#include "BLI_string.h"
10
12
13#include "gl_debug.hh"
14#include "gl_texture.hh"
15#include "gl_uniform_buffer.hh"
16
17namespace blender::gpu {
18
19/* -------------------------------------------------------------------- */
23GLUniformBuf::GLUniformBuf(size_t size, const char *name) : UniformBuf(size, name)
24{
25 /* Do not create ubo GL buffer here to allow allocation from any thread. */
27}
28
33
36/* -------------------------------------------------------------------- */
40void GLUniformBuf::init()
41{
43
44 glGenBuffers(1, &ubo_id_);
45 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
46 glBufferData(GL_UNIFORM_BUFFER, size_in_bytes_, nullptr, GL_DYNAMIC_DRAW);
47
48 debug::object_label(GL_UNIFORM_BUFFER, ubo_id_, name_);
49}
50
51void GLUniformBuf::update(const void *data)
52{
53 if (ubo_id_ == 0) {
54 this->init();
55 }
56 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
57 glBufferSubData(GL_UNIFORM_BUFFER, 0, size_in_bytes_, data);
58 glBindBuffer(GL_UNIFORM_BUFFER, 0);
59}
60
62{
63 if (ubo_id_ == 0) {
64 this->init();
65 }
66
67 uint32_t data = 0;
68 eGPUTextureFormat internal_format = GPU_R32UI;
69 eGPUDataFormat data_format = GPU_DATA_UINT;
70
72 glClearNamedBufferData(ubo_id_,
73 to_gl_internal_format(internal_format),
74 to_gl_data_format(internal_format),
75 to_gl(data_format),
76 &data);
77 }
78 else {
79 /* WATCH(@fclem): This should be ok since we only use clear outside of drawing functions. */
80 glBindBuffer(GL_UNIFORM_BUFFER, ubo_id_);
81 glClearBufferData(GL_UNIFORM_BUFFER,
82 to_gl_internal_format(internal_format),
83 to_gl_data_format(internal_format),
84 to_gl(data_format),
85 &data);
86 glBindBuffer(GL_UNIFORM_BUFFER, 0);
87 }
88}
89
92/* -------------------------------------------------------------------- */
96void GLUniformBuf::bind(int slot)
97{
98 if (slot >= GLContext::max_ubo_binds) {
99 fprintf(
100 stderr,
101 "Error: Trying to bind \"%s\" ubo to slot %d which is above the reported limit of %d.\n",
102 name_,
103 slot,
105 return;
106 }
107
108 if (ubo_id_ == 0) {
109 this->init();
110 }
111
112 if (data_ != nullptr) {
113 this->update(data_);
115 }
116
117 slot_ = slot;
118 glBindBufferBase(GL_UNIFORM_BUFFER, slot_, ubo_id_);
119
120#ifndef NDEBUG
121 BLI_assert(slot < 16);
122 GLContext::get()->bound_ubo_slots |= 1 << slot;
123#endif
124}
125
127{
128 if (ubo_id_ == 0) {
129 this->init();
130 }
131 if (data_ != nullptr) {
132 this->update(data_);
134 }
135
136 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, ubo_id_);
137#ifndef NDEBUG
138 BLI_assert(slot < 16);
139 GLContext::get()->bound_ssbo_slots |= 1 << slot;
140#endif
141}
142
144{
145#ifndef NDEBUG
146 /* NOTE: This only unbinds the last bound slot. */
147 glBindBufferBase(GL_UNIFORM_BUFFER, slot_, 0);
148 /* Hope that the context did not change. */
149 GLContext::get()->bound_ubo_slots &= ~(1 << slot_);
150#endif
151 slot_ = 0;
152}
153
156} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:50
eGPUDataFormat
@ GPU_DATA_UINT
eGPUTextureFormat
#define MEM_SAFE_FREE(v)
static void buf_free(GLuint buf_id)
static GLint max_ubo_binds
Definition gl_context.hh:45
static GLint max_ubo_size
Definition gl_context.hh:44
static bool direct_state_access_support
Definition gl_context.hh:52
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
SHADOW_TILEMAP_RES tiles_buf[] statistics_buf render_view_buf[SHADOW_VIEW_MAX] GPU_R32UI
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:344
GLenum to_gl_internal_format(eGPUTextureFormat format)
GLenum to_gl_data_format(eGPUTextureFormat format)
static GLenum to_gl(const GPUAttachmentType type)
unsigned int uint32_t
Definition stdint.h:80