diff options
Diffstat (limited to 'intern/gawain/gawain')
-rw-r--r-- | intern/gawain/gawain/gwn_attr_binding.h | 19 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_attr_binding_private.h | 20 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_batch.h | 169 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_batch_private.h | 30 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_buffer_id.h | 30 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_common.h | 36 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_context.h | 34 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_element.h | 79 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_imm_util.h | 22 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_immediate.h | 120 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_primitive.h | 42 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_primitive_private.h | 14 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_shader_interface.h | 81 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_vertex_array_id.h | 34 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_vertex_buffer.h | 125 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_vertex_format.h | 78 | ||||
-rw-r--r-- | intern/gawain/gawain/gwn_vertex_format_private.h | 16 |
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); |