diff options
author | Mike Erwin <significant.bit@gmail.com> | 2017-03-17 06:32:35 +0300 |
---|---|---|
committer | Mike Erwin <significant.bit@gmail.com> | 2017-03-17 06:32:35 +0300 |
commit | 4452bea2f170ec7fe48c223c8c499f1eb9b5356c (patch) | |
tree | 28dcc9ac042fcce5c77f3c60b4ce8af8677fa4a8 /source | |
parent | b4e8dc8c82dfcae60f33e39684272867745a8af2 (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')
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); |