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/gawain')
-rw-r--r--intern/gawain/gawain/gwn_attr_binding.h19
-rw-r--r--intern/gawain/gawain/gwn_attr_binding_private.h20
-rw-r--r--intern/gawain/gawain/gwn_batch.h169
-rw-r--r--intern/gawain/gawain/gwn_batch_private.h30
-rw-r--r--intern/gawain/gawain/gwn_buffer_id.h30
-rw-r--r--intern/gawain/gawain/gwn_common.h36
-rw-r--r--intern/gawain/gawain/gwn_context.h34
-rw-r--r--intern/gawain/gawain/gwn_element.h79
-rw-r--r--intern/gawain/gawain/gwn_imm_util.h22
-rw-r--r--intern/gawain/gawain/gwn_immediate.h120
-rw-r--r--intern/gawain/gawain/gwn_primitive.h42
-rw-r--r--intern/gawain/gawain/gwn_primitive_private.h14
-rw-r--r--intern/gawain/gawain/gwn_shader_interface.h81
-rw-r--r--intern/gawain/gawain/gwn_vertex_array_id.h34
-rw-r--r--intern/gawain/gawain/gwn_vertex_buffer.h125
-rw-r--r--intern/gawain/gawain/gwn_vertex_format.h78
-rw-r--r--intern/gawain/gawain/gwn_vertex_format_private.h16
17 files changed, 949 insertions, 0 deletions
diff --git a/intern/gawain/gawain/gwn_attr_binding.h b/intern/gawain/gawain/gwn_attr_binding.h
new file mode 100644
index 00000000000..a209e1c4f0f
--- /dev/null
+++ b/intern/gawain/gawain/gwn_attr_binding.h
@@ -0,0 +1,19 @@
+
+// Gawain vertex attribute binding
+//
+// 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/.
+
+#pragma once
+
+#include "gwn_common.h"
+
+typedef struct Gwn_AttrBinding {
+ uint64_t loc_bits; // store 4 bits for each of the 16 attribs
+ uint16_t enabled_bits; // 1 bit for each attrib
+} Gwn_AttrBinding;
diff --git a/intern/gawain/gawain/gwn_attr_binding_private.h b/intern/gawain/gawain/gwn_attr_binding_private.h
new file mode 100644
index 00000000000..300945d464b
--- /dev/null
+++ b/intern/gawain/gawain/gwn_attr_binding_private.h
@@ -0,0 +1,20 @@
+
+// Gawain vertex attribute binding
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 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/.
+
+#pragma once
+
+#include "gwn_vertex_format.h"
+#include "gwn_shader_interface.h"
+
+void AttribBinding_clear(Gwn_AttrBinding*);
+
+void get_attrib_locations(const Gwn_VertFormat*, Gwn_AttrBinding*, const Gwn_ShaderInterface*);
+unsigned read_attrib_location(const Gwn_AttrBinding*, unsigned a_idx);
diff --git a/intern/gawain/gawain/gwn_batch.h b/intern/gawain/gawain/gwn_batch.h
new file mode 100644
index 00000000000..07ef96061b7
--- /dev/null
+++ b/intern/gawain/gawain/gwn_batch.h
@@ -0,0 +1,169 @@
+
+// Gawain geometry batch
+//
+// 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/.
+
+#pragma once
+
+#include "gwn_vertex_buffer.h"
+#include "gwn_element.h"
+#include "gwn_shader_interface.h"
+
+typedef enum {
+ GWN_BATCH_READY_TO_FORMAT,
+ GWN_BATCH_READY_TO_BUILD,
+ GWN_BATCH_BUILDING,
+ GWN_BATCH_READY_TO_DRAW
+} Gwn_BatchPhase;
+
+#define GWN_BATCH_VBO_MAX_LEN 3
+#define GWN_BATCH_VAO_STATIC_LEN 3
+#define GWN_BATCH_VAO_DYN_ALLOC_COUNT 16
+
+typedef struct Gwn_Batch {
+ // geometry
+ Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; // verts[0] is required, others can be NULL
+ Gwn_VertBuf* inst; // instance attribs
+ Gwn_IndexBuf* elem; // NULL if element list not needed
+ GLenum gl_prim_type;
+
+ // cached values (avoid dereferencing later)
+ GLuint vao_id;
+ GLuint program;
+ const struct Gwn_ShaderInterface* interface;
+
+ // book-keeping
+ unsigned owns_flag;
+ struct Gwn_Context *context; // used to free all vaos. this implies all vaos were created under the same context.
+ Gwn_BatchPhase phase;
+ bool program_in_use;
+
+ // Vao management: remembers all geometry state (vertex attrib bindings & element buffer)
+ // for each shader interface. Start with a static number of vaos and fallback to dynamic count
+ // if necessary. Once a batch goes dynamic it does not go back.
+ bool is_dynamic_vao_count;
+ union {
+ // Static handle count
+ struct {
+ const struct Gwn_ShaderInterface* interfaces[GWN_BATCH_VAO_STATIC_LEN];
+ GLuint vao_ids[GWN_BATCH_VAO_STATIC_LEN];
+ } static_vaos;
+ // Dynamic handle count
+ struct {
+ unsigned count;
+ const struct Gwn_ShaderInterface** interfaces;
+ GLuint* vao_ids;
+ } dynamic_vaos;
+ };
+
+ // XXX This is the only solution if we want to have some data structure using
+ // batches as key to identify nodes. We must destroy these nodes with this callback.
+ void (*free_callback)(struct Gwn_Batch*, void*);
+ void* callback_data;
+} Gwn_Batch;
+
+enum {
+ GWN_BATCH_OWNS_VBO = (1 << 0),
+ /* each vbo index gets bit-shifted */
+ GWN_BATCH_OWNS_INSTANCES = (1 << 30),
+ GWN_BATCH_OWNS_INDEX = (1 << 31),
+};
+
+Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag);
+void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag);
+Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src);
+
+#define GWN_batch_create(prim, verts, elem) \
+ GWN_batch_create_ex(prim, verts, elem, 0)
+#define GWN_batch_init(batch, prim, verts, elem) \
+ GWN_batch_init_ex(batch, prim, verts, elem, 0)
+
+void GWN_batch_discard(Gwn_Batch*); // verts & elem are not discarded
+
+void GWN_batch_callback_free_set(Gwn_Batch*, void (*callback)(Gwn_Batch*, void*), void*);
+
+void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); // Instancing
+
+int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo);
+
+#define GWN_batch_vertbuf_add(batch, verts) \
+ GWN_batch_vertbuf_add_ex(batch, verts, false)
+
+void GWN_batch_program_set_no_use(Gwn_Batch*, GLuint program, const Gwn_ShaderInterface*);
+void GWN_batch_program_set(Gwn_Batch*, GLuint program, const Gwn_ShaderInterface*);
+// Entire batch draws with one shader program, but can be redrawn later with another program.
+// Vertex shader's inputs must be compatible with the batch's vertex format.
+
+void GWN_batch_program_use_begin(Gwn_Batch*); // call before Batch_Uniform (temp hack?)
+void GWN_batch_program_use_end(Gwn_Batch*);
+
+void GWN_batch_uniform_1ui(Gwn_Batch*, const char* name, int value);
+void GWN_batch_uniform_1i(Gwn_Batch*, const char* name, int value);
+void GWN_batch_uniform_1b(Gwn_Batch*, const char* name, bool value);
+void GWN_batch_uniform_1f(Gwn_Batch*, const char* name, float value);
+void GWN_batch_uniform_2f(Gwn_Batch*, const char* name, float x, float y);
+void GWN_batch_uniform_3f(Gwn_Batch*, const char* name, float x, float y, float z);
+void GWN_batch_uniform_4f(Gwn_Batch*, const char* name, float x, float y, float z, float w);
+void GWN_batch_uniform_2fv(Gwn_Batch*, const char* name, const float data[2]);
+void GWN_batch_uniform_3fv(Gwn_Batch*, const char* name, const float data[3]);
+void GWN_batch_uniform_4fv(Gwn_Batch*, const char* name, const float data[4]);
+void GWN_batch_uniform_2fv_array(Gwn_Batch*, const char* name, int len, const float *data);
+void GWN_batch_uniform_4fv_array(Gwn_Batch*, const char* name, int len, const float *data);
+void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4]);
+
+void GWN_batch_draw(Gwn_Batch*);
+
+// This does not bind/unbind shader and does not call gpuBindMatrices()
+void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance);
+
+// Does not even need batch
+void GWN_draw_primitive(Gwn_PrimType, int v_count);
+
+#if 0 // future plans
+
+// Can multiple batches share a Gwn_VertBuf? Use ref count?
+
+
+// We often need a batch with its own data, to be created and discarded together.
+// WithOwn variants reduce number of system allocations.
+
+typedef struct BatchWithOwnVertexBuffer {
+ Gwn_Batch batch;
+ Gwn_VertBuf verts; // link batch.verts to this
+} BatchWithOwnVertexBuffer;
+
+typedef struct BatchWithOwnElementList {
+ Gwn_Batch batch;
+ Gwn_IndexBuf elem; // link batch.elem to this
+} BatchWithOwnElementList;
+
+typedef struct BatchWithOwnVertexBufferAndElementList {
+ Gwn_Batch batch;
+ Gwn_IndexBuf elem; // link batch.elem to this
+ Gwn_VertBuf verts; // link batch.verts to this
+} BatchWithOwnVertexBufferAndElementList;
+
+Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, unsigned v_ct, Gwn_IndexBuf*);
+Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, unsigned prim_ct);
+Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, unsigned v_ct, unsigned prim_ct);
+// verts: shared, own
+// elem: none, shared, own
+Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStuff);
+
+#endif // future plans
+
+
+/* Macros */
+
+#define GWN_BATCH_DISCARD_SAFE(batch) do { \
+ if (batch != NULL) { \
+ GWN_batch_discard(batch); \
+ batch = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/gwn_batch_private.h b/intern/gawain/gawain/gwn_batch_private.h
new file mode 100644
index 00000000000..6503429c237
--- /dev/null
+++ b/intern/gawain/gawain/gwn_batch_private.h
@@ -0,0 +1,30 @@
+
+// Gawain context
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2018 Mike Erwin, Clément Foucault
+//
+// 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/.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_batch.h"
+#include "gwn_context.h"
+#include "gwn_shader_interface.h"
+
+void gwn_batch_remove_interface_ref(Gwn_Batch*, const Gwn_ShaderInterface*);
+void gwn_batch_vao_cache_clear(Gwn_Batch*);
+
+void gwn_context_add_batch(Gwn_Context*, Gwn_Batch*);
+void gwn_context_remove_batch(Gwn_Context*, Gwn_Batch*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/gwn_buffer_id.h b/intern/gawain/gawain/gwn_buffer_id.h
new file mode 100644
index 00000000000..6f51ca6905d
--- /dev/null
+++ b/intern/gawain/gawain/gwn_buffer_id.h
@@ -0,0 +1,30 @@
+
+// Gawain buffer IDs
+//
+// 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/.
+
+#pragma once
+
+// Manage GL buffer IDs in a thread-safe way
+// Use these instead of glGenBuffers & its friends
+// - alloc must be called from main thread
+// - free can be called from any thread
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_common.h"
+
+GLuint GWN_buf_id_alloc(void);
+void GWN_buf_id_free(GLuint buffer_id);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/gwn_common.h b/intern/gawain/gawain/gwn_common.h
new file mode 100644
index 00000000000..dc0a52ca096
--- /dev/null
+++ b/intern/gawain/gawain/gwn_common.h
@@ -0,0 +1,36 @@
+
+// Gawain common #defines and #includes
+//
+// 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/.
+
+#pragma once
+
+#define PROGRAM_NO_OPTI 0
+
+#if defined(NDEBUG)
+ #define TRUST_NO_ONE 0
+#else
+ // strict error checking, enabled for debug builds during early development
+ #define TRUST_NO_ONE 1
+#endif
+
+#include <GL/glew.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#if TRUST_NO_ONE
+ #include <assert.h>
+#endif
+
+/* GWN_INLINE */
+#if defined(_MSC_VER)
+# define GWN_INLINE static __forceinline
+#else
+# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__))
+#endif \ No newline at end of file
diff --git a/intern/gawain/gawain/gwn_context.h b/intern/gawain/gawain/gwn_context.h
new file mode 100644
index 00000000000..3addce762b3
--- /dev/null
+++ b/intern/gawain/gawain/gwn_context.h
@@ -0,0 +1,34 @@
+
+// Gawain context
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2018 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/.
+
+#pragma once
+
+// This interface allow Gawain to manage VAOs for mutiple context and threads.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_common.h"
+#include "gwn_batch.h"
+#include "gwn_shader_interface.h"
+
+typedef struct Gwn_Context Gwn_Context;
+
+Gwn_Context* GWN_context_create(void);
+void GWN_context_discard(Gwn_Context*);
+
+void GWN_context_active_set(Gwn_Context*);
+Gwn_Context* GWN_context_active_get(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/gwn_element.h b/intern/gawain/gawain/gwn_element.h
new file mode 100644
index 00000000000..a80da71e0e8
--- /dev/null
+++ b/intern/gawain/gawain/gwn_element.h
@@ -0,0 +1,79 @@
+
+// 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/.
+
+#pragma once
+
+#include "gwn_primitive.h"
+
+#define GWN_TRACK_INDEX_RANGE 1
+
+#define GWN_PRIM_RESTART 0xFFFFFFFF
+
+typedef enum {
+ GWN_INDEX_U8, // GL has this, Vulkan does not
+ GWN_INDEX_U16,
+ GWN_INDEX_U32
+} Gwn_IndexBufType;
+
+typedef struct Gwn_IndexBuf {
+ unsigned index_ct;
+#if GWN_TRACK_INDEX_RANGE
+ Gwn_IndexBufType index_type;
+ GLenum gl_index_type;
+ unsigned min_index;
+ unsigned max_index;
+ unsigned base_index;
+#endif
+ GLuint vbo_id; // 0 indicates not yet sent to VRAM
+ bool use_prim_restart;
+} Gwn_IndexBuf;
+
+void GWN_indexbuf_use(Gwn_IndexBuf*);
+unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf*);
+
+typedef struct Gwn_IndexBufBuilder {
+ unsigned max_allowed_index;
+ unsigned max_index_ct;
+ unsigned index_ct;
+ Gwn_PrimType prim_type;
+ unsigned* data;
+ bool use_prim_restart;
+} Gwn_IndexBufBuilder;
+
+
+// supports all primitive types.
+void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, unsigned index_ct, unsigned vertex_ct, bool use_prim_restart);
+
+// supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS.
+void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, unsigned prim_ct, unsigned vertex_ct);
+
+void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, unsigned v);
+void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder*);
+
+void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, unsigned v);
+void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2);
+void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2, unsigned v3);
+void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2, unsigned v3, unsigned v4);
+
+Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder*);
+void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder*, Gwn_IndexBuf*);
+
+void GWN_indexbuf_discard(Gwn_IndexBuf*);
+
+
+/* Macros */
+
+#define GWN_INDEXBUF_DISCARD_SAFE(elem) do { \
+ if (elem != NULL) { \
+ GWN_indexbuf_discard(elem); \
+ elem = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/gwn_imm_util.h b/intern/gawain/gawain/gwn_imm_util.h
new file mode 100644
index 00000000000..5d17ec50669
--- /dev/null
+++ b/intern/gawain/gawain/gwn_imm_util.h
@@ -0,0 +1,22 @@
+
+// Gawain immediate mode drawing utilities
+//
+// 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/.
+
+#pragma once
+
+
+// Draw 2D rectangles (replaces glRect functions)
+// caller is reponsible for vertex format & shader
+void immRectf(unsigned pos, float x1, float y1, float x2, float y2);
+void immRecti(unsigned pos, int x1, int y1, int x2, int y2);
+
+// Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS.
+void immRectf_fast_with_color(unsigned pos, unsigned col, float x1, float y1, float x2, float y2, const float color[4]);
+void immRecti_fast_with_color(unsigned pos, unsigned col, int x1, int y1, int x2, int y2, const float color[4]);
diff --git a/intern/gawain/gawain/gwn_immediate.h b/intern/gawain/gawain/gwn_immediate.h
new file mode 100644
index 00000000000..7866f83e774
--- /dev/null
+++ b/intern/gawain/gawain/gwn_immediate.h
@@ -0,0 +1,120 @@
+
+// Gawain immediate mode work-alike
+//
+// 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/.
+
+#pragma once
+
+#include "gwn_vertex_format.h"
+#include "gwn_primitive.h"
+#include "gwn_shader_interface.h"
+
+#define IMM_BATCH_COMBO 1
+
+
+Gwn_VertFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
+
+void immBindProgram(GLuint program, const Gwn_ShaderInterface*); // every immBegin must have a program bound first
+void immUnbindProgram(void); // call after your last immEnd, or before binding another program
+
+void immBegin(Gwn_PrimType, unsigned vertex_ct); // must supply exactly vertex_ct vertices
+void immBeginAtMost(Gwn_PrimType, unsigned max_vertex_ct); // can supply fewer vertices
+void immEnd(void); // finishes and draws
+
+#if IMM_BATCH_COMBO
+#include "gwn_batch.h"
+// immBegin a batch, then use standard immFunctions as usual.
+// immEnd will finalize the batch instead of drawing.
+// Then you can draw it as many times as you like! Partially replaces the need for display lists.
+Gwn_Batch* immBeginBatch(Gwn_PrimType, unsigned vertex_ct);
+Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, unsigned vertex_ct);
+#endif
+
+
+// provide attribute values that can change per vertex
+// first vertex after immBegin must have all its attributes specified
+// skipped attributes will continue using the previous value for that attrib_id
+void immAttrib1f(unsigned attrib_id, float x);
+void immAttrib2f(unsigned attrib_id, float x, float y);
+void immAttrib3f(unsigned attrib_id, float x, float y, float z);
+void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w);
+
+void immAttrib2i(unsigned attrib_id, int x, int y);
+
+void immAttrib1u(unsigned attrib_id, unsigned x);
+
+void immAttrib2s(unsigned attrib_id, short x, short y);
+
+void immAttrib2fv(unsigned attrib_id, const float data[2]);
+void immAttrib3fv(unsigned attrib_id, const float data[3]);
+void immAttrib4fv(unsigned attrib_id, const float data[4]);
+
+void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b);
+void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+
+void immAttrib3ubv(unsigned attrib_id, const unsigned char data[4]);
+void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4]);
+
+// explicitly skip an attribute
+// this advanced option kills automatic value copying for this attrib_id
+void immSkipAttrib(unsigned attrib_id);
+
+
+// provide one last attribute value & end the current vertex
+// this is most often used for 2D or 3D position (similar to glVertex)
+void immVertex2f(unsigned attrib_id, float x, float y);
+void immVertex3f(unsigned attrib_id, float x, float y, float z);
+void immVertex4f(unsigned attrib_id, float x, float y, float z, float w);
+
+void immVertex2i(unsigned attrib_id, int x, int y);
+
+void immVertex2s(unsigned attrib_id, short x, short y);
+
+void immVertex2fv(unsigned attrib_id, const float data[2]);
+void immVertex3fv(unsigned attrib_id, const float data[3]);
+
+void immVertex2iv(unsigned attrib_id, const int data[2]);
+
+
+// provide uniform values that don't change for the entire draw call
+void immUniform1i(const char* name, int x);
+void immUniform4iv(const char* name, const int data[4]);
+void immUniform1f(const char* name, float x);
+void immUniform2f(const char* name, float x, float y);
+void immUniform2fv(const char* name, const float data[2]);
+void immUniform3f(const char* name, float x, float y, float z);
+void immUniform3fv(const char* name, const float data[3]);
+void immUniformArray3fv(const char* name, const float *data, int count);
+void immUniform4f(const char* name, float x, float y, float z, float w);
+void immUniform4fv(const char* name, const float data[4]);
+void immUniformArray4fv(const char* bare_name, const float *data, int count);
+void immUniformMatrix4fv(const char* name, const float data[4][4]);
+
+
+// convenience functions for setting "uniform vec4 color"
+// the rgb functions have implicit alpha = 1.0
+void immUniformColor4f(float r, float g, float b, float a);
+void immUniformColor4fv(const float rgba[4]);
+void immUniformColor3f(float r, float g, float b);
+void immUniformColor3fv(const float rgb[3]);
+void immUniformColor3fvAlpha(const float rgb[3], float a);
+
+void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b);
+void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void immUniformColor3ubv(const unsigned char rgb[3]);
+void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a);
+void immUniformColor4ubv(const unsigned char rgba[4]);
+
+
+// these are called by the system -- not part of drawing API
+
+void immInit(void);
+void immActivate(void);
+void immDeactivate(void);
+void immDestroy(void);
diff --git a/intern/gawain/gawain/gwn_primitive.h b/intern/gawain/gawain/gwn_primitive.h
new file mode 100644
index 00000000000..3359b3582bb
--- /dev/null
+++ b/intern/gawain/gawain/gwn_primitive.h
@@ -0,0 +1,42 @@
+
+// Gawain geometric primitives
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 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/.
+
+#pragma once
+
+#include "gwn_common.h"
+
+typedef enum {
+ GWN_PRIM_POINTS,
+ GWN_PRIM_LINES,
+ GWN_PRIM_TRIS,
+ GWN_PRIM_LINE_STRIP,
+ GWN_PRIM_LINE_LOOP, // GL has this, Vulkan does not
+ GWN_PRIM_TRI_STRIP,
+ GWN_PRIM_TRI_FAN,
+
+ GWN_PRIM_LINES_ADJ,
+ GWN_PRIM_TRIS_ADJ,
+ GWN_PRIM_LINE_STRIP_ADJ,
+
+ GWN_PRIM_NONE
+} Gwn_PrimType;
+
+// what types of primitives does each shader expect?
+typedef enum {
+ GWN_PRIM_CLASS_NONE = 0,
+ GWN_PRIM_CLASS_POINT = (1 << 0),
+ GWN_PRIM_CLASS_LINE = (1 << 1),
+ GWN_PRIM_CLASS_SURFACE = (1 << 2),
+ GWN_PRIM_CLASS_ANY = GWN_PRIM_CLASS_POINT | GWN_PRIM_CLASS_LINE | GWN_PRIM_CLASS_SURFACE
+} Gwn_PrimClass;
+
+Gwn_PrimClass GWN_primtype_class(Gwn_PrimType);
+bool GWN_primtype_belongs_to_class(Gwn_PrimType, Gwn_PrimClass);
diff --git a/intern/gawain/gawain/gwn_primitive_private.h b/intern/gawain/gawain/gwn_primitive_private.h
new file mode 100644
index 00000000000..d959cd89852
--- /dev/null
+++ b/intern/gawain/gawain/gwn_primitive_private.h
@@ -0,0 +1,14 @@
+
+// Gawain geometric primitives (private interface for use inside Gawain)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 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/.
+
+#pragma once
+
+GLenum convert_prim_type_to_gl(Gwn_PrimType);
diff --git a/intern/gawain/gawain/gwn_shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h
new file mode 100644
index 00000000000..150b3b4fcc0
--- /dev/null
+++ b/intern/gawain/gawain/gwn_shader_interface.h
@@ -0,0 +1,81 @@
+
+// Gawain shader interface (C --> GLSL)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2017 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/.
+
+#pragma once
+
+#include "gwn_common.h"
+
+typedef enum {
+ GWN_UNIFORM_NONE = 0, // uninitialized/unknown
+
+ GWN_UNIFORM_MODEL, // mat4 ModelMatrix
+ GWN_UNIFORM_VIEW, // mat4 ViewMatrix
+ GWN_UNIFORM_MODELVIEW, // mat4 ModelViewMatrix
+ GWN_UNIFORM_PROJECTION, // mat4 ProjectionMatrix
+ GWN_UNIFORM_VIEWPROJECTION, // mat4 ViewProjectionMatrix
+ GWN_UNIFORM_MVP, // mat4 ModelViewProjectionMatrix
+
+ GWN_UNIFORM_MODEL_INV, // mat4 ModelMatrixInverse
+ GWN_UNIFORM_VIEW_INV, // mat4 ViewMatrixInverse
+ GWN_UNIFORM_MODELVIEW_INV, // mat4 ModelViewMatrixInverse
+ GWN_UNIFORM_PROJECTION_INV, // mat4 ProjectionMatrixInverse
+ GWN_UNIFORM_VIEWPROJECTION_INV, // mat4 ViewProjectionMatrixInverse
+
+ GWN_UNIFORM_NORMAL, // mat3 NormalMatrix
+ GWN_UNIFORM_WORLDNORMAL, // mat3 WorldNormalMatrix
+ GWN_UNIFORM_CAMERATEXCO, // vec4 CameraTexCoFactors
+ GWN_UNIFORM_ORCO, // vec3 OrcoTexCoFactors[]
+
+ GWN_UNIFORM_COLOR, // vec4 color
+ GWN_UNIFORM_EYE, // vec3 eye
+ GWN_UNIFORM_CALLID, // int callId
+
+ GWN_UNIFORM_CUSTOM, // custom uniform, not one of the above built-ins
+
+ GWN_NUM_UNIFORMS, // Special value, denotes number of builtin uniforms.
+} Gwn_UniformBuiltin;
+
+typedef struct Gwn_ShaderInput {
+ struct Gwn_ShaderInput* next;
+ uint32_t name_offset;
+ unsigned name_hash;
+ Gwn_UniformBuiltin builtin_type; // only for uniform inputs
+ GLenum gl_type; // only for attrib inputs
+ GLint size; // only for attrib inputs
+ GLint location;
+} Gwn_ShaderInput;
+
+#define GWN_NUM_SHADERINTERFACE_BUCKETS 257
+#define GWN_SHADERINTERFACE_REF_ALLOC_COUNT 16
+
+typedef struct Gwn_ShaderInterface {
+ GLint program;
+ uint32_t name_buffer_offset;
+ Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
+ Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
+ Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
+ Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS];
+ char* name_buffer;
+ struct Gwn_Batch** batches; // references to batches using this interface
+ unsigned batches_ct;
+} Gwn_ShaderInterface;
+
+Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program_id);
+void GWN_shaderinterface_discard(Gwn_ShaderInterface*);
+
+const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface*, const char* name);
+const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface*, Gwn_UniformBuiltin);
+const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name);
+const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name);
+
+// keep track of batches using this interface
+void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*);
+void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*);
diff --git a/intern/gawain/gawain/gwn_vertex_array_id.h b/intern/gawain/gawain/gwn_vertex_array_id.h
new file mode 100644
index 00000000000..1c093d428ce
--- /dev/null
+++ b/intern/gawain/gawain/gwn_vertex_array_id.h
@@ -0,0 +1,34 @@
+
+// Gawain buffer IDs
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2018 Mike Erwin, Clément Foucault
+//
+// 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/.
+
+#pragma once
+
+// Manage GL vertex array IDs in a thread-safe way
+// Use these instead of glGenBuffers & its friends
+// - alloc must be called from a thread that is bound
+// to the context that will be used for drawing with
+// this vao.
+// - free can be called from any thread
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gwn_common.h"
+#include "gwn_context.h"
+
+GLuint GWN_vao_default(void);
+GLuint GWN_vao_alloc(void);
+void GWN_vao_free(GLuint vao_id, Gwn_Context*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/gawain/gawain/gwn_vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h
new file mode 100644
index 00000000000..e9a37519b36
--- /dev/null
+++ b/intern/gawain/gawain/gwn_vertex_buffer.h
@@ -0,0 +1,125 @@
+
+// Gawain vertex 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/.
+
+#pragma once
+
+#include "gwn_vertex_format.h"
+
+#define VRAM_USAGE 1
+// How to create a Gwn_VertBuf:
+// 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts)
+// 2) GWN_vertformat_attr_add(verts->format, ...)
+// 3) GWN_vertbuf_data_alloc(verts, vertex_ct) <-- finalizes/packs vertex format
+// 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer)
+
+// Is Gwn_VertBuf always used as part of a Gwn_Batch?
+
+typedef enum {
+ // can be extended to support more types
+ GWN_USAGE_STREAM,
+ GWN_USAGE_STATIC, // do not keep data in memory
+ GWN_USAGE_DYNAMIC
+} Gwn_UsageType;
+
+typedef struct Gwn_VertBuf {
+ Gwn_VertFormat format;
+ unsigned vertex_ct; // number of verts we want to draw
+ unsigned vertex_alloc; // number of verts data
+ bool dirty;
+ GLubyte* data; // NULL indicates data in VRAM (unmapped)
+ GLuint vbo_id; // 0 indicates not yet allocated
+ Gwn_UsageType usage; // usage hint for GL optimisation
+} Gwn_VertBuf;
+
+Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType);
+Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat*, Gwn_UsageType);
+
+#define GWN_vertbuf_create_with_format(format) \
+ GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_STATIC)
+
+void GWN_vertbuf_discard(Gwn_VertBuf*);
+
+void GWN_vertbuf_init(Gwn_VertBuf*, Gwn_UsageType);
+void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf*, const Gwn_VertFormat*, Gwn_UsageType);
+
+#define GWN_vertbuf_init_with_format(verts, format) \
+ GWN_vertbuf_init_with_format_ex(verts, format, GWN_USAGE_STATIC)
+
+unsigned GWN_vertbuf_size_get(const Gwn_VertBuf*);
+void GWN_vertbuf_data_alloc(Gwn_VertBuf*, unsigned v_ct);
+void GWN_vertbuf_data_resize(Gwn_VertBuf*, unsigned v_ct);
+void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, unsigned v_ct);
+
+// The most important set_attrib variant is the untyped one. Get it right first.
+// It takes a void* so the app developer is responsible for matching their app data types
+// to the vertex attribute's type and component count. They're in control of both, so this
+// should not be a problem.
+
+void GWN_vertbuf_attr_set(Gwn_VertBuf*, unsigned a_idx, unsigned v_idx, const void* data);
+void GWN_vertbuf_attr_fill(Gwn_VertBuf*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data
+void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, unsigned a_idx, unsigned stride, const void* data);
+
+// For low level access only
+typedef struct Gwn_VertBufRaw {
+ unsigned size;
+ unsigned stride;
+ GLubyte* data;
+ GLubyte* data_init;
+#if TRUST_NO_ONE
+ // Only for overflow check
+ GLubyte* _data_end;
+#endif
+} Gwn_VertBufRaw;
+
+GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a)
+ {
+ GLubyte* data = a->data;
+ a->data += a->stride;
+#if TRUST_NO_ONE
+ assert(data < a->_data_end);
+#endif
+ return (void *)data;
+ }
+
+GWN_INLINE unsigned GWN_vertbuf_raw_used(Gwn_VertBufRaw *a)
+ {
+ return ((a->data - a->data_init) / a->stride);
+ }
+
+void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, unsigned a_idx, Gwn_VertBufRaw *access);
+
+// TODO: decide whether to keep the functions below
+// doesn't immediate mode satisfy these needs?
+
+// void setAttrib1f(unsigned a_idx, unsigned v_idx, float x);
+// void setAttrib2f(unsigned a_idx, unsigned v_idx, float x, float y);
+// void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z);
+// void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w);
+//
+// void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b);
+// void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+
+void GWN_vertbuf_use(Gwn_VertBuf*);
+
+
+// Metrics
+
+unsigned GWN_vertbuf_get_memory_usage(void);
+
+
+// Macros
+
+#define GWN_VERTBUF_DISCARD_SAFE(verts) do { \
+ if (verts != NULL) { \
+ GWN_vertbuf_discard(verts); \
+ verts = NULL; \
+ } \
+} while (0)
diff --git a/intern/gawain/gawain/gwn_vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h
new file mode 100644
index 00000000000..503c2d03c42
--- /dev/null
+++ b/intern/gawain/gawain/gwn_vertex_format.h
@@ -0,0 +1,78 @@
+
+// Gawain vertex format
+//
+// 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/.
+
+#pragma once
+
+#include "gwn_common.h"
+
+#define GWN_VERT_ATTR_MAX_LEN 16
+#define GWN_VERT_ATTR_MAX_NAMES 3
+#define GWN_VERT_ATTR_NAME_AVERAGE_LEN 11
+#define GWN_VERT_ATTR_NAMES_BUF_LEN ((GWN_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GWN_VERT_ATTR_MAX_LEN)
+
+typedef enum {
+ GWN_COMP_I8,
+ GWN_COMP_U8,
+ GWN_COMP_I16,
+ GWN_COMP_U16,
+ GWN_COMP_I32,
+ GWN_COMP_U32,
+
+ GWN_COMP_F32,
+
+ GWN_COMP_I10
+} Gwn_VertCompType;
+
+typedef enum {
+ GWN_FETCH_FLOAT,
+ GWN_FETCH_INT,
+ GWN_FETCH_INT_TO_FLOAT_UNIT, // 127 (ubyte) -> 0.5 (and so on for other int types)
+ GWN_FETCH_INT_TO_FLOAT // 127 (any int type) -> 127.0
+} Gwn_VertFetchMode;
+
+typedef struct Gwn_VertAttr {
+ Gwn_VertFetchMode fetch_mode;
+ Gwn_VertCompType comp_type;
+ unsigned gl_comp_type;
+ unsigned comp_ct; // 1 to 4 or 8 or 12 or 16
+ unsigned sz; // size in bytes, 1 to 64
+ unsigned offset; // from beginning of vertex, in bytes
+ unsigned name_ct; // up to GWN_VERT_ATTR_MAX_NAMES
+ const char* name[GWN_VERT_ATTR_MAX_NAMES];
+} Gwn_VertAttr;
+
+typedef struct Gwn_VertFormat {
+ unsigned attrib_ct; // 0 to 16 (GWN_VERT_ATTR_MAX_LEN)
+ unsigned name_ct; // total count of active vertex attrib
+ unsigned stride; // stride in bytes, 1 to 256
+ unsigned name_offset;
+ bool packed;
+ char names[GWN_VERT_ATTR_NAMES_BUF_LEN];
+ Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; // TODO: variable-size attribs array
+} Gwn_VertFormat;
+
+void GWN_vertformat_clear(Gwn_VertFormat*);
+void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src);
+
+unsigned GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, unsigned comp_ct, Gwn_VertFetchMode);
+void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias);
+
+// format conversion
+
+typedef struct Gwn_PackedNormal {
+ int x : 10;
+ int y : 10;
+ int z : 10;
+ int w : 2; // 0 by default, can manually set to { -2, -1, 0, 1 }
+} Gwn_PackedNormal;
+
+Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]);
+Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]);
diff --git a/intern/gawain/gawain/gwn_vertex_format_private.h b/intern/gawain/gawain/gwn_vertex_format_private.h
new file mode 100644
index 00000000000..c1a0f734eda
--- /dev/null
+++ b/intern/gawain/gawain/gwn_vertex_format_private.h
@@ -0,0 +1,16 @@
+
+// Gawain vertex format (private interface for use inside Gawain)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016-2017 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/.
+
+#pragma once
+
+void VertexFormat_pack(Gwn_VertFormat*);
+unsigned padding(unsigned offset, unsigned alignment);
+unsigned vertex_buffer_size(const Gwn_VertFormat*, unsigned vertex_ct);