From 7edd8a7738481b3d4f0720a173dca2a1853996d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 20 Aug 2020 23:09:37 +0200 Subject: GPUUniformBuf: Rename struct and change API a bit This follows the GPU module naming of other buffers. We pass name to distinguish each GPUUniformBuf in debug mode. Also remove DRW_uniform_buffer interface. --- source/blender/gpu/intern/gpu_codegen.c | 2 +- source/blender/gpu/intern/gpu_material.c | 37 ++-- source/blender/gpu/intern/gpu_node_graph.c | 8 +- source/blender/gpu/intern/gpu_shader.cc | 2 +- source/blender/gpu/intern/gpu_shader_builtin.c | 2 +- source/blender/gpu/intern/gpu_uniform_buffer.cc | 282 ++++++++++++++++++++++++ source/blender/gpu/intern/gpu_uniformbuffer.cc | 276 ----------------------- source/blender/gpu/intern/gpu_viewport.c | 6 +- 8 files changed, 313 insertions(+), 302 deletions(-) create mode 100644 source/blender/gpu/intern/gpu_uniform_buffer.cc delete mode 100644 source/blender/gpu/intern/gpu_uniformbuffer.cc (limited to 'source/blender/gpu/intern') diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index b051d4fe59a..1629584e841 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -43,7 +43,7 @@ #include "GPU_extensions.h" #include "GPU_material.h" #include "GPU_shader.h" -#include "GPU_uniformbuffer.h" +#include "GPU_uniform_buffer.h" #include "GPU_vertex_format.h" #include "BLI_sys_types.h" /* for intptr_t support */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 8df1f94238a..95fb0aa56fc 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -47,7 +47,7 @@ #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_texture.h" -#include "GPU_uniformbuffer.h" +#include "GPU_uniform_buffer.h" #include "DRW_engine.h" @@ -88,11 +88,11 @@ struct GPUMaterial { eGPUMatFlag flag; /* Used by 2.8 pipeline */ - GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ + GPUUniformBuf *ubo; /* UBOs for shader uniforms. */ /* Eevee SSS */ - GPUUniformBuffer *sss_profile; /* UBO containing SSS profile. */ - GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */ + GPUUniformBuf *sss_profile; /* UBO containing SSS profile. */ + GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */ float sss_enabled; float sss_radii[3]; int sss_samples; @@ -174,13 +174,13 @@ static void gpu_material_free_single(GPUMaterial *material) GPU_pass_release(material->pass); } if (material->ubo != NULL) { - GPU_uniformbuffer_free(material->ubo); + GPU_uniformbuf_free(material->ubo); } if (material->sss_tex_profile != NULL) { GPU_texture_free(material->sss_tex_profile); } if (material->sss_profile != NULL) { - GPU_uniformbuffer_free(material->sss_profile); + GPU_uniformbuf_free(material->sss_profile); } if (material->coba_tex != NULL) { GPU_texture_free(material->coba_tex); @@ -220,7 +220,7 @@ Material *GPU_material_get_material(GPUMaterial *material) return material->ma; } -GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material) +GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material) { return material->ubo; } @@ -232,7 +232,12 @@ GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material) */ void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs) { - material->ubo = GPU_uniformbuffer_dynamic_create(inputs, NULL); +#ifndef NDEBUG + const char *name = material->name; +#else + const char *name = NULL; +#endif + material->ubo = GPU_uniformbuf_dynamic_create(inputs, name); } /* Eevee Subsurface scattering. */ @@ -507,13 +512,13 @@ void GPU_material_sss_profile_create(GPUMaterial *material, /* Update / Create UBO */ if (material->sss_profile == NULL) { - material->sss_profile = GPU_uniformbuffer_create(sizeof(GPUSssKernelData), NULL, NULL); + material->sss_profile = GPU_uniformbuf_create(sizeof(GPUSssKernelData)); } } -struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, - int sample_len, - GPUTexture **tex_profile) +struct GPUUniformBuf *GPU_material_sss_profile_get(GPUMaterial *material, + int sample_len, + GPUTexture **tex_profile) { if (!material->sss_enabled) { return NULL; @@ -530,7 +535,7 @@ struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, compute_sss_kernel(&kd, material->sss_radii, sample_len, material->sss_falloff, sharpness); /* Update / Create UBO */ - GPU_uniformbuffer_update(material->sss_profile, &kd); + GPU_uniformbuf_update(material->sss_profile, &kd); /* Update / Create Tex */ float *translucence_profile; @@ -555,9 +560,9 @@ struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, return material->sss_profile; } -struct GPUUniformBuffer *GPU_material_create_sss_profile_ubo(void) +struct GPUUniformBuf *GPU_material_create_sss_profile_ubo(void) { - return GPU_uniformbuffer_create(sizeof(GPUSssKernelData), NULL, NULL); + return GPU_uniformbuf_create(sizeof(GPUSssKernelData)); } #undef SSS_EXPONENT @@ -735,7 +740,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene, gpu_node_graph_free(&mat->graph); } - /* Only free after GPU_pass_shader_get where GPUUniformBuffer + /* Only free after GPU_pass_shader_get where GPUUniformBuf * read data from the local tree. */ ntreeFreeLocalTree(localtree); MEM_freeN(localtree); diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 81cf2d69f4d..1b8a5e20240 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -592,10 +592,10 @@ bool GPU_stack_link(GPUMaterial *material, return true; } -GPUNodeLink *GPU_uniformbuffer_link_out(GPUMaterial *mat, - bNode *node, - GPUNodeStack *stack, - const int index) +GPUNodeLink *GPU_uniformbuf_link_out(GPUMaterial *mat, + bNode *node, + GPUNodeStack *stack, + const int index) { return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT); } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 21678548b13..9437da19b78 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -41,7 +41,7 @@ #include "GPU_platform.h" #include "GPU_shader.h" #include "GPU_texture.h" -#include "GPU_uniformbuffer.h" +#include "GPU_uniform_buffer.h" #include "gpu_backend.hh" #include "gpu_context_private.hh" diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c index da5bcaeca17..ed95a236da5 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -40,7 +40,7 @@ #include "GPU_platform.h" #include "GPU_shader.h" #include "GPU_texture.h" -#include "GPU_uniformbuffer.h" +#include "GPU_uniform_buffer.h" /* Adjust these constants as needed. */ #define MAX_DEFINE_LENGTH 256 diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc new file mode 100644 index 00000000000..76459dcf9f0 --- /dev/null +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -0,0 +1,282 @@ +/* + * 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) 2005 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "MEM_guardedalloc.h" +#include + +#include "BLI_blenlib.h" +#include "BLI_math_base.h" + +#include "gpu_context_private.hh" +#include "gpu_node_graph.h" + +#include "GPU_extensions.h" +#include "GPU_glew.h" +#include "GPU_material.h" +#include "GPU_uniform_buffer.h" + +typedef struct GPUUniformBuf { + /** Data size in bytes. */ + int size; + /** GL handle for UBO. */ + GLuint bindcode; + /** Current binding point. */ + int bindpoint; + /** Continuous memory block to copy to GPU. Is own by the GPUUniformBuf. */ + void *data; + +#ifndef NDEBUG + char name[64]; +#endif +} GPUUniformBuf; + +GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name) +{ + /* Make sure that UBO is padded to size of vec4 */ + BLI_assert((size % 16) == 0); + + if (size > GPU_max_ubo_size()) { + fprintf(stderr, "GPUUniformBuf: UBO too big. %s", name); + return NULL; + } + + GPUUniformBuf *ubo = (GPUUniformBuf *)MEM_mallocN(sizeof(GPUUniformBuf), __func__); + ubo->size = size; + ubo->data = NULL; + ubo->bindcode = 0; + ubo->bindpoint = -1; + +#ifndef NDEBUG + BLI_strncpy(ubo->name, name, sizeof(ubo->name)); +#endif + + /* Direct init. */ + if (data != NULL) { + GPU_uniformbuf_update(ubo, data); + } + + return ubo; +} + +void GPU_uniformbuf_free(GPUUniformBuf *ubo) +{ + MEM_SAFE_FREE(ubo->data); + GPU_buf_free(ubo->bindcode); + MEM_freeN(ubo); +} + +/** + * We need to pad some data types (vec3) on the C side + * To match the GPU expected memory block alignment. + */ +static eGPUType get_padded_gpu_type(LinkData *link) +{ + GPUInput *input = (GPUInput *)link->data; + eGPUType gputype = input->type; + /* Unless the vec3 is followed by a float we need to treat it as a vec4. */ + if (gputype == GPU_VEC3 && (link->next != NULL) && + (((GPUInput *)link->next->data)->type != GPU_FLOAT)) { + gputype = GPU_VEC4; + } + return gputype; +} + +/** + * Returns 1 if the first item should be after second item. + * We make sure the vec4 uniforms come first. + */ +static int inputs_cmp(const void *a, const void *b) +{ + const LinkData *link_a = (const LinkData *)a, *link_b = (const LinkData *)b; + const GPUInput *input_a = (const GPUInput *)link_a->data; + const GPUInput *input_b = (const GPUInput *)link_b->data; + return input_a->type < input_b->type ? 1 : 0; +} + +/** + * Make sure we respect the expected alignment of UBOs. + * mat4, vec4, pad vec3 as vec4, then vec2, then floats. + */ +static void gpu_uniformbuffer_inputs_sort(ListBase *inputs) +{ +/* Only support up to this type, if you want to extend it, make sure the + * padding logic is correct for the new types. */ +#define MAX_UBO_GPU_TYPE GPU_MAT4 + + /* Order them as mat4, vec4, vec3, vec2, float. */ + BLI_listbase_sort(inputs, inputs_cmp); + + /* Creates a lookup table for the different types; */ + LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL}; + eGPUType cur_type = static_cast(MAX_UBO_GPU_TYPE + 1); + + LISTBASE_FOREACH (LinkData *, link, inputs) { + GPUInput *input = (GPUInput *)link->data; + + if (input->type == GPU_MAT3) { + /* Alignment for mat3 is not handled currently, so not supported */ + BLI_assert(!"mat3 not supported in UBO"); + continue; + } + if (input->type > MAX_UBO_GPU_TYPE) { + BLI_assert(!"GPU type not supported in UBO"); + continue; + } + + if (input->type == cur_type) { + continue; + } + + inputs_lookup[input->type] = link; + cur_type = input->type; + } + + /* If there is no GPU_VEC3 there is no need for alignment. */ + if (inputs_lookup[GPU_VEC3] == NULL) { + return; + } + + LinkData *link = inputs_lookup[GPU_VEC3]; + while (link != NULL && ((GPUInput *)link->data)->type == GPU_VEC3) { + LinkData *link_next = link->next; + + /* If GPU_VEC3 is followed by nothing or a GPU_FLOAT, no need for alignment. */ + if ((link_next == NULL) || ((GPUInput *)link_next->data)->type == GPU_FLOAT) { + break; + } + + /* If there is a float, move it next to current vec3. */ + if (inputs_lookup[GPU_FLOAT] != NULL) { + LinkData *float_input = inputs_lookup[GPU_FLOAT]; + inputs_lookup[GPU_FLOAT] = float_input->next; + + BLI_remlink(inputs, float_input); + BLI_insertlinkafter(inputs, link, float_input); + } + + link = link_next; + } +#undef MAX_UBO_GPU_TYPE +} + +/** + * Create dynamic UBO from parameters + * Return NULL if failed to create or if \param inputs: is empty. + * + * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput). + */ +GPUUniformBuf *GPU_uniformbuf_dynamic_create(ListBase *inputs, const char *name) +{ + /* There is no point on creating an UBO if there is no arguments. */ + if (BLI_listbase_is_empty(inputs)) { + return NULL; + } + /* Make sure we comply to the ubo alignment requirements. */ + gpu_uniformbuffer_inputs_sort(inputs); + + size_t buffer_size = 0; + + LISTBASE_FOREACH (LinkData *, link, inputs) { + const eGPUType gputype = get_padded_gpu_type(link); + buffer_size += gputype * sizeof(float); + } + /* Round up to size of vec4. (Opengl Requirement) */ + size_t alignment = sizeof(float[4]); + buffer_size = divide_ceil_u(buffer_size, alignment) * alignment; + void *data = MEM_mallocN(buffer_size, __func__); + + /* Now that we know the total ubo size we can start populating it. */ + float *offset = (float *)data; + LISTBASE_FOREACH (LinkData *, link, inputs) { + GPUInput *input = (GPUInput *)link->data; + memcpy(offset, input->vec, input->type * sizeof(float)); + offset += get_padded_gpu_type(link); + } + + /* Pass data as NULL for late init. */ + GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(buffer_size, NULL, name); + /* Data will be update just before binding. */ + ubo->data = data; + return ubo; +} + +static void gpu_uniformbuffer_init(GPUUniformBuf *ubo) +{ + BLI_assert(ubo->bindcode == 0); + ubo->bindcode = GPU_buf_alloc(); + + if (ubo->bindcode == 0) { + fprintf(stderr, "GPUUniformBuf: UBO create failed"); + BLI_assert(0); + return; + } + + glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); + glBufferData(GL_UNIFORM_BUFFER, ubo->size, NULL, GL_DYNAMIC_DRAW); +} + +void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data) +{ + if (ubo->bindcode == 0) { + gpu_uniformbuffer_init(ubo); + } + + glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); + glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +void GPU_uniformbuf_bind(GPUUniformBuf *ubo, int number) +{ + if (number >= GPU_max_ubo_binds()) { + fprintf(stderr, "GPUUniformBuf: UBO too big."); + return; + } + + if (ubo->bindcode == 0) { + gpu_uniformbuffer_init(ubo); + } + + if (ubo->data != NULL) { + GPU_uniformbuf_update(ubo, ubo->data); + MEM_SAFE_FREE(ubo->data); + } + + glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode); + ubo->bindpoint = number; +} + +void GPU_uniformbuf_unbind(GPUUniformBuf *ubo) +{ +#ifndef NDEBUG + glBindBufferBase(GL_UNIFORM_BUFFER, ubo->bindpoint, 0); +#endif + ubo->bindpoint = 0; +} + +void GPU_uniformbuf_unbind_all(void) +{ + for (int i = 0; i < GPU_max_ubo_binds(); i++) { + glBindBufferBase(GL_UNIFORM_BUFFER, i, 0); + } +} diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.cc b/source/blender/gpu/intern/gpu_uniformbuffer.cc deleted file mode 100644 index e203ffd848f..00000000000 --- a/source/blender/gpu/intern/gpu_uniformbuffer.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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) 2005 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup gpu - */ - -#include "MEM_guardedalloc.h" -#include - -#include "BLI_blenlib.h" -#include "BLI_math_base.h" - -#include "gpu_context_private.hh" -#include "gpu_node_graph.h" - -#include "GPU_extensions.h" -#include "GPU_glew.h" -#include "GPU_material.h" -#include "GPU_uniformbuffer.h" - -typedef struct GPUUniformBuffer { - /** Data size in bytes. */ - int size; - /** GL handle for UBO. */ - GLuint bindcode; - /** Current binding point. */ - int bindpoint; - /** Continuous memory block to copy to GPU. Is own by the GPUUniformBuffer. */ - void *data; -} GPUUniformBuffer; - -GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]) -{ - /* Make sure that UBO is padded to size of vec4 */ - BLI_assert((size % 16) == 0); - - if (size > GPU_max_ubo_size()) { - if (err_out) { - BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256); - } - return NULL; - } - - GPUUniformBuffer *ubo = (GPUUniformBuffer *)MEM_mallocN(sizeof(GPUUniformBuffer), __func__); - ubo->size = size; - ubo->data = NULL; - ubo->bindcode = 0; - ubo->bindpoint = -1; - - /* Direct init. */ - if (data != NULL) { - GPU_uniformbuffer_update(ubo, data); - } - - return ubo; -} - -void GPU_uniformbuffer_free(GPUUniformBuffer *ubo) -{ - MEM_SAFE_FREE(ubo->data); - GPU_buf_free(ubo->bindcode); - MEM_freeN(ubo); -} - -/** - * We need to pad some data types (vec3) on the C side - * To match the GPU expected memory block alignment. - */ -static eGPUType get_padded_gpu_type(LinkData *link) -{ - GPUInput *input = (GPUInput *)link->data; - eGPUType gputype = input->type; - /* Unless the vec3 is followed by a float we need to treat it as a vec4. */ - if (gputype == GPU_VEC3 && (link->next != NULL) && - (((GPUInput *)link->next->data)->type != GPU_FLOAT)) { - gputype = GPU_VEC4; - } - return gputype; -} - -/** - * Returns 1 if the first item should be after second item. - * We make sure the vec4 uniforms come first. - */ -static int inputs_cmp(const void *a, const void *b) -{ - const LinkData *link_a = (const LinkData *)a, *link_b = (const LinkData *)b; - const GPUInput *input_a = (const GPUInput *)link_a->data; - const GPUInput *input_b = (const GPUInput *)link_b->data; - return input_a->type < input_b->type ? 1 : 0; -} - -/** - * Make sure we respect the expected alignment of UBOs. - * mat4, vec4, pad vec3 as vec4, then vec2, then floats. - */ -static void gpu_uniformbuffer_inputs_sort(ListBase *inputs) -{ -/* Only support up to this type, if you want to extend it, make sure the - * padding logic is correct for the new types. */ -#define MAX_UBO_GPU_TYPE GPU_MAT4 - - /* Order them as mat4, vec4, vec3, vec2, float. */ - BLI_listbase_sort(inputs, inputs_cmp); - - /* Creates a lookup table for the different types; */ - LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL}; - eGPUType cur_type = static_cast(MAX_UBO_GPU_TYPE + 1); - - LISTBASE_FOREACH (LinkData *, link, inputs) { - GPUInput *input = (GPUInput *)link->data; - - if (input->type == GPU_MAT3) { - /* Alignment for mat3 is not handled currently, so not supported */ - BLI_assert(!"mat3 not supported in UBO"); - continue; - } - if (input->type > MAX_UBO_GPU_TYPE) { - BLI_assert(!"GPU type not supported in UBO"); - continue; - } - - if (input->type == cur_type) { - continue; - } - - inputs_lookup[input->type] = link; - cur_type = input->type; - } - - /* If there is no GPU_VEC3 there is no need for alignment. */ - if (inputs_lookup[GPU_VEC3] == NULL) { - return; - } - - LinkData *link = inputs_lookup[GPU_VEC3]; - while (link != NULL && ((GPUInput *)link->data)->type == GPU_VEC3) { - LinkData *link_next = link->next; - - /* If GPU_VEC3 is followed by nothing or a GPU_FLOAT, no need for alignment. */ - if ((link_next == NULL) || ((GPUInput *)link_next->data)->type == GPU_FLOAT) { - break; - } - - /* If there is a float, move it next to current vec3. */ - if (inputs_lookup[GPU_FLOAT] != NULL) { - LinkData *float_input = inputs_lookup[GPU_FLOAT]; - inputs_lookup[GPU_FLOAT] = float_input->next; - - BLI_remlink(inputs, float_input); - BLI_insertlinkafter(inputs, link, float_input); - } - - link = link_next; - } -#undef MAX_UBO_GPU_TYPE -} - -/** - * Create dynamic UBO from parameters - * Return NULL if failed to create or if \param inputs: is empty. - * - * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput). - */ -GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256]) -{ - /* There is no point on creating an UBO if there is no arguments. */ - if (BLI_listbase_is_empty(inputs)) { - return NULL; - } - /* Make sure we comply to the ubo alignment requirements. */ - gpu_uniformbuffer_inputs_sort(inputs); - - size_t buffer_size = 0; - - LISTBASE_FOREACH (LinkData *, link, inputs) { - const eGPUType gputype = get_padded_gpu_type(link); - buffer_size += gputype * sizeof(float); - } - /* Round up to size of vec4. (Opengl Requirement) */ - size_t alignment = sizeof(float[4]); - buffer_size = divide_ceil_u(buffer_size, alignment) * alignment; - void *data = MEM_mallocN(buffer_size, __func__); - - /* Now that we know the total ubo size we can start populating it. */ - float *offset = (float *)data; - LISTBASE_FOREACH (LinkData *, link, inputs) { - GPUInput *input = (GPUInput *)link->data; - memcpy(offset, input->vec, input->type * sizeof(float)); - offset += get_padded_gpu_type(link); - } - - /* Pass data as NULL for late init. */ - GPUUniformBuffer *ubo = GPU_uniformbuffer_create(buffer_size, NULL, err_out); - /* Data will be update just before binding. */ - ubo->data = data; - return ubo; -} - -static void gpu_uniformbuffer_init(GPUUniformBuffer *ubo) -{ - BLI_assert(ubo->bindcode == 0); - ubo->bindcode = GPU_buf_alloc(); - - if (ubo->bindcode == 0) { - fprintf(stderr, "GPUUniformBuffer: UBO create failed"); - BLI_assert(0); - return; - } - - glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); - glBufferData(GL_UNIFORM_BUFFER, ubo->size, NULL, GL_DYNAMIC_DRAW); -} - -void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data) -{ - if (ubo->bindcode == 0) { - gpu_uniformbuffer_init(ubo); - } - - glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode); - glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); -} - -void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number) -{ - if (number >= GPU_max_ubo_binds()) { - fprintf(stderr, "Not enough UBO slots.\n"); - return; - } - - if (ubo->bindcode == 0) { - gpu_uniformbuffer_init(ubo); - } - - if (ubo->data != NULL) { - GPU_uniformbuffer_update(ubo, ubo->data); - MEM_SAFE_FREE(ubo->data); - } - - glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode); - ubo->bindpoint = number; -} - -void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo) -{ -#ifndef NDEBUG - glBindBufferBase(GL_UNIFORM_BUFFER, ubo->bindpoint, 0); -#endif - ubo->bindpoint = 0; -} - -void GPU_uniformbuffer_unbind_all(void) -{ - for (int i = 0; i < GPU_max_ubo_binds(); i++) { - glBindBufferBase(GL_UNIFORM_BUFFER, i, 0); - } -} diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index ba938349761..fd1265dc2a6 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -41,7 +41,7 @@ #include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_texture.h" -#include "GPU_uniformbuffer.h" +#include "GPU_uniform_buffer.h" #include "GPU_viewport.h" #include "DRW_engine.h" @@ -1020,8 +1020,8 @@ void GPU_viewport_free(GPUViewport *viewport) } for (int i = 0; i < viewport->vmempool.ubo_len; i++) { - GPU_uniformbuffer_free(viewport->vmempool.matrices_ubo[i]); - GPU_uniformbuffer_free(viewport->vmempool.obinfos_ubo[i]); + GPU_uniformbuf_free(viewport->vmempool.matrices_ubo[i]); + GPU_uniformbuf_free(viewport->vmempool.obinfos_ubo[i]); } MEM_SAFE_FREE(viewport->vmempool.matrices_ubo); MEM_SAFE_FREE(viewport->vmempool.obinfos_ubo); -- cgit v1.2.3