2018-07-17 14:46:44 +02:00
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2016 by Mike Erwin.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup gpu
|
2018-07-17 14:46:44 +02:00
|
|
|
*
|
2018-07-18 00:12:21 +02:00
|
|
|
* GPU vertex buffer
|
2018-07-17 14:46:44 +02:00
|
|
|
*/
|
2016-09-13 02:41:43 -04:00
|
|
|
|
2018-07-31 16:54:58 +02:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
#include "gpu_backend.hh"
|
2018-07-17 21:11:23 +02:00
|
|
|
#include "gpu_vertex_format_private.h"
|
2018-07-19 15:48:13 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
#include "gl_vertex_buffer.hh" /* TODO remove */
|
|
|
|
#include "gpu_context_private.hh" /* TODO remove */
|
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
#include "gpu_vertex_buffer_private.hh"
|
2016-09-13 02:41:43 -04:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
#include <cstring>
|
2016-09-15 16:51:10 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
#define VRAM_USAGE 1
|
2017-05-04 21:22:41 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name VertBuf
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
namespace blender::gpu {
|
|
|
|
|
|
|
|
size_t VertBuf::memory_usage = 0;
|
|
|
|
|
|
|
|
} // namespace blender::gpu
|
2018-03-17 16:58:43 +01:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name C-API
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
using namespace blender;
|
|
|
|
using namespace blender::gpu;
|
|
|
|
|
|
|
|
static uint GPU_vertbuf_size_get(const VertBuf *verts);
|
|
|
|
|
|
|
|
/* -------- Creation & deletion -------- */
|
|
|
|
|
|
|
|
GPUVertBuf *GPU_vertbuf_calloc(void)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
return wrap(GPUBackend::get()->vertbuf_alloc());
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-14 16:28:16 +02:00
|
|
|
|
2018-07-18 23:09:31 +10:00
|
|
|
GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *format, GPUUsageType usage)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
GPUVertBuf *verts = GPU_vertbuf_calloc();
|
|
|
|
GPU_vertbuf_init_with_format_ex(verts, format, usage);
|
2019-04-17 06:17:24 +02:00
|
|
|
return verts;
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-15 21:45:10 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts_,
|
|
|
|
const GPUVertFormat *format,
|
|
|
|
GPUUsageType usage)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
verts->usage = usage;
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag = GPU_VERTBUF_DATA_DIRTY;
|
2020-08-10 01:35:59 +02:00
|
|
|
verts->handle_refcount = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
GPU_vertformat_copy(&verts->format, format);
|
|
|
|
if (!format->packed) {
|
|
|
|
VertexFormat_pack(&verts->format);
|
|
|
|
}
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_INIT;
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-15 21:45:10 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts_)
|
2020-06-19 17:02:55 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
|
|
|
VertBuf *verts_dst = unwrap(GPU_vertbuf_calloc());
|
2020-06-19 17:02:55 +02:00
|
|
|
/* Full copy. */
|
|
|
|
*verts_dst = *verts;
|
2020-09-06 23:45:51 +02:00
|
|
|
verts_dst->handle_refcount = 1;
|
2020-06-19 17:02:55 +02:00
|
|
|
GPU_vertformat_copy(&verts_dst->format, &verts->format);
|
|
|
|
|
|
|
|
if (verts->vbo_id) {
|
|
|
|
uint buffer_sz = GPU_vertbuf_size_get(verts);
|
|
|
|
|
|
|
|
verts_dst->vbo_id = GPU_buf_alloc();
|
|
|
|
|
|
|
|
glBindBuffer(GL_COPY_READ_BUFFER, verts->vbo_id);
|
|
|
|
glBindBuffer(GL_COPY_WRITE_BUFFER, verts_dst->vbo_id);
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
glBufferData(GL_COPY_WRITE_BUFFER, buffer_sz, NULL, to_gl(verts->usage));
|
2020-06-19 17:02:55 +02:00
|
|
|
|
|
|
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, buffer_sz);
|
2020-09-06 23:45:51 +02:00
|
|
|
|
|
|
|
VertBuf::memory_usage += GPU_vertbuf_size_get(verts);
|
2020-06-19 17:02:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (verts->data) {
|
2020-07-28 02:15:22 +02:00
|
|
|
verts_dst->data = (uchar *)MEM_dupallocN(verts->data);
|
2020-06-19 17:02:55 +02:00
|
|
|
}
|
2020-09-06 23:45:51 +02:00
|
|
|
return wrap(verts_dst);
|
2020-06-19 17:02:55 +02:00
|
|
|
}
|
|
|
|
|
2019-05-13 17:27:35 +02:00
|
|
|
/** Same as discard but does not free. */
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_clear(GPUVertBuf *verts_)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
if (verts->vbo_id) {
|
|
|
|
GPU_buf_free(verts->vbo_id);
|
2019-05-13 17:27:35 +02:00
|
|
|
verts->vbo_id = 0;
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf::memory_usage -= GPU_vertbuf_size_get(verts);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
if (verts->data) {
|
2019-05-13 17:27:35 +02:00
|
|
|
MEM_SAFE_FREE(verts->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-09-06 23:45:51 +02:00
|
|
|
verts->flag = GPU_VERTBUF_INVALID;
|
2019-05-13 17:27:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void GPU_vertbuf_discard(GPUVertBuf *verts)
|
|
|
|
{
|
|
|
|
GPU_vertbuf_clear(verts);
|
2020-08-10 01:35:59 +02:00
|
|
|
GPU_vertbuf_handle_ref_remove(verts);
|
|
|
|
}
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_handle_ref_add(GPUVertBuf *verts_)
|
2020-08-10 01:35:59 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2020-08-10 01:35:59 +02:00
|
|
|
verts->handle_refcount++;
|
|
|
|
}
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts_)
|
2020-08-10 01:35:59 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2020-08-10 01:35:59 +02:00
|
|
|
BLI_assert(verts->handle_refcount > 0);
|
|
|
|
verts->handle_refcount--;
|
|
|
|
if (verts->handle_refcount == 0) {
|
|
|
|
/* Should already have been cleared. */
|
|
|
|
BLI_assert(verts->vbo_id == 0 && verts->data == NULL);
|
|
|
|
MEM_freeN(verts);
|
|
|
|
}
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-10-23 23:16:54 -04:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
uint GPU_vertbuf_size_get(const VertBuf *verts)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return vertex_buffer_size(&verts->format, verts->vertex_len);
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-15 21:45:10 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
/* -------- Data update -------- */
|
|
|
|
|
2018-07-17 14:46:44 +02:00
|
|
|
/* create a new allocation, discarding any existing data */
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_data_alloc(GPUVertBuf *verts_, uint v_len)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
GPUVertFormat *format = &verts->format;
|
|
|
|
if (!format->packed) {
|
|
|
|
VertexFormat_pack(format);
|
|
|
|
}
|
2018-03-17 16:58:43 +01:00
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
/* catch any unnecessary use */
|
|
|
|
assert(verts->vertex_alloc != v_len || verts->data == NULL);
|
2018-03-17 16:58:43 +01:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
/* discard previous data if any */
|
|
|
|
if (verts->data) {
|
|
|
|
MEM_freeN(verts->data);
|
|
|
|
}
|
2020-09-06 23:45:51 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
uint new_size = vertex_buffer_size(&verts->format, v_len);
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf::memory_usage += new_size - GPU_vertbuf_size_get(verts);
|
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2019-04-17 06:17:24 +02:00
|
|
|
verts->vertex_len = verts->vertex_alloc = v_len;
|
2020-07-28 02:15:22 +02:00
|
|
|
verts->data = (uchar *)MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), __func__);
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-15 21:45:10 +02:00
|
|
|
|
2018-07-17 14:46:44 +02:00
|
|
|
/* resize buffer keeping existing data */
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_data_resize(GPUVertBuf *verts_, uint v_len)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2016-09-15 21:45:10 +02:00
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
assert(verts->data != NULL);
|
|
|
|
assert(verts->vertex_alloc != v_len);
|
2016-09-15 21:45:10 +02:00
|
|
|
#endif
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
uint new_size = vertex_buffer_size(&verts->format, v_len);
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf::memory_usage += new_size - GPU_vertbuf_size_get(verts);
|
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2019-04-17 06:17:24 +02:00
|
|
|
verts->vertex_len = verts->vertex_alloc = v_len;
|
2020-07-28 02:15:22 +02:00
|
|
|
verts->data = (uchar *)MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts));
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2018-03-30 18:10:08 +02:00
|
|
|
|
2018-07-17 14:46:44 +02:00
|
|
|
/* Set vertex count but does not change allocation.
|
|
|
|
* Only this many verts will be uploaded to the GPU and rendered.
|
2018-09-24 18:46:51 +02:00
|
|
|
* This is useful for streaming data. */
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_data_len_set(GPUVertBuf *verts_, uint v_len)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
|
|
|
BLI_assert(verts->data != NULL); /* Only for dynamic data. */
|
|
|
|
BLI_assert(v_len <= verts->vertex_alloc);
|
2018-03-17 16:58:43 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
uint new_size = vertex_buffer_size(&verts->format, v_len);
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf::memory_usage += new_size - GPU_vertbuf_size_get(verts);
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
verts->vertex_len = v_len;
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-14 16:28:16 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_attr_set(GPUVertBuf *verts_, uint a_idx, uint v_idx, const void *data)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
const GPUVertFormat *format = &verts->format;
|
|
|
|
const GPUVertAttr *a = &format->attrs[a_idx];
|
2016-09-14 16:28:16 +02:00
|
|
|
|
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
assert(a_idx < format->attr_len);
|
|
|
|
assert(v_idx < verts->vertex_alloc);
|
|
|
|
assert(verts->data != NULL);
|
2016-09-14 16:28:16 +02:00
|
|
|
#endif
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2020-09-06 23:45:51 +02:00
|
|
|
memcpy((uchar *)verts->data + a->offset + v_idx * format->stride, data, a->sz);
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-14 16:28:16 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_attr_fill(GPUVertBuf *verts_, uint a_idx, const void *data)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
const GPUVertFormat *format = &verts->format;
|
|
|
|
const GPUVertAttr *a = &format->attrs[a_idx];
|
2016-09-14 16:28:16 +02:00
|
|
|
|
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
assert(a_idx < format->attr_len);
|
2016-09-14 16:28:16 +02:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
const uint stride = a->sz; /* tightly packed input data */
|
2020-09-06 23:45:51 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2016-09-14 16:28:16 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
GPU_vertbuf_attr_fill_stride(verts_, a_idx, stride, data);
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-14 16:28:16 +02:00
|
|
|
|
2020-04-03 16:59:34 +11:00
|
|
|
/** Fills a whole vertex (all attributes). Data must match packed layout. */
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_vert_set(GPUVertBuf *verts_, uint v_idx, const void *data)
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-12-02 01:40:58 +01:00
|
|
|
const GPUVertFormat *format = &verts->format;
|
|
|
|
|
|
|
|
#if TRUST_NO_ONE
|
|
|
|
assert(v_idx < verts->vertex_alloc);
|
|
|
|
assert(verts->data != NULL);
|
|
|
|
#endif
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2020-09-06 23:45:51 +02:00
|
|
|
memcpy((uchar *)verts->data + v_idx * format->stride, data, format->stride);
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts_, uint a_idx, uint stride, const void *data)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
const GPUVertFormat *format = &verts->format;
|
|
|
|
const GPUVertAttr *a = &format->attrs[a_idx];
|
2016-09-14 16:28:16 +02:00
|
|
|
|
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
assert(a_idx < format->attr_len);
|
|
|
|
assert(verts->data != NULL);
|
2016-09-14 16:28:16 +02:00
|
|
|
#endif
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2019-04-17 06:17:24 +02:00
|
|
|
const uint vertex_len = verts->vertex_len;
|
|
|
|
|
|
|
|
if (format->attr_len == 1 && stride == format->stride) {
|
|
|
|
/* we can copy it all at once */
|
|
|
|
memcpy(verts->data, data, vertex_len * a->sz);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* we must copy it per vertex */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (uint v = 0; v < vertex_len; v++) {
|
2020-09-06 23:45:51 +02:00
|
|
|
memcpy((uchar *)verts->data + a->offset + v * format->stride,
|
|
|
|
(const uchar *)data + v * stride,
|
2019-04-17 06:17:24 +02:00
|
|
|
a->sz);
|
|
|
|
}
|
|
|
|
}
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2016-09-15 16:51:10 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts_, uint a_idx, GPUVertBufRaw *access)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
const GPUVertFormat *format = &verts->format;
|
|
|
|
const GPUVertAttr *a = &format->attrs[a_idx];
|
2017-06-29 20:09:05 +10:00
|
|
|
|
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
assert(a_idx < format->attr_len);
|
|
|
|
assert(verts->data != NULL);
|
2017-06-29 20:09:05 +10:00
|
|
|
#endif
|
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag |= GPU_VERTBUF_DATA_DIRTY;
|
2020-09-06 23:45:51 +02:00
|
|
|
verts->flag &= ~GPU_VERTBUF_DATA_UPLOADED;
|
2019-04-17 06:17:24 +02:00
|
|
|
access->size = a->sz;
|
|
|
|
access->stride = format->stride;
|
2020-09-06 23:45:51 +02:00
|
|
|
access->data = (uchar *)verts->data + a->offset;
|
2019-04-17 06:17:24 +02:00
|
|
|
access->data_init = access->data;
|
2017-06-29 20:09:05 +10:00
|
|
|
#if TRUST_NO_ONE
|
2019-04-17 06:17:24 +02:00
|
|
|
access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride);
|
2017-06-29 20:09:05 +10:00
|
|
|
#endif
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2017-06-29 20:09:05 +10:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
/* -------- Getters -------- */
|
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
/* NOTE: Be careful when using this. The data needs to match the expected format. */
|
|
|
|
void *GPU_vertbuf_get_data(const GPUVertBuf *verts)
|
|
|
|
{
|
|
|
|
/* TODO Assert that the format has no padding. */
|
2020-09-06 23:45:51 +02:00
|
|
|
return unwrap(verts)->data;
|
2020-09-06 16:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns the data buffer and set it to null internally to avoid freeing.
|
|
|
|
* NOTE: Be careful when using this. The data needs to match the expected format. */
|
2020-09-06 23:45:51 +02:00
|
|
|
void *GPU_vertbuf_steal_data(GPUVertBuf *verts_)
|
2020-09-06 16:40:07 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2020-09-06 16:40:07 +02:00
|
|
|
/* TODO Assert that the format has no padding. */
|
|
|
|
BLI_assert(verts->data);
|
|
|
|
void *data = verts->data;
|
|
|
|
verts->data = nullptr;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
const GPUVertFormat *GPU_vertbuf_get_format(const GPUVertBuf *verts)
|
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
return &unwrap(verts)->format;
|
2020-09-06 16:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts)
|
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
return unwrap(verts)->vertex_alloc;
|
2020-09-06 16:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts)
|
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
return unwrap(verts)->vertex_len;
|
2020-09-06 16:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts)
|
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
return unwrap(verts)->flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint GPU_vertbuf_get_memory_usage(void)
|
|
|
|
{
|
|
|
|
return VertBuf::memory_usage;
|
2020-09-06 16:40:07 +02:00
|
|
|
}
|
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
static void VertBuffer_upload_data(GPUVertBuf *verts_)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
uint buffer_sz = GPU_vertbuf_size_get(verts);
|
|
|
|
|
|
|
|
/* orphan the vbo to avoid sync */
|
2020-09-06 23:45:51 +02:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, to_gl(verts->usage));
|
2019-04-17 06:17:24 +02:00
|
|
|
/* upload data */
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data);
|
|
|
|
|
|
|
|
if (verts->usage == GPU_USAGE_STATIC) {
|
2020-09-06 23:45:51 +02:00
|
|
|
MEM_SAFE_FREE(verts->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-09-06 16:40:07 +02:00
|
|
|
verts->flag &= ~GPU_VERTBUF_DATA_DIRTY;
|
|
|
|
verts->flag |= GPU_VERTBUF_DATA_UPLOADED;
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2018-03-19 16:13:00 +01:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
void GPU_vertbuf_use(GPUVertBuf *verts_)
|
2018-07-17 14:46:44 +02:00
|
|
|
{
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuf *verts = unwrap(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
/* only create the buffer the 1st time */
|
|
|
|
if (verts->vbo_id == 0) {
|
|
|
|
verts->vbo_id = GPU_buf_alloc();
|
|
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
|
2020-09-06 16:40:07 +02:00
|
|
|
if (verts->flag & GPU_VERTBUF_DATA_DIRTY) {
|
2020-09-06 23:45:51 +02:00
|
|
|
VertBuffer_upload_data(verts_);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-07-17 14:46:44 +02:00
|
|
|
}
|
2017-05-04 21:22:41 +02:00
|
|
|
|
2020-09-06 23:45:51 +02:00
|
|
|
/** \} */
|