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')
-rw-r--r--intern/gawain/CMakeLists.txt48
-rw-r--r--intern/gawain/gawain/gwn_attr_binding.h (renamed from intern/gawain/gawain/attrib_binding.h)4
-rw-r--r--intern/gawain/gawain/gwn_attr_binding_private.h (renamed from intern/gawain/gawain/attrib_binding_private.h)4
-rw-r--r--intern/gawain/gawain/gwn_batch.h (renamed from intern/gawain/gawain/batch.h)42
-rw-r--r--intern/gawain/gawain/gwn_buffer_id.h (renamed from intern/gawain/gawain/buffer_id.h)2
-rw-r--r--intern/gawain/gawain/gwn_common.h (renamed from intern/gawain/gawain/common.h)7
-rw-r--r--intern/gawain/gawain/gwn_element.h (renamed from intern/gawain/gawain/element.h)6
-rw-r--r--intern/gawain/gawain/gwn_imm_util.h (renamed from intern/gawain/gawain/imm_util.h)0
-rw-r--r--intern/gawain/gawain/gwn_immediate.h (renamed from intern/gawain/gawain/immediate.h)8
-rw-r--r--intern/gawain/gawain/gwn_primitive.h (renamed from intern/gawain/gawain/primitive.h)2
-rw-r--r--intern/gawain/gawain/gwn_primitive_private.h (renamed from intern/gawain/gawain/primitive_private.h)0
-rw-r--r--intern/gawain/gawain/gwn_shader_interface.h74
-rw-r--r--intern/gawain/gawain/gwn_vertex_buffer.h (renamed from intern/gawain/gawain/vertex_buffer.h)34
-rw-r--r--intern/gawain/gawain/gwn_vertex_format.h (renamed from intern/gawain/gawain/vertex_format.h)14
-rw-r--r--intern/gawain/gawain/gwn_vertex_format_private.h (renamed from intern/gawain/gawain/vertex_format_private.h)0
-rw-r--r--intern/gawain/gawain/shader_interface.h53
-rw-r--r--intern/gawain/src/gwn_attr_binding.c (renamed from intern/gawain/src/attrib_binding.c)4
-rw-r--r--intern/gawain/src/gwn_batch.c (renamed from intern/gawain/src/batch.c)75
-rw-r--r--intern/gawain/src/gwn_buffer_id.cpp (renamed from intern/gawain/src/buffer_id.cpp)2
-rw-r--r--intern/gawain/src/gwn_element.c (renamed from intern/gawain/src/element.c)4
-rw-r--r--intern/gawain/src/gwn_imm_util.c (renamed from intern/gawain/src/imm_util.c)4
-rw-r--r--intern/gawain/src/gwn_immediate.c (renamed from intern/gawain/src/immediate.c)12
-rw-r--r--intern/gawain/src/gwn_primitive.c (renamed from intern/gawain/src/primitive.c)4
-rw-r--r--intern/gawain/src/gwn_shader_interface.c311
-rw-r--r--intern/gawain/src/gwn_vertex_buffer.c (renamed from intern/gawain/src/vertex_buffer.c)45
-rw-r--r--intern/gawain/src/gwn_vertex_format.c (renamed from intern/gawain/src/vertex_format.c)14
-rw-r--r--intern/gawain/src/shader_interface.c311
27 files changed, 610 insertions, 474 deletions
diff --git a/intern/gawain/CMakeLists.txt b/intern/gawain/CMakeLists.txt
index 48392012176..9924daa8cd1 100644
--- a/intern/gawain/CMakeLists.txt
+++ b/intern/gawain/CMakeLists.txt
@@ -8,31 +8,31 @@ set(INC_SYS
)
set(SRC
- src/attrib_binding.c
- src/batch.c
- src/element.c
- src/buffer_id.cpp
- src/immediate.c
- src/imm_util.c
- src/primitive.c
- src/shader_interface.c
- src/vertex_buffer.c
- src/vertex_format.c
+ src/gwn_attr_binding.c
+ src/gwn_batch.c
+ src/gwn_element.c
+ src/gwn_buffer_id.cpp
+ src/gwn_immediate.c
+ src/gwn_imm_util.c
+ src/gwn_primitive.c
+ src/gwn_shader_interface.c
+ src/gwn_vertex_buffer.c
+ src/gwn_vertex_format.c
- gawain/attrib_binding.h
- gawain/attrib_binding_private.h
- gawain/batch.h
- gawain/buffer_id.h
- gawain/common.h
- gawain/element.h
- gawain/imm_util.h
- gawain/immediate.h
- gawain/primitive.h
- gawain/primitive_private.h
- gawain/shader_interface.h
- gawain/vertex_buffer.h
- gawain/vertex_format.h
- gawain/vertex_format_private.h
+ gawain/gwn_attr_binding.h
+ gawain/gwn_attr_binding_private.h
+ gawain/gwn_batch.h
+ gawain/gwn_buffer_id.h
+ gawain/gwn_common.h
+ gawain/gwn_element.h
+ gawain/gwn_imm_util.h
+ gawain/gwn_immediate.h
+ gawain/gwn_primitive.h
+ gawain/gwn_primitive_private.h
+ gawain/gwn_shader_interface.h
+ gawain/gwn_vertex_buffer.h
+ gawain/gwn_vertex_format.h
+ gawain/gwn_vertex_format_private.h
)
add_definitions(${GL_DEFINITIONS})
diff --git a/intern/gawain/gawain/attrib_binding.h b/intern/gawain/gawain/gwn_attr_binding.h
index a254f05dc05..a209e1c4f0f 100644
--- a/intern/gawain/gawain/attrib_binding.h
+++ b/intern/gawain/gawain/gwn_attr_binding.h
@@ -11,9 +11,9 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
-typedef struct {
+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/attrib_binding_private.h b/intern/gawain/gawain/gwn_attr_binding_private.h
index 53fdecff9ce..300945d464b 100644
--- a/intern/gawain/gawain/attrib_binding_private.h
+++ b/intern/gawain/gawain/gwn_attr_binding_private.h
@@ -11,8 +11,8 @@
#pragma once
-#include "vertex_format.h"
-#include "shader_interface.h"
+#include "gwn_vertex_format.h"
+#include "gwn_shader_interface.h"
void AttribBinding_clear(Gwn_AttrBinding*);
diff --git a/intern/gawain/gawain/batch.h b/intern/gawain/gawain/gwn_batch.h
index 6e2f32c1996..ee1599845c8 100644
--- a/intern/gawain/gawain/batch.h
+++ b/intern/gawain/gawain/gwn_batch.h
@@ -11,9 +11,9 @@
#pragma once
-#include "vertex_buffer.h"
-#include "element.h"
-#include "shader_interface.h"
+#include "gwn_vertex_buffer.h"
+#include "gwn_element.h"
+#include "gwn_shader_interface.h"
typedef enum {
GWN_BATCH_READY_TO_FORMAT,
@@ -36,21 +36,36 @@ typedef struct Gwn_Batch {
Gwn_BatchPhase phase;
bool program_dirty;
bool program_in_use;
+ unsigned owns_flag;
// state
GLuint program;
const Gwn_ShaderInterface* interface;
} Gwn_Batch;
-Gwn_Batch* GWN_batch_create(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*);
-void GWN_batch_init(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*);
+enum {
+ GWN_BATCH_OWNS_VBO = (1 << 0),
+ /* each vbo index gets bit-shifted */
+ 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);
+
+#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_discard_all(Gwn_Batch*); // including verts & elem
-int GWN_batch_vertbuf_add(Gwn_Batch*, Gwn_VertBuf*);
+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(Gwn_Batch*, GLuint program, const Gwn_ShaderInterface*);
+void GWN_batch_program_unset(Gwn_Batch*);
// 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.
@@ -63,6 +78,7 @@ 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]);
@@ -87,17 +103,17 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch*, Gwn_Batch*);
// We often need a batch with its own data, to be created and discarded together.
// WithOwn variants reduce number of system allocations.
-typedef struct {
+typedef struct BatchWithOwnVertexBuffer {
Gwn_Batch batch;
Gwn_VertBuf verts; // link batch.verts to this
} BatchWithOwnVertexBuffer;
-typedef struct {
+typedef struct BatchWithOwnElementList {
Gwn_Batch batch;
Gwn_IndexBuf elem; // link batch.elem to this
} BatchWithOwnElementList;
-typedef struct {
+typedef struct BatchWithOwnVertexBufferAndElementList {
Gwn_Batch batch;
Gwn_IndexBuf elem; // link batch.elem to this
Gwn_VertBuf verts; // link batch.verts to this
@@ -121,9 +137,3 @@ Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStu
batch = NULL; \
} \
} while (0)
-#define BATCH_DISCARD_ALL_SAFE(batch) do { \
- if (batch != NULL) { \
- GWN_batch_discard_all(batch); \
- batch = NULL; \
- } \
-} while (0)
diff --git a/intern/gawain/gawain/buffer_id.h b/intern/gawain/gawain/gwn_buffer_id.h
index e978eec67d8..db5df99f526 100644
--- a/intern/gawain/gawain/buffer_id.h
+++ b/intern/gawain/gawain/gwn_buffer_id.h
@@ -20,7 +20,7 @@
extern "C" {
#endif
-#include "common.h"
+#include "gwn_common.h"
GLuint GWN_buf_id_alloc(void);
void GWN_buf_id_free(GLuint buffer_id);
diff --git a/intern/gawain/gawain/common.h b/intern/gawain/gawain/gwn_common.h
index e21b241160d..e96a3b5c2a2 100644
--- a/intern/gawain/gawain/common.h
+++ b/intern/gawain/gawain/gwn_common.h
@@ -25,3 +25,10 @@
#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/element.h b/intern/gawain/gawain/gwn_element.h
index 771462be7c5..3081305769f 100644
--- a/intern/gawain/gawain/element.h
+++ b/intern/gawain/gawain/gwn_element.h
@@ -11,7 +11,7 @@
#pragma once
-#include "primitive.h"
+#include "gwn_primitive.h"
#define GWN_TRACK_INDEX_RANGE 1
@@ -21,7 +21,7 @@ typedef enum {
GWN_INDEX_U32
} Gwn_IndexBufType;
-typedef struct {
+typedef struct Gwn_IndexBuf {
unsigned index_ct;
#if GWN_TRACK_INDEX_RANGE
Gwn_IndexBufType index_type;
@@ -37,7 +37,7 @@ typedef struct {
void GWN_indexbuf_use(Gwn_IndexBuf*);
unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf*);
-typedef struct {
+typedef struct Gwn_IndexBufBuilder {
unsigned max_allowed_index;
unsigned max_index_ct;
unsigned index_ct;
diff --git a/intern/gawain/gawain/imm_util.h b/intern/gawain/gawain/gwn_imm_util.h
index 730bd7c1a3c..730bd7c1a3c 100644
--- a/intern/gawain/gawain/imm_util.h
+++ b/intern/gawain/gawain/gwn_imm_util.h
diff --git a/intern/gawain/gawain/immediate.h b/intern/gawain/gawain/gwn_immediate.h
index 39ba76db931..386b26b63b1 100644
--- a/intern/gawain/gawain/immediate.h
+++ b/intern/gawain/gawain/gwn_immediate.h
@@ -11,9 +11,9 @@
#pragma once
-#include "vertex_format.h"
-#include "primitive.h"
-#include "shader_interface.h"
+#include "gwn_vertex_format.h"
+#include "gwn_primitive.h"
+#include "gwn_shader_interface.h"
#define IMM_BATCH_COMBO 1
@@ -28,7 +28,7 @@ void immBeginAtMost(Gwn_PrimType, unsigned max_vertex_ct); // can supply fewer v
void immEnd(void); // finishes and draws
#if IMM_BATCH_COMBO
-#include "batch.h"
+#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.
diff --git a/intern/gawain/gawain/primitive.h b/intern/gawain/gawain/gwn_primitive.h
index c6786dc1993..5e5b8019889 100644
--- a/intern/gawain/gawain/primitive.h
+++ b/intern/gawain/gawain/gwn_primitive.h
@@ -11,7 +11,7 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
typedef enum {
GWN_PRIM_POINTS,
diff --git a/intern/gawain/gawain/primitive_private.h b/intern/gawain/gawain/gwn_primitive_private.h
index d959cd89852..d959cd89852 100644
--- a/intern/gawain/gawain/primitive_private.h
+++ b/intern/gawain/gawain/gwn_primitive_private.h
diff --git a/intern/gawain/gawain/gwn_shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h
new file mode 100644
index 00000000000..345ad8d389b
--- /dev/null
+++ b/intern/gawain/gawain/gwn_shader_interface.h
@@ -0,0 +1,74 @@
+
+// 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_CLIPPLANES, // vec4 ClipPlanes[]
+
+ GWN_UNIFORM_COLOR, // vec4 color
+ GWN_UNIFORM_EYE, // vec3 eye
+
+ 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
+
+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;
+} 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);
diff --git a/intern/gawain/gawain/vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h
index 46f83f5c551..5ad82251e79 100644
--- a/intern/gawain/gawain/vertex_buffer.h
+++ b/intern/gawain/gawain/gwn_vertex_buffer.h
@@ -11,7 +11,7 @@
#pragma once
-#include "vertex_format.h"
+#include "gwn_vertex_format.h"
// How to create a Gwn_VertBuf:
// 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts)
@@ -21,7 +21,7 @@
// Is Gwn_VertBuf always used as part of a Gwn_Batch?
-typedef struct {
+typedef struct Gwn_VertBuf {
Gwn_VertFormat format;
unsigned vertex_ct;
GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
@@ -31,6 +31,7 @@ typedef struct {
Gwn_VertBuf* GWN_vertbuf_create(void);
Gwn_VertBuf* GWN_vertbuf_create_with_format(const Gwn_VertFormat*);
+void GWN_vertbuf_clear(Gwn_VertBuf* verts);
void GWN_vertbuf_discard(Gwn_VertBuf*);
void GWN_vertbuf_init(Gwn_VertBuf*);
@@ -49,6 +50,35 @@ void GWN_vertbuf_attr_set(Gwn_VertBuf*, unsigned a_idx, unsigned v_idx, const vo
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?
diff --git a/intern/gawain/gawain/vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h
index 3b2a3be4209..348e6399afa 100644
--- a/intern/gawain/gawain/vertex_format.h
+++ b/intern/gawain/gawain/gwn_vertex_format.h
@@ -11,7 +11,7 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
#define GWN_VERT_ATTR_MAX_LEN 16
#define MAX_ATTRIB_NAMES 3
@@ -38,7 +38,7 @@ typedef enum {
GWN_FETCH_INT_TO_FLOAT // 127 (any int type) -> 127.0
} Gwn_VertFetchMode;
-typedef struct {
+typedef struct Gwn_VertAttr {
Gwn_VertCompType comp_type;
unsigned gl_comp_type;
unsigned comp_ct; // 1 to 4
@@ -49,7 +49,7 @@ typedef struct {
unsigned name_ct;
} Gwn_VertAttr;
-typedef struct {
+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
@@ -67,12 +67,12 @@ void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias);
// format conversion
-typedef struct {
+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 }
-} PackedNormal;
+} Gwn_PackedNormal;
-PackedNormal convert_i10_v3(const float data[3]);
-PackedNormal convert_i10_s3(const short data[3]);
+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/vertex_format_private.h b/intern/gawain/gawain/gwn_vertex_format_private.h
index c1a0f734eda..c1a0f734eda 100644
--- a/intern/gawain/gawain/vertex_format_private.h
+++ b/intern/gawain/gawain/gwn_vertex_format_private.h
diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/shader_interface.h
deleted file mode 100644
index 5304cc9fa51..00000000000
--- a/intern/gawain/gawain/shader_interface.h
+++ /dev/null
@@ -1,53 +0,0 @@
-
-// 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 "common.h"
-
-typedef enum {
- GWN_UNIFORM_NONE, // uninitialized/unknown
-
- GWN_UNIFORM_MODELVIEW, // mat4 ModelViewMatrix
- GWN_UNIFORM_PROJECTION, // mat4 ProjectionMatrix
- GWN_UNIFORM_MVP, // mat4 ModelViewProjectionMatrix
-
- GWN_UNIFORM_MODELVIEW_INV, // mat4 ModelViewInverseMatrix
- GWN_UNIFORM_PROJECTION_INV, // mat4 ProjectionInverseMatrix
-
- GWN_UNIFORM_NORMAL, // mat3 NormalMatrix
-
- GWN_UNIFORM_COLOR, // vec4 color
-
- GWN_UNIFORM_CUSTOM // custom uniform, not one of the above built-ins
-} Gwn_UniformBuiltin;
-
-typedef struct {
- const char* name;
- unsigned name_hash;
- GLenum gl_type;
- Gwn_UniformBuiltin builtin_type; // only for uniform inputs
- GLint size;
- GLint location;
-} Gwn_ShaderInput;
-
-typedef struct {
- uint16_t uniform_ct;
- uint16_t attrib_ct;
- Gwn_ShaderInput inputs[0]; // dynamic size, uniforms followed by attribs
-} 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_attr(const Gwn_ShaderInterface*, const char* name);
diff --git a/intern/gawain/src/attrib_binding.c b/intern/gawain/src/gwn_attr_binding.c
index 6cdb8a0e542..7647a927b1e 100644
--- a/intern/gawain/src/attrib_binding.c
+++ b/intern/gawain/src/gwn_attr_binding.c
@@ -9,8 +9,8 @@
// 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/.
-#include "attrib_binding.h"
-#include "attrib_binding_private.h"
+#include "gwn_attr_binding.h"
+#include "gwn_attr_binding_private.h"
#include <stddef.h>
#if GWN_VERT_ATTR_MAX_LEN != 16
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/gwn_batch.c
index 17e45084613..c651fb3a26f 100644
--- a/intern/gawain/src/batch.c
+++ b/intern/gawain/src/gwn_batch.c
@@ -9,25 +9,29 @@
// 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/.
-#include "batch.h"
-#include "buffer_id.h"
-#include "primitive_private.h"
+#include "gwn_batch.h"
+#include "gwn_buffer_id.h"
+#include "gwn_primitive_private.h"
#include <stdlib.h>
// necessary functions from matrix API
extern void gpuBindMatrices(const Gwn_ShaderInterface* shaderface);
extern bool gpuMatricesDirty(void); // how best to use this here?
-Gwn_Batch* GWN_batch_create(Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem)
+Gwn_Batch* GWN_batch_create_ex(
+ Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem,
+ unsigned owns_flag)
{
Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch));
- GWN_batch_init(batch, prim_type, verts, elem);
+ GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag);
return batch;
}
-void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem)
+void GWN_batch_init_ex(
+ Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem,
+ unsigned owns_flag)
{
#if TRUST_NO_ONE
assert(verts != NULL);
@@ -40,32 +44,34 @@ void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts
batch->prim_type = prim_type;
batch->gl_prim_type = convert_prim_type_to_gl(prim_type);
batch->phase = GWN_BATCH_READY_TO_DRAW;
+ batch->owns_flag = owns_flag;
}
void GWN_batch_discard(Gwn_Batch* batch)
{
- if (batch->vao_id)
- GWN_vao_free(batch->vao_id);
-
- free(batch);
- }
+ if (batch->owns_flag & GWN_BATCH_OWNS_INDEX)
+ GWN_indexbuf_discard(batch->elem);
-void GWN_batch_discard_all(Gwn_Batch* batch)
- {
- for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
+ if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0)
{
- if (batch->verts[v] == NULL)
- break;
- GWN_vertbuf_discard(batch->verts[v]);
+ for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
+ {
+ if (batch->verts[v] == NULL)
+ break;
+ if (batch->owns_flag & (1 << v))
+ GWN_vertbuf_discard(batch->verts[v]);
+ }
}
- if (batch->elem)
- GWN_indexbuf_discard(batch->elem);
+ if (batch->vao_id)
+ GWN_vao_free(batch->vao_id);
- GWN_batch_discard(batch);
+ free(batch);
}
-int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts)
+int GWN_batch_vertbuf_add_ex(
+ Gwn_Batch* batch, Gwn_VertBuf* verts,
+ bool own_vbo)
{
for (unsigned v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
{
@@ -78,6 +84,8 @@ int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts)
#endif
batch->verts[v] = verts;
// TODO: mark dirty so we can keep attrib bindings up-to-date
+ if (own_vbo)
+ batch->owns_flag |= (1 << v);
return v;
}
}
@@ -102,6 +110,14 @@ void GWN_batch_program_set(Gwn_Batch* batch, GLuint program, const Gwn_ShaderInt
GWN_batch_program_use_begin(batch); // hack! to make Batch_Uniform* simpler
}
+// fclem : hack !
+// we need this because we don't want to unbind the shader between drawcalls
+// but we still want the correct shader to be bound outside the draw manager
+void GWN_batch_program_unset(Gwn_Batch* batch)
+ {
+ batch->program_in_use = false;
+ }
+
static void Batch_update_program_bindings(Gwn_Batch* batch)
{
// disable all as a precaution
@@ -219,6 +235,12 @@ void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x)
glUniform1f(uniform->location, x);
}
+void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2])
+ {
+ GET_UNIFORM
+ glUniform2fv(uniform->location, 1, data);
+ }
+
void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3])
{
GET_UNIFORM
@@ -365,8 +387,11 @@ void GWN_batch_draw_stupid_instanced(Gwn_Batch* batch, unsigned int instance_vbo
if (batch->elem)
{
const Gwn_IndexBuf* el = batch->elem;
-
+#if GWN_TRACK_INDEX_RANGE
+ glDrawElementsInstancedBaseVertex(batch->gl_prim_type, el->index_ct, el->gl_index_type, 0, instance_count, el->base_index);
+#else
glDrawElementsInstanced(batch->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
+#endif
}
else
glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_ct, instance_count);
@@ -432,11 +457,15 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_
{
const Gwn_IndexBuf* el = batch_instanced->elem;
+#if GWN_TRACK_INDEX_RANGE
+ glDrawElementsInstancedBaseVertex(batch_instanced->gl_prim_type, el->index_ct, el->gl_index_type, 0, verts->vertex_ct, el->base_index);
+#else
glDrawElementsInstanced(batch_instanced->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, verts->vertex_ct);
+#endif
}
else
glDrawArraysInstanced(batch_instanced->gl_prim_type, 0, batch_instanced->verts[0]->vertex_ct, verts->vertex_ct);
// GWN_batch_program_use_end(batch);
glBindVertexArray(0);
- } \ No newline at end of file
+ }
diff --git a/intern/gawain/src/buffer_id.cpp b/intern/gawain/src/gwn_buffer_id.cpp
index 59a6b9c89e7..a93c3950d29 100644
--- a/intern/gawain/src/buffer_id.cpp
+++ b/intern/gawain/src/gwn_buffer_id.cpp
@@ -9,7 +9,7 @@
// 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/.#include "buffer_id.h"
-#include "buffer_id.h"
+#include "gwn_buffer_id.h"
#include <mutex>
#include <vector>
diff --git a/intern/gawain/src/element.c b/intern/gawain/src/gwn_element.c
index ecf555fbfe8..f31b64fa232 100644
--- a/intern/gawain/src/element.c
+++ b/intern/gawain/src/gwn_element.c
@@ -9,8 +9,8 @@
// 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/.
-#include "element.h"
-#include "buffer_id.h"
+#include "gwn_element.h"
+#include "gwn_buffer_id.h"
#include <stdlib.h>
#define KEEP_SINGLE_COPY 1
diff --git a/intern/gawain/src/imm_util.c b/intern/gawain/src/gwn_imm_util.c
index b06778c9045..45d8a7036e8 100644
--- a/intern/gawain/src/imm_util.c
+++ b/intern/gawain/src/gwn_imm_util.c
@@ -9,8 +9,8 @@
// 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/.
-#include "imm_util.h"
-#include "immediate.h"
+#include "gwn_imm_util.h"
+#include "gwn_immediate.h"
void immRectf(unsigned pos, float x1, float y1, float x2, float y2)
diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/gwn_immediate.c
index 5eb5ebb8336..1c0776d1bbf 100644
--- a/intern/gawain/src/immediate.c
+++ b/intern/gawain/src/gwn_immediate.c
@@ -9,12 +9,12 @@
// 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/.
-#include "immediate.h"
-#include "buffer_id.h"
-#include "attrib_binding.h"
-#include "attrib_binding_private.h"
-#include "vertex_format_private.h"
-#include "primitive_private.h"
+#include "gwn_immediate.h"
+#include "gwn_buffer_id.h"
+#include "gwn_attr_binding.h"
+#include "gwn_attr_binding_private.h"
+#include "gwn_vertex_format_private.h"
+#include "gwn_primitive_private.h"
#include <string.h>
// necessary functions from matrix API
diff --git a/intern/gawain/src/primitive.c b/intern/gawain/src/gwn_primitive.c
index b9d92a6bdf8..b206b3ae1b3 100644
--- a/intern/gawain/src/primitive.c
+++ b/intern/gawain/src/gwn_primitive.c
@@ -9,8 +9,8 @@
// 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/.
-#include "primitive.h"
-#include "primitive_private.h"
+#include "gwn_primitive.h"
+#include "gwn_primitive_private.h"
Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type)
{
diff --git a/intern/gawain/src/gwn_shader_interface.c b/intern/gawain/src/gwn_shader_interface.c
new file mode 100644
index 00000000000..1fb941f9225
--- /dev/null
+++ b/intern/gawain/src/gwn_shader_interface.c
@@ -0,0 +1,311 @@
+
+// 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/.
+
+#include "gwn_shader_interface.h"
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#define DEBUG_SHADER_INTERFACE 0
+
+#if DEBUG_SHADER_INTERFACE
+ #include <stdio.h>
+#endif
+
+static const char* BuiltinUniform_name(Gwn_UniformBuiltin u)
+ {
+ static const char* names[] =
+ {
+ [GWN_UNIFORM_NONE] = NULL,
+
+ [GWN_UNIFORM_MODEL] = "ModelMatrix",
+ [GWN_UNIFORM_VIEW] = "ViewMatrix",
+ [GWN_UNIFORM_MODELVIEW] = "ModelViewMatrix",
+ [GWN_UNIFORM_PROJECTION] = "ProjectionMatrix",
+ [GWN_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix",
+ [GWN_UNIFORM_MVP] = "ModelViewProjectionMatrix",
+
+ [GWN_UNIFORM_MODEL_INV] = "ModelMatrixInverse",
+ [GWN_UNIFORM_VIEW_INV] = "ViewMatrixInverse",
+ [GWN_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse",
+ [GWN_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse",
+ [GWN_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse",
+
+ [GWN_UNIFORM_NORMAL] = "NormalMatrix",
+ [GWN_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix",
+ [GWN_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors",
+ [GWN_UNIFORM_ORCO] = "OrcoTexCoFactors",
+ [GWN_UNIFORM_CLIPPLANES] = "ClipPlanes",
+
+ [GWN_UNIFORM_COLOR] = "color",
+ [GWN_UNIFORM_EYE] = "eye",
+
+ [GWN_UNIFORM_CUSTOM] = NULL,
+ [GWN_NUM_UNIFORMS] = NULL,
+ };
+
+ return names[u];
+ }
+
+GWN_INLINE bool match(const char* a, const char* b)
+ {
+ return strcmp(a, b) == 0;
+ }
+
+GWN_INLINE unsigned hash_string(const char *str)
+ {
+ unsigned i = 0, c;
+
+ while ((c = *str++))
+ {
+ i = i * 37 + c;
+ }
+
+ return i;
+ }
+
+GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* input,
+ const char* name, uint32_t name_len)
+ {
+ input->name_offset = shaderface->name_buffer_offset;
+ input->name_hash = hash_string(name);
+ shaderface->name_buffer_offset += name_len + 1; // include NULL terminator
+ }
+
+GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input,
+ Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS])
+ {
+ const unsigned bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS;
+ input->next = buckets[bucket_index];
+ buckets[bucket_index] = input;
+ }
+
+GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS],
+ const char *name_buffer, const char *name)
+ {
+ const unsigned name_hash = hash_string(name);
+ const unsigned bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS;
+ const Gwn_ShaderInput* input = buckets[bucket_index];
+ if (input == NULL)
+ {
+ // Requested uniform is not found at all.
+ return NULL;
+ }
+ // Optimization bit: if there is no hash collision detected when constructing shader interface
+ // it means we can only request the single possible uniform. Surely, it's possible we request
+ // uniform which causes hash collision, but that will be detected in debug builds.
+ if (input->next == NULL)
+ {
+ if (name_hash == input->name_hash)
+ {
+#if TRUST_NO_ONE
+ assert(match(name_buffer + input->name_offset, name));
+#endif
+ return input;
+ }
+ return NULL;
+ }
+ // Work through possible collisions.
+ const Gwn_ShaderInput* next = input;
+ while (next != NULL)
+ {
+ input = next;
+ next = input->next;
+
+ if (input->name_hash != name_hash)
+ {
+ continue;
+ }
+ if (match(name_buffer + input->name_offset, name))
+ {
+ return input;
+ }
+ }
+ return NULL; // not found
+ }
+
+GWN_INLINE void buckets_free(Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS])
+ {
+ for (unsigned bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index)
+ {
+ Gwn_ShaderInput *input = buckets[bucket_index];
+ while (input != NULL)
+ {
+ Gwn_ShaderInput *input_next = input->next;
+ free(input);
+ input = input_next;
+ }
+ }
+ }
+
+static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name)
+ {
+ // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
+
+ // detect built-in uniforms (name must match)
+ for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u)
+ {
+ const char* builtin_name = BuiltinUniform_name(u);
+ if (match(name, builtin_name))
+ {
+ input->builtin_type = u;
+ return true;
+ }
+ }
+
+ input->builtin_type = GWN_UNIFORM_CUSTOM;
+ return false;
+ }
+
+static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const char* name)
+ {
+ Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput));
+
+ input->location = glGetUniformLocation(shaderface->program, name);
+
+ unsigned name_len = strlen(name);
+ shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); // include NULL terminator
+ char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset;
+ strcpy(name_buffer, name);
+
+ set_input_name(shaderface, input, name, name_len);
+ setup_builtin_uniform(input, name);
+
+ shader_input_to_bucket(input, shaderface->uniform_buckets);
+ if (input->builtin_type != GWN_UNIFORM_NONE &&
+ input->builtin_type != GWN_UNIFORM_CUSTOM)
+ {
+ shaderface->builtin_uniforms[input->builtin_type] = input;
+ }
+#if DEBUG_SHADER_INTERFACE
+ printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, shaderface->program, name, input->location);
+#endif
+ return input;
+ }
+
+Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program)
+ {
+ Gwn_ShaderInterface* shaderface = calloc(1, sizeof(Gwn_ShaderInterface));
+ shaderface->program = program;
+
+#if DEBUG_SHADER_INTERFACE
+ printf("%s {\n", __func__); // enter function
+ printf("Gwn_ShaderInterface %p, program %d\n", shaderface, program);
+#endif
+
+ GLint max_attrib_name_len, attrib_ct;
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attrib_ct);
+
+ GLint max_ubo_name_len, ubo_ct;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len);
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_ct);
+
+ const uint32_t name_buffer_len = attrib_ct * max_attrib_name_len + ubo_ct * max_ubo_name_len;
+ shaderface->name_buffer = malloc(name_buffer_len);
+
+ // Attributes
+ for (uint32_t i = 0; i < attrib_ct; ++i)
+ {
+ Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput));
+ GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset;
+ char* name = shaderface->name_buffer + shaderface->name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
+
+ // TODO: reject DOUBLE gl_types
+
+ input->location = glGetAttribLocation(program, name);
+
+ set_input_name(shaderface, input, name, name_len);
+
+ shader_input_to_bucket(input, shaderface->attrib_buckets);
+
+#if DEBUG_SHADER_INTERFACE
+ printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
+#endif
+ }
+
+ // Uniform Blocks
+ for (uint32_t i = 0; i < ubo_ct; ++i)
+ {
+ Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput));
+ GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset;
+ char* name = shaderface->name_buffer + shaderface->name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name);
+
+ input->location = i;
+
+ set_input_name(shaderface, input, name, name_len);
+
+ shader_input_to_bucket(input, shaderface->ubo_buckets);
+
+#if DEBUG_SHADER_INTERFACE
+ printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
+#endif
+ }
+
+ return shaderface;
+ }
+
+void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface)
+ {
+ // Free memory used by buckets and has entries.
+ buckets_free(shaderface->uniform_buckets);
+ buckets_free(shaderface->attrib_buckets);
+ buckets_free(shaderface->ubo_buckets);
+ // Free memory used by name_buffer.
+ free(shaderface->name_buffer);
+ // Free memory used by shader interface by its self.
+ free(shaderface);
+ }
+
+const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name)
+ {
+ // TODO: Warn if we find a matching builtin, since these can be looked up much quicker.
+ const Gwn_ShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name);
+
+ // If input is not found add it so it's found next time.
+ if (input == NULL)
+ input = add_uniform((Gwn_ShaderInterface*)shaderface, name);
+
+ return (input->location != -1) ? input : NULL;
+ }
+
+const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin)
+ {
+#if TRUST_NO_ONE
+ assert(builtin != GWN_UNIFORM_NONE);
+ assert(builtin != GWN_UNIFORM_CUSTOM);
+ assert(builtin != GWN_NUM_UNIFORMS);
+#endif
+
+ const Gwn_ShaderInput* input = shaderface->builtin_uniforms[builtin];
+
+ // If input is not found add it so it's found next time.
+ if (input == NULL)
+ input = add_uniform((Gwn_ShaderInterface*)shaderface, BuiltinUniform_name(builtin));
+
+ return (input->location != -1) ? input : NULL;
+ }
+
+const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name)
+ {
+ return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name);
+ }
+
+const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name)
+ {
+ return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name);
+ }
diff --git a/intern/gawain/src/vertex_buffer.c b/intern/gawain/src/gwn_vertex_buffer.c
index 03691b0c21d..2019d7d50bc 100644
--- a/intern/gawain/src/vertex_buffer.c
+++ b/intern/gawain/src/gwn_vertex_buffer.c
@@ -9,9 +9,9 @@
// 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/.
-#include "vertex_buffer.h"
-#include "buffer_id.h"
-#include "vertex_format_private.h"
+#include "gwn_vertex_buffer.h"
+#include "gwn_buffer_id.h"
+#include "gwn_vertex_format_private.h"
#include <stdlib.h>
#include <string.h>
@@ -51,6 +51,25 @@ void GWN_vertbuf_init_with_format(Gwn_VertBuf* verts, const Gwn_VertFormat* form
VertexFormat_pack(&verts->format);
}
+/**
+ * Like #GWN_vertbuf_discard but doesn't free.
+ */
+void GWN_vertbuf_clear(Gwn_VertBuf* verts)
+ {
+ if (verts->vbo_id) {
+ GWN_buf_id_free(verts->vbo_id);
+ vbo_memory_usage -= GWN_vertbuf_size_get(verts);
+ }
+#if KEEP_SINGLE_COPY
+ else
+#endif
+ if (verts->data)
+ {
+ free(verts->data);
+ verts->data = NULL;
+ }
+ }
+
void GWN_vertbuf_discard(Gwn_VertBuf* verts)
{
if (verts->vbo_id) {
@@ -151,6 +170,26 @@ void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, unsigned a_idx, unsigned s
}
}
+void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, unsigned a_idx, Gwn_VertBufRaw *access)
+ {
+ const Gwn_VertFormat* format = &verts->format;
+ const Gwn_VertAttr* a = format->attribs + a_idx;
+
+#if TRUST_NO_ONE
+ assert(a_idx < format->attrib_ct);
+ assert(verts->data != NULL); // data must be in main mem
+#endif
+
+ access->size = a->sz;
+ access->stride = format->stride;
+ access->data = (GLubyte*)verts->data + a->offset;
+ access->data_init = access->data;
+#if TRUST_NO_ONE
+ access->_data_end = access->data_init + (size_t)(verts->vertex_ct * format->stride);
+#endif
+ }
+
+
static void VertexBuffer_prime(Gwn_VertBuf* verts)
{
const unsigned buffer_sz = GWN_vertbuf_size_get(verts);
diff --git a/intern/gawain/src/vertex_format.c b/intern/gawain/src/gwn_vertex_format.c
index 139a76cf7ef..d6367935703 100644
--- a/intern/gawain/src/vertex_format.c
+++ b/intern/gawain/src/gwn_vertex_format.c
@@ -9,8 +9,8 @@
// 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/.
-#include "vertex_format.h"
-#include "vertex_format_private.h"
+#include "gwn_vertex_format.h"
+#include "gwn_vertex_format_private.h"
#include <stddef.h>
#include <string.h>
@@ -251,7 +251,7 @@ void VertexFormat_pack(Gwn_VertFormat* format)
// OpenGL ES packs in a different order as desktop GL but component conversion is the same.
-// Of the code here, only struct PackedNormal needs to change.
+// Of the code here, only struct Gwn_PackedNormal needs to change.
#define SIGNED_INT_10_MAX 511
#define SIGNED_INT_10_MIN -512
@@ -283,14 +283,14 @@ static int convert_i16(short x)
// TODO: round?
}
-PackedNormal convert_i10_v3(const float data[3])
+Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3])
{
- PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) };
+ Gwn_PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) };
return n;
}
-PackedNormal convert_i10_s3(const short data[3])
+Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3])
{
- PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) };
+ Gwn_PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) };
return n;
}
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c
deleted file mode 100644
index dff2c06f531..00000000000
--- a/intern/gawain/src/shader_interface.c
+++ /dev/null
@@ -1,311 +0,0 @@
-
-// 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/.
-
-#include "shader_interface.h"
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-
-#define SUPPORT_LEGACY_GLSL 1
-#define DEBUG_SHADER_INTERFACE 0
-
-#if DEBUG_SHADER_INTERFACE
- #include <stdio.h>
-#endif
-
-static const char* BuiltinUniform_name(Gwn_UniformBuiltin u)
- {
- static const char* names[] =
- {
- [GWN_UNIFORM_NONE] = NULL,
-
- [GWN_UNIFORM_MODELVIEW] = "ModelViewMatrix",
- [GWN_UNIFORM_PROJECTION] = "ProjectionMatrix",
- [GWN_UNIFORM_MVP] = "ModelViewProjectionMatrix",
-
- [GWN_UNIFORM_MODELVIEW_INV] = "ModelViewInverseMatrix",
- [GWN_UNIFORM_PROJECTION_INV] = "ProjectionInverseMatrix",
-
- [GWN_UNIFORM_NORMAL] = "NormalMatrix",
-
- [GWN_UNIFORM_COLOR] = "color",
-
- [GWN_UNIFORM_CUSTOM] = NULL
- };
-
- return names[u];
- }
-
-static bool match(const char* a, const char* b)
- {
- return strcmp(a, b) == 0;
- }
-
-static unsigned hash_string(const char *str)
- {
- unsigned i = 0, c;
-
- while ((c = *str++))
- {
- i = i * 37 + c;
- }
-
- return i;
- }
-
-static void set_input_name(Gwn_ShaderInput* input, const char* name)
- {
- input->name = name;
- input->name_hash = hash_string(name);
- }
-
-// keep these in sync with Gwn_UniformBuiltin order
-#define FIRST_MAT4_UNIFORM GWN_UNIFORM_MODELVIEW
-#define LAST_MAT4_UNIFORM GWN_UNIFORM_PROJECTION_INV
-
-static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name)
- {
- // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
-
- // detect built-in uniforms (gl_type and name must match)
- // if a match is found, use BuiltinUniform_name so name buffer space can be reclaimed
- switch (input->gl_type)
- {
- case GL_FLOAT_MAT4:
- for (Gwn_UniformBuiltin u = FIRST_MAT4_UNIFORM; u <= LAST_MAT4_UNIFORM; ++u)
- {
- const char* builtin_name = BuiltinUniform_name(u);
- if (match(name, builtin_name))
- {
- set_input_name(input, builtin_name);
- input->builtin_type = u;
- return true;
- }
- }
- break;
- case GL_FLOAT_MAT3:
- {
- const char* builtin_name = BuiltinUniform_name(GWN_UNIFORM_NORMAL);
- if (match(name, builtin_name))
- {
- set_input_name(input, builtin_name);
- input->builtin_type = GWN_UNIFORM_NORMAL;
- return true;
- }
- }
- break;
- case GL_FLOAT_VEC4:
- {
- const char* builtin_name = BuiltinUniform_name(GWN_UNIFORM_COLOR);
- if (match(name, builtin_name))
- {
- set_input_name(input, builtin_name);
- input->builtin_type = GWN_UNIFORM_COLOR;
- return true;
- }
- }
- break;
- default:
- ;
- }
-
- input->builtin_type = GWN_UNIFORM_CUSTOM;
- return false;
- }
-
-Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program)
- {
-#if DEBUG_SHADER_INTERFACE
- printf("%s {\n", __func__); // enter function
-#endif
-
- GLint uniform_ct, attrib_ct;
- glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniform_ct);
- glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attrib_ct);
- const GLint input_ct = uniform_ct + attrib_ct;
-
- GLint max_uniform_name_len, max_attrib_name_len;
- glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_len);
- glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len);
- const uint32_t name_buffer_len = uniform_ct * max_uniform_name_len + attrib_ct * max_attrib_name_len;
-
- // allocate enough space for input counts, details for each input, and a buffer for name strings
- Gwn_ShaderInterface* shaderface = calloc(1, offsetof(Gwn_ShaderInterface, inputs) + input_ct * sizeof(Gwn_ShaderInput) + name_buffer_len);
- shaderface->uniform_ct = uniform_ct;
- shaderface->attrib_ct = attrib_ct;
-
- char* name_buffer = (char*)shaderface + offsetof(Gwn_ShaderInterface, inputs) + input_ct * sizeof(Gwn_ShaderInput);
- uint32_t name_buffer_offset = 0;
-
- for (uint32_t i = 0; i < uniform_ct; ++i)
- {
- Gwn_ShaderInput* input = shaderface->inputs + i;
- GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
- char* name = name_buffer + name_buffer_offset;
- GLsizei name_len = 0;
-
- glGetActiveUniform(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
-
- input->location = glGetUniformLocation(program, name);
-
-#if SUPPORT_LEGACY_GLSL
- if (input->location != -1)
- {
-#elif TRUST_NO_ONE
- assert(input->location != -1);
-#endif
-
- if (setup_builtin_uniform(input, name))
- ; // reclaim space from name buffer (don't advance offset)
- else
- {
- set_input_name(input, name);
- name_buffer_offset += name_len + 1; // include NULL terminator
- }
-#if SUPPORT_LEGACY_GLSL
- }
-#endif
-
-#if DEBUG_SHADER_INTERFACE
- printf("uniform[%u] '%s' at location %d\n", i, name, input->location);
-#endif
- }
-
- for (uint32_t i = 0; i < attrib_ct; ++i)
- {
- Gwn_ShaderInput* input = shaderface->inputs + uniform_ct + i;
- GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
- char* name = name_buffer + name_buffer_offset;
- GLsizei name_len = 0;
-
- glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
-
- // TODO: reject DOUBLE gl_types
-
- input->location = glGetAttribLocation(program, name);
-
-#if SUPPORT_LEGACY_GLSL
- if (input->location != -1)
- {
-#elif TRUST_NO_ONE
- assert(input->location != -1);
-#endif
-
- set_input_name(input, name);
- name_buffer_offset += name_len + 1; // include NULL terminator
-#if SUPPORT_LEGACY_GLSL
- }
-#endif
-
-#if DEBUG_SHADER_INTERFACE
- printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
-#endif
- }
-
- const uint32_t name_buffer_used = name_buffer_offset;
-
-#if DEBUG_SHADER_INTERFACE
- printf("using %u of %u bytes from name buffer\n", name_buffer_used, name_buffer_len);
- printf("}\n"); // exit function
-#endif
-
- if (name_buffer_used < name_buffer_len)
- {
- // realloc shaderface to shrink name buffer
- const size_t shaderface_alloc =
- offsetof(Gwn_ShaderInterface, inputs) + (input_ct * sizeof(Gwn_ShaderInput)) + name_buffer_used;
- const char* shaderface_orig_start = (const char*)shaderface;
- const char* shaderface_orig_end = &shaderface_orig_start[shaderface_alloc];
- shaderface = realloc(shaderface, shaderface_alloc);
- const ptrdiff_t delta = (char*)shaderface - shaderface_orig_start;
-
- if (delta)
- {
- // each input->name will need adjustment (except static built-in names)
- for (uint32_t i = 0; i < input_ct; ++i)
- {
- Gwn_ShaderInput* input = shaderface->inputs + i;
-
- if (input->name >= shaderface_orig_start && input->name < shaderface_orig_end)
- input->name += delta;
- }
- }
- }
-
- return shaderface;
- }
-
-void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface)
- {
- // allocated as one chunk, so discard is simple
- free(shaderface);
- }
-
-const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name)
- {
- const unsigned name_hash = hash_string(name);
- for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
- {
- const Gwn_ShaderInput* uniform = shaderface->inputs + i;
-
-#if SUPPORT_LEGACY_GLSL
- if (uniform->name == NULL) continue;
-#endif
-
- if (uniform->name_hash != name_hash) continue;
-
- if (match(uniform->name, name))
- return uniform;
-
- // TODO: warn if we find a matching builtin, since these can be looked up much quicker --v
- }
-
- return NULL; // not found
- }
-
-const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin)
- {
-#if TRUST_NO_ONE
- assert(builtin != GWN_UNIFORM_NONE);
- assert(builtin != GWN_UNIFORM_CUSTOM);
-#endif
-
- // look up by enum, not name
- for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
- {
- const Gwn_ShaderInput* uniform = shaderface->inputs + i;
-
- if (uniform->builtin_type == builtin)
- return uniform;
- }
- return NULL; // not found
- }
-
-const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name)
- {
- // attribs are stored after uniforms
- const uint32_t input_ct = shaderface->uniform_ct + shaderface->attrib_ct;
- const unsigned name_hash = hash_string(name);
- for (uint32_t i = shaderface->uniform_ct; i < input_ct; ++i)
- {
- const Gwn_ShaderInput* attrib = shaderface->inputs + i;
-
-#if SUPPORT_LEGACY_GLSL
- if (attrib->name == NULL) continue;
-#endif
-
- if (attrib->name_hash != name_hash) continue;
-
- if (match(attrib->name, name))
- return attrib;
- }
- return NULL; // not found
- }