diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_vertex_buffer.h | 42 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch.cc | 8 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 7 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_immediate.cc | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_private.hh | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.cc | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_buffer.cc | 64 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_buffer_private.hh | 46 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_drawlist.cc | 1 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.cc | 1 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_vertex_array.cc | 5 |
12 files changed, 137 insertions, 42 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 3bb188c3fa8..799e146183a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -148,6 +148,7 @@ set(SRC intern/gpu_state_private.hh intern/gpu_texture_private.hh intern/gpu_uniform_buffer_private.hh + intern/gpu_vertex_buffer_private.hh intern/gpu_vertex_format_private.h opengl/gl_backend.hh diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index bd1019bb1f5..070c93df412 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -25,8 +25,23 @@ #pragma once +#include "BLI_utildefines.h" + #include "GPU_vertex_format.h" +typedef enum { + /** Initial state. */ + GPU_VERTBUF_INVALID = 0, + /** Was init with a vertex format. */ + GPU_VERTBUF_INIT = (1 << 0), + /** Data has been touched and need to be reuploaded. */ + GPU_VERTBUF_DATA_DIRTY = (1 << 1), + /** The buffer has been created inside GPU memory. */ + GPU_VERTBUF_DATA_UPLOADED = (1 << 2), +} GPUVertBufStatus; + +ENUM_OPERATORS(GPUVertBufStatus) + #ifdef __cplusplus extern "C" { #endif @@ -40,8 +55,6 @@ extern "C" { * 4) GPU_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ -/* Is GPUVertBuf always used as part of a GPUBatch? */ - typedef enum { /* can be extended to support more types */ GPU_USAGE_STREAM, @@ -49,22 +62,7 @@ typedef enum { GPU_USAGE_DYNAMIC, } GPUUsageType; -typedef struct GPUVertBuf { - GPUVertFormat format; - /** Number of verts we want to draw. */ - uint vertex_len; - /** Number of verts data. */ - uint vertex_alloc; - /** 0 indicates not yet allocated. */ - uint32_t vbo_id; - /** Usage hint for GL optimisation. */ - GPUUsageType usage; - /** This counter will only avoid freeing the GPUVertBuf, not the data. */ - char handle_refcount; - /** Data has been touched and need to be reuploaded to GPU. */ - bool dirty; - uchar *data; /* NULL indicates data in VRAM (unmapped) */ -} GPUVertBuf; +typedef struct GPUVertBuf GPUVertBuf; GPUVertBuf *GPU_vertbuf_create(GPUUsageType); GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageType); @@ -135,6 +133,14 @@ GPU_INLINE uint GPU_vertbuf_raw_used(GPUVertBufRaw *a) void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access); +void *GPU_vertbuf_steal_data(GPUVertBuf *verts); + +void *GPU_vertbuf_get_data(const GPUVertBuf *verts); +const GPUVertFormat *GPU_vertbuf_get_format(const GPUVertBuf *verts); +uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts); +uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts); +GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts); + void GPU_vertbuf_use(GPUVertBuf *); /* Metrics */ diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 75419e1a242..864843a6d01 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -36,11 +36,12 @@ #include "GPU_shader.h" #include "gpu_backend.hh" -#include "gpu_batch_private.hh" #include "gpu_context_private.hh" #include "gpu_index_buffer_private.hh" #include "gpu_shader_private.hh" -#include "gpu_vertex_format_private.h" +#include "gpu_vertex_buffer_private.hh" + +#include "gpu_batch_private.hh" #include <string.h> @@ -198,7 +199,8 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) if (batch->verts[v] == NULL) { /* for now all VertexBuffers must have same vertex_len */ if (batch->verts[0] != NULL) { - BLI_assert(verts->vertex_len == batch->verts[0]->vertex_len); + /* This is an issue for the HACK inside DRW_vbo_request(). */ + // BLI_assert(verts->vertex_len == batch->verts[0]->vertex_len); } batch->verts[v] = verts; SET_FLAG_FROM_TEST(batch->flag, own_vbo, (eGPUBatchFlag)(GPU_BATCH_OWNS_VBO << v)); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 83d70b32b7b..606af5b1a15 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -153,13 +153,14 @@ static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, uint vert_len) /* Initialize vertex buffer (match 'VertexBufferFormat'). */ buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&g_vbo_id.format, GPU_USAGE_STATIC); } - if (buffers->vert_buf->data == NULL || buffers->vert_buf->vertex_len != vert_len) { + if (GPU_vertbuf_get_data(buffers->vert_buf) == NULL || + GPU_vertbuf_get_vertex_len(buffers->vert_buf) != vert_len) { /* Allocate buffer if not allocated yet or size changed. */ GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); } #endif - return buffers->vert_buf->data != NULL; + return GPU_vertbuf_get_data(buffers->vert_buf) != NULL; } static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim) @@ -1119,7 +1120,7 @@ void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers) } /* Force flushing to the GPU. */ - if (buffers->vert_buf && buffers->vert_buf->data) { + if (buffers->vert_buf && GPU_vertbuf_get_data(buffers->vert_buf)) { GPU_vertbuf_use(buffers->vert_buf); } } diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index c5dd84ddbd0..c1b5e11698d 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -34,6 +34,7 @@ #include "gpu_context_private.hh" #include "gpu_immediate_private.hh" #include "gpu_shader_private.hh" +#include "gpu_vertex_buffer_private.hh" #include "gpu_vertex_format_private.h" using namespace blender::gpu; diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index 9c9aa835b97..fa086892760 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -23,7 +23,7 @@ #include "BLI_span.hh" #include "GPU_shader.h" -#include "GPU_vertex_buffer.h" +#include "gpu_vertex_buffer_private.hh" #include "gpu_shader_interface.hh" namespace blender { diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index bdbf623a391..e2330b7f990 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -29,6 +29,7 @@ #include "gpu_backend.hh" #include "gpu_context_private.hh" #include "gpu_framebuffer_private.hh" +#include "gpu_vertex_buffer_private.hh" #include "gpu_texture_private.hh" diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc index debf9835c90..4f0caa19a5c 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.cc +++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc @@ -25,13 +25,10 @@ #include "MEM_guardedalloc.h" -#include "GPU_vertex_buffer.h" - #include "gpu_context_private.hh" #include "gpu_vertex_format_private.h" -#include <stdlib.h> -#include <string.h> +#include "gpu_vertex_buffer_private.hh" #define KEEP_SINGLE_COPY 1 @@ -66,6 +63,7 @@ GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *format, GPUUs if (!format->packed) { VertexFormat_pack(&verts->format); } + verts->flag |= GPU_VERTBUF_INIT; return verts; /* this function might seem redundant, but there is potential for memory savings here... */ @@ -76,7 +74,7 @@ void GPU_vertbuf_init(GPUVertBuf *verts, GPUUsageType usage) { memset(verts, 0, sizeof(GPUVertBuf)); verts->usage = usage; - verts->dirty = true; + verts->flag = GPU_VERTBUF_DATA_DIRTY; verts->handle_refcount = 1; } @@ -89,6 +87,7 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, if (!format->packed) { VertexFormat_pack(&verts->format); } + verts->flag |= GPU_VERTBUF_INIT; } GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts) @@ -181,7 +180,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) uint new_size = vertex_buffer_size(&verts->format, v_len); vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; verts->vertex_len = verts->vertex_alloc = v_len; verts->data = (uchar *)MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), __func__); } @@ -198,7 +197,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) uint new_size = vertex_buffer_size(&verts->format, v_len); vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; verts->vertex_len = verts->vertex_alloc = v_len; verts->data = (uchar *)MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); } @@ -230,7 +229,7 @@ void GPU_vertbuf_attr_set(GPUVertBuf *verts, uint a_idx, uint v_idx, const void assert(v_idx < verts->vertex_alloc); assert(verts->data != NULL); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; memcpy((GLubyte *)verts->data + a->offset + v_idx * format->stride, data, a->sz); } @@ -256,7 +255,7 @@ void GPU_vertbuf_vert_set(GPUVertBuf *verts, uint v_idx, const void *data) assert(v_idx < verts->vertex_alloc); assert(verts->data != NULL); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; memcpy((GLubyte *)verts->data + v_idx * format->stride, data, format->stride); } @@ -269,7 +268,7 @@ void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts, uint a_idx, uint stride, co assert(a_idx < format->attr_len); assert(verts->data != NULL); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; const uint vertex_len = verts->vertex_len; if (format->attr_len == 1 && stride == format->stride) { @@ -296,7 +295,7 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts, uint a_idx, GPUVertBufRaw assert(verts->data != NULL); #endif - verts->dirty = true; + verts->flag |= GPU_VERTBUF_DATA_DIRTY; access->size = a->sz; access->stride = format->stride; @@ -307,6 +306,44 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts, uint a_idx, GPUVertBufRaw #endif } +/* 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. */ + return verts->data; +} + +/* 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. */ +void *GPU_vertbuf_steal_data(GPUVertBuf *verts) +{ + /* 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) +{ + return &verts->format; +} + +uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts) +{ + return verts->vertex_alloc; +} + +uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts) +{ + return verts->vertex_len; +} + +GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts) +{ + return verts->flag; +} + static void VertBuffer_upload_data(GPUVertBuf *verts) { uint buffer_sz = GPU_vertbuf_size_get(verts); @@ -320,7 +357,8 @@ static void VertBuffer_upload_data(GPUVertBuf *verts) MEM_freeN(verts->data); verts->data = NULL; } - verts->dirty = false; + verts->flag &= ~GPU_VERTBUF_DATA_DIRTY; + verts->flag |= GPU_VERTBUF_DATA_UPLOADED; } void GPU_vertbuf_use(GPUVertBuf *verts) @@ -330,7 +368,7 @@ void GPU_vertbuf_use(GPUVertBuf *verts) verts->vbo_id = GPU_buf_alloc(); } glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); - if (verts->dirty) { + if (verts->flag & GPU_VERTBUF_DATA_DIRTY) { VertBuffer_upload_data(verts); } } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh new file mode 100644 index 00000000000..24e95a729c7 --- /dev/null +++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh @@ -0,0 +1,46 @@ +/* + * 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. + */ + +/** \file + * \ingroup gpu + * + * GPU vertex buffer + */ + +#pragma once + +#include "GPU_vertex_buffer.h" + +struct GPUVertBuf { + GPUVertFormat format; + /** Number of verts we want to draw. */ + uint vertex_len; + /** Number of verts data. */ + uint vertex_alloc; + /** 0 indicates not yet allocated. */ + uint32_t vbo_id; + /** Usage hint for GL optimisation. */ + GPUUsageType usage; + /** Status flag. */ + GPUVertBufStatus flag; + /** This counter will only avoid freeing the GPUVertBuf, not the data. */ + char handle_refcount; + /** NULL indicates data in VRAM (unmapped) */ + uchar *data; +};
\ No newline at end of file diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index 9670e580819..de729487226 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -33,6 +33,7 @@ #include "gpu_context_private.hh" #include "gpu_drawlist_private.hh" +#include "gpu_vertex_buffer_private.hh" #include "gl_backend.hh" #include "gl_drawlist.hh" diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index a79490b9283..498d0442fca 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -32,6 +32,7 @@ #include "gl_backend.hh" #include "gl_debug.hh" #include "gl_state.hh" +#include "gpu_vertex_buffer_private.hh" /* TODO shoud be gl_vertex_buffer.hh */ #include "gl_texture.hh" diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index 358b92a9979..bfd3bd6e6cc 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -21,11 +21,8 @@ * \ingroup gpu */ -#include "GPU_glew.h" - -#include "GPU_vertex_buffer.h" - #include "gpu_shader_interface.hh" +#include "gpu_vertex_buffer_private.hh" #include "gpu_vertex_format_private.h" #include "gl_batch.hh" |