Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_buffers.c')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c167
1 files changed, 100 insertions, 67 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 072ff5235bf..370841327aa 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -53,8 +53,6 @@
#include "BKE_mesh.h"
#include "BKE_pbvh.h"
-#include "DNA_userdef_types.h"
-
#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_basic_shader.h"
@@ -107,10 +105,12 @@ static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
/* multires global buffer, can be used for many grids having the same grid size */
-static GPUBuffer *mres_glob_buffer = NULL;
-static int mres_prev_gridsize = -1;
-static GLenum mres_prev_index_type = 0;
-static unsigned mres_prev_totquad = 0;
+typedef struct GridCommonGPUBuffer {
+ GPUBuffer *mres_buffer;
+ int mres_prev_gridsize;
+ GLenum mres_prev_index_type;
+ unsigned mres_prev_totquad;
+} GridCommonGPUBuffer;
void GPU_buffer_material_finalize(GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat)
{
@@ -407,33 +407,6 @@ void GPU_buffer_free(GPUBuffer *buffer)
BLI_mutex_unlock(&buffer_mutex);
}
-void GPU_buffer_multires_free(bool force)
-{
- if (!mres_glob_buffer) {
- /* Early output, no need to lock in this case, */
- return;
- }
-
- if (force && BLI_thread_is_main()) {
- if (mres_glob_buffer) {
- if (mres_glob_buffer->id)
- glDeleteBuffers(1, &mres_glob_buffer->id);
- MEM_freeN(mres_glob_buffer);
- }
- }
- else {
- BLI_mutex_lock(&buffer_mutex);
- gpu_buffer_free_intern(mres_glob_buffer);
- BLI_mutex_unlock(&buffer_mutex);
- }
-
- mres_glob_buffer = NULL;
- mres_prev_gridsize = -1;
- mres_prev_index_type = 0;
- mres_prev_totquad = 0;
-}
-
-
void GPU_drawobject_free(DerivedMesh *dm)
{
GPUDrawObject *gdo;
@@ -822,8 +795,14 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda
for (i = 0; i < numdata; i++) {
glEnableVertexAttribArray(data[i].index);
+ int info = 0;
+ if (data[i].type == GL_UNSIGNED_BYTE) {
+ info |= GPU_ATTR_INFO_SRGB;
+ }
+ glUniform1i(data[i].info_index, info);
+
glVertexAttribPointer(data[i].index, data[i].size, data[i].type,
- GL_FALSE, elementsize, BUFFER_OFFSET(offset));
+ GL_TRUE, elementsize, BUFFER_OFFSET(offset));
offset += data[i].size * GPU_typesize(data[i].type);
attribData[i].index = data[i].index;
@@ -937,7 +916,7 @@ void GPU_buffer_unlock(GPUBuffer *UNUSED(buffer), GPUBindingType binding)
{
int bindtypegl = gpu_binding_type_gl[binding];
/* note: this operation can fail, could return
- * an error code from this function? */
+ * an error code from this function? */
glUnmapBuffer(bindtypegl);
glBindBuffer(bindtypegl, 0);
}
@@ -1003,6 +982,7 @@ struct GPU_PBVH_Buffers {
const int *grid_indices;
int totgrid;
bool has_hidden;
+ bool is_index_buf_global; /* Means index_buf uses global bvh's grid_common_gpu_buffer, **DO NOT** free it! */
bool use_bmesh;
@@ -1053,7 +1033,7 @@ static void gpu_color_from_mask_quad_copy(const CCGKey *key,
void GPU_update_mesh_pbvh_buffers(
GPU_PBVH_Buffers *buffers, const MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
- const int (*face_vert_indices)[4], bool show_diffuse_color)
+ const int (*face_vert_indices)[3], bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j;
@@ -1181,7 +1161,7 @@ void GPU_update_mesh_pbvh_buffers(
}
GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
- const int (*face_vert_indices)[4],
+ const int (*face_vert_indices)[3],
const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
const MVert *mvert,
const int *face_indices,
@@ -1220,8 +1200,10 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
/* An element index buffer is used for smooth shading, but flat
* shading requires separate vertex normals so an index buffer is
* can't be used there. */
- if (buffers->smooth)
+ if (buffers->smooth) {
buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3);
+ buffers->is_index_buf_global = false;
+ }
if (buffers->index_buf) {
/* Fill the triangle buffer */
@@ -1242,8 +1224,11 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
}
else {
- GPU_buffer_free(buffers->index_buf);
+ if (!buffers->is_index_buf_global) {
+ GPU_buffer_free(buffers->index_buf);
+ }
buffers->index_buf = NULL;
+ buffers->is_index_buf_global = false;
}
}
@@ -1410,22 +1395,33 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
} (void)0
/* end FILL_QUAD_BUFFER */
-static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad)
+static GPUBuffer *gpu_get_grid_buffer(
+ int gridsize, GLenum *index_type, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer)
{
/* used in the FILL_QUAD_BUFFER macro */
BLI_bitmap * const *grid_hidden = NULL;
const int *grid_indices = NULL;
int totgrid = 1;
+ GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
+
+ if (gridbuff == NULL) {
+ *grid_common_gpu_buffer = gridbuff = MEM_mallocN(sizeof(GridCommonGPUBuffer), __func__);
+ gridbuff->mres_buffer = NULL;
+ gridbuff->mres_prev_gridsize = -1;
+ gridbuff->mres_prev_index_type = 0;
+ gridbuff->mres_prev_totquad = 0;
+ }
+
/* VBO is already built */
- if (mres_glob_buffer && mres_prev_gridsize == gridsize) {
- *index_type = mres_prev_index_type;
- *totquad = mres_prev_totquad;
- return mres_glob_buffer;
+ if (gridbuff->mres_buffer && gridbuff->mres_prev_gridsize == gridsize) {
+ *index_type = gridbuff->mres_prev_index_type;
+ *totquad = gridbuff->mres_prev_totquad;
+ return gridbuff->mres_buffer;
}
/* we can't reuse old, delete the existing buffer */
- else if (mres_glob_buffer) {
- GPU_buffer_free(mres_glob_buffer);
+ else if (gridbuff->mres_buffer) {
+ GPU_buffer_free(gridbuff->mres_buffer);
}
/* Build new VBO */
@@ -1433,17 +1429,17 @@ static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned
if (gridsize * gridsize < USHRT_MAX) {
*index_type = GL_UNSIGNED_SHORT;
- FILL_QUAD_BUFFER(unsigned short, *totquad, mres_glob_buffer);
+ FILL_QUAD_BUFFER(unsigned short, *totquad, gridbuff->mres_buffer);
}
else {
*index_type = GL_UNSIGNED_INT;
- FILL_QUAD_BUFFER(unsigned int, *totquad, mres_glob_buffer);
+ FILL_QUAD_BUFFER(unsigned int, *totquad, gridbuff->mres_buffer);
}
- mres_prev_gridsize = gridsize;
- mres_prev_index_type = *index_type;
- mres_prev_totquad = *totquad;
- return mres_glob_buffer;
+ gridbuff->mres_prev_gridsize = gridsize;
+ gridbuff->mres_prev_index_type = *index_type;
+ gridbuff->mres_prev_totquad = *totquad;
+ return gridbuff->mres_buffer;
}
#define FILL_FAST_BUFFER(type_) \
@@ -1470,8 +1466,9 @@ static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned
} \
} (void)0
-GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
- BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key)
+GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(
+ int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key,
+ GridCommonGPUBuffer **grid_common_gpu_buffer)
{
GPU_PBVH_Buffers *buffers;
int totquad;
@@ -1500,8 +1497,10 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
}
if (totquad == fully_visible_totquad) {
- buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
+ buffers->index_buf = gpu_get_grid_buffer(
+ gridsize, &buffers->index_type, &buffers->tot_quad, grid_common_gpu_buffer);
buffers->has_hidden = false;
+ buffers->is_index_buf_global = true;
}
else {
buffers->tot_quad = totquad;
@@ -1516,6 +1515,7 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
}
buffers->has_hidden = true;
+ buffers->is_index_buf_global = false;
}
/* Build coord/normal VBO */
@@ -1740,8 +1740,9 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
const int use_short = (maxvert < USHRT_MAX);
/* Initialize triangle index buffer */
- if (buffers->index_buf)
+ if (buffers->index_buf && !buffers->is_index_buf_global)
GPU_buffer_free(buffers->index_buf);
+ buffers->is_index_buf_global = false;
buffers->index_buf = GPU_buffer_alloc((use_short ?
sizeof(unsigned short) :
sizeof(unsigned int)) * 3 * tottri);
@@ -1786,12 +1787,19 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
}
else {
/* Memory map failed */
- GPU_buffer_free(buffers->index_buf);
+ if (!buffers->is_index_buf_global) {
+ GPU_buffer_free(buffers->index_buf);
+ }
buffers->index_buf = NULL;
+ buffers->is_index_buf_global = false;
}
}
else if (buffers->index_buf) {
- GPU_buffer_free(buffers->index_buf);
+ if (!buffers->is_index_buf_global) {
+ GPU_buffer_free(buffers->index_buf);
+ }
+ buffers->index_buf = NULL;
+ buffers->is_index_buf_global = false;
}
}
@@ -1835,15 +1843,15 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
if (buffers->vert_buf) {
char *base = NULL;
char *index_base = NULL;
- int bound_options = 0;
+ /* weak inspection of bound options, should not be necessary ideally */
+ const int bound_options_old = GPU_basic_shader_bound_options();
+ int bound_options_new = 0;
glEnableClientState(GL_VERTEX_ARRAY);
if (!wireframe) {
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
- /* weak inspection of bound options, should not be necessary ideally */
- bound_options = GPU_basic_shader_bound_options();
- GPU_basic_shader_bind(bound_options | GPU_SHADER_USE_COLOR);
+ bound_options_new |= GPU_SHADER_USE_COLOR;
}
GPU_buffer_bind(buffers->vert_buf, GPU_BINDING_ARRAY);
@@ -1855,10 +1863,18 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
GPU_buffer_bind(buffers->index_buf, GPU_BINDING_INDEX);
}
- if (wireframe)
+ if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- else
- glShadeModel((buffers->smooth || buffers->face_indices_len) ? GL_SMOOTH : GL_FLAT);
+ }
+ else {
+ if ((buffers->smooth == false) && (buffers->face_indices_len == 0)) {
+ bound_options_new |= GPU_SHADER_FLAT_NORMAL;
+ }
+ }
+
+ if (bound_options_new & ~bound_options_old) {
+ GPU_basic_shader_bind(bound_options_old | bound_options_new);
+ }
if (buffers->tot_quad) {
const char *offset = base;
@@ -1932,7 +1948,10 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
if (!wireframe) {
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
- GPU_basic_shader_bind(bound_options);
+ }
+
+ if (bound_options_new & ~bound_options_old) {
+ GPU_basic_shader_bind(bound_options_old);
}
}
}
@@ -1985,7 +2004,7 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
if (buffers) {
if (buffers->vert_buf)
GPU_buffer_free(buffers->vert_buf);
- if (buffers->index_buf && (buffers->tot_tri || buffers->has_hidden))
+ if (buffers->index_buf && !buffers->is_index_buf_global)
GPU_buffer_free(buffers->index_buf);
if (buffers->index_buf_fast)
GPU_buffer_free(buffers->index_buf_fast);
@@ -1998,6 +2017,20 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
}
}
+void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer)
+{
+ GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
+
+ if (gridbuff) {
+ if (gridbuff->mres_buffer) {
+ BLI_mutex_lock(&buffer_mutex);
+ gpu_buffer_free_intern(gridbuff->mres_buffer);
+ BLI_mutex_unlock(&buffer_mutex);
+ }
+ MEM_freeN(gridbuff);
+ *grid_common_gpu_buffer = NULL;
+ }
+}
/* debug function, draws the pbvh BB */
void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)