Blender V5.0
gl_index_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 "gl_context.hh"
10
11#include "gl_index_buffer.hh"
12
13namespace blender::gpu {
14
19
21{
22 if (is_subrange_) {
23 static_cast<GLIndexBuf *>(src_)->bind();
24 return;
25 }
26
27 const bool allocate_on_device = ibo_id_ == 0;
28 if (allocate_on_device) {
29 glGenBuffers(1, &ibo_id_);
30 }
31
32 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id_);
33
34 if (data_ != nullptr || allocate_on_device) {
35 size_t size = this->size_get();
36 /* Pad the buffer to avoid out of bound reads when using vertex pulling mode. */
37 glBufferData(GL_ELEMENT_ARRAY_BUFFER, ceil_to_multiple_ul(size, 16), nullptr, GL_STATIC_DRAW);
38
39 if (data_ != nullptr) {
40 /* Sends data to GPU. */
41 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data_);
42 }
43 /* No need to keep copy of data in system memory. */
45 }
46}
47
49{
50 if (is_subrange_) {
51 src_->bind_as_ssbo(binding);
52 return;
53 }
54
55 if (ibo_id_ == 0 || data_ != nullptr) {
56 /* Calling `glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id_)` changes the index buffer
57 * of the currently bound VAO.
58 *
59 * In the OpenGL backend, the VAO state persists even after `GLVertArray::update_bindings`
60 * is called.
61 *
62 * NOTE: For safety, we could call `glBindVertexArray(0)` right after drawing a `gpu::Batch`.
63 * However, for performance reasons, we have chosen not to do so. */
64 glBindVertexArray(0);
65 bind();
66 }
67
68 BLI_assert(ibo_id_ != 0);
69 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, ibo_id_);
70
71#ifndef NDEBUG
72 BLI_assert(binding < 16);
73 GLContext::get()->bound_ssbo_slots |= 1 << binding;
74#endif
75}
76
77void GLIndexBuf::read(uint32_t *data) const
78{
79 BLI_assert(is_active());
80 const void *buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
81 memcpy(data, buffer, size_get());
82 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
83}
84
85bool GLIndexBuf::is_active() const
86{
87 if (!ibo_id_) {
88 return false;
89 }
90 int active_ibo_id = 0;
91 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &active_ibo_id);
92 return ibo_id_ == active_ibo_id;
93}
94
96{
97 bind();
98}
99
100void GLIndexBuf::update_sub(uint start, uint len, const void *data)
101{
102 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, start, len, data);
103}
104
105} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE uint64_t ceil_to_multiple_ul(uint64_t a, uint64_t b)
unsigned int uint
#define MEM_SAFE_FREE(v)
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static void buffer_free(GLuint buf_id)
static GLContext * get()
void bind_as_ssbo(uint binding) override
void update_sub(uint start, uint len, const void *data) override
void read(uint32_t *data) const override
uint len