Blender V5.0
gl_vertex_buffer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "GPU_texture.hh"
10
11#include "gl_context.hh"
12
13#include "gl_vertex_buffer.hh"
14
15namespace blender::gpu {
16
18{
20 return;
21 }
22
23 /* Discard previous data if any. */
26}
27
29{
31 return;
32 }
33
34 data_ = (uchar *)MEM_reallocN(data_, sizeof(uchar) * this->size_alloc_get());
35}
36
38{
39 if (is_wrapper_) {
40 return;
41 }
42
43 if (vbo_id_ != 0) {
44 GPU_TEXTURE_FREE_SAFE(buffer_texture_);
46 vbo_id_ = 0;
47 memory_usage -= vbo_size_;
48 }
49
51}
52
54{
55 this->bind();
56}
57
59{
60 BLI_assert(GLContext::get() != nullptr);
61
62 if (vbo_id_ == 0) {
63 glGenBuffers(1, &vbo_id_);
64 }
65
66 glBindBuffer(GL_ARRAY_BUFFER, vbo_id_);
67
69 vbo_size_ = this->size_used_get();
70
71 /* This is fine on some systems but will crash on others. */
72 BLI_assert(vbo_size_ != 0);
73 /* Orphan the vbo to avoid sync then upload data. */
74 glBufferData(GL_ARRAY_BUFFER, ceil_to_multiple_ul(vbo_size_, 16), nullptr, to_gl(usage_));
75 /* Do not transfer data from host to device when buffer is device only. */
77 glBufferSubData(GL_ARRAY_BUFFER, 0, vbo_size_, data_);
78 }
79 memory_usage += vbo_size_;
80
81 if (usage_ == GPU_USAGE_STATIC) {
83 }
86 }
87}
88
90{
91 bind();
92 BLI_assert(vbo_id_ != 0);
93 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, vbo_id_);
94
95#ifndef NDEBUG
96 BLI_assert(binding < 16);
97 GLContext::get()->bound_ssbo_slots |= 1 << binding;
98#endif
99}
100
102{
103 bind();
104 BLI_assert(vbo_id_ != 0);
105 if (buffer_texture_ == nullptr) {
106 buffer_texture_ = GPU_texture_create_from_vertbuf("vertbuf_as_texture", this);
107 }
108 GPU_texture_bind(buffer_texture_, binding);
109}
110
111void GLVertBuf::read(void *data) const
112{
113 BLI_assert(is_active());
114 void *result = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
115 memcpy(data, result, size_used_get());
116 glUnmapBuffer(GL_ARRAY_BUFFER);
117}
118
120{
121 BLI_assert(vbo_id_ == 0);
122 BLI_assert(glIsBuffer(uint(handle)));
123 is_wrapper_ = true;
124 vbo_id_ = uint(handle);
125 /* We assume the data is already on the device, so no need to allocate or send it. */
127}
128
129bool GLVertBuf::is_active() const
130{
131 if (!vbo_id_) {
132 return false;
133 }
134 int active_vbo_id = 0;
135 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &active_vbo_id);
136 return vbo_id_ == active_vbo_id;
137}
138
139void GLVertBuf::update_sub(uint start, uint len, const void *data)
140{
141 glBufferSubData(GL_ARRAY_BUFFER, start, len, data);
142}
143
144} // 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 char uchar
unsigned int uint
#define GPU_TEXTURE_FREE_SAFE(texture)
blender::gpu::Texture * GPU_texture_create_from_vertbuf(const char *name, blender::gpu::VertBuf *vertex_buf)
void GPU_texture_bind(blender::gpu::Texture *texture, int unit)
@ GPU_VERTBUF_DATA_DIRTY
@ GPU_VERTBUF_DATA_UPLOADED
@ GPU_USAGE_STATIC
@ GPU_USAGE_DEVICE_ONLY
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
unsigned long long int uint64_t
static void buffer_free(GLuint buf_id)
static GLContext * get()
void bind_as_texture(uint binding) override
void read(void *data) const override
void bind_as_ssbo(uint binding) override
void wrap_handle(uint64_t handle) override
void update_sub(uint start, uint len, const void *data) override
MutableSpan< T > data()
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
static GLenum to_gl(const GPUAttachmentType type)
uint len