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>2017-09-12 00:15:29 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-09-12 00:15:29 +0300
commitd126ffbea4fc549072100022c8be15bd4e3f62ca (patch)
tree5360575e84f51c903a37ed4be28d3d4810ce3eb1 /source/blender/draw/intern
parent4757404eef04267880ed114823332818087e8aee (diff)
DRW: Use static list (array) of texture/ubo to track bound textures/ubos.
This is in order to use the same texture on multiple sampler. Also texture counter is reset after each shading group. This mimics the previous behaviour.
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/draw_manager.c155
1 files changed, 82 insertions, 73 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index bc9cb46168e..aad1f6d9e45 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -181,7 +181,6 @@ struct DRWUniform {
int location;
int length;
int arraysize;
- int bindloc;
const void *value;
};
@@ -219,10 +218,6 @@ struct DRWInterface {
int orcotexfac;
int eye;
int clipplanes;
- /* Textures */
- int tex_bind; /* next texture binding point */
- /* UBO */
- int ubo_bind; /* next ubo binding point */
/* Dynamic batch */
Gwn_Batch *instance_batch; /* contains instances attributes */
GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
@@ -327,8 +322,10 @@ enum {
static struct DRWGlobalState {
/* Rendering state */
GPUShader *shader;
- ListBase bound_texs;
- int tex_bind_id;
+ GPUTexture **bound_texs;
+ GPUUniformBuffer **bound_ubos;
+ int bind_tex_inc;
+ int bind_ubo_inc;
/* Managed by `DRW_state_set`, `DRW_state_reset` */
DRWState state;
@@ -659,8 +656,6 @@ static DRWInterface *DRW_interface_create(GPUShader *shader)
interface->attribs_stride = 0;
interface->instance_vbo = 0;
interface->instance_batch = NULL;
- interface->tex_bind = GPU_max_textures() - 1;
- interface->ubo_bind = GPU_max_ubo_binds() - 1;
memset(&interface->vbo_format, 0, sizeof(Gwn_VertFormat));
@@ -681,7 +676,7 @@ static DRWInterface *DRW_interface_duplicate(DRWInterface *interface_src)
#endif
static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
- DRWUniformType type, const void *value, int length, int arraysize, int bindloc)
+ DRWUniformType type, const void *value, int length, int arraysize)
{
DRWUniform *uni = MEM_mallocN(sizeof(DRWUniform), "DRWUniform");
@@ -698,7 +693,6 @@ static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
uni->value = value;
uni->length = length;
uni->arraysize = arraysize;
- uni->bindloc = bindloc; /* for textures */
if (uni->location == -1) {
if (G.debug & G_DEBUG)
@@ -1114,102 +1108,77 @@ void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int si
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
{
- DRWInterface *interface = shgroup->interface;
-
- if (interface->tex_bind < 0) {
- /* TODO alert user */
- printf("Not enough texture slot for %s\n", name);
- return;
- }
-
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1, interface->tex_bind--);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1);
}
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo)
{
- DRWInterface *interface = shgroup->interface;
-
- /* Be carefull: there is also a limit per shader stage. Usually 1/3 of normal limit. */
- if (interface->ubo_bind < 0) {
- /* TODO alert user */
- printf("Not enough ubo slots for %s\n", name);
- return;
- }
-
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1, interface->ubo_bind--);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1);
}
void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
{
- DRWInterface *interface = shgroup->interface;
-
- if (interface->tex_bind < 0) {
- /* TODO alert user */
- printf("Not enough texture slot for %s\n", name);
- return;
- }
-
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, tex, 0, 1, interface->tex_bind--);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, tex, 0, 1);
}
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize);
}
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize);
}
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize);
}
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize);
}
void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize);
}
void DRW_shgroup_uniform_short_to_int(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_INT, value, 1, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_INT, value, 1, arraysize);
}
void DRW_shgroup_uniform_short_to_float(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_FLOAT, value, 1, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_FLOAT, value, 1, arraysize);
}
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize);
}
void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize);
}
void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize);
}
void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1);
}
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value)
{
- DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
+ DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1);
}
/* Creates a VBO containing OGL primitives for all DRWCallDynamic */
@@ -1859,13 +1828,49 @@ static void draw_geometry(DRWShadingGroup *shgroup, Gwn_Batch *geom, const float
draw_geometry_execute(shgroup, geom);
}
+static void draw_bind_texture(GPUTexture *tex)
+{
+ int bind = GPU_texture_bound_number(tex);
+ if (bind == -1) {
+ if (DST.bind_tex_inc >= 0) {
+ if (DST.bound_texs[DST.bind_tex_inc] != NULL) {
+ GPU_texture_unbind(DST.bound_texs[DST.bind_tex_inc]);
+ }
+ DST.bound_texs[DST.bind_tex_inc] = tex;
+ GPU_texture_bind(tex, DST.bind_tex_inc);
+
+ DST.bind_tex_inc--;
+ }
+ else {
+ printf("Not enough texture slots! Reduce number of textures used by your shader.\n");
+ }
+ }
+}
+
+static void draw_bind_ubo(GPUUniformBuffer *ubo)
+{
+ if (DST.bound_ubos[DST.bind_ubo_inc] != ubo) {
+ if (DST.bind_ubo_inc >= 0) {
+ DST.bound_ubos[DST.bind_ubo_inc] = ubo;
+ GPU_uniformbuffer_bind(ubo, DST.bind_ubo_inc);
+ }
+ else {
+ printf("Not enough ubo slots!\n");
+ }
+ }
+ DST.bind_ubo_inc--;
+}
+
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
{
BLI_assert(shgroup->shader);
BLI_assert(shgroup->interface);
+ DST.bind_tex_inc = GPU_max_textures() - 1; /* Reset texture counter. */
+ DST.bind_ubo_inc = GPU_max_ubo_binds() - 1; /* Reset UBO counter. */
DRWInterface *interface = shgroup->interface;
GPUTexture *tex;
+ GPUUniformBuffer *ubo;
int val;
float fval;
@@ -1886,8 +1891,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
/* Binding Uniform */
/* Don't check anything, Interface should already contain the least uniform as possible */
for (DRWUniform *uni = interface->uniforms.first; uni; uni = uni->next) {
- DRWBoundTexture *bound_tex;
-
switch (uni->type) {
case DRW_UNIFORM_SHORT_TO_INT:
val = (int)*((short *)uni->value);
@@ -1913,12 +1916,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
case DRW_UNIFORM_TEXTURE:
tex = (GPUTexture *)uni->value;
BLI_assert(tex);
- GPU_texture_bind(tex, uni->bindloc);
-
- bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
- bound_tex->tex = tex;
- BLI_addtail(&DST.bound_texs, bound_tex);
-
+ draw_bind_texture(tex);
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
break;
case DRW_UNIFORM_BUFFER:
@@ -1927,17 +1925,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
tex = *((GPUTexture **)uni->value);
BLI_assert(tex);
- GPU_texture_bind(tex, uni->bindloc);
-
- bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
- bound_tex->tex = tex;
- BLI_addtail(&DST.bound_texs, bound_tex);
-
+ draw_bind_texture(tex);
GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
break;
case DRW_UNIFORM_BLOCK:
- GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
- GPU_shader_uniform_buffer(shgroup->shader, uni->location, (GPUUniformBuffer *)uni->value);
+ ubo = (GPUUniformBuffer *)uni->value;
+ draw_bind_ubo(ubo);
+ GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo);
break;
}
}
@@ -2034,10 +2028,8 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
{
/* Start fresh */
DST.shader = NULL;
- DST.tex_bind_id = 0;
DRW_state_set(pass->state);
- BLI_listbase_clear(&DST.bound_texs);
DRW_stats_query_start(pass->name);
@@ -2050,11 +2042,12 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
}
/* Clear Bound textures */
- for (DRWBoundTexture *bound_tex = DST.bound_texs.first; bound_tex; bound_tex = bound_tex->next) {
- GPU_texture_unbind(bound_tex->tex);
+ for (int i = 0; i < GPU_max_textures(); i++) {
+ if (DST.bound_texs[i] != NULL) {
+ GPU_texture_unbind(DST.bound_texs[i]);
+ DST.bound_texs[i] = NULL;
+ }
}
- DST.tex_bind_id = 0;
- BLI_freelistN(&DST.bound_texs);
if (DST.shader) {
GPU_shader_unbind();
@@ -2521,6 +2514,16 @@ static void DRW_viewport_var_init(void)
DST.frontface = GL_CCW;
DST.backface = GL_CW;
glFrontFace(DST.frontface);
+
+ /* Alloc array of texture reference. */
+ if (DST.bound_texs == NULL) {
+ DST.bound_texs = MEM_callocN(sizeof(GPUTexture *) * GPU_max_textures(), "Bound GPUTexture refs");
+ }
+
+ /* Alloc array of ubos reference. */
+ if (DST.bound_ubos == NULL) {
+ DST.bound_ubos = MEM_callocN(sizeof(GPUUniformBuffer *) * GPU_max_ubo_binds(), "Bound GPUUniformBuffer refs");
+ }
}
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
@@ -3231,6 +3234,8 @@ void DRW_draw_render_loop_ex(
#ifdef DEBUG
/* Avoid accidental reuse. */
+ MEM_freeN(DST.bound_texs);
+ MEM_freeN(DST.bound_ubos);
memset(&DST, 0xFF, sizeof(DST));
#endif
}
@@ -3383,6 +3388,8 @@ void DRW_draw_select_loop(
#ifdef DEBUG
/* Avoid accidental reuse. */
+ MEM_freeN(DST.bound_texs);
+ MEM_freeN(DST.bound_ubos);
memset(&DST, 0xFF, sizeof(DST));
#endif
@@ -3471,6 +3478,8 @@ void DRW_draw_depth_loop(
#ifdef DEBUG
/* Avoid accidental reuse. */
+ MEM_freeN(DST.bound_texs);
+ MEM_freeN(DST.bound_ubos);
memset(&DST, 0xFF, sizeof(DST));
#endif