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 'intern/gawain/src/gwn_element.c')
-rw-r--r--intern/gawain/src/gwn_element.c265
1 files changed, 134 insertions, 131 deletions
diff --git a/intern/gawain/src/gwn_element.c b/intern/gawain/src/gwn_element.c
index 257338fe089..a8c99f20860 100644
--- a/intern/gawain/src/gwn_element.c
+++ b/intern/gawain/src/gwn_element.c
@@ -1,13 +1,33 @@
-
-// Gawain element list (AKA index buffer)
-//
-// This code is part of the Gawain library, with modifications
-// specific to integration with Blender.
-//
-// Copyright 2016 Mike Erwin
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
-// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gwn_element.c
+ * \ingroup gpu
+ *
+ * Gawain element list (AKA index buffer)
+ */
#include "gwn_element.h"
#include "gwn_buffer_id.h"
@@ -16,44 +36,45 @@
#define KEEP_SINGLE_COPY 1
static GLenum convert_index_type_to_gl(Gwn_IndexBufType type)
- {
+{
static const GLenum table[] = {
- [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, // GL has this, Vulkan does not
+ [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */
[GWN_INDEX_U16] = GL_UNSIGNED_SHORT,
[GWN_INDEX_U32] = GL_UNSIGNED_INT
- };
+ };
return table[type];
- }
+}
-unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf* elem)
- {
+uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem)
+{
#if GWN_TRACK_INDEX_RANGE
- static const unsigned table[] = {
- [GWN_INDEX_U8] = sizeof(GLubyte), // GL has this, Vulkan does not
+ static const uint table[] = {
+ [GWN_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */
[GWN_INDEX_U16] = sizeof(GLushort),
[GWN_INDEX_U32] = sizeof(GLuint)
- };
+ };
return elem->index_len * table[elem->index_type];
#else
return elem->index_len * sizeof(GLuint);
#endif
- }
+}
-void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, unsigned index_len, unsigned vertex_len, bool use_prim_restart)
- {
+void GWN_indexbuf_init_ex(
+ Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type,
+ uint index_len, uint vertex_len, bool use_prim_restart)
+{
builder->use_prim_restart = use_prim_restart;
builder->max_allowed_index = vertex_len - 1;
builder->max_index_len = index_len;
builder->index_len = 0; // start empty
builder->prim_type = prim_type;
- builder->data = calloc(builder->max_index_len, sizeof(unsigned));
- }
+ builder->data = calloc(builder->max_index_len, sizeof(uint));
+}
-void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, unsigned prim_len, unsigned vertex_len)
- {
- unsigned verts_per_prim = 0;
- switch (prim_type)
- {
+void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uint prim_len, uint vertex_len)
+{
+ uint verts_per_prim = 0;
+ switch (prim_type) {
case GWN_PRIM_POINTS:
verts_per_prim = 1;
break;
@@ -71,234 +92,216 @@ void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uns
assert(false);
#endif
return;
- }
+ }
GWN_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false);
- }
+}
-void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, unsigned v)
- {
+void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v)
+{
#if TRUST_NO_ONE
assert(builder->data != NULL);
assert(builder->index_len < builder->max_index_len);
assert(v <= builder->max_allowed_index);
#endif
-
builder->data[builder->index_len++] = v;
- }
+}
void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder* builder)
- {
+{
#if TRUST_NO_ONE
assert(builder->data != NULL);
assert(builder->index_len < builder->max_index_len);
assert(builder->use_prim_restart);
#endif
-
builder->data[builder->index_len++] = GWN_PRIM_RESTART;
- }
+}
-void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, unsigned v)
- {
+void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, uint v)
+{
#if TRUST_NO_ONE
assert(builder->prim_type == GWN_PRIM_POINTS);
#endif
-
GWN_indexbuf_add_generic_vert(builder, v);
- }
+}
-void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2)
- {
+void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2)
+{
#if TRUST_NO_ONE
assert(builder->prim_type == GWN_PRIM_LINES);
assert(v1 != v2);
#endif
-
GWN_indexbuf_add_generic_vert(builder, v1);
GWN_indexbuf_add_generic_vert(builder, v2);
- }
+}
-void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2, unsigned v3)
- {
+void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3)
+{
#if TRUST_NO_ONE
assert(builder->prim_type == GWN_PRIM_TRIS);
assert(v1 != v2 && v2 != v3 && v3 != v1);
#endif
-
GWN_indexbuf_add_generic_vert(builder, v1);
GWN_indexbuf_add_generic_vert(builder, v2);
GWN_indexbuf_add_generic_vert(builder, v3);
- }
+}
-void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2, unsigned v3, unsigned v4)
- {
+void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4)
+{
#if TRUST_NO_ONE
assert(builder->prim_type == GWN_PRIM_LINES_ADJ);
assert(v2 != v3); /* only the line need diff indices */
#endif
-
GWN_indexbuf_add_generic_vert(builder, v1);
GWN_indexbuf_add_generic_vert(builder, v2);
GWN_indexbuf_add_generic_vert(builder, v3);
GWN_indexbuf_add_generic_vert(builder, v4);
- }
+}
#if GWN_TRACK_INDEX_RANGE
-// Everything remains 32 bit while building to keep things simple.
-// Find min/max after, then convert to smallest index type possible.
+/* Everything remains 32 bit while building to keep things simple.
+ * Find min/max after, then convert to smallest index type possible. */
-static unsigned index_range(const unsigned values[], unsigned value_len, unsigned* min_out, unsigned* max_out)
- {
- if (value_len == 0)
- {
+static uint index_range(const uint values[], uint value_len, uint* min_out, uint* max_out)
+{
+ if (value_len == 0) {
*min_out = 0;
*max_out = 0;
return 0;
- }
- unsigned min_value = values[0];
- unsigned max_value = values[0];
- for (unsigned i = 1; i < value_len; ++i)
- {
- const unsigned value = values[i];
+ }
+ uint min_value = values[0];
+ uint max_value = values[0];
+ for (uint i = 1; i < value_len; ++i) {
+ const uint value = values[i];
if (value == GWN_PRIM_RESTART)
continue;
else if (value < min_value)
min_value = value;
else if (value > max_value)
max_value = value;
- }
+ }
*min_out = min_value;
*max_out = max_value;
return max_value - min_value;
- }
+}
static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem)
- {
- const unsigned *values = builder->data;
- const unsigned index_len = elem->index_len;
+{
+ const uint *values = builder->data;
+ const uint index_len = elem->index_len;
- // data will never be *larger* than builder->data...
- // converting in place to avoid extra allocation
+ /* data will never be *larger* than builder->data...
+ * converting in place to avoid extra allocation */
GLubyte *data = (GLubyte *)builder->data;
- if (elem->max_index > 0xFF)
- {
- const unsigned base = elem->min_index;
-
+ if (elem->max_index > 0xFF) {
+ const uint base = elem->min_index;
elem->base_index = base;
elem->min_index = 0;
elem->max_index -= base;
-
- for (unsigned i = 0; i < index_len; ++i)
+ for (uint i = 0; i < index_len; ++i) {
data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base);
}
- else
- {
+ }
+ else {
elem->base_index = 0;
-
- for (unsigned i = 0; i < index_len; ++i)
+ for (uint i = 0; i < index_len; ++i) {
data[i] = (GLubyte)(values[i]);
}
}
+}
static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem)
- {
- const unsigned *values = builder->data;
- const unsigned index_len = elem->index_len;
+{
+ const uint *values = builder->data;
+ const uint index_len = elem->index_len;
- // data will never be *larger* than builder->data...
- // converting in place to avoid extra allocation
+ /* data will never be *larger* than builder->data...
+ * converting in place to avoid extra allocation */
GLushort *data = (GLushort *)builder->data;
- if (elem->max_index > 0xFFFF)
- {
- const unsigned base = elem->min_index;
-
+ if (elem->max_index > 0xFFFF) {
+ const uint base = elem->min_index;
elem->base_index = base;
elem->min_index = 0;
elem->max_index -= base;
-
- for (unsigned i = 0; i < index_len; ++i)
+ for (uint i = 0; i < index_len; ++i) {
data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base);
}
- else
- {
+ }
+ else {
elem->base_index = 0;
-
- for (unsigned i = 0; i < index_len; ++i)
+ for (uint i = 0; i < index_len; ++i) {
data[i] = (GLushort)(values[i]);
}
}
+}
-#endif // GWN_TRACK_INDEX_RANGE
+#endif /* GWN_TRACK_INDEX_RANGE */
Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder* builder)
- {
+{
Gwn_IndexBuf* elem = calloc(1, sizeof(Gwn_IndexBuf));
GWN_indexbuf_build_in_place(builder, elem);
return elem;
- }
+}
void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* elem)
- {
+{
#if TRUST_NO_ONE
assert(builder->data != NULL);
#endif
-
elem->index_len = builder->index_len;
elem->use_prim_restart = builder->use_prim_restart;
#if GWN_TRACK_INDEX_RANGE
- unsigned range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index);
+ uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index);
- // count the primitive restart index.
- if (elem->use_prim_restart)
+ /* count the primitive restart index. */
+ if (elem->use_prim_restart) {
range += 1;
+ }
- if (range <= 0xFF)
- {
+ if (range <= 0xFF) {
elem->index_type = GWN_INDEX_U8;
squeeze_indices_byte(builder, elem);
- }
- else if (range <= 0xFFFF)
- {
+ }
+ else if (range <= 0xFFFF) {
elem->index_type = GWN_INDEX_U16;
squeeze_indices_short(builder, elem);
- }
- else
- {
+ }
+ else {
elem->index_type = GWN_INDEX_U32;
elem->base_index = 0;
- }
-
+ }
elem->gl_index_type = convert_index_type_to_gl(elem->index_type);
#endif
- if (elem->vbo_id == 0)
+ if (elem->vbo_id == 0) {
elem->vbo_id = GWN_buf_id_alloc();
-
- // send data to GPU
- // GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound,
- // so we use the GL_ARRAY_BUFFER here to create a buffer without
- // interfering in the VAO state.
+ }
+ /* send data to GPU */
+ /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound,
+ * so we use the GL_ARRAY_BUFFER here to create a buffer without
+ * interfering in the VAO state. */
glBindBuffer(GL_ARRAY_BUFFER, elem->vbo_id);
glBufferData(GL_ARRAY_BUFFER, GWN_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW);
- // discard builder (one-time use)
+ /* discard builder (one-time use) */
free(builder->data);
builder->data = NULL;
- // other fields are safe to leave
- }
+ /* other fields are safe to leave */
+}
void GWN_indexbuf_use(Gwn_IndexBuf* elem)
- {
+{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
- }
+}
void GWN_indexbuf_discard(Gwn_IndexBuf* elem)
- {
- if (elem->vbo_id)
+{
+ if (elem->vbo_id) {
GWN_buf_id_free(elem->vbo_id);
-
- free(elem);
}
+ free(elem);
+}