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:
authorMike Erwin <significant.bit@gmail.com>2017-03-17 06:32:35 +0300
committerMike Erwin <significant.bit@gmail.com>2017-03-17 06:32:35 +0300
commit4452bea2f170ec7fe48c223c8c499f1eb9b5356c (patch)
tree28dcc9ac042fcce5c77f3c60b4ce8af8677fa4a8 /source/blender
parentb4e8dc8c82dfcae60f33e39684272867745a8af2 (diff)
move Gawain library to intern
Before now it lived in source/blender/gpu for convenience. Only a few files in the gpu module use Gawain directly. Tested on Mac, time to push and test on Windows. Todo: some CMake magic to make it easy to #include "gawain/some_header.h" from any C or H file. Main problem here is the many editors that include GPU_immediate.h which includes Gawain's immediate.h -- is there a way to avoid changing every editor's CMakeLists?
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/gpu/CMakeLists.txt23
-rw-r--r--source/blender/gpu/GPU_batch.h6
-rw-r--r--source/blender/gpu/GPU_immediate.h9
-rw-r--r--source/blender/gpu/gawain/attrib_binding.c69
-rw-r--r--source/blender/gpu/gawain/attrib_binding.h24
-rw-r--r--source/blender/gpu/gawain/batch.c405
-rw-r--r--source/blender/gpu/gawain/batch.h110
-rw-r--r--source/blender/gpu/gawain/buffer_id.cpp115
-rw-r--r--source/blender/gpu/gawain/buffer_id.h34
-rw-r--r--source/blender/gpu/gawain/common.h40
-rw-r--r--source/blender/gpu/gawain/element.c283
-rw-r--r--source/blender/gpu/gawain/element.h64
-rw-r--r--source/blender/gpu/gawain/imm_util.c46
-rw-r--r--source/blender/gpu/gawain/imm_util.h18
-rw-r--r--source/blender/gpu/gawain/immediate.c880
-rw-r--r--source/blender/gpu/gawain/immediate.h112
-rw-r--r--source/blender/gpu/gawain/primitive.c41
-rw-r--r--source/blender/gpu/gawain/primitive.h43
-rw-r--r--source/blender/gpu/gawain/shader_interface.c140
-rw-r--r--source/blender/gpu/gawain/shader_interface.h49
-rw-r--r--source/blender/gpu/gawain/vertex_buffer.c170
-rw-r--r--source/blender/gpu/gawain/vertex_buffer.h64
-rw-r--r--source/blender/gpu/gawain/vertex_format.c248
-rw-r--r--source/blender/gpu/gawain/vertex_format.h87
24 files changed, 13 insertions, 3067 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 391efdaeb00..1791b34d4c8 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -42,6 +42,7 @@ set(INC
../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/smoke/extern
+ ../../../intern/gawain
)
set(INC_SYS
@@ -70,28 +71,6 @@ set(SRC
intern/gpu_uniformbuffer.c
intern/gpu_viewport.c
- gawain/attrib_binding.c
- gawain/attrib_binding.h
- gawain/batch.c
- gawain/batch.h
- gawain/buffer_id.h
- gawain/buffer_id.cpp
- gawain/common.h
- gawain/element.c
- gawain/element.h
- gawain/immediate.c
- gawain/immediate.h
- gawain/imm_util.c
- gawain/imm_util.h
- gawain/primitive.h
- gawain/primitive.c
- gawain/shader_interface.c
- gawain/shader_interface.h
- gawain/vertex_buffer.c
- gawain/vertex_buffer.h
- gawain/vertex_format.c
- gawain/vertex_format.h
-
shaders/gpu_shader_fx_lib.glsl
shaders/gpu_shader_fx_ssao_frag.glsl
shaders/gpu_shader_fx_dof_frag.glsl
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 6d63965952a..2232e333bb6 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -30,7 +30,11 @@
#pragma once
-#include "gawain/batch.h"
+#include "../../../intern/gawain/gawain/batch.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/batch.h"
+
#include "GPU_shader.h"
/* Extend Batch_set_program to use Blender’s library of built-in shader programs. */
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index 4a0840e22c0..35964a81030 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -30,8 +30,13 @@
#pragma once
-#include "gawain/immediate.h"
-#include "gawain/imm_util.h"
+#include "../../../intern/gawain/gawain/immediate.h"
+#include "../../../intern/gawain/gawain/imm_util.h"
+
+// TODO: CMake magic to do this:
+// #include "gawain/immediate.h"
+// #include "gawain/imm_util.h"
+
#include "GPU_shader.h"
/* Extend immBindProgram to use Blender’s library of built-in shader programs.
diff --git a/source/blender/gpu/gawain/attrib_binding.c b/source/blender/gpu/gawain/attrib_binding.c
deleted file mode 100644
index bb42aaf66eb..00000000000
--- a/source/blender/gpu/gawain/attrib_binding.c
+++ /dev/null
@@ -1,69 +0,0 @@
-
-// 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/.
-
-#include "attrib_binding.h"
-
-#if MAX_VERTEX_ATTRIBS != 16
- #error "attrib binding code assumes MAX_VERTEX_ATTRIBS = 16"
-#endif
-
-void clear_AttribBinding(AttribBinding* binding)
- {
- binding->loc_bits = 0;
- binding->enabled_bits = 0;
- }
-
-unsigned read_attrib_location(const AttribBinding* binding, unsigned a_idx)
- {
-#if TRUST_NO_ONE
- assert(a_idx < MAX_VERTEX_ATTRIBS);
- assert(binding->enabled_bits & (1 << a_idx));
-#endif
-
- return (binding->loc_bits >> (4 * a_idx)) & 0xF;
- }
-
-static void write_attrib_location(AttribBinding* binding, unsigned a_idx, unsigned location)
- {
-#if TRUST_NO_ONE
- assert(a_idx < MAX_VERTEX_ATTRIBS);
- assert(location < MAX_VERTEX_ATTRIBS);
-#endif
-
- const unsigned shift = 4 * a_idx;
- const uint64_t mask = ((uint64_t)0xF) << shift;
- // overwrite this attrib's previous location
- binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift);
- // mark this attrib as enabled
- binding->enabled_bits |= 1 << a_idx;
- }
-
-void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, GLuint program)
- {
-#if TRUST_NO_ONE
- assert(glIsProgram(program));
-#endif
-
- clear_AttribBinding(binding);
-
- for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
- {
- const Attrib* a = format->attribs + a_idx;
- GLint loc = glGetAttribLocation(program, a->name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
- // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
-#endif
-
- write_attrib_location(binding, a_idx, loc);
- }
- }
diff --git a/source/blender/gpu/gawain/attrib_binding.h b/source/blender/gpu/gawain/attrib_binding.h
deleted file mode 100644
index 9e2431ca379..00000000000
--- a/source/blender/gpu/gawain/attrib_binding.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-// 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 "vertex_format.h"
-
-typedef struct {
- uint64_t loc_bits; // store 4 bits for each of the 16 attribs
- uint16_t enabled_bits; // 1 bit for each attrib
-} AttribBinding;
-
-void clear_AttribBinding(AttribBinding*);
-
-void get_attrib_locations(const VertexFormat*, AttribBinding*, GLuint program);
-unsigned read_attrib_location(const AttribBinding*, unsigned a_idx);
diff --git a/source/blender/gpu/gawain/batch.c b/source/blender/gpu/gawain/batch.c
deleted file mode 100644
index cac34d445bb..00000000000
--- a/source/blender/gpu/gawain/batch.c
+++ /dev/null
@@ -1,405 +0,0 @@
-
-// 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/.
-
-#include "batch.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-
-// necessary functions from matrix API
-extern void gpuBindMatrices(GLuint program);
-extern bool gpuMatricesDirty(void); // how best to use this here?
-
-Batch* Batch_create(PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
- {
- Batch* batch = calloc(1, sizeof(Batch));
-
- Batch_init(batch, prim_type, verts, elem);
-
- return batch;
- }
-
-void Batch_init(Batch* batch, PrimitiveType prim_type, VertexBuffer* verts, ElementList* elem)
- {
-#if TRUST_NO_ONE
- assert(verts != NULL);
- // assert(prim_type == PRIM_POINTS || prim_type == PRIM_LINES || prim_type == PRIM_TRIANGLES);
- // we will allow other primitive types in a future update
-#endif
-
- batch->verts[0] = verts;
- for (int v = 1; v < BATCH_MAX_VBO_CT; ++v)
- batch->verts[v] = NULL;
- batch->elem = elem;
- batch->prim_type = prim_type;
- batch->phase = READY_TO_DRAW;
- }
-
-void Batch_discard(Batch* batch)
- {
- if (batch->vao_id)
- vao_id_free(batch->vao_id);
-
- free(batch);
- }
-
-void Batch_discard_all(Batch* batch)
- {
- for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
- {
- if (batch->verts[v] == NULL)
- break;
- VertexBuffer_discard(batch->verts[v]);
- }
-
- if (batch->elem)
- ElementList_discard(batch->elem);
-
- Batch_discard(batch);
- }
-
-int Batch_add_VertexBuffer(Batch* batch, VertexBuffer* verts)
- {
- for (unsigned v = 0; v < BATCH_MAX_VBO_CT; ++v)
- {
- if (batch->verts[v] == NULL)
- {
-#if TRUST_NO_ONE
- // for now all VertexBuffers must have same vertex_ct
- assert(verts->vertex_ct == batch->verts[0]->vertex_ct);
- // in the near future we will enable instanced attribs which have their own vertex_ct
-#endif
- batch->verts[v] = verts;
- // TODO: mark dirty so we can keep attrib bindings up-to-date
- return v;
- }
- }
-
- // we only make it this far if there is no room for another VertexBuffer
-#if TRUST_NO_ONE
- assert(false);
-#endif
- return -1;
- }
-
-void Batch_set_program(Batch* batch, GLuint program)
- {
-#if TRUST_NO_ONE
- assert(glIsProgram(program));
-#endif
-
- batch->program = program;
- batch->program_dirty = true;
-
- Batch_use_program(batch); // hack! to make Batch_Uniform* simpler
- }
-
-static void Batch_update_program_bindings(Batch* batch)
- {
- // disable all as a precaution
- // why are we not using prev_attrib_enabled_bits?? see immediate.c
- for (unsigned a_idx = 0; a_idx < MAX_VERTEX_ATTRIBS; ++a_idx)
- glDisableVertexAttribArray(a_idx);
-
- for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
- {
- VertexBuffer* verts = batch->verts[v];
- if (verts == NULL)
- break;
-
- const VertexFormat* format = &verts->format;
-
- const unsigned attrib_ct = format->attrib_ct;
- const unsigned stride = format->stride;
-
- VertexBuffer_use(verts);
-
- for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
- {
- const Attrib* a = format->attribs + a_idx;
-
- const GLvoid* pointer = (const GLubyte*)0 + a->offset;
-
- const GLint loc = glGetAttribLocation(batch->program, a->name);
-
- if (loc == -1) continue;
-
- glEnableVertexAttribArray(loc);
-
- switch (a->fetch_mode)
- {
- case KEEP_FLOAT:
- case CONVERT_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_FALSE, stride, pointer);
- break;
- case NORMALIZE_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_TRUE, stride, pointer);
- break;
- case KEEP_INT:
- glVertexAttribIPointer(loc, a->comp_ct, a->comp_type, stride, pointer);
- }
- }
- }
-
- batch->program_dirty = false;
- }
-
-void Batch_use_program(Batch* batch)
- {
- // NOTE: use_program & done_using_program are fragile, depend on staying in sync with
- // the GL context's active program. use_program doesn't mark other programs as "not used".
- // TODO: make not fragile (somehow)
-
- if (!batch->program_in_use)
- {
- glUseProgram(batch->program);
- batch->program_in_use = true;
- }
- }
-
-void Batch_done_using_program(Batch* batch)
- {
- if (batch->program_in_use)
- {
- glUseProgram(0);
- batch->program_in_use = false;
- }
- }
-
-void Batch_Uniform1i(Batch* batch, const char* name, int value)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, value);
- }
-
-void Batch_Uniform1b(Batch* batch, const char* name, bool value)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, value ? GL_TRUE : GL_FALSE);
- }
-
-void Batch_Uniform2f(Batch* batch, const char* name, float x, float y)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
- }
-
-void Batch_Uniform3f(Batch* batch, const char* name, float x, float y, float z)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3f(loc, x, y, z);
- }
-
-void Batch_Uniform4f(Batch* batch, const char* name, float x, float y, float z, float w)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
- }
-
-void Batch_Uniform1f(Batch* batch, const char* name, float x)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1f(loc, x);
- }
-
-void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
- }
-
-void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
- {
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
- }
-
-static void Batch_prime(Batch* batch)
- {
- batch->vao_id = vao_id_alloc();
- glBindVertexArray(batch->vao_id);
-
- for (int v = 0; v < BATCH_MAX_VBO_CT; ++v)
- {
- if (batch->verts[v] == NULL)
- break;
- VertexBuffer_use(batch->verts[v]);
- }
-
- if (batch->elem)
- ElementList_use(batch->elem);
-
- // vertex attribs and element list remain bound to this VAO
- }
-
-void Batch_draw(Batch* batch)
- {
-#if TRUST_NO_ONE
- assert(batch->phase == READY_TO_DRAW);
- assert(glIsProgram(batch->program));
-#endif
-
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- Batch_use_program(batch);
-
- gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
-#if TRACK_INDEX_RANGE
- if (el->base_index)
- glDrawRangeElementsBaseVertex(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0, el->base_index);
- else
- glDrawRangeElements(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0);
-#else
- glDrawElements(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
-#endif
- }
- else
- glDrawArrays(batch->prim_type, 0, batch->verts[0]->vertex_ct);
-
- Batch_done_using_program(batch);
- glBindVertexArray(0);
- }
-
-
-
-// clement : temp stuff
-void Batch_draw_stupid(Batch* batch)
-{
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- // Batch_use_program(batch);
-
- //gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
-#if TRACK_INDEX_RANGE
- if (el->base_index)
- glDrawRangeElementsBaseVertex(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0, el->base_index);
- else
- glDrawRangeElements(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0);
-#else
- glDrawElements(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
-#endif
- }
- else
- glDrawArrays(batch->prim_type, 0, batch->verts[0]->vertex_ct);
-
- // Batch_done_using_program(batch);
- glBindVertexArray(0);
-}
-
-// clement : temp stuff
-void Batch_draw_stupid_instanced(Batch* batch, unsigned int instance_vbo, int instance_count,
- int attrib_nbr, int attrib_stride, int attrib_size[16], int attrib_loc[16])
-{
- if (batch->vao_id)
- glBindVertexArray(batch->vao_id);
- else
- Batch_prime(batch);
-
- if (batch->program_dirty)
- Batch_update_program_bindings(batch);
-
- glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
- int ptr_ofs = 0;
- for (int i = 0; i < attrib_nbr; ++i) {
- int size = attrib_size[i];
- int loc = attrib_loc[i];
- int atr_ofs = 0;
-
- while (size > 0) {
- glEnableVertexAttribArray(loc + atr_ofs);
- glVertexAttribPointer(loc + atr_ofs, (size > 4) ? 4 : size, GL_FLOAT, GL_FALSE,
- sizeof(float) * attrib_stride, (GLvoid*)(sizeof(float) * ptr_ofs));
- glVertexAttribDivisor(loc + atr_ofs, 1);
- atr_ofs++;
- ptr_ofs += (size > 4) ? 4 : size;
- size -= 4;
- }
- }
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- // Batch_use_program(batch);
-
- //gpuBindMatrices(batch->program);
-
- if (batch->elem)
- {
- const ElementList* el = batch->elem;
-
- glDrawElementsInstanced(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
- }
- else
- glDrawArraysInstanced(batch->prim_type, 0, batch->verts[0]->vertex_ct, instance_count);
-
- // Batch_done_using_program(batch);
- glBindVertexArray(0);
-}
-
diff --git a/source/blender/gpu/gawain/batch.h b/source/blender/gpu/gawain/batch.h
deleted file mode 100644
index 189a586f964..00000000000
--- a/source/blender/gpu/gawain/batch.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-// 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 "vertex_buffer.h"
-#include "element.h"
-
-typedef enum {
- READY_TO_FORMAT,
- READY_TO_BUILD,
- BUILDING,
- READY_TO_DRAW
-} BatchPhase;
-
-#define BATCH_MAX_VBO_CT 3
-
-typedef struct Batch {
- // geometry
- VertexBuffer* verts[BATCH_MAX_VBO_CT]; // verts[0] is required, others can be NULL
- ElementList* elem; // NULL if element list not needed
- PrimitiveType prim_type;
-
- // book-keeping
- GLuint vao_id; // remembers all geometry state (vertex attrib bindings & element buffer)
- BatchPhase phase;
- bool program_dirty;
- bool program_in_use;
-
- // state
- GLuint program;
-} Batch;
-
-Batch* Batch_create(PrimitiveType, VertexBuffer*, ElementList*);
-void Batch_init(Batch*, PrimitiveType, VertexBuffer*, ElementList*);
-
-void Batch_discard(Batch*); // verts & elem are not discarded
-void Batch_discard_all(Batch*); // including verts & elem
-
-int Batch_add_VertexBuffer(Batch*, VertexBuffer*);
-
-void Batch_set_program(Batch*, GLuint program);
-// 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 Batch_use_program(Batch*); // call before Batch_Uniform (temp hack?)
-void Batch_done_using_program(Batch*);
-
-void Batch_Uniform1i(Batch*, const char* name, int value);
-void Batch_Uniform1b(Batch*, const char* name, bool value);
-void Batch_Uniform1f(Batch*, const char* name, float value);
-void Batch_Uniform2f(Batch*, const char* name, float x, float y);
-void Batch_Uniform3f(Batch*, const char* name, float x, float y, float z);
-void Batch_Uniform4f(Batch*, const char* name, float x, float y, float z, float w);
-void Batch_Uniform3fv(Batch*, const char* name, const float data[3]);
-void Batch_Uniform4fv(Batch*, const char* name, const float data[4]);
-
-void Batch_draw(Batch*);
-
-
-// clement : temp stuff
-void Batch_draw_stupid(Batch*);
-void Batch_draw_stupid_instanced(Batch*, unsigned int instance_vbo, int instance_count,
- int attrib_nbr, int attrib_stride, int attrib_loc[16], int attrib_size[16]);
-
-
-
-
-
-
-#if 0 // future plans
-
-// Can multiple batches share a VertexBuffer? 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 {
- Batch batch;
- VertexBuffer verts; // link batch.verts to this
-} BatchWithOwnVertexBuffer;
-
-typedef struct {
- Batch batch;
- ElementList elem; // link batch.elem to this
-} BatchWithOwnElementList;
-
-typedef struct {
- Batch batch;
- ElementList elem; // link batch.elem to this
- VertexBuffer verts; // link batch.verts to this
-} BatchWithOwnVertexBufferAndElementList;
-
-Batch* create_BatchWithOwnVertexBuffer(PrimitiveType, VertexFormat*, unsigned v_ct, ElementList*);
-Batch* create_BatchWithOwnElementList(PrimitiveType, VertexBuffer*, unsigned prim_ct);
-Batch* create_BatchWithOwnVertexBufferAndElementList(PrimitiveType, VertexFormat*, unsigned v_ct, unsigned prim_ct);
-// verts: shared, own
-// elem: none, shared, own
-Batch* create_BatchInGeneral(PrimitiveType, VertexBufferStuff, ElementListStuff);
-
-#endif // future plans
diff --git a/source/blender/gpu/gawain/buffer_id.cpp b/source/blender/gpu/gawain/buffer_id.cpp
deleted file mode 100644
index 450656c4ebf..00000000000
--- a/source/blender/gpu/gawain/buffer_id.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-
-// 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/.#include "buffer_id.h"
-
-#include "buffer_id.h"
-#include <mutex>
-#include <vector>
-
-#define ORPHAN_DEBUG 0
-
-#if ORPHAN_DEBUG
- #include <cstdio>
-#endif
-
-static std::vector<GLuint> orphaned_buffer_ids;
-static std::vector<GLuint> orphaned_vao_ids;
-
-static std::mutex orphan_mutex;
-
-extern "C" {
-extern int BLI_thread_is_main(void); // Blender-specific function
-}
-
-static bool thread_is_main()
- {
- // "main" here means the GL context's thread
- return BLI_thread_is_main();
- }
-
-GLuint buffer_id_alloc()
- {
-#if TRUST_NO_ONE
- assert(thread_is_main());
-#endif
-
- // delete orphaned IDs
- orphan_mutex.lock();
- if (!orphaned_buffer_ids.empty())
- {
- const auto orphaned_buffer_ct = (unsigned)orphaned_buffer_ids.size();
-#if ORPHAN_DEBUG
- printf("deleting %u orphaned VBO%s\n", orphaned_buffer_ct, orphaned_buffer_ct == 1 ? "" : "s");
-#endif
- glDeleteBuffers(orphaned_buffer_ct, orphaned_buffer_ids.data());
- orphaned_buffer_ids.clear();
- }
- orphan_mutex.unlock();
-
- GLuint new_buffer_id = 0;
- glGenBuffers(1, &new_buffer_id);
- return new_buffer_id;
- }
-
-void buffer_id_free(GLuint buffer_id)
- {
- if (thread_is_main())
- glDeleteBuffers(1, &buffer_id);
- else
- {
- // add this ID to the orphaned list
- orphan_mutex.lock();
-#if ORPHAN_DEBUG
- printf("orphaning VBO %u\n", buffer_id);
-#endif
- orphaned_buffer_ids.emplace_back(buffer_id);
- orphan_mutex.unlock();
- }
- }
-
-GLuint vao_id_alloc()
- {
-#if TRUST_NO_ONE
- assert(thread_is_main());
-#endif
-
- // delete orphaned IDs
- orphan_mutex.lock();
- if (!orphaned_vao_ids.empty())
- {
- const auto orphaned_vao_ct = (unsigned)orphaned_vao_ids.size();
-#if ORPHAN_DEBUG
- printf("deleting %u orphaned VAO%s\n", orphaned_vao_ct, orphaned_vao_ct == 1 ? "" : "s");
-#endif
- glDeleteVertexArrays(orphaned_vao_ct, orphaned_vao_ids.data());
- orphaned_vao_ids.clear();
- }
- orphan_mutex.unlock();
-
- GLuint new_vao_id = 0;
- glGenVertexArrays(1, &new_vao_id);
- return new_vao_id;
- }
-
-void vao_id_free(GLuint vao_id)
- {
- if (thread_is_main())
- glDeleteVertexArrays(1, &vao_id);
- else
- {
- // add this ID to the orphaned list
- orphan_mutex.lock();
-#if ORPHAN_DEBUG
- printf("orphaning VAO %u\n", vao_id);
-#endif
- orphaned_vao_ids.emplace_back(vao_id);
- orphan_mutex.unlock();
- }
- }
diff --git a/source/blender/gpu/gawain/buffer_id.h b/source/blender/gpu/gawain/buffer_id.h
deleted file mode 100644
index 3f67458d060..00000000000
--- a/source/blender/gpu/gawain/buffer_id.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-// 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 "common.h"
-
-GLuint buffer_id_alloc(void);
-void buffer_id_free(GLuint buffer_id);
-
-GLuint vao_id_alloc(void);
-void vao_id_free(GLuint vao_id);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/gawain/common.h b/source/blender/gpu/gawain/common.h
deleted file mode 100644
index a4c1e6cba6e..00000000000
--- a/source/blender/gpu/gawain/common.h
+++ /dev/null
@@ -1,40 +0,0 @@
-
-// 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 TRUST_NO_ONE !defined(NDEBUG)
-// strict error checking, enabled for debug builds during early development
-
-#include <GL/glew.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#if TRUST_NO_ONE
- #include <assert.h>
-#endif
-
-#define PER_THREAD
-// #define PER_THREAD __thread
-// MSVC uses __declspec(thread) for C code
-
-#define APPLE_LEGACY (defined(__APPLE__) && defined(WITH_GL_PROFILE_COMPAT))
-
-#if APPLE_LEGACY
- #undef glGenVertexArrays
- #define glGenVertexArrays glGenVertexArraysAPPLE
-
- #undef glDeleteVertexArrays
- #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
-
- #undef glBindVertexArray
- #define glBindVertexArray glBindVertexArrayAPPLE
-#endif
diff --git a/source/blender/gpu/gawain/element.c b/source/blender/gpu/gawain/element.c
deleted file mode 100644
index 3c3ca1c7626..00000000000
--- a/source/blender/gpu/gawain/element.c
+++ /dev/null
@@ -1,283 +0,0 @@
-
-// 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/.
-
-#include "element.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-
-#define KEEP_SINGLE_COPY 1
-
-unsigned ElementList_size(const ElementList* elem)
- {
-#if TRACK_INDEX_RANGE
- switch (elem->index_type)
- {
- case INDEX_U8: return elem->index_ct * sizeof(GLubyte);
- case INDEX_U16: return elem->index_ct * sizeof(GLushort);
- case INDEX_U32: return elem->index_ct * sizeof(GLuint);
- default:
- #if TRUST_NO_ONE
- assert(false);
- #endif
- return 0;
- }
-
-#else
- return elem->index_ct * sizeof(GLuint);
-#endif
- }
-
-static void ElementList_prime(ElementList* elem)
- {
- elem->vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
- // fill with delicious data & send to GPU the first time only
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementList_size(elem), elem->data, GL_STATIC_DRAW);
-
-#if KEEP_SINGLE_COPY
- // now that GL has a copy, discard original
- free(elem->data);
- elem->data = NULL;
-#endif
- }
-
-void ElementList_use(ElementList* elem)
- {
- if (elem->vbo_id)
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
- else
- ElementList_prime(elem);
- }
-
-void ElementListBuilder_init(ElementListBuilder* builder, PrimitiveType prim_type, unsigned prim_ct, unsigned vertex_ct)
- {
- unsigned verts_per_prim = 0;
- switch (prim_type)
- {
- case PRIM_POINTS:
- verts_per_prim = 1;
- break;
- case PRIM_LINES:
- verts_per_prim = 2;
- break;
- case PRIM_TRIANGLES:
- verts_per_prim = 3;
- break;
- default:
-#if TRUST_NO_ONE
- assert(false);
-#endif
- return;
- }
-
- builder->max_allowed_index = vertex_ct - 1;
- builder->max_index_ct = prim_ct * verts_per_prim;
- builder->index_ct = 0; // start empty
- builder->prim_type = prim_type;
- builder->data = calloc(builder->max_index_ct, sizeof(unsigned));
- }
-
-void add_generic_vertex(ElementListBuilder* builder, unsigned v)
- {
-#if TRUST_NO_ONE
- assert(builder->data != NULL);
- assert(builder->index_ct < builder->max_index_ct);
- assert(v <= builder->max_allowed_index);
-#endif
-
- builder->data[builder->index_ct++] = v;
- }
-
-void add_point_vertex(ElementListBuilder* builder, unsigned v)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_POINTS);
-#endif
-
- add_generic_vertex(builder, v);
- }
-
-void add_line_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_LINES);
- assert(v1 != v2);
-#endif
-
- add_generic_vertex(builder, v1);
- add_generic_vertex(builder, v2);
- }
-
-void add_triangle_vertices(ElementListBuilder* builder, unsigned v1, unsigned v2, unsigned v3)
- {
-#if TRUST_NO_ONE
- assert(builder->prim_type == PRIM_TRIANGLES);
- assert(v1 != v2 && v2 != v3 && v3 != v1);
-#endif
-
- add_generic_vertex(builder, v1);
- add_generic_vertex(builder, v2);
- add_generic_vertex(builder, v3);
- }
-
-#if TRACK_INDEX_RANGE
-// Everything remains 32 bit while building to keep things simple.
-// Find min/max after, then convert to smallest index type possible.
-
-static unsigned index_range(const unsigned values[], unsigned value_ct, unsigned* min_out, unsigned* max_out)
- {
- unsigned min_value = values[0];
- unsigned max_value = values[0];
- for (unsigned i = 1; i < value_ct; ++i)
- {
- const unsigned value = values[i];
- if (value < min_value)
- min_value = value;
- else if (value > max_value)
- max_value = value;
- }
- *min_out = min_value;
- *max_out = max_value;
- return max_value - min_value;
- }
-
-static void squeeze_indices_byte(const unsigned values[], ElementList* elem)
- {
- const unsigned index_ct = elem->index_ct;
- GLubyte* data = malloc(index_ct * sizeof(GLubyte));
-
- if (elem->max_index > 0xFF)
- {
- const unsigned base = elem->min_index;
-
- elem->base_index = base;
- elem->min_index = 0;
- elem->max_index -= base;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLubyte)(values[i] - base);
- }
- else
- {
- elem->base_index = 0;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLubyte)(values[i]);
- }
-
- elem->data = data;
- }
-
-static void squeeze_indices_short(const unsigned values[], ElementList* elem)
- {
- const unsigned index_ct = elem->index_ct;
- GLushort* data = malloc(index_ct * sizeof(GLushort));
-
- if (elem->max_index > 0xFFFF)
- {
- const unsigned base = elem->min_index;
-
- elem->base_index = base;
- elem->min_index = 0;
- elem->max_index -= base;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLushort)(values[i] - base);
- }
- else
- {
- elem->base_index = 0;
-
- for (unsigned i = 0; i < index_ct; ++i)
- data[i] = (GLushort)(values[i]);
- }
-
- elem->data = data;
- }
-
-#endif // TRACK_INDEX_RANGE
-
-ElementList* ElementList_build(ElementListBuilder* builder)
- {
- ElementList* elem = calloc(1, sizeof(ElementList));
- ElementList_build_in_place(builder, elem);
- return elem;
- }
-
-void ElementList_build_in_place(ElementListBuilder* builder, ElementList* elem)
- {
-#if TRUST_NO_ONE
- assert(builder->data != NULL);
-#endif
-
- elem->index_ct = builder->index_ct;
-
-#if TRACK_INDEX_RANGE
- const unsigned range = index_range(builder->data, builder->index_ct, &elem->min_index, &elem->max_index);
-
- if (range <= 0xFF)
- {
- elem->index_type = INDEX_U8;
- squeeze_indices_byte(builder->data, elem);
- }
- else if (range <= 0xFFFF)
- {
- elem->index_type = INDEX_U16;
- squeeze_indices_short(builder->data, elem);
- }
- else
- {
- elem->index_type = INDEX_U32;
- elem->base_index = 0;
-
- if (builder->index_ct < builder->max_index_ct)
- {
- builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
- // TODO: realloc only if index_ct is much smaller than max_index_ct
- }
-
- elem->data = builder->data;
- }
-#else
- if (builder->index_ct < builder->max_index_ct)
- {
- builder->data = realloc(builder->data, builder->index_ct * sizeof(unsigned));
- // TODO: realloc only if index_ct is much smaller than max_index_ct
- }
-
- elem->data = builder->data;
-#endif
-
- // elem->data will never be *larger* than builder->data... how about converting
- // in place to avoid extra allocation?
-
- elem->vbo_id = 0;
- // TODO: create GL buffer object directly, based on an input flag
-
- // discard builder (one-time use)
- if (builder->data != elem->data)
- free(builder->data);
- builder->data = NULL;
- // other fields are safe to leave
- }
-
-void ElementList_discard(ElementList* elem)
- {
- if (elem->vbo_id)
- buffer_id_free(elem->vbo_id);
-#if KEEP_SINGLE_COPY
- else
-#endif
- if (elem->data)
- free(elem->data);
-
- free(elem);
- }
diff --git a/source/blender/gpu/gawain/element.h b/source/blender/gpu/gawain/element.h
deleted file mode 100644
index f22d7c0ffda..00000000000
--- a/source/blender/gpu/gawain/element.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-// 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 "primitive.h"
-
-#define TRACK_INDEX_RANGE 1
-
-typedef enum {
- INDEX_U8 = GL_UNSIGNED_BYTE, // GL has this, Vulkan does not
- INDEX_U16 = GL_UNSIGNED_SHORT,
- INDEX_U32 = GL_UNSIGNED_INT
-} IndexType;
-
-typedef struct {
- unsigned index_ct;
-#if TRACK_INDEX_RANGE
- IndexType index_type;
- unsigned min_index;
- unsigned max_index;
- unsigned base_index;
-#endif
- void* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
- GLuint vbo_id; // 0 indicates not yet sent to VRAM
-} ElementList;
-
-void ElementList_use(ElementList*);
-unsigned ElementList_size(const ElementList*);
-
-typedef struct {
- unsigned max_allowed_index;
- unsigned max_index_ct;
- unsigned index_ct;
- PrimitiveType prim_type;
- unsigned* data;
-} ElementListBuilder;
-
-// supported primitives:
-// PRIM_POINTS
-// PRIM_LINES
-// PRIM_TRIANGLES
-
-void ElementListBuilder_init(ElementListBuilder*, PrimitiveType, unsigned prim_ct, unsigned vertex_ct);
-//void ElementListBuilder_init_custom(ElementListBuilder*, PrimitiveType, unsigned index_ct, unsigned vertex_ct);
-
-void add_generic_vertex(ElementListBuilder*, unsigned v);
-
-void add_point_vertex(ElementListBuilder*, unsigned v);
-void add_line_vertices(ElementListBuilder*, unsigned v1, unsigned v2);
-void add_triangle_vertices(ElementListBuilder*, unsigned v1, unsigned v2, unsigned v3);
-
-ElementList* ElementList_build(ElementListBuilder*);
-void ElementList_build_in_place(ElementListBuilder*, ElementList*);
-
-void ElementList_discard(ElementList*);
diff --git a/source/blender/gpu/gawain/imm_util.c b/source/blender/gpu/gawain/imm_util.c
deleted file mode 100644
index 74caeb6fd3a..00000000000
--- a/source/blender/gpu/gawain/imm_util.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-// 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/.
-
-#include "imm_util.h"
-#include "immediate.h"
-
-
-void immRectf(unsigned pos, float x1, float y1, float x2, float y2)
-{
- immBegin(PRIM_TRIANGLE_FAN, 4);
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y1);
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x1, y2);
- immEnd();
-}
-
-void immRecti(unsigned pos, int x1, int y1, int x2, int y2)
-{
- immBegin(PRIM_TRIANGLE_FAN, 4);
- immVertex2i(pos, x1, y1);
- immVertex2i(pos, x2, y1);
- immVertex2i(pos, x2, y2);
- immVertex2i(pos, x1, y2);
- immEnd();
-}
-
-#if 0 // more complete version in case we want that
-void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4])
-{
- VertexFormat *format = immVertexFormat();
- unsigned pos = add_attrib(format, "pos", COMP_I32, 2, CONVERT_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(color);
- immRecti(pos, x1, y1, x2, y2);
- immUnbindProgram();
-}
-#endif
diff --git a/source/blender/gpu/gawain/imm_util.h b/source/blender/gpu/gawain/imm_util.h
deleted file mode 100644
index 730bd7c1a3c..00000000000
--- a/source/blender/gpu/gawain/imm_util.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-// 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);
diff --git a/source/blender/gpu/gawain/immediate.c b/source/blender/gpu/gawain/immediate.c
deleted file mode 100644
index f52e9271fe5..00000000000
--- a/source/blender/gpu/gawain/immediate.c
+++ /dev/null
@@ -1,880 +0,0 @@
-
-// 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/.
-
-#include "immediate.h"
-#include "attrib_binding.h"
-#include "buffer_id.h"
-#include <string.h>
-
-// necessary functions from matrix API
-extern void gpuBindMatrices(GLuint program);
-extern bool gpuMatricesDirty(void);
-
-typedef struct {
- // TODO: organize this struct by frequency of change (run-time)
-
-#if IMM_BATCH_COMBO
- Batch* batch;
-#endif
-
- // current draw call
- GLubyte* buffer_data;
- unsigned buffer_offset;
- unsigned buffer_bytes_mapped;
- unsigned vertex_ct;
- bool strict_vertex_ct;
- PrimitiveType prim_type;
-
- VertexFormat vertex_format;
-
- // current vertex
- unsigned vertex_idx;
- GLubyte* vertex_data;
- uint16_t unassigned_attrib_bits; // which attributes of current vertex have not been given values?
-
- GLuint vbo_id;
- GLuint vao_id;
-
- GLuint bound_program;
- AttribBinding attrib_binding;
- uint16_t prev_enabled_attrib_bits; // <-- only affects this VAO, so we're ok
-} Immediate;
-
-// size of internal buffer -- make this adjustable?
-#define IMM_BUFFER_SIZE (4 * 1024 * 1024)
-
-static PER_THREAD bool initialized = false;
-static PER_THREAD Immediate imm;
-
-void immInit(void)
- {
-#if TRUST_NO_ONE
- assert(!initialized);
-#endif
-
- memset(&imm, 0, sizeof(Immediate));
-
- imm.vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
- glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
-
-#if APPLE_LEGACY
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
-#endif
-
- imm.prim_type = PRIM_NONE;
- imm.strict_vertex_ct = true;
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- initialized = true;
-
- immActivate();
- }
-
-void immActivate(void)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
- assert(imm.vao_id == 0);
-#endif
-
- imm.vao_id = vao_id_alloc();
- }
-
-void immDeactivate(void)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we're not between a Begin/End pair
- assert(imm.vao_id != 0);
-#endif
-
- vao_id_free(imm.vao_id);
- imm.vao_id = 0;
- imm.prev_enabled_attrib_bits = 0;
- }
-
-void immDestroy(void)
- {
- immDeactivate();
- buffer_id_free(imm.vbo_id);
- initialized = false;
- }
-
-VertexFormat* immVertexFormat(void)
- {
- VertexFormat_clear(&imm.vertex_format);
- return &imm.vertex_format;
- }
-
-void immBindProgram(GLuint program)
- {
-#if TRUST_NO_ONE
- assert(imm.bound_program == 0);
- assert(glIsProgram(program));
-#endif
-
- if (!imm.vertex_format.packed)
- VertexFormat_pack(&imm.vertex_format);
-
- glUseProgram(program);
- get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program);
- imm.bound_program = program;
-
- gpuBindMatrices(program);
- }
-
-void immUnbindProgram(void)
- {
-#if TRUST_NO_ONE
- assert(imm.bound_program != 0);
-#endif
-
- glUseProgram(0);
- imm.bound_program = 0;
- }
-
-static bool vertex_count_makes_sense_for_primitive(unsigned vertex_ct, PrimitiveType prim_type)
- {
- // does vertex_ct make sense for this primitive type?
- if (vertex_ct == 0)
- return false;
-
- switch (prim_type)
- {
- case PRIM_POINTS:
- return true;
- case PRIM_LINES:
- return vertex_ct % 2 == 0;
- case PRIM_LINE_STRIP:
- case PRIM_LINE_LOOP:
- return vertex_ct >= 2;
- case PRIM_TRIANGLES:
- return vertex_ct % 3 == 0;
- case PRIM_TRIANGLE_STRIP:
- case PRIM_TRIANGLE_FAN:
- return vertex_ct >= 3;
- #ifdef WITH_GL_PROFILE_COMPAT
- case PRIM_QUADS:
- return vertex_ct % 4 == 0;
- #endif
- default:
- return false;
- }
- }
-
-void immBegin(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
- assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
-#endif
-
- imm.prim_type = prim_type;
- imm.vertex_ct = vertex_ct;
- imm.vertex_idx = 0;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
-
- // how many bytes do we need for this draw call?
- const unsigned bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_ct);
-
-#if TRUST_NO_ONE
- assert(bytes_needed <= IMM_BUFFER_SIZE);
-#endif
-
- glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id);
-
- // does the current buffer have enough room?
- const unsigned available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset;
- // ensure vertex data is aligned
- const unsigned pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); // might waste a little space, but it's safe
- if ((bytes_needed + pre_padding) <= available_bytes)
- imm.buffer_offset += pre_padding;
- else
- {
- // orphan this buffer & start with a fresh one
-#if APPLE_LEGACY
- glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
-#else
- if (GLEW_VERSION_4_3 || GLEW_ARB_invalidate_subdata)
- glInvalidateBufferData(imm.vbo_id);
- else
- glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, GL_MAP_INVALIDATE_BUFFER_BIT);
-#endif
-
- imm.buffer_offset = 0;
- }
-
-// printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1);
-
-#if APPLE_LEGACY
- imm.buffer_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY) + imm.buffer_offset;
-#else
- imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed,
- GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_ct ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT));
-#endif
-
-#if TRUST_NO_ONE
- assert(imm.buffer_data != NULL);
-#endif
-
- imm.buffer_bytes_mapped = bytes_needed;
- imm.vertex_data = imm.buffer_data;
- }
-
-void immBeginAtMost(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(vertex_ct > 0);
-#endif
-
- imm.strict_vertex_ct = false;
- immBegin(prim_type, vertex_ct);
- }
-
-#if IMM_BATCH_COMBO
-
-Batch* immBeginBatch(PrimitiveType prim_type, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.prim_type == PRIM_NONE); // make sure we haven't already begun
- assert(vertex_count_makes_sense_for_primitive(vertex_ct, prim_type));
-#endif
-
- imm.prim_type = prim_type;
- imm.vertex_ct = vertex_ct;
- imm.vertex_idx = 0;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
-
- VertexBuffer* verts = VertexBuffer_create_with_format(&imm.vertex_format);
- VertexBuffer_allocate_data(verts, vertex_ct);
-
- imm.buffer_bytes_mapped = VertexBuffer_size(verts);
- imm.vertex_data = verts->data;
-
- imm.batch = Batch_create(prim_type, verts, NULL);
- imm.batch->phase = BUILDING;
-
- Batch_set_program(imm.batch, imm.bound_program);
-
- return imm.batch;
- }
-
-Batch* immBeginBatchAtMost(PrimitiveType prim_type, unsigned vertex_ct)
- {
- imm.strict_vertex_ct = false;
- return immBeginBatch(prim_type, vertex_ct);
- }
-
-#endif // IMM_BATCH_COMBO
-
-static void immDrawSetup(void)
- {
- // set up VAO -- can be done during Begin or End really
- glBindVertexArray(imm.vao_id);
-
- // enable/disable vertex attribs as needed
- if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits)
- {
- for (unsigned loc = 0; loc < MAX_VERTEX_ATTRIBS; ++loc)
- {
- bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc);
- bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc);
-
- if (is_enabled && !was_enabled)
- {
-// printf("enabling attrib %u\n", loc);
- glEnableVertexAttribArray(loc);
- }
- else if (was_enabled && !is_enabled)
- {
-// printf("disabling attrib %u\n", loc);
- glDisableVertexAttribArray(loc);
- }
- }
-
- imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits;
- }
-
- const unsigned stride = imm.vertex_format.stride;
-
- for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
- {
- const Attrib* a = imm.vertex_format.attribs + a_idx;
-
- const unsigned offset = imm.buffer_offset + a->offset;
- const GLvoid* pointer = (const GLubyte*)0 + offset;
-
- const unsigned loc = read_attrib_location(&imm.attrib_binding, a_idx);
-
-// printf("specifying attrib %u '%s' with offset %u, stride %u\n", loc, a->name, offset, stride);
-
- switch (a->fetch_mode)
- {
- case KEEP_FLOAT:
- case CONVERT_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_FALSE, stride, pointer);
- break;
- case NORMALIZE_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_TRUE, stride, pointer);
- break;
- case KEEP_INT:
- glVertexAttribIPointer(loc, a->comp_ct, a->comp_type, stride, pointer);
- }
- }
-
- if (gpuMatricesDirty())
- gpuBindMatrices(imm.bound_program);
- }
-
-void immEnd(void)
- {
-#if TRUST_NO_ONE
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- unsigned buffer_bytes_used;
- if (imm.strict_vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx == imm.vertex_ct); // with all vertices defined
-#endif
- buffer_bytes_used = imm.buffer_bytes_mapped;
- }
- else
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx <= imm.vertex_ct);
-#endif
- // printf("used %u of %u verts,", imm.vertex_idx, imm.vertex_ct);
- if (imm.vertex_idx == imm.vertex_ct)
- {
- buffer_bytes_used = imm.buffer_bytes_mapped;
- }
- else
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type));
-#endif
- imm.vertex_ct = imm.vertex_idx;
- buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_ct);
- // unused buffer bytes are available to the next immBegin
- // printf(" %u of %u bytes\n", buffer_bytes_used, imm.buffer_bytes_mapped);
- }
-#if !APPLE_LEGACY
- // tell OpenGL what range was modified so it doesn't copy the whole mapped range
- // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
- glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used);
-#endif
- }
-
-#if IMM_BATCH_COMBO
- if (imm.batch)
- {
- if (buffer_bytes_used != imm.buffer_bytes_mapped)
- {
- VertexBuffer_resize_data(imm.batch->verts[0], imm.vertex_ct);
- // TODO: resize only if vertex count is much smaller
- }
-
- imm.batch->phase = READY_TO_DRAW;
- imm.batch = NULL; // don't free, batch belongs to caller
- }
- else
-#endif
- {
-#if APPLE_LEGACY
- // tell OpenGL what range was modified so it doesn't copy the whole buffer
- // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
- glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, imm.buffer_offset, buffer_bytes_used);
-#endif
- glUnmapBuffer(GL_ARRAY_BUFFER);
-
- if (imm.vertex_ct > 0)
- {
- immDrawSetup();
- glDrawArrays(imm.prim_type, 0, imm.vertex_ct);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- // prep for next immBegin
- imm.buffer_offset += buffer_bytes_used;
- }
-
- // prep for next immBegin
- imm.prim_type = PRIM_NONE;
- imm.strict_vertex_ct = true;
- }
-
-static void setAttribValueBit(unsigned attrib_id)
- {
- uint16_t mask = 1 << attrib_id;
-
-#if TRUST_NO_ONE
- assert(imm.unassigned_attrib_bits & mask); // not already set
-#endif
-
- imm.unassigned_attrib_bits &= ~mask;
- }
-
-
-// --- generic attribute functions ---
-
-void immAttrib1f(unsigned attrib_id, float x)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 1);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- }
-
-void immAttrib2f(unsigned attrib_id, float x, float y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib3f(unsigned attrib_id, float x, float y, float z)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 3);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- data[2] = z;
- }
-
-void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_F32);
- assert(attrib->comp_ct == 4);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- float* data = (float*)(imm.vertex_data + attrib->offset);
-// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data);
-
- data[0] = x;
- data[1] = y;
- data[2] = z;
- data[3] = w;
- }
-
-void immAttrib2i(unsigned attrib_id, int x, int y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_I32);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- int* data = (int*)(imm.vertex_data + attrib->offset);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib2s(unsigned attrib_id, short x, short y)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_I16);
- assert(attrib->comp_ct == 2);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- short* data = (short*)(imm.vertex_data + attrib->offset);
-
- data[0] = x;
- data[1] = y;
- }
-
-void immAttrib3fv(unsigned attrib_id, const float data[3])
- {
- immAttrib3f(attrib_id, data[0], data[1], data[2]);
- }
-
-void immAttrib4fv(unsigned attrib_id, const float data[4])
- {
- immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]);
- }
-
-void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_U8);
- assert(attrib->comp_ct == 3);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- GLubyte* data = imm.vertex_data + attrib->offset;
-// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
-
- data[0] = r;
- data[1] = g;
- data[2] = b;
- }
-
-void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
- {
- Attrib* attrib = imm.vertex_format.attribs + attrib_id;
-
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(attrib->comp_type == COMP_U8);
- assert(attrib->comp_ct == 4);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
-
- GLubyte* data = imm.vertex_data + attrib->offset;
-// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data);
-
- data[0] = r;
- data[1] = g;
- data[2] = b;
- data[3] = a;
- }
-
-void immAttrib3ubv(unsigned attrib_id, const unsigned char data[3])
- {
- immAttrib3ub(attrib_id, data[0], data[1], data[2]);
- }
-
-void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4])
- {
- immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]);
- }
-
-void immSkipAttrib(unsigned attrib_id)
- {
-#if TRUST_NO_ONE
- assert(attrib_id < imm.vertex_format.attrib_ct);
- assert(imm.vertex_idx < imm.vertex_ct);
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
-#endif
-
- setAttribValueBit(attrib_id);
- }
-
-static void immEndVertex(void) // and move on to the next vertex
- {
-#if TRUST_NO_ONE
- assert(imm.prim_type != PRIM_NONE); // make sure we're between a Begin/End pair
- assert(imm.vertex_idx < imm.vertex_ct);
-#endif
-
- // have all attribs been assigned values?
- // if not, copy value from previous vertex
- if (imm.unassigned_attrib_bits)
- {
-#if TRUST_NO_ONE
- assert(imm.vertex_idx > 0); // first vertex must have all attribs specified
-#endif
-
- for (unsigned a_idx = 0; a_idx < imm.vertex_format.attrib_ct; ++a_idx)
- {
- if ((imm.unassigned_attrib_bits >> a_idx) & 1)
- {
- const Attrib* a = imm.vertex_format.attribs + a_idx;
-
-// printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx);
-
- GLubyte* data = imm.vertex_data + a->offset;
- memcpy(data, data - imm.vertex_format.stride, a->sz);
- // TODO: consolidate copy of adjacent attributes
- }
- }
- }
-
- imm.vertex_idx++;
- imm.vertex_data += imm.vertex_format.stride;
- imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits;
- }
-
-void immVertex2f(unsigned attrib_id, float x, float y)
- {
- immAttrib2f(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex3f(unsigned attrib_id, float x, float y, float z)
- {
- immAttrib3f(attrib_id, x, y, z);
- immEndVertex();
- }
-
-void immVertex2i(unsigned attrib_id, int x, int y)
- {
- immAttrib2i(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex2s(unsigned attrib_id, short x, short y)
- {
- immAttrib2s(attrib_id, x, y);
- immEndVertex();
- }
-
-void immVertex2fv(unsigned attrib_id, const float data[2])
- {
- immAttrib2f(attrib_id, data[0], data[1]);
- immEndVertex();
- }
-
-void immVertex3fv(unsigned attrib_id, const float data[3])
- {
- immAttrib3f(attrib_id, data[0], data[1], data[2]);
- immEndVertex();
- }
-
-void immVertex2iv(unsigned attrib_id, const int data[2])
- {
- immAttrib2i(attrib_id, data[0], data[1]);
- immEndVertex();
- }
-
-
-// --- generic uniform functions ---
-
-void immUniform1f(const char* name, float x)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1f(loc, x);
- }
-
-void immUniform2f(const char* name, float x, float y)
-{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
-}
-
-void immUniform2fv(const char* name, const float data[2])
-{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2fv(loc, 1, data);
-}
-
-void immUniform3f(const char* name, float x, float y, float z)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3f(loc, x, y, z);
- }
-
-void immUniform3fv(const char* name, const float data[3])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
- }
-
-void immUniformArray3fv(const char* name, const float *data, int count)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
- assert(count > 0);
-#endif
-
- glUniform3fv(loc, count, data);
- }
-
-void immUniform4f(const char* name, float x, float y, float z, float w)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
- }
-
-void immUniform4fv(const char* name, const float data[4])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
- }
-
-void immUniformMatrix4fv(const char* name, const float data[4][4])
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniformMatrix4fv(loc, 1, GL_FALSE, (float *)data);
- }
-
-void immUniform1i(const char* name, int x)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, x);
- }
-
-
-// --- convenience functions for setting "uniform vec4 color" ---
-
-void immUniformColor4f(float r, float g, float b, float a)
- {
- immUniform4f("color", r, g, b, a);
- }
-
-void immUniformColor4fv(const float rgba[4])
- {
- immUniform4fv("color", rgba);
- }
-
-void immUniformColor3f(float r, float g, float b)
- {
- immUniform4f("color", r, g, b, 1.0f);
- }
-
-void immUniformColor3fv(const float rgb[3])
- {
- immUniform4f("color", rgb[0], rgb[1], rgb[2], 1.0f);
- }
-
-void immUniformColor3fvAlpha(const float rgb[3], float a)
- {
- immUniform4f("color", rgb[0], rgb[1], rgb[2], a);
- }
-
-// TODO: v-- treat as sRGB? --v
-
-void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
- {
- const float scale = 1.0f / 255.0f;
- immUniform4f("color", scale * r, scale * g, scale * b, 1.0f);
- }
-
-void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
- {
- const float scale = 1.0f / 255.0f;
- immUniform4f("color", scale * r, scale * g, scale * b, scale * a);
- }
-
-void immUniformColor3ubv(const unsigned char rgb[3])
- {
- immUniformColor3ub(rgb[0], rgb[1], rgb[2]);
- }
-
-void immUniformColor4ubv(const unsigned char rgba[4])
- {
- immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
diff --git a/source/blender/gpu/gawain/immediate.h b/source/blender/gpu/gawain/immediate.h
deleted file mode 100644
index 6a039542065..00000000000
--- a/source/blender/gpu/gawain/immediate.h
+++ /dev/null
@@ -1,112 +0,0 @@
-
-// 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 "vertex_format.h"
-#include "primitive.h"
-
-#define IMM_BATCH_COMBO 1
-
-
-VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
-
-void immBindProgram(GLuint program); // every immBegin must have a program bound first
-void immUnbindProgram(void); // call after your last immEnd, or before binding another program
-
-void immBegin(PrimitiveType, unsigned vertex_ct); // must supply exactly vertex_ct vertices
-void immBeginAtMost(PrimitiveType, unsigned max_vertex_ct); // can supply fewer vertices
-void immEnd(void); // finishes and draws
-
-#if IMM_BATCH_COMBO
-#include "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.
-Batch* immBeginBatch(PrimitiveType, unsigned vertex_ct);
-Batch* immBeginBatchAtMost(PrimitiveType, 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 immAttrib2s(unsigned attrib_id, short x, short y);
-
-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 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 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 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 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/source/blender/gpu/gawain/primitive.c b/source/blender/gpu/gawain/primitive.c
deleted file mode 100644
index 95472c289e8..00000000000
--- a/source/blender/gpu/gawain/primitive.c
+++ /dev/null
@@ -1,41 +0,0 @@
-
-// 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/.
-
-#include "primitive.h"
-
-PrimitiveClass prim_class_of_type(PrimitiveType prim_type)
- {
- static const PrimitiveClass classes[] =
- {
- [PRIM_NONE] = PRIM_CLASS_NONE,
- [PRIM_POINTS] = PRIM_CLASS_POINT,
- [PRIM_LINES] = PRIM_CLASS_LINE,
- [PRIM_LINE_STRIP] = PRIM_CLASS_LINE,
- [PRIM_LINE_LOOP] = PRIM_CLASS_LINE,
- [PRIM_TRIANGLES] = PRIM_CLASS_SURFACE,
- [PRIM_TRIANGLE_STRIP] = PRIM_CLASS_SURFACE,
- [PRIM_TRIANGLE_FAN] = PRIM_CLASS_SURFACE,
-
-#ifdef WITH_GL_PROFILE_COMPAT
- [PRIM_QUADS] = PRIM_CLASS_SURFACE,
-#endif
- };
-
- return classes[prim_type];
- }
-
-bool prim_type_belongs_to_class(PrimitiveType prim_type, PrimitiveClass prim_class)
- {
- if (prim_class == PRIM_CLASS_NONE && prim_type == PRIM_NONE)
- return true;
-
- return prim_class & prim_class_of_type(prim_type);
- }
diff --git a/source/blender/gpu/gawain/primitive.h b/source/blender/gpu/gawain/primitive.h
deleted file mode 100644
index d1b8f5b3ec7..00000000000
--- a/source/blender/gpu/gawain/primitive.h
+++ /dev/null
@@ -1,43 +0,0 @@
-
-// 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 "common.h"
-
-typedef enum {
- PRIM_POINTS = GL_POINTS,
- PRIM_LINES = GL_LINES,
- PRIM_TRIANGLES = GL_TRIANGLES,
-
-#ifdef WITH_GL_PROFILE_COMPAT
- PRIM_QUADS = GL_QUADS, // legacy GL has this, modern GL & Vulkan do not
-#endif
-
- PRIM_LINE_STRIP = GL_LINE_STRIP,
- PRIM_LINE_LOOP = GL_LINE_LOOP, // GL has this, Vulkan does not
- PRIM_TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
- PRIM_TRIANGLE_FAN = GL_TRIANGLE_FAN,
-
- PRIM_NONE = 0xF
-} PrimitiveType;
-
-// what types of primitives does each shader expect?
-typedef enum {
- PRIM_CLASS_NONE = 0,
- PRIM_CLASS_POINT = (1 << 0),
- PRIM_CLASS_LINE = (1 << 1),
- PRIM_CLASS_SURFACE = (1 << 2),
- PRIM_CLASS_ANY = PRIM_CLASS_POINT | PRIM_CLASS_LINE | PRIM_CLASS_SURFACE
-} PrimitiveClass;
-
-PrimitiveClass prim_class_of_type(PrimitiveType);
-bool prim_type_belongs_to_class(PrimitiveType, PrimitiveClass);
diff --git a/source/blender/gpu/gawain/shader_interface.c b/source/blender/gpu/gawain/shader_interface.c
deleted file mode 100644
index 93a1283d895..00000000000
--- a/source/blender/gpu/gawain/shader_interface.c
+++ /dev/null
@@ -1,140 +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>
-
-#define DEBUG_SHADER_INTERFACE 0
-
-#if DEBUG_SHADER_INTERFACE
- #include <stdio.h>
-#endif
-
-#if 0
-
-static const char* BuiltinUniform_name(BuiltinUniform u)
- {
- static const char* names[] =
- {
- [UNIFORM_NONE] = NULL,
-
- [UNIFORM_MODELVIEW_3D] = "ModelViewMatrix",
- [UNIFORM_PROJECTION_3D] = "ProjectionMatrix",
- [UNIFORM_MVP_3D] = "ModelViewProjectionMatrix",
- [UNIFORM_NORMAL_3D] = "NormalMatrix",
- [UNIFORM_INV_NORMAL_3D] = "InverseNormalMatrix",
-
- [UNIFORM_MODELVIEW_2D] = "ModelViewMatrix",
- [UNIFORM_PROJECTION_2D] = "ProjectionMatrix",
- [UNIFORM_MVP_2D] = "ModelViewProjectionMatrix",
-
- [UNIFORM_COLOR] = "color",
-
- [UNIFORM_CUSTOM] = NULL
- };
-
- return names[u];
- }
-
-#endif
-
-static bool setup_builtin_uniform(ShaderInput* input, const char* name)
- {
- // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
-
- // TODO: 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
- input->name = name;
- input->builtin_type = UNIFORM_CUSTOM;
- return false;
- }
-
-ShaderInterface* 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
- ShaderInterface* shaderface = calloc(1, offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput) + name_buffer_len);
-
- char* name_buffer = (char*)shaderface + offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput);
- uint32_t name_buffer_offset = 0;
-
- for (uint32_t i = 0; i < uniform_ct; ++i)
- {
- 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);
-
- if (setup_builtin_uniform(input, name))
- ; // reclaim space from name buffer (don't advance offset)
- else
- name_buffer_offset += name_len + 1; // include NULL terminator
-
- input->location = glGetUniformLocation(program, name);
-
-#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)
- {
- 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->name = name;
- name_buffer_offset += name_len + 1; // include NULL terminator
-
- input->location = glGetAttribLocation(program, name);
-
-#if DEBUG_SHADER_INTERFACE
- printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
-#endif
- }
-
- // TODO: realloc shaderface to shrink name buffer
- // each input->name will need adjustment (except static built-in names)
-
-#if DEBUG_SHADER_INTERFACE
- printf("using %u of %u bytes from name buffer\n", name_buffer_offset, name_buffer_len);
- printf("}\n"); // exit function
-#endif
-
- return shaderface;
- }
-
-void ShaderInterface_discard(ShaderInterface* shaderface)
- {
- // allocated as one chunk, so discard is simple
- free(shaderface);
- }
diff --git a/source/blender/gpu/gawain/shader_interface.h b/source/blender/gpu/gawain/shader_interface.h
deleted file mode 100644
index bdb0bbf4a8c..00000000000
--- a/source/blender/gpu/gawain/shader_interface.h
+++ /dev/null
@@ -1,49 +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 {
- UNIFORM_NONE, // uninitialized/unknown
-
- UNIFORM_MODELVIEW_3D, // mat4 ModelViewMatrix
- UNIFORM_PROJECTION_3D, // mat4 ProjectionMatrix
- UNIFORM_MVP_3D, // mat4 ModelViewProjectionMatrix
- UNIFORM_NORMAL_3D, // mat3 NormalMatrix
- UNIFORM_INV_NORMAL_3D, // mat3 InverseNormalMatrix
-
- UNIFORM_MODELVIEW_2D, // mat3 ModelViewMatrix
- UNIFORM_PROJECTION_2D, // mat3 ProjectionMatrix
- UNIFORM_MVP_2D, // mat3 ModelViewProjectionMatrix
-
- UNIFORM_COLOR, // vec4 color
-
- UNIFORM_CUSTOM // custom uniform, not one of the above built-ins
-} BuiltinUniform;
-
-typedef struct {
- const char* name;
- GLenum gl_type;
- BuiltinUniform builtin_type; // only for uniform inputs
- GLint size;
- GLint location;
-} ShaderInput;
-
-typedef struct {
- uint16_t uniform_ct;
- uint16_t attrib_ct;
- ShaderInput inputs[0]; // dynamic size, uniforms followed by attribs
-} ShaderInterface;
-
-ShaderInterface* ShaderInterface_create(GLint program_id);
-void ShaderInterface_discard(ShaderInterface*);
diff --git a/source/blender/gpu/gawain/vertex_buffer.c b/source/blender/gpu/gawain/vertex_buffer.c
deleted file mode 100644
index 827703403e3..00000000000
--- a/source/blender/gpu/gawain/vertex_buffer.c
+++ /dev/null
@@ -1,170 +0,0 @@
-
-// 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/.
-
-#include "vertex_buffer.h"
-#include "buffer_id.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define KEEP_SINGLE_COPY 1
-
-VertexBuffer* VertexBuffer_create(void)
- {
- VertexBuffer* verts = malloc(sizeof(VertexBuffer));
- VertexBuffer_init(verts);
- return verts;
- }
-
-VertexBuffer* VertexBuffer_create_with_format(const VertexFormat* format)
- {
- VertexBuffer* verts = VertexBuffer_create();
- VertexFormat_copy(&verts->format, format);
- if (!format->packed)
- VertexFormat_pack(&verts->format);
- return verts;
-
- // this function might seem redundant, but there is potential for memory savings here...
- // TODO: implement those memory savings
- }
-
-void VertexBuffer_init(VertexBuffer* verts)
- {
- memset(verts, 0, sizeof(VertexBuffer));
- }
-
-void VertexBuffer_init_with_format(VertexBuffer* verts, const VertexFormat* format)
- {
- VertexBuffer_init(verts);
- VertexFormat_copy(&verts->format, format);
- if (!format->packed)
- VertexFormat_pack(&verts->format);
- }
-
-void VertexBuffer_discard(VertexBuffer* verts)
- {
- if (verts->vbo_id)
- buffer_id_free(verts->vbo_id);
-#if KEEP_SINGLE_COPY
- else
-#endif
- if (verts->data)
- free(verts->data);
-
- free(verts);
- }
-
-unsigned VertexBuffer_size(const VertexBuffer* verts)
- {
- return vertex_buffer_size(&verts->format, verts->vertex_ct);
- }
-
-void VertexBuffer_allocate_data(VertexBuffer* verts, unsigned v_ct)
- {
- VertexFormat* format = &verts->format;
- if (!format->packed)
- VertexFormat_pack(format);
-
- verts->vertex_ct = v_ct;
-
- // Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
- verts->data = malloc(VertexBuffer_size(verts));
- }
-
-void VertexBuffer_resize_data(VertexBuffer* verts, unsigned v_ct)
- {
-#if TRUST_NO_ONE
- assert(verts->vertex_ct != v_ct); // allow this?
- assert(verts->data != NULL); // has already been allocated
- assert(verts->vbo_id == 0); // has not been sent to VRAM
-#endif
-
- verts->vertex_ct = v_ct;
- verts->data = realloc(verts->data, VertexBuffer_size(verts));
- // TODO: skip realloc if v_ct < existing vertex count
- // extra space will be reclaimed, and never sent to VRAM (see VertexBuffer_prime)
- }
-
-void setAttrib(VertexBuffer* verts, unsigned a_idx, unsigned v_idx, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* a = format->attribs + a_idx;
-
-#if TRUST_NO_ONE
- assert(a_idx < format->attrib_ct);
- assert(v_idx < verts->vertex_ct);
- assert(verts->data != NULL); // data must be in main mem
-#endif
-
- memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz);
- }
-
-void fillAttrib(VertexBuffer* verts, unsigned a_idx, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* a = format->attribs + a_idx;
-
-#if TRUST_NO_ONE
- assert(a_idx < format->attrib_ct);
-#endif
-
- const unsigned stride = a->sz; // tightly packed input data
-
- fillAttribStride(verts, a_idx, stride, data);
- }
-
-void fillAttribStride(VertexBuffer* verts, unsigned a_idx, unsigned stride, const void* data)
- {
- const VertexFormat* format = &verts->format;
- const Attrib* 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
-
- const unsigned vertex_ct = verts->vertex_ct;
-
- if (format->attrib_ct == 1 && stride == format->stride)
- {
- // we can copy it all at once
- memcpy(verts->data, data, vertex_ct * a->sz);
- }
- else
- {
- // we must copy it per vertex
- for (unsigned v = 0; v < vertex_ct; ++v)
- memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz);
- }
- }
-
-static void VertexBuffer_prime(VertexBuffer* verts)
- {
- const VertexFormat* format = &verts->format;
-
- verts->vbo_id = buffer_id_alloc();
- glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
- // fill with delicious data & send to GPU the first time only
- glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size(format, verts->vertex_ct), verts->data, GL_STATIC_DRAW);
-
-#if KEEP_SINGLE_COPY
- // now that GL has a copy, discard original
- free(verts->data);
- verts->data = NULL;
-#endif
- }
-
-void VertexBuffer_use(VertexBuffer* verts)
- {
- if (verts->vbo_id)
- glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
- else
- VertexBuffer_prime(verts);
- }
diff --git a/source/blender/gpu/gawain/vertex_buffer.h b/source/blender/gpu/gawain/vertex_buffer.h
deleted file mode 100644
index 6a72cfe6ff3..00000000000
--- a/source/blender/gpu/gawain/vertex_buffer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-// 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 "vertex_format.h"
-
-// How to create a VertexBuffer:
-// 1) verts = create_VertexBuffer() or init_VertexBuffer(verts)
-// 2) add_attrib(verts->format, ...)
-// 3) allocate_vertex_data(verts, vertex_ct) <-- finalizes/packs vertex format
-// 4) fillAttrib(verts, pos, application_pos_buffer)
-// 5) prime_VertexBuffer(verts);
-
-// Is VertexBuffer always used as part of a Batch?
-
-typedef struct {
- VertexFormat format;
- unsigned vertex_ct;
- GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
- GLuint vbo_id; // 0 indicates not yet sent to VRAM
-} VertexBuffer;
-
-VertexBuffer* VertexBuffer_create(void);
-VertexBuffer* VertexBuffer_create_with_format(const VertexFormat*);
-
-void VertexBuffer_discard(VertexBuffer*);
-
-void VertexBuffer_init(VertexBuffer*);
-void VertexBuffer_init_with_format(VertexBuffer*, const VertexFormat*);
-
-unsigned VertexBuffer_size(const VertexBuffer*);
-void VertexBuffer_allocate_data(VertexBuffer*, unsigned v_ct);
-void VertexBuffer_resize_data(VertexBuffer*, unsigned v_ct);
-
-// The most important setAttrib 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 setAttrib(VertexBuffer*, unsigned a_idx, unsigned v_idx, const void* data);
-void fillAttrib(VertexBuffer*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data
-void fillAttribStride(VertexBuffer*, unsigned a_idx, unsigned stride, const void* data);
-
-// 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 VertexBuffer_use(VertexBuffer*);
diff --git a/source/blender/gpu/gawain/vertex_format.c b/source/blender/gpu/gawain/vertex_format.c
deleted file mode 100644
index d42398f3a4f..00000000000
--- a/source/blender/gpu/gawain/vertex_format.c
+++ /dev/null
@@ -1,248 +0,0 @@
-
-// 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/.
-
-#include "vertex_format.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define PACK_DEBUG 0
-
-#if PACK_DEBUG
- #include <stdio.h>
-#endif
-
-void VertexFormat_clear(VertexFormat* format)
- {
-#if TRUST_NO_ONE
- memset(format, 0, sizeof(VertexFormat));
-#else
- format->attrib_ct = 0;
- format->packed = false;
- format->name_offset = 0;
-#endif
- }
-
-void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
- {
- // copy regular struct fields
- memcpy(dest, src, sizeof(VertexFormat));
- }
-
-static unsigned comp_sz(VertexCompType type)
- {
-#if TRUST_NO_ONE
- assert(type >= GL_BYTE && type <= GL_FLOAT);
-#endif
-
- const GLubyte sizes[] = {1,1,2,2,4,4,4};
- return sizes[type - GL_BYTE];
- }
-
-static unsigned attrib_sz(const Attrib *a)
- {
-#if USE_10_10_10
- if (a->comp_type == COMP_I10)
- return 4; // always packed as 10_10_10_2
-#endif
-
- return a->comp_ct * comp_sz(a->comp_type);
- }
-
-static unsigned attrib_align(const Attrib *a)
- {
-#if USE_10_10_10
- if (a->comp_type == COMP_I10)
- return 4; // always packed as 10_10_10_2
-#endif
-
- unsigned c = comp_sz(a->comp_type);
- if (a->comp_ct == 3 && c <= 2)
- return 4 * c; // AMD HW can't fetch these well, so pad it out (other vendors too?)
- else
- return c; // most fetches are ok if components are naturally aligned
- }
-
-unsigned vertex_buffer_size(const VertexFormat* format, unsigned vertex_ct)
- {
-#if TRUST_NO_ONE
- assert(format->packed && format->stride > 0);
-#endif
-
- return format->stride * vertex_ct;
- }
-
-static const char* copy_attrib_name(VertexFormat* format, const char* name)
- {
- // strncpy does 110% of what we need; let's do exactly 100%
- char* name_copy = format->names + format->name_offset;
- unsigned available = VERTEX_ATTRIB_NAMES_BUFFER_LEN - format->name_offset;
- bool terminated = false;
-
- for (unsigned i = 0; i < available; ++i)
- {
- const char c = name[i];
- name_copy[i] = c;
- if (c == '\0')
- {
- terminated = true;
- format->name_offset += (i + 1);
- break;
- }
- }
-
-#if TRUST_NO_ONE
- assert(terminated);
- assert(format->name_offset <= VERTEX_ATTRIB_NAMES_BUFFER_LEN);
-#endif
-
- return name_copy;
- }
-
-unsigned add_attrib(VertexFormat* format, const char* name, VertexCompType comp_type, unsigned comp_ct, VertexFetchMode fetch_mode)
- {
-#if TRUST_NO_ONE
- assert(format->attrib_ct < MAX_VERTEX_ATTRIBS); // there's room for more
- assert(!format->packed); // packed means frozen/locked
- assert(comp_ct >= 1 && comp_ct <= 4);
- switch (comp_type)
- {
- case COMP_F32:
- // float type can only kept as float
- assert(fetch_mode == KEEP_FLOAT);
- break;
- #if USE_10_10_10
- case COMP_I10:
- // 10_10_10 format intended for normals (xyz) or colors (rgb)
- // extra component packed.w can be manually set to { -2, -1, 0, 1 }
- assert(comp_ct == 3 || comp_ct == 4);
- assert(fetch_mode == NORMALIZE_INT_TO_FLOAT); // not strictly required, may relax later
- break;
- #endif
- default:
- // integer types can be kept as int or converted/normalized to float
- assert(fetch_mode != KEEP_FLOAT);
- }
-#endif
-
- const unsigned attrib_id = format->attrib_ct++;
- Attrib* attrib = format->attribs + attrib_id;
-
- attrib->name = copy_attrib_name(format, name);
- attrib->comp_type = comp_type;
-#if USE_10_10_10
- attrib->comp_ct = (comp_type == COMP_I10) ? 4 : comp_ct; // system needs 10_10_10_2 to be 4 or BGRA
-#else
- attrib->comp_ct = comp_ct;
-#endif
- attrib->sz = attrib_sz(attrib);
- attrib->offset = 0; // offsets & stride are calculated later (during pack)
- attrib->fetch_mode = fetch_mode;
-
- return attrib_id;
- }
-
-unsigned padding(unsigned offset, unsigned alignment)
- {
- const unsigned mod = offset % alignment;
- return (mod == 0) ? 0 : (alignment - mod);
- }
-
-#if PACK_DEBUG
-static void show_pack(unsigned a_idx, unsigned sz, unsigned pad)
- {
- const char c = 'A' + a_idx;
- for (unsigned i = 0; i < pad; ++i)
- putchar('-');
- for (unsigned i = 0; i < sz; ++i)
- putchar(c);
- }
-#endif
-
-void VertexFormat_pack(VertexFormat* format)
- {
- // for now, attributes are packed in the order they were added,
- // making sure each attrib is naturally aligned (add padding where necessary)
-
- // later we can implement more efficient packing w/ reordering
- // (keep attrib ID order, adjust their offsets to reorder in buffer)
-
- // TODO:
- // realloc just enough to hold the final combo string. And just enough to
- // hold used attribs, not all 16.
-
- Attrib* a0 = format->attribs + 0;
- a0->offset = 0;
- unsigned offset = a0->sz;
-
-#if PACK_DEBUG
- show_pack(0, a0->sz, 0);
-#endif
-
- for (unsigned a_idx = 1; a_idx < format->attrib_ct; ++a_idx)
- {
- Attrib* a = format->attribs + a_idx;
- unsigned mid_padding = padding(offset, attrib_align(a));
- offset += mid_padding;
- a->offset = offset;
- offset += a->sz;
-
-#if PACK_DEBUG
- show_pack(a_idx, a->sz, mid_padding);
-#endif
- }
-
- unsigned end_padding = padding(offset, attrib_align(a0));
-
-#if PACK_DEBUG
- show_pack(0, 0, end_padding);
- putchar('\n');
-#endif
-
- format->stride = offset + end_padding;
- format->packed = true;
- }
-
-
-#if USE_10_10_10
-
-// 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.
-
-#define SIGNED_INT_10_MAX 511
-#define SIGNED_INT_10_MIN -512
-
-static int clampi(int x, int min_allowed, int max_allowed)
- {
-#if TRUST_NO_ONE
- assert(min_allowed <= max_allowed);
-#endif
-
- if (x < min_allowed)
- return min_allowed;
- else if (x > max_allowed)
- return max_allowed;
- else
- return x;
- }
-
-static int quantize(float x)
- {
- int qx = x * 511.0f;
- return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX);
- }
-
-PackedNormal convert_i10_v3(const float data[3])
- {
- PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) };
- return n;
- }
-
-#endif // USE_10_10_10
diff --git a/source/blender/gpu/gawain/vertex_format.h b/source/blender/gpu/gawain/vertex_format.h
deleted file mode 100644
index 4ed9e58f376..00000000000
--- a/source/blender/gpu/gawain/vertex_format.h
+++ /dev/null
@@ -1,87 +0,0 @@
-
-// 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 "common.h"
-
-#define MAX_VERTEX_ATTRIBS 16
-#define AVG_VERTEX_ATTRIB_NAME_LEN 5
-#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
-
-#define USE_10_10_10 defined(_WIN32)
-// (GLEW_VERSION_3_3 || GLEW_ARB_vertex_type_2_10_10_10_rev)
-// ^-- this is only guaranteed on Windows right now, will be true on all platforms soon
-
-typedef enum {
- COMP_I8 = GL_BYTE,
- COMP_U8 = GL_UNSIGNED_BYTE,
- COMP_I16 = GL_SHORT,
- COMP_U16 = GL_UNSIGNED_SHORT,
- COMP_I32 = GL_INT,
- COMP_U32 = GL_UNSIGNED_INT,
-
- COMP_F32 = GL_FLOAT, // TODO: drop the GL_ equivalence here, use a private lookup table
-
-#if USE_10_10_10
- COMP_I10 = GL_INT_2_10_10_10_REV
-#endif
-} VertexCompType;
-
-typedef enum {
- KEEP_FLOAT,
- KEEP_INT,
- NORMALIZE_INT_TO_FLOAT, // 127 (ubyte) -> 0.5 (and so on for other int types)
- CONVERT_INT_TO_FLOAT // 127 (any int type) -> 127.0
-} VertexFetchMode;
-
-typedef struct {
- VertexCompType comp_type;
- unsigned comp_ct; // 1 to 4
- unsigned sz; // size in bytes, 1 to 16
- unsigned offset; // from beginning of vertex, in bytes
- VertexFetchMode fetch_mode;
- const char* name;
-} Attrib;
-
-typedef struct {
- unsigned attrib_ct; // 0 to 16 (MAX_VERTEX_ATTRIBS)
- unsigned stride; // stride in bytes, 1 to 256
- bool packed;
- Attrib attribs[MAX_VERTEX_ATTRIBS]; // TODO: variable-size attribs array
- char names[VERTEX_ATTRIB_NAMES_BUFFER_LEN];
- unsigned name_offset;
-} VertexFormat;
-
-void VertexFormat_clear(VertexFormat*);
-void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src);
-
-unsigned add_attrib(VertexFormat*, const char* name, VertexCompType, unsigned comp_ct, VertexFetchMode);
-
-// format conversion
-
-#if USE_10_10_10
-
-typedef struct {
- int x : 10;
- int y : 10;
- int z : 10;
- int w : 2; // 0 by default, can manually set to { -2, -1, 0, 1 }
-} PackedNormal;
-
-PackedNormal convert_i10_v3(const float data[3]);
-
-#endif // USE_10_10_10
-
-// for internal use
-void VertexFormat_pack(VertexFormat*);
-unsigned padding(unsigned offset, unsigned alignment);
-unsigned vertex_buffer_size(const VertexFormat*, unsigned vertex_ct);