diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_element.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_element.c | 366 |
1 files changed, 186 insertions, 180 deletions
diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 2c80fff75a6..9fcc9821227 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -35,128 +35,134 @@ 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, - }; - return table[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, + }; + return table[type]; } 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), - }; - return elem->index_len * table[elem->index_type]; + 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), + }; + return elem->index_len * table[elem->index_type]; #else - return elem->index_len * sizeof(GLuint); + return elem->index_len * sizeof(GLuint); #endif } int GPU_indexbuf_primitive_len(GPUPrimType prim_type) { - switch (prim_type) { - case GPU_PRIM_POINTS: - return 1; - case GPU_PRIM_LINES: - return 2; - case GPU_PRIM_TRIS: - return 3; - case GPU_PRIM_LINES_ADJ: - return 4; - default: - break; - } + switch (prim_type) { + case GPU_PRIM_POINTS: + return 1; + case GPU_PRIM_LINES: + return 2; + case GPU_PRIM_TRIS: + return 3; + case GPU_PRIM_LINES_ADJ: + return 4; + default: + break; + } #if TRUST_NO_ONE - assert(false); + assert(false); #endif - return -1; + return -1; } -void GPU_indexbuf_init_ex( - GPUIndexBufBuilder *builder, GPUPrimType prim_type, - uint index_len, uint vertex_len, bool use_prim_restart) +void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder, + GPUPrimType prim_type, + uint index_len, + uint vertex_len, + bool use_prim_restart) { - 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 - builder->prim_type = prim_type; - builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data"); + 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 + builder->prim_type = prim_type; + builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data"); } -void GPU_indexbuf_init(GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) +void GPU_indexbuf_init(GPUIndexBufBuilder *builder, + GPUPrimType prim_type, + uint prim_len, + uint vertex_len) { - int verts_per_prim = GPU_indexbuf_primitive_len(prim_type); + int verts_per_prim = GPU_indexbuf_primitive_len(prim_type); #if TRUST_NO_ONE - assert(verts_per_prim != -1); + 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, false); } void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v) { #if TRUST_NO_ONE - assert(builder->data != NULL); - assert(builder->index_len < builder->max_index_len); - assert(v <= builder->max_allowed_index); + assert(builder->data != NULL); + assert(builder->index_len < builder->max_index_len); + assert(v <= builder->max_allowed_index); #endif - builder->data[builder->index_len++] = v; + builder->data[builder->index_len++] = v; } 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); + 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++] = GPU_PRIM_RESTART; } void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *builder, uint v) { #if TRUST_NO_ONE - assert(builder->prim_type == GPU_PRIM_POINTS); + assert(builder->prim_type == GPU_PRIM_POINTS); #endif - GPU_indexbuf_add_generic_vert(builder, v); + GPU_indexbuf_add_generic_vert(builder, v); } void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *builder, uint v1, uint v2) { #if TRUST_NO_ONE - assert(builder->prim_type == GPU_PRIM_LINES); - assert(v1 != v2); + assert(builder->prim_type == GPU_PRIM_LINES); + assert(v1 != v2); #endif - GPU_indexbuf_add_generic_vert(builder, v1); - GPU_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); } void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *builder, uint v1, uint v2, uint v3) { #if TRUST_NO_ONE - assert(builder->prim_type == GPU_PRIM_TRIS); - assert(v1 != v2 && v2 != v3 && v3 != v1); + assert(builder->prim_type == GPU_PRIM_TRIS); + assert(v1 != v2 && v2 != v3 && v3 != v1); #endif - GPU_indexbuf_add_generic_vert(builder, v1); - GPU_indexbuf_add_generic_vert(builder, v2); - GPU_indexbuf_add_generic_vert(builder, v3); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v3); } -void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *builder, uint v1, uint v2, uint v3, uint v4) +void GPU_indexbuf_add_line_adj_verts( + GPUIndexBufBuilder *builder, uint v1, uint v2, uint v3, uint v4) { #if TRUST_NO_ONE - assert(builder->prim_type == GPU_PRIM_LINES_ADJ); - assert(v2 != v3); /* only the line need diff indices */ + assert(builder->prim_type == GPU_PRIM_LINES_ADJ); + assert(v2 != v3); /* only the line need diff indices */ #endif - GPU_indexbuf_add_generic_vert(builder, v1); - GPU_indexbuf_add_generic_vert(builder, v2); - GPU_indexbuf_add_generic_vert(builder, v3); - GPU_indexbuf_add_generic_vert(builder, v4); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v3); + GPU_indexbuf_add_generic_vert(builder, v4); } #if GPU_TRACK_INDEX_RANGE @@ -165,154 +171,154 @@ void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *builder, uint v1, uint static uint index_range(const uint values[], uint value_len, uint *min_out, uint *max_out) { - if (value_len == 0) { - *min_out = 0; - *max_out = 0; - return 0; - } - uint min_value = values[0]; - uint max_value = values[0]; - for (uint i = 1; i < value_len; ++i) { - const uint value = values[i]; - if (value == GPU_PRIM_RESTART) - continue; - else 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; + if (value_len == 0) { + *min_out = 0; + *max_out = 0; + return 0; + } + uint min_value = values[0]; + uint max_value = values[0]; + for (uint i = 1; i < value_len; ++i) { + const uint value = values[i]; + if (value == GPU_PRIM_RESTART) + continue; + else 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(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]); - } - } + 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) { - 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 */ - 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; - for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); - } - } - else { - elem->base_index = 0; - for (uint i = 0; i < index_len; ++i) { - data[i] = (GLushort)(values[i]); - } - } + 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 */ + 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; + for (uint i = 0; i < index_len; ++i) { + data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); + } + } + else { + elem->base_index = 0; + for (uint i = 0; i < index_len; ++i) { + data[i] = (GLushort)(values[i]); + } + } } #endif /* GPU_TRACK_INDEX_RANGE */ GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder) { - GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); - GPU_indexbuf_build_in_place(builder, elem); - return elem; + GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); + GPU_indexbuf_build_in_place(builder, elem); + return elem; } void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) { #if TRUST_NO_ONE - assert(builder->data != NULL); + 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. */ + 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); - - /* count the primitive restart index. */ - if (elem->use_prim_restart) { - range += 1; - } - - if (range <= 0xFF) { - elem->index_type = GPU_INDEX_U8; - squeeze_indices_byte(builder, elem); - } - else if (range <= 0xFFFF) { - elem->index_type = GPU_INDEX_U16; - squeeze_indices_short(builder, elem); - } - else { - elem->index_type = GPU_INDEX_U32; - elem->base_index = 0; - } - elem->gl_index_type = convert_index_type_to_gl(elem->index_type); + uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); + + /* count the primitive restart index. */ + if (elem->use_prim_restart) { + range += 1; + } + + if (range <= 0xFF) { + elem->index_type = GPU_INDEX_U8; + squeeze_indices_byte(builder, elem); + } + else if (range <= 0xFFFF) { + elem->index_type = GPU_INDEX_U16; + squeeze_indices_short(builder, elem); + } + else { + elem->index_type = GPU_INDEX_U32; + elem->base_index = 0; + } + elem->gl_index_type = convert_index_type_to_gl(elem->index_type); #endif - /* Transfer data ownership to GPUIndexBuf. - * It will be uploaded upon first use. */ - elem->data = builder->data; - builder->data = NULL; - /* other fields are safe to leave */ + /* Transfer data ownership to GPUIndexBuf. + * It will be uploaded upon first use. */ + elem->data = builder->data; + builder->data = NULL; + /* other fields are safe to leave */ } static void indexbuf_upload_data(GPUIndexBuf *elem) { - /* send data to GPU */ - glBufferData(GL_ELEMENT_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), elem->data, GL_STATIC_DRAW); - /* No need to keep copy of data in system memory. */ - MEM_freeN(elem->data); - elem->data = NULL; + /* send data to GPU */ + glBufferData(GL_ELEMENT_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), elem->data, GL_STATIC_DRAW); + /* No need to keep copy of data in system memory. */ + MEM_freeN(elem->data); + elem->data = NULL; } void GPU_indexbuf_use(GPUIndexBuf *elem) { - if (elem->ibo_id == 0) { - elem->ibo_id = GPU_buf_alloc(); - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->ibo_id); - if (elem->data != NULL) { - indexbuf_upload_data(elem); - } + if (elem->ibo_id == 0) { + elem->ibo_id = GPU_buf_alloc(); + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->ibo_id); + if (elem->data != NULL) { + indexbuf_upload_data(elem); + } } void GPU_indexbuf_discard(GPUIndexBuf *elem) { - if (elem->ibo_id) { - GPU_buf_free(elem->ibo_id); - } - if (elem->data) { - MEM_freeN(elem->data); - } - MEM_freeN(elem); + if (elem->ibo_id) { + GPU_buf_free(elem->ibo_id); + } + if (elem->data) { + MEM_freeN(elem->data); + } + MEM_freeN(elem); } |