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:
authorClément Foucault <foucault.clem@gmail.com>2020-08-31 16:14:47 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-31 16:14:47 +0300
commit1804eb57fd27fceb0ed113e3ef2f4a55db0d03c8 (patch)
tree003ceca6cdb280e5f6fc408b6833dea8b36f2bd6 /source/blender/gpu/intern
parent1b3a0ae2316063d9817210a8fe5fd4588cee47cf (diff)
GPUImmediate: GL backend isolation
This is part of the Vulkan backend task T68990. This is mostly a cleanup, however, there is a small change: We don't use a special Vertex Array binding function for Immediate anymore and just reuse the one for batches. This might create a bit more state changes but this could be fixed easily if it causes perf regression. # Conflicts: # source/blender/gpu/intern/gpu_context.cc
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_context.cc1
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc492
-rw-r--r--source/blender/gpu/intern/gpu_immediate_private.hh66
4 files changed, 208 insertions, 353 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index f188f5e9fda..229456f9aa5 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -75,6 +75,7 @@ GPUContext::~GPUContext()
delete back_left;
delete front_right;
delete back_right;
+ delete imm;
}
bool GPUContext::is_active_on_thread(void)
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index 04b347d1bff..b32406bfc44 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -30,6 +30,7 @@
#include "GPU_context.h"
#include "gpu_framebuffer_private.hh"
+#include "gpu_immediate_private.hh"
#include "gpu_shader_private.hh"
#include "gpu_state_private.hh"
@@ -48,6 +49,7 @@ struct GPUContext {
blender::gpu::FrameBuffer *active_fb = NULL;
GPUMatrixState *matrix_state = NULL;
blender::gpu::GPUStateManager *state_manager = NULL;
+ blender::gpu::Immediate *imm = NULL;
/**
* All 4 window framebuffers.
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index b0deb1d9551..51843917f58 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -20,7 +20,7 @@
/** \file
* \ingroup gpu
*
- * GPU immediate mode work-alike
+ * Mimics old style opengl immediate mode drawing.
*/
#ifndef GPU_STANDALONE
@@ -34,122 +34,53 @@
#include "gpu_attr_binding_private.h"
#include "gpu_context_private.hh"
+#include "gpu_immediate_private.hh"
#include "gpu_primitive_private.h"
#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
-#include <stdlib.h>
-#include <string.h>
-
-typedef struct ImmediateDrawBuffer {
- GLuint vbo_id;
- GLubyte *buffer_data;
- uint buffer_offset;
- uint buffer_size;
-} ImmediateDrawBuffer;
-
-typedef struct {
- GPUBatch *batch;
- GPUContext *context;
-
- /* current draw call */
- bool strict_vertex_len;
- uint vertex_len;
- uint buffer_bytes_mapped;
- ImmediateDrawBuffer *active_buffer;
- GPUPrimType prim_type;
- GPUVertFormat vertex_format;
- ImmediateDrawBuffer draw_buffer;
- ImmediateDrawBuffer draw_buffer_strict;
-
- /* current vertex */
- uint vertex_idx;
- GLubyte *vertex_data;
- /** which attributes of current vertex have not been given values? */
- uint16_t unassigned_attr_bits;
-
- GLuint vao_id;
-
- GPUShader *bound_program;
- GPUAttrBinding attr_binding;
- uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
-} Immediate;
-
-/* size of internal buffer */
-#define DEFAULT_INTERNAL_BUFFER_SIZE (4 * 1024 * 1024)
-
-static bool initialized = false;
-static Immediate imm;
+using namespace blender::gpu;
+
+static Immediate *imm = NULL;
void immInit(void)
{
- BLI_assert(!initialized);
-
- memset(&imm, 0, sizeof(Immediate));
-
- imm.draw_buffer.vbo_id = GPU_buf_alloc();
- imm.draw_buffer.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
- glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer.vbo_id);
- glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer.buffer_size, NULL, GL_DYNAMIC_DRAW);
-
- imm.draw_buffer_strict.vbo_id = GPU_buf_alloc();
- imm.draw_buffer_strict.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
- glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer_strict.vbo_id);
- glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer_strict.buffer_size, NULL, GL_DYNAMIC_DRAW);
-
- imm.prim_type = GPU_PRIM_NONE;
- imm.strict_vertex_len = true;
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- initialized = true;
+ /* TODO Remove */
}
void immActivate(void)
{
- BLI_assert(initialized);
- BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */
- BLI_assert(imm.vao_id == 0);
-
- imm.vao_id = GPU_vao_alloc();
- imm.context = GPU_context_active_get();
+ imm = GPU_context_active_get()->imm;
}
void immDeactivate(void)
{
- BLI_assert(initialized);
- BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */
- BLI_assert(imm.vao_id != 0);
-
- GPU_vao_free(imm.vao_id, imm.context);
- imm.vao_id = 0;
- imm.prev_enabled_attr_bits = 0;
+ imm = NULL;
}
void immDestroy(void)
{
- GPU_buf_free(imm.draw_buffer.vbo_id);
- GPU_buf_free(imm.draw_buffer_strict.vbo_id);
- initialized = false;
+ /* TODO Remove */
}
GPUVertFormat *immVertexFormat(void)
{
- GPU_vertformat_clear(&imm.vertex_format);
- return &imm.vertex_format;
+ GPU_vertformat_clear(&imm->vertex_format);
+ return &imm->vertex_format;
}
void immBindShader(GPUShader *shader)
{
- BLI_assert(imm.bound_program == NULL);
+ BLI_assert(imm->shader == NULL);
- imm.bound_program = shader;
+ imm->shader = shader;
- if (!imm.vertex_format.packed) {
- VertexFormat_pack(&imm.vertex_format);
+ if (!imm->vertex_format.packed) {
+ VertexFormat_pack(&imm->vertex_format);
+ imm->enabled_attr_bits = 0xFFFFu & ~(0xFFFFu << imm->vertex_format.attr_len);
}
GPU_shader_bind(shader);
- get_attr_locations(&imm.vertex_format, &imm.attr_binding, shader);
GPU_matrix_bind(shader);
GPU_shader_set_srgb_uniform(shader);
}
@@ -162,16 +93,16 @@ void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUnbindProgram(void)
{
- BLI_assert(imm.bound_program != NULL);
+ BLI_assert(imm->shader != NULL);
GPU_shader_unbind();
- imm.bound_program = NULL;
+ imm->shader = NULL;
}
/* XXX do not use it. Special hack to use OCIO with batch API. */
GPUShader *immGetShader(void)
{
- return imm.bound_program;
+ return imm->shader;
}
#ifndef NDEBUG
@@ -205,267 +136,122 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType
void immBegin(GPUPrimType prim_type, uint vertex_len)
{
- BLI_assert(initialized);
- BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */
+ BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure we haven't already begun. */
BLI_assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type));
- BLI_assert(imm.active_buffer == NULL);
-
- GPU_context_active_get()->state_manager->apply_state();
-
- imm.prim_type = prim_type;
- imm.vertex_len = vertex_len;
- imm.vertex_idx = 0;
- imm.unassigned_attr_bits = imm.attr_binding.enabled_bits;
-
- /* how many bytes do we need for this draw call? */
- const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len);
- ImmediateDrawBuffer *active_buffer = imm.strict_vertex_len ? &imm.draw_buffer_strict :
- &imm.draw_buffer;
- imm.active_buffer = active_buffer;
-
- glBindBuffer(GL_ARRAY_BUFFER, active_buffer->vbo_id);
-
- /* does the current buffer have enough room? */
- const uint available_bytes = active_buffer->buffer_size - active_buffer->buffer_offset;
-
- bool recreate_buffer = false;
- if (bytes_needed > active_buffer->buffer_size) {
- /* expand the internal buffer */
- active_buffer->buffer_size = bytes_needed;
- recreate_buffer = true;
- }
- else if (bytes_needed < DEFAULT_INTERNAL_BUFFER_SIZE &&
- active_buffer->buffer_size > DEFAULT_INTERNAL_BUFFER_SIZE) {
- /* shrink the internal buffer */
- active_buffer->buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE;
- recreate_buffer = true;
- }
-
- /* ensure vertex data is aligned */
- /* Might waste a little space, but it's safe. */
- const uint pre_padding = padding(active_buffer->buffer_offset, imm.vertex_format.stride);
-
- if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) {
- active_buffer->buffer_offset += pre_padding;
- }
- else {
- /* orphan this buffer & start with a fresh one */
- /* this method works on all platforms, old & new */
- glBufferData(GL_ARRAY_BUFFER, active_buffer->buffer_size, NULL, GL_DYNAMIC_DRAW);
-
- active_buffer->buffer_offset = 0;
- }
-
- /* printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */
-
-#ifndef NDEBUG
- {
- GLint bufsize;
- glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bufsize);
- BLI_assert(active_buffer->buffer_offset + bytes_needed <= bufsize);
- }
-#endif
-
- active_buffer->buffer_data = (GLubyte *)glMapBufferRange(
- GL_ARRAY_BUFFER,
- active_buffer->buffer_offset,
- bytes_needed,
- GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT |
- (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT));
- BLI_assert(active_buffer->buffer_data != NULL);
+ imm->prim_type = prim_type;
+ imm->vertex_len = vertex_len;
+ imm->vertex_idx = 0;
+ imm->unassigned_attr_bits = imm->enabled_attr_bits;
- imm.buffer_bytes_mapped = bytes_needed;
- imm.vertex_data = active_buffer->buffer_data;
+ imm->vertex_data = imm->begin();
}
void immBeginAtMost(GPUPrimType prim_type, uint vertex_len)
{
BLI_assert(vertex_len > 0);
-
- imm.strict_vertex_len = false;
+ imm->strict_vertex_len = false;
immBegin(prim_type, vertex_len);
}
GPUBatch *immBeginBatch(GPUPrimType prim_type, uint vertex_len)
{
- BLI_assert(initialized);
- BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */
+ BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure we haven't already begun. */
BLI_assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type));
- imm.prim_type = prim_type;
- imm.vertex_len = vertex_len;
- imm.vertex_idx = 0;
- imm.unassigned_attr_bits = imm.attr_binding.enabled_bits;
+ imm->prim_type = prim_type;
+ imm->vertex_len = vertex_len;
+ imm->vertex_idx = 0;
+ imm->unassigned_attr_bits = imm->enabled_attr_bits;
- GPUVertBuf *verts = GPU_vertbuf_create_with_format(&imm.vertex_format);
+ GPUVertBuf *verts = GPU_vertbuf_create_with_format(&imm->vertex_format);
GPU_vertbuf_data_alloc(verts, vertex_len);
- imm.buffer_bytes_mapped = GPU_vertbuf_size_get(verts);
- imm.vertex_data = verts->data;
+ imm->vertex_data = verts->data;
- imm.batch = GPU_batch_create_ex(prim_type, verts, NULL, GPU_BATCH_OWNS_VBO);
- imm.batch->flag |= GPU_BATCH_BUILDING;
+ imm->batch = GPU_batch_create_ex(prim_type, verts, NULL, GPU_BATCH_OWNS_VBO);
+ imm->batch->flag |= GPU_BATCH_BUILDING;
- return imm.batch;
+ return imm->batch;
}
GPUBatch *immBeginBatchAtMost(GPUPrimType prim_type, uint vertex_len)
{
- imm.strict_vertex_len = false;
+ BLI_assert(vertex_len > 0);
+ imm->strict_vertex_len = false;
return immBeginBatch(prim_type, vertex_len);
}
-static void immDrawSetup(void)
-{
- /* set up VAO -- can be done during Begin or End really */
- glBindVertexArray(imm.vao_id);
-
- /* Enable/Disable vertex attributes as needed. */
- if (imm.attr_binding.enabled_bits != imm.prev_enabled_attr_bits) {
- for (uint loc = 0; loc < GPU_VERT_ATTR_MAX_LEN; loc++) {
- bool is_enabled = imm.attr_binding.enabled_bits & (1 << loc);
- bool was_enabled = imm.prev_enabled_attr_bits & (1 << loc);
-
- if (is_enabled && !was_enabled) {
- glEnableVertexAttribArray(loc);
- }
- else if (was_enabled && !is_enabled) {
- glDisableVertexAttribArray(loc);
- }
- }
-
- imm.prev_enabled_attr_bits = imm.attr_binding.enabled_bits;
- }
-
- const uint stride = imm.vertex_format.stride;
-
- for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) {
- const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx];
-
- const uint offset = imm.active_buffer->buffer_offset + a->offset;
- const GLvoid *pointer = (const GLubyte *)0 + offset;
-
- const uint loc = read_attr_location(&imm.attr_binding, a_idx);
- const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type));
-
- switch (a->fetch_mode) {
- case GPU_FETCH_FLOAT:
- case GPU_FETCH_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_len, type, GL_FALSE, stride, pointer);
- break;
- case GPU_FETCH_INT_TO_FLOAT_UNIT:
- glVertexAttribPointer(loc, a->comp_len, type, GL_TRUE, stride, pointer);
- break;
- case GPU_FETCH_INT:
- glVertexAttribIPointer(loc, a->comp_len, type, stride, pointer);
- }
- }
-
- if (GPU_matrix_dirty_get()) {
- GPU_matrix_bind(imm.bound_program);
- }
-}
-
void immEnd(void)
{
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
- BLI_assert(imm.active_buffer || imm.batch);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* Make sure we're between a Begin/End pair. */
+ BLI_assert(imm->vertex_data || imm->batch);
- uint buffer_bytes_used;
- if (imm.strict_vertex_len) {
- BLI_assert(imm.vertex_idx == imm.vertex_len); /* with all vertices defined */
- buffer_bytes_used = imm.buffer_bytes_mapped;
+ if (imm->strict_vertex_len) {
+ BLI_assert(imm->vertex_idx == imm->vertex_len); /* With all vertices defined. */
}
else {
- BLI_assert(imm.vertex_idx <= imm.vertex_len);
- if (imm.vertex_idx == imm.vertex_len) {
- buffer_bytes_used = imm.buffer_bytes_mapped;
- }
- else {
- BLI_assert(imm.vertex_idx == 0 ||
- vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type));
- imm.vertex_len = imm.vertex_idx;
- buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_len);
- /* unused buffer bytes are available to the next immBegin */
- }
- /* tell OpenGL what range was modified so it doesn't copy the whole mapped range */
- glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used);
+ BLI_assert(imm->vertex_idx <= imm->vertex_len);
+ BLI_assert(imm->vertex_idx == 0 ||
+ vertex_count_makes_sense_for_primitive(imm->vertex_idx, imm->prim_type));
}
- if (imm.batch) {
- if (buffer_bytes_used != imm.buffer_bytes_mapped) {
- GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len);
+ if (imm->batch) {
+ if (imm->vertex_idx < imm->vertex_len) {
+ GPU_vertbuf_data_resize(imm->batch->verts[0], imm->vertex_len);
/* TODO: resize only if vertex count is much smaller */
}
- GPU_batch_set_shader(imm.batch, imm.bound_program);
- imm.batch->flag &= ~GPU_BATCH_BUILDING;
- imm.batch = NULL; /* don't free, batch belongs to caller */
+ GPU_batch_set_shader(imm->batch, imm->shader);
+ imm->batch->flag &= ~GPU_BATCH_BUILDING;
+ imm->batch = NULL; /* don't free, batch belongs to caller */
}
else {
- glUnmapBuffer(GL_ARRAY_BUFFER);
-
- if (imm.vertex_len > 0) {
- immDrawSetup();
-#ifdef __APPLE__
- glDisable(GL_PRIMITIVE_RESTART);
-#endif
- glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_len);
-#ifdef __APPLE__
- glEnable(GL_PRIMITIVE_RESTART);
-#endif
- }
- /* These lines are causing crash on startup on some old GPU + drivers.
- * They are not required so just comment them. (T55722) */
- // glBindBuffer(GL_ARRAY_BUFFER, 0);
- // glBindVertexArray(0);
- /* prep for next immBegin */
- imm.active_buffer->buffer_offset += buffer_bytes_used;
+ imm->end();
}
- /* prep for next immBegin */
- imm.prim_type = GPU_PRIM_NONE;
- imm.strict_vertex_len = true;
- imm.active_buffer = NULL;
+ /* Prepare for next immBegin. */
+ imm->prim_type = GPU_PRIM_NONE;
+ imm->strict_vertex_len = true;
+ imm->vertex_data = NULL;
}
static void setAttrValueBit(uint attr_id)
{
uint16_t mask = 1 << attr_id;
- BLI_assert(imm.unassigned_attr_bits & mask); /* not already set */
- imm.unassigned_attr_bits &= ~mask;
+ BLI_assert(imm->unassigned_attr_bits & mask); /* not already set */
+ imm->unassigned_attr_bits &= ~mask;
}
/* --- generic attribute functions --- */
void immAttr1f(uint attr_id, float x)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 1);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- float *data = (float *)(imm.vertex_data + attr->offset);
- /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */
+ float *data = (float *)(imm->vertex_data + attr->offset);
+ /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm->buffer_data, data); */
data[0] = x;
}
void immAttr2f(uint attr_id, float x, float y)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 2);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- float *data = (float *)(imm.vertex_data + attr->offset);
- /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */
+ float *data = (float *)(imm->vertex_data + attr->offset);
+ /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm->buffer_data, data); */
data[0] = x;
data[1] = y;
@@ -473,16 +259,16 @@ void immAttr2f(uint attr_id, float x, float y)
void immAttr3f(uint attr_id, float x, float y, float z)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 3);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- float *data = (float *)(imm.vertex_data + attr->offset);
- /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */
+ float *data = (float *)(imm->vertex_data + attr->offset);
+ /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm->buffer_data, data); */
data[0] = x;
data[1] = y;
@@ -491,16 +277,16 @@ void immAttr3f(uint attr_id, float x, float y, float z)
void immAttr4f(uint attr_id, float x, float y, float z, float w)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_F32);
BLI_assert(attr->comp_len == 4);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- float *data = (float *)(imm.vertex_data + attr->offset);
- /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */
+ float *data = (float *)(imm->vertex_data + attr->offset);
+ /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm->buffer_data, data); */
data[0] = x;
data[1] = y;
@@ -510,30 +296,30 @@ void immAttr4f(uint attr_id, float x, float y, float z, float w)
void immAttr1u(uint attr_id, uint x)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U32);
BLI_assert(attr->comp_len == 1);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- uint *data = (uint *)(imm.vertex_data + attr->offset);
+ uint *data = (uint *)(imm->vertex_data + attr->offset);
data[0] = x;
}
void immAttr2i(uint attr_id, int x, int y)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_I32);
BLI_assert(attr->comp_len == 2);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- int *data = (int *)(imm.vertex_data + attr->offset);
+ int *data = (int *)(imm->vertex_data + attr->offset);
data[0] = x;
data[1] = y;
@@ -541,15 +327,15 @@ void immAttr2i(uint attr_id, int x, int y)
void immAttr2s(uint attr_id, short x, short y)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_I16);
BLI_assert(attr->comp_len == 2);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- short *data = (short *)(imm.vertex_data + attr->offset);
+ short *data = (short *)(imm->vertex_data + attr->offset);
data[0] = x;
data[1] = y;
@@ -572,16 +358,16 @@ void immAttr4fv(uint attr_id, const float data[4])
void immAttr3ub(uint attr_id, uchar r, uchar g, uchar b)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U8);
BLI_assert(attr->comp_len == 3);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- GLubyte *data = imm.vertex_data + attr->offset;
- /* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */
+ uchar *data = imm->vertex_data + attr->offset;
+ /* printf("%s %td %p\n", __FUNCTION__, data - imm->buffer_data, data); */
data[0] = r;
data[1] = g;
@@ -590,16 +376,16 @@ void immAttr3ub(uint attr_id, uchar r, uchar g, uchar b)
void immAttr4ub(uint attr_id, uchar r, uchar g, uchar b, uchar a)
{
- GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id];
- BLI_assert(attr_id < imm.vertex_format.attr_len);
+ GPUVertAttr *attr = &imm->vertex_format.attrs[attr_id];
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
BLI_assert(attr->comp_type == GPU_COMP_U8);
BLI_assert(attr->comp_len == 4);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
- GLubyte *data = imm.vertex_data + attr->offset;
- /* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */
+ uchar *data = imm->vertex_data + attr->offset;
+ /* printf("%s %td %p\n", __FUNCTION__, data - imm->buffer_data, data); */
data[0] = r;
data[1] = g;
@@ -619,39 +405,39 @@ void immAttr4ubv(uint attr_id, const uchar data[4])
void immAttrSkip(uint attr_id)
{
- BLI_assert(attr_id < imm.vertex_format.attr_len);
- BLI_assert(imm.vertex_idx < imm.vertex_len);
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(attr_id < imm->vertex_format.attr_len);
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
setAttrValueBit(attr_id);
}
static void immEndVertex(void) /* and move on to the next vertex */
{
- BLI_assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
- BLI_assert(imm.vertex_idx < imm.vertex_len);
+ BLI_assert(imm->prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */
+ BLI_assert(imm->vertex_idx < imm->vertex_len);
/* Have all attributes been assigned values?
* If not, copy value from previous vertex. */
- if (imm.unassigned_attr_bits) {
- BLI_assert(imm.vertex_idx > 0); /* first vertex must have all attributes specified */
- for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) {
- if ((imm.unassigned_attr_bits >> a_idx) & 1) {
- const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx];
+ if (imm->unassigned_attr_bits) {
+ BLI_assert(imm->vertex_idx > 0); /* first vertex must have all attributes specified */
+ for (uint a_idx = 0; a_idx < imm->vertex_format.attr_len; a_idx++) {
+ if ((imm->unassigned_attr_bits >> a_idx) & 1) {
+ const GPUVertAttr *a = &imm->vertex_format.attrs[a_idx];
#if 0
- printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx);
+ printf("copying %s from vertex %u to %u\n", a->name, imm->vertex_idx - 1, imm->vertex_idx);
#endif
- GLubyte *data = imm.vertex_data + a->offset;
- memcpy(data, data - imm.vertex_format.stride, a->sz);
+ 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_attr_bits = imm.attr_binding.enabled_bits;
+ imm->vertex_idx++;
+ imm->vertex_data += imm->vertex_format.stride;
+ imm->unassigned_attr_bits = imm->enabled_attr_bits;
}
void immVertex2f(uint attr_id, float x, float y)
@@ -706,64 +492,64 @@ void immVertex2iv(uint attr_id, const int data[2])
void immUniform1f(const char *name, float x)
{
- GPU_shader_uniform_1f(imm.bound_program, name, x);
+ GPU_shader_uniform_1f(imm->shader, name, x);
}
void immUniform2f(const char *name, float x, float y)
{
- GPU_shader_uniform_2f(imm.bound_program, name, x, y);
+ GPU_shader_uniform_2f(imm->shader, name, x, y);
}
void immUniform2fv(const char *name, const float data[2])
{
- GPU_shader_uniform_2fv(imm.bound_program, name, data);
+ GPU_shader_uniform_2fv(imm->shader, name, data);
}
void immUniform3f(const char *name, float x, float y, float z)
{
- GPU_shader_uniform_3f(imm.bound_program, name, x, y, z);
+ GPU_shader_uniform_3f(imm->shader, name, x, y, z);
}
void immUniform3fv(const char *name, const float data[3])
{
- GPU_shader_uniform_3fv(imm.bound_program, name, data);
+ GPU_shader_uniform_3fv(imm->shader, name, data);
}
void immUniform4f(const char *name, float x, float y, float z, float w)
{
- GPU_shader_uniform_4f(imm.bound_program, name, x, y, z, w);
+ GPU_shader_uniform_4f(imm->shader, name, x, y, z, w);
}
void immUniform4fv(const char *name, const float data[4])
{
- GPU_shader_uniform_4fv(imm.bound_program, name, data);
+ GPU_shader_uniform_4fv(imm->shader, name, data);
}
/* Note array index is not supported for name (i.e: "array[0]"). */
void immUniformArray4fv(const char *name, const float *data, int count)
{
- GPU_shader_uniform_4fv_array(imm.bound_program, name, count, (float(*)[4])data);
+ GPU_shader_uniform_4fv_array(imm->shader, name, count, (float(*)[4])data);
}
void immUniformMatrix4fv(const char *name, const float data[4][4])
{
- GPU_shader_uniform_mat4(imm.bound_program, name, data);
+ GPU_shader_uniform_mat4(imm->shader, name, data);
}
void immUniform1i(const char *name, int x)
{
- GPU_shader_uniform_1i(imm.bound_program, name, x);
+ GPU_shader_uniform_1i(imm->shader, name, x);
}
void immBindTexture(const char *name, GPUTexture *tex)
{
- int binding = GPU_shader_get_texture_binding(imm.bound_program, name);
+ int binding = GPU_shader_get_texture_binding(imm->shader, name);
GPU_texture_bind(tex, binding);
}
void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state)
{
- int binding = GPU_shader_get_texture_binding(imm.bound_program, name);
+ int binding = GPU_shader_get_texture_binding(imm->shader, name);
GPU_texture_bind_ex(tex, state, binding, true);
}
@@ -771,10 +557,10 @@ void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState s
void immUniformColor4f(float r, float g, float b, float a)
{
- int32_t uniform_loc = GPU_shader_get_builtin_uniform(imm.bound_program, GPU_UNIFORM_COLOR);
+ int32_t uniform_loc = GPU_shader_get_builtin_uniform(imm->shader, GPU_UNIFORM_COLOR);
BLI_assert(uniform_loc != -1);
float data[4] = {r, g, b, a};
- GPU_shader_uniform_vector(imm.bound_program, uniform_loc, 4, 1, data);
+ GPU_shader_uniform_vector(imm->shader, uniform_loc, 4, 1, data);
}
void immUniformColor4fv(const float rgba[4])
diff --git a/source/blender/gpu/intern/gpu_immediate_private.hh b/source/blender/gpu/intern/gpu_immediate_private.hh
new file mode 100644
index 00000000000..aa99fb9a438
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_immediate_private.hh
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 by Mike Erwin.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * Mimics old style opengl immediate mode drawing.
+ */
+
+#pragma once
+
+#include "GPU_batch.h"
+#include "GPU_primitive.h"
+#include "GPU_shader.h"
+#include "GPU_vertex_format.h"
+
+namespace blender::gpu {
+
+class Immediate {
+ public:
+ /** Pointer to the mapped buffer data for the currect vertex. */
+ uchar *vertex_data = NULL;
+ /** Current vertex index. */
+ uint vertex_idx = 0;
+ /** Length of the buffer in vertices. */
+ uint vertex_len = 0;
+ /** Which attributes of current vertex have not been given values? */
+ uint16_t unassigned_attr_bits = 0;
+ /** Attributes that needs to be set. One bit per attribute. */
+ uint16_t enabled_attr_bits = 0;
+
+ /** Current draw call specification. */
+ GPUPrimType prim_type = GPU_PRIM_NONE;
+ GPUVertFormat vertex_format;
+ GPUShader *shader = NULL;
+ /** Enforce strict vertex count (disabled when using immBeginAtMost). */
+ bool strict_vertex_len = true;
+
+ /** Batch in construction when using immBeginBatch. */
+ GPUBatch *batch = NULL;
+
+ public:
+ Immediate(){};
+ virtual ~Immediate(){};
+
+ virtual uchar *begin(void) = 0;
+ virtual void end(void) = 0;
+};
+
+} // namespace blender::gpu \ No newline at end of file