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:
Diffstat (limited to 'source/blender/gpu/intern/gpu_uniformbuffer.c')
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c395
1 files changed, 196 insertions, 199 deletions
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
index a5559b2558a..651e3c1aaa7 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -35,28 +35,28 @@
#include "GPU_uniformbuffer.h"
typedef enum eGPUUniformBufferFlag {
- GPU_UBO_FLAG_INITIALIZED = (1 << 0),
- GPU_UBO_FLAG_DIRTY = (1 << 1),
+ GPU_UBO_FLAG_INITIALIZED = (1 << 0),
+ GPU_UBO_FLAG_DIRTY = (1 << 1),
} eGPUUniformBufferFlag;
typedef enum eGPUUniformBufferType {
- GPU_UBO_STATIC = 0,
- GPU_UBO_DYNAMIC = 1,
+ GPU_UBO_STATIC = 0,
+ GPU_UBO_DYNAMIC = 1,
} eGPUUniformBufferType;
struct GPUUniformBuffer {
- int size; /* in bytes */
- GLuint bindcode; /* opengl identifier for UBO */
- int bindpoint; /* current binding point */
- eGPUUniformBufferType type;
+ int size; /* in bytes */
+ GLuint bindcode; /* opengl identifier for UBO */
+ int bindpoint; /* current binding point */
+ eGPUUniformBufferType type;
};
#define GPUUniformBufferStatic GPUUniformBuffer
typedef struct GPUUniformBufferDynamic {
- GPUUniformBuffer buffer;
- void *data; /* Continuous memory block to copy to GPU. */
- char flag;
+ GPUUniformBuffer buffer;
+ void *data; /* Continuous memory block to copy to GPU. */
+ char flag;
} GPUUniformBufferDynamic;
/* Prototypes */
@@ -69,38 +69,38 @@ static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data)
{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
{
- GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBufferStatic), "GPUUniformBufferStatic");
- ubo->size = size;
- ubo->bindpoint = -1;
-
- /* Generate Buffer object */
- ubo->bindcode = GPU_buf_alloc();
-
- if (!ubo->bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- if (ubo->size > GPU_max_ubo_size()) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
- }
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- gpu_uniformbuffer_initialize(ubo, data);
- return ubo;
+ GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBufferStatic), "GPUUniformBufferStatic");
+ ubo->size = size;
+ ubo->bindpoint = -1;
+
+ /* Generate Buffer object */
+ ubo->bindcode = GPU_buf_alloc();
+
+ if (!ubo->bindcode) {
+ if (err_out) {
+ BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
+ }
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ if (ubo->size > GPU_max_ubo_size()) {
+ if (err_out) {
+ BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
+ }
+ GPU_uniformbuffer_free(ubo);
+ return NULL;
+ }
+
+ gpu_uniformbuffer_initialize(ubo, data);
+ return ubo;
}
/**
@@ -111,59 +111,60 @@ GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_
*/
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;
- }
-
- GPUUniformBufferDynamic *ubo = MEM_callocN(sizeof(GPUUniformBufferDynamic), "GPUUniformBufferDynamic");
- ubo->buffer.type = GPU_UBO_DYNAMIC;
- ubo->buffer.bindpoint = -1;
- ubo->flag = GPU_UBO_FLAG_DIRTY;
-
- /* Generate Buffer object. */
- ubo->buffer.bindcode = GPU_buf_alloc();
-
- if (!ubo->buffer.bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(&ubo->buffer);
- return NULL;
- }
-
- if (ubo->buffer.size > GPU_max_ubo_size()) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
- }
- GPU_uniformbuffer_free(&ubo->buffer);
- return NULL;
- }
-
- /* Make sure we comply to the ubo alignment requirements. */
- gpu_uniformbuffer_inputs_sort(inputs);
-
- for (LinkData *link = inputs->first; link; link = link->next) {
- const eGPUType gputype = get_padded_gpu_type(link);
- ubo->buffer.size += gputype * sizeof(float);
- }
-
- /* Allocate the data. */
- ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
-
- /* Now that we know the total ubo size we can start populating it. */
- float *offset = ubo->data;
- for (LinkData *link = inputs->first; link; link = link->next) {
- GPUInput *input = link->data;
- memcpy(offset, input->vec, input->type * sizeof(float));
- offset += get_padded_gpu_type(link);
- }
-
- /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one,
- * we don't create the UBO in the GPU here. This will happen when we first bind the UBO.
- */
-
- return &ubo->buffer;
+ /* There is no point on creating an UBO if there is no arguments. */
+ if (BLI_listbase_is_empty(inputs)) {
+ return NULL;
+ }
+
+ GPUUniformBufferDynamic *ubo = MEM_callocN(sizeof(GPUUniformBufferDynamic),
+ "GPUUniformBufferDynamic");
+ ubo->buffer.type = GPU_UBO_DYNAMIC;
+ ubo->buffer.bindpoint = -1;
+ ubo->flag = GPU_UBO_FLAG_DIRTY;
+
+ /* Generate Buffer object. */
+ ubo->buffer.bindcode = GPU_buf_alloc();
+
+ if (!ubo->buffer.bindcode) {
+ if (err_out) {
+ BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
+ }
+ GPU_uniformbuffer_free(&ubo->buffer);
+ return NULL;
+ }
+
+ if (ubo->buffer.size > GPU_max_ubo_size()) {
+ if (err_out) {
+ BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
+ }
+ GPU_uniformbuffer_free(&ubo->buffer);
+ return NULL;
+ }
+
+ /* Make sure we comply to the ubo alignment requirements. */
+ gpu_uniformbuffer_inputs_sort(inputs);
+
+ for (LinkData *link = inputs->first; link; link = link->next) {
+ const eGPUType gputype = get_padded_gpu_type(link);
+ ubo->buffer.size += gputype * sizeof(float);
+ }
+
+ /* Allocate the data. */
+ ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
+
+ /* Now that we know the total ubo size we can start populating it. */
+ float *offset = ubo->data;
+ for (LinkData *link = inputs->first; link; link = link->next) {
+ GPUInput *input = link->data;
+ memcpy(offset, input->vec, input->type * sizeof(float));
+ offset += get_padded_gpu_type(link);
+ }
+
+ /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one,
+ * we don't create the UBO in the GPU here. This will happen when we first bind the UBO.
+ */
+
+ return &ubo->buffer;
}
/**
@@ -171,36 +172,36 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou
*/
static void gpu_uniformbuffer_dynamic_free(GPUUniformBuffer *ubo_)
{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
+ BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
+ GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
- ubo->buffer.size = 0;
- if (ubo->data) {
- MEM_freeN(ubo->data);
- }
+ ubo->buffer.size = 0;
+ if (ubo->data) {
+ MEM_freeN(ubo->data);
+ }
}
void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
{
- if (ubo->type == GPU_UBO_DYNAMIC) {
- gpu_uniformbuffer_dynamic_free(ubo);
- }
+ if (ubo->type == GPU_UBO_DYNAMIC) {
+ gpu_uniformbuffer_dynamic_free(ubo);
+ }
- GPU_buf_free(ubo->bindcode);
- MEM_freeN(ubo);
+ GPU_buf_free(ubo->bindcode);
+ MEM_freeN(ubo);
}
static void gpu_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
{
- BLI_assert(ubo->type == GPU_UBO_STATIC);
- gpu_uniformbuffer_update(ubo, data);
+ BLI_assert(ubo->type == GPU_UBO_STATIC);
+ gpu_uniformbuffer_update(ubo, data);
}
/**
@@ -209,18 +210,18 @@ void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
*/
void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
-
- if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
- gpu_uniformbuffer_update(ubo_, ubo->data);
- }
- else {
- ubo->flag |= GPU_UBO_FLAG_INITIALIZED;
- gpu_uniformbuffer_initialize(ubo_, ubo->data);
- }
-
- ubo->flag &= ~GPU_UBO_FLAG_DIRTY;
+ BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
+ GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
+
+ if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
+ gpu_uniformbuffer_update(ubo_, ubo->data);
+ }
+ else {
+ ubo->flag |= GPU_UBO_FLAG_INITIALIZED;
+ gpu_uniformbuffer_initialize(ubo_, ubo->data);
+ }
+
+ ubo->flag &= ~GPU_UBO_FLAG_DIRTY;
}
/**
@@ -229,18 +230,16 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
*/
static eGPUType get_padded_gpu_type(LinkData *link)
{
- GPUInput *input = 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;
+ GPUInput *input = 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;
}
/**
@@ -249,9 +248,9 @@ static eGPUType get_padded_gpu_type(LinkData *link)
*/
static int inputs_cmp(const void *a, const void *b)
{
- const LinkData *link_a = a, *link_b = b;
- const GPUInput *input_a = link_a->data, *input_b = link_b->data;
- return input_a->type < input_b->type ? 1 : 0;
+ const LinkData *link_a = a, *link_b = b;
+ const GPUInput *input_a = link_a->data, *input_b = link_b->data;
+ return input_a->type < input_b->type ? 1 : 0;
}
/**
@@ -260,82 +259,80 @@ static int inputs_cmp(const void *a, const void *b)
*/
static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
{
- /* Order them as 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 = MAX_UBO_GPU_TYPE + 1;
-
- for (LinkData *link = inputs->first; link; link = link->next) {
- GPUInput *input = link->data;
- if (input->type == cur_type) {
- continue;
- }
- else {
- 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;
- }
+ /* Order them as 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 = MAX_UBO_GPU_TYPE + 1;
+
+ for (LinkData *link = inputs->first; link; link = link->next) {
+ GPUInput *input = link->data;
+ if (input->type == cur_type) {
+ continue;
+ }
+ else {
+ 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;
+ }
}
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
{
- if (number >= GPU_max_ubo_binds()) {
- fprintf(stderr, "Not enough UBO slots.\n");
- return;
- }
-
- if (ubo->type == GPU_UBO_DYNAMIC) {
- GPUUniformBufferDynamic *ubo_dynamic = (GPUUniformBufferDynamic *)ubo;
- if (ubo_dynamic->flag & GPU_UBO_FLAG_DIRTY) {
- GPU_uniformbuffer_dynamic_update(ubo);
- }
- }
-
- if (ubo->bindcode != 0) {
- glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
- }
-
- ubo->bindpoint = number;
+ if (number >= GPU_max_ubo_binds()) {
+ fprintf(stderr, "Not enough UBO slots.\n");
+ return;
+ }
+
+ if (ubo->type == GPU_UBO_DYNAMIC) {
+ GPUUniformBufferDynamic *ubo_dynamic = (GPUUniformBufferDynamic *)ubo;
+ if (ubo_dynamic->flag & GPU_UBO_FLAG_DIRTY) {
+ GPU_uniformbuffer_dynamic_update(ubo);
+ }
+ }
+
+ if (ubo->bindcode != 0) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ }
+
+ ubo->bindpoint = number;
}
void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo)
{
- ubo->bindpoint = -1;
+ ubo->bindpoint = -1;
}
int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
{
- return ubo->bindpoint;
+ return ubo->bindpoint;
}
#undef MAX_UBO_GPU_TYPE