diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_element.h | 10 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch.c | 40 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 10 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_element.c | 71 |
4 files changed, 41 insertions, 90 deletions
diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h index d1a199f8193..4ac89d2658b 100644 --- a/source/blender/gpu/GPU_element.h +++ b/source/blender/gpu/GPU_element.h @@ -30,10 +30,7 @@ #define GPU_TRACK_INDEX_RANGE 1 -#define GPU_PRIM_RESTART 0xFFFFFFFF - typedef enum { - GPU_INDEX_U8, /* GL has this, Vulkan does not */ GPU_INDEX_U16, GPU_INDEX_U32, } GPUIndexBufType; @@ -43,13 +40,10 @@ typedef struct GPUIndexBuf { #if GPU_TRACK_INDEX_RANGE GPUIndexBufType index_type; uint32_t gl_index_type; - uint min_index; - uint max_index; uint base_index; #endif uint32_t ibo_id; /* 0 indicates not yet sent to VRAM */ void *data; /* non-NULL indicates not yet sent to VRAM */ - bool use_prim_restart; } GPUIndexBuf; void GPU_indexbuf_use(GPUIndexBuf *); @@ -61,12 +55,10 @@ typedef struct GPUIndexBufBuilder { uint index_len; GPUPrimType prim_type; uint *data; - bool use_prim_restart; } GPUIndexBufBuilder; /* supports all primitive types. */ -void GPU_indexbuf_init_ex( - GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len, bool use_prim_restart); +void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len); /* supports only GPU_PRIM_POINTS, GPU_PRIM_LINES and GPU_PRIM_TRIS. */ void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len); diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index d1cfd5c337d..fb2a87fc8d1 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -545,36 +545,26 @@ void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[ glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); } -static void primitive_restart_enable(const GPUIndexBuf *el) +static void primitive_restart_index(const GPUIndexBuf *el) { - // TODO(fclem) Replace by GL_PRIMITIVE_RESTART_FIXED_INDEX when we have ogl 4.3 - glEnable(GL_PRIMITIVE_RESTART); - GLuint restart_index = (GLuint)0xFFFFFFFF; - #if GPU_TRACK_INDEX_RANGE - if (el->index_type == GPU_INDEX_U8) { - restart_index = (GLuint)0xFF; - } - else if (el->index_type == GPU_INDEX_U16) { - restart_index = (GLuint)0xFFFF; + /* Can be removed if GL 4.3 is available. */ + if (!GLEW_ARB_ES3_compatibility) { + /* Stay sync with GPU_state_init(). */ + static int last_type = GPU_INDEX_U32; + if (el->index_type != last_type) { + GLuint restart_index = (el->index_type == GPU_INDEX_U16) ? (GLuint)0xFFFF : + (GLuint)0xFFFFFFFF; + glPrimitiveRestartIndex(restart_index); + } } #endif - - glPrimitiveRestartIndex(restart_index); -} - -static void primitive_restart_disable(void) -{ - glDisable(GL_PRIMITIVE_RESTART); } static void *elem_offset(const GPUIndexBuf *el, int v_first) { #if GPU_TRACK_INDEX_RANGE - if (el->index_type == GPU_INDEX_U8) { - return (GLubyte *)0 + v_first; - } - else if (el->index_type == GPU_INDEX_U16) { + if (el->index_type == GPU_INDEX_U16) { return (GLushort *)0 + v_first; } #endif @@ -641,9 +631,7 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi #endif void *v_first_ofs = elem_offset(el, v_first); - if (el->use_prim_restart) { - primitive_restart_enable(el); - } + primitive_restart_index(el); if (GLEW_ARB_base_instance) { glDrawElementsInstancedBaseVertexBaseInstance( @@ -653,10 +641,6 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi glDrawElementsInstancedBaseVertex( batch->gl_prim_type, v_count, index_type, v_first_ofs, i_count, base_index); } - - if (el->use_prim_restart) { - primitive_restart_disable(); - } } else { if (GLEW_ARB_base_instance) { diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 5f27a0e93cd..c3c05c39c00 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1372,6 +1372,16 @@ void GPU_state_init(void) glDisable(GL_CULL_FACE); gpu_disable_multisample(); + + /* This is a bit dangerous since addons could change this. */ + glEnable(GL_PRIMITIVE_RESTART); + glPrimitiveRestartIndex((GLuint)0xFFFFFFFF); + + /* TODO: Should become default. But needs at least GL 4.3 */ + if (GLEW_ARB_ES3_compatibility) { + /* Takes predecence over GL_PRIMITIVE_RESTART */ + glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + } } /** \name Framebuffer color depth, for selection codes diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 0b7f37af522..380de4c4e65 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -33,10 +33,11 @@ #define KEEP_SINGLE_COPY 1 +#define RESTART_INDEX 0xFFFFFFFF + static GLenum convert_index_type_to_gl(GPUIndexBufType type) { static const GLenum table[] = { - [GPU_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ [GPU_INDEX_U16] = GL_UNSIGNED_SHORT, [GPU_INDEX_U32] = GL_UNSIGNED_INT, }; @@ -47,7 +48,6 @@ uint GPU_indexbuf_size_get(const GPUIndexBuf *elem) { #if GPU_TRACK_INDEX_RANGE static const uint table[] = { - [GPU_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ [GPU_INDEX_U16] = sizeof(GLushort), [GPU_INDEX_U32] = sizeof(GLuint), }; @@ -80,10 +80,8 @@ int GPU_indexbuf_primitive_len(GPUPrimType prim_type) void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint index_len, - uint vertex_len, - bool use_prim_restart) + uint vertex_len) { - builder->use_prim_restart = use_prim_restart; builder->max_allowed_index = vertex_len - 1; builder->max_index_len = index_len; builder->index_len = 0; // start empty @@ -100,7 +98,7 @@ void GPU_indexbuf_init(GPUIndexBufBuilder *builder, #if TRUST_NO_ONE assert(verts_per_prim != -1); #endif - GPU_indexbuf_init_ex(builder, prim_type, prim_len * (uint)verts_per_prim, vertex_len, false); + GPU_indexbuf_init_ex(builder, prim_type, prim_len * (uint)verts_per_prim, vertex_len); } void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v) @@ -118,9 +116,8 @@ void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *builder) #if TRUST_NO_ONE assert(builder->data != NULL); assert(builder->index_len < builder->max_index_len); - assert(builder->use_prim_restart); #endif - builder->data[builder->index_len++] = GPU_PRIM_RESTART; + builder->data[builder->index_len++] = RESTART_INDEX; } void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *builder, uint v) @@ -180,7 +177,7 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint uint max_value = values[0]; for (uint i = 1; i < value_len; ++i) { const uint value = values[i]; - if (value == GPU_PRIM_RESTART) { + if (value == RESTART_INDEX) { continue; } else if (value < min_value) { @@ -195,33 +192,10 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint return max_value - min_value; } -static void squeeze_indices_byte(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) -{ - const uint *values = builder->data; - const uint index_len = elem->index_len; - - /* data will never be *larger* than builder->data... - * converting in place to avoid extra allocation */ - GLubyte *data = (GLubyte *)builder->data; - - if (elem->max_index > 0xFF) { - const uint base = elem->min_index; - elem->base_index = base; - elem->min_index = 0; - elem->max_index -= base; - for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); - } - } - else { - elem->base_index = 0; - for (uint i = 0; i < index_len; ++i) { - data[i] = (GLubyte)(values[i]); - } - } -} - -static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) +static void squeeze_indices_short(GPUIndexBufBuilder *builder, + GPUIndexBuf *elem, + uint min_index, + uint max_index) { const uint *values = builder->data; const uint index_len = elem->index_len; @@ -230,13 +204,10 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf *elem * converting in place to avoid extra allocation */ GLushort *data = (GLushort *)builder->data; - if (elem->max_index > 0xFFFF) { - const uint base = elem->min_index; - elem->base_index = base; - elem->min_index = 0; - elem->max_index -= base; + if (max_index > 0xFFFF) { + elem->base_index = min_index; for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); + data[i] = (values[i] == RESTART_INDEX) ? 0xFFFF : (GLushort)(values[i] - min_index); } } else { @@ -262,24 +233,18 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) assert(builder->data != NULL); #endif elem->index_len = builder->index_len; - elem->use_prim_restart = builder->use_prim_restart; elem->ibo_id = 0; /* Created at first use. */ #if GPU_TRACK_INDEX_RANGE - uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); + uint min_index, max_index; + uint range = index_range(builder->data, builder->index_len, &min_index, &max_index); /* count the primitive restart index. */ - if (elem->use_prim_restart) { - range += 1; - } + range += 1; - if (range <= 0xFF) { - elem->index_type = GPU_INDEX_U8; - squeeze_indices_byte(builder, elem); - } - else if (range <= 0xFFFF) { + if (range <= 0xFFFF) { elem->index_type = GPU_INDEX_U16; - squeeze_indices_short(builder, elem); + squeeze_indices_short(builder, elem, min_index, max_index); } else { elem->index_type = GPU_INDEX_U32; |