diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 36 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 45 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 217 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 6 | ||||
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 42 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 40 |
8 files changed, 120 insertions, 272 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f2096073ac4..e7dff422105 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -591,9 +591,6 @@ static void drw_viewport_var_init(void) ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d); } - /* Alloc array of texture reference. */ - memset(&DST.RST, 0x0, sizeof(DST.RST)); - if (G_draw.view_ubo == NULL) { G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL); } diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 295e45c0fb3..b8c344bf80d 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -277,13 +277,9 @@ typedef enum { DRW_UNIFORM_FLOAT, DRW_UNIFORM_FLOAT_COPY, DRW_UNIFORM_TEXTURE, - DRW_UNIFORM_TEXTURE_PERSIST, DRW_UNIFORM_TEXTURE_REF, - DRW_UNIFORM_TEXTURE_REF_PERSIST, DRW_UNIFORM_BLOCK, - DRW_UNIFORM_BLOCK_PERSIST, DRW_UNIFORM_BLOCK_REF, - DRW_UNIFORM_BLOCK_REF_PERSIST, DRW_UNIFORM_TFEEDBACK_TARGET, /** Per drawcall uniforms/UBO */ DRW_UNIFORM_BLOCK_OBMATS, @@ -303,11 +299,25 @@ struct DRWUniform { union { /* For reference or array/vector types. */ const void *pvalue; - /* Single values. */ + /* DRW_UNIFORM_TEXTURE */ + struct { + union { + GPUTexture *texture; + GPUTexture **texture_ref; + }; + eGPUSamplerState sampler_state; + }; + /* DRW_UNIFORM_BLOCK */ + union { + GPUUniformBuffer *block; + GPUUniformBuffer **block_ref; + }; + /* DRW_UNIFORM_FLOAT_COPY */ float fvalue[4]; + /* DRW_UNIFORM_INT_COPY */ int ivalue[4]; }; - int location; + int location; /* Use as binding point for textures and ubos. */ uint32_t type : 5; /* DRWUniformType */ uint32_t length : 5; /* cannot be more than 16 */ uint32_t arraysize : 5; /* cannot be more than 16 too */ @@ -549,20 +559,6 @@ typedef struct DRWManager { GPUDrawList *draw_list; - /** GPU Resource State: Memory storage between drawing. */ - struct { - /* High end GPUs supports up to 32 binds per shader stage. - * We only use textures during the vertex and fragment stage, - * so 2 * 32 slots is a nice limit. */ - GPUTexture *bound_texs[DST_MAX_SLOTS]; - uint64_t bound_tex_slots; - uint64_t bound_tex_slots_persist; - - GPUUniformBuffer *bound_ubos[DST_MAX_SLOTS]; - uint64_t bound_ubo_slots; - uint64_t bound_ubo_slots_persist; - } RST; - struct { /* TODO(fclem) optimize: use chunks. */ DRWDebugLine *lines; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 8c89aa826e1..8a1ae666057 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -202,6 +202,20 @@ static DRWUniform *drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup, BLI_assert(length <= 4); memcpy(uni->fvalue, value, sizeof(float) * length); break; + case DRW_UNIFORM_BLOCK: + uni->block = (GPUUniformBuffer *)value; + break; + case DRW_UNIFORM_BLOCK_REF: + uni->block_ref = (GPUUniformBuffer **)value; + break; + case DRW_UNIFORM_TEXTURE: + uni->texture = (GPUTexture *)value; + uni->sampler_state = GPU_SAMPLER_MAX; /* Use texture state for now. */ + break; + case DRW_UNIFORM_TEXTURE_REF: + uni->texture_ref = (GPUTexture **)value; + uni->sampler_state = GPU_SAMPLER_MAX; /* Use texture state for now. */ + break; default: uni->pvalue = (const float *)value; break; @@ -228,12 +242,11 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup, int arraysize) { int location; - if (ELEM(type, - DRW_UNIFORM_BLOCK, - DRW_UNIFORM_BLOCK_PERSIST, - DRW_UNIFORM_BLOCK_REF, - DRW_UNIFORM_BLOCK_REF_PERSIST)) { - location = GPU_shader_get_uniform_block(shgroup->shader, name); + if (ELEM(type, DRW_UNIFORM_BLOCK, DRW_UNIFORM_BLOCK_REF)) { + location = GPU_shader_get_uniform_block_binding(shgroup->shader, name); + } + else if (ELEM(type, DRW_UNIFORM_TEXTURE, DRW_UNIFORM_TEXTURE_REF)) { + location = GPU_shader_get_texture_binding(shgroup->shader, name); } else { location = GPU_shader_get_uniform(shgroup->shader, name); @@ -259,12 +272,13 @@ void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, con /* Same as DRW_shgroup_uniform_texture but is guaranteed to be bound if shader does not change * between shgrp. */ +/* TODO remove */ void DRW_shgroup_uniform_texture_persistent(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex) { BLI_assert(tex != NULL); - drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_PERSIST, tex, 0, 1); + drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1); } void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex) @@ -275,12 +289,13 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, /* Same as DRW_shgroup_uniform_texture_ref but is guaranteed to be bound if shader does not change * between shgrp. */ +/* TODO remove */ void DRW_shgroup_uniform_texture_ref_persistent(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex) { BLI_assert(tex != NULL); - drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF_PERSIST, tex, 0, 1); + drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE_REF, tex, 0, 1); } void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, @@ -293,12 +308,13 @@ void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, /* Same as DRW_shgroup_uniform_block but is guaranteed to be bound if shader does not change * between shgrp. */ +/* TODO remove */ void DRW_shgroup_uniform_block_persistent(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo) { BLI_assert(ubo != NULL); - drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_PERSIST, ubo, 0, 1); + drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1); } void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup, @@ -311,12 +327,13 @@ void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup, /* Same as DRW_shgroup_uniform_block_ref but is guaranteed to be bound if shader does not change * between shgrp. */ +/* TODO remove */ void DRW_shgroup_uniform_block_ref_persistent(DRWShadingGroup *shgroup, const char *name, GPUUniformBuffer **ubo) { BLI_assert(ubo != NULL); - drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF_PERSIST, ubo, 0, 1); + drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK_REF, ubo, 0, 1); } void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, @@ -1208,9 +1225,9 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) shgroup->uniforms = NULL; /* TODO(fclem) make them builtin. */ - int view_ubo_location = GPU_shader_get_uniform_block(shader, "viewBlock"); - int model_ubo_location = GPU_shader_get_uniform_block(shader, "modelBlock"); - int info_ubo_location = GPU_shader_get_uniform_block(shader, "infoBlock"); + int view_ubo_location = GPU_shader_get_uniform_block_binding(shader, "viewBlock"); + int model_ubo_location = GPU_shader_get_uniform_block_binding(shader, "modelBlock"); + int info_ubo_location = GPU_shader_get_uniform_block_binding(shader, "infoBlock"); int baseinst_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_BASE_INSTANCE); int chunkid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_CHUNK); int resourceid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_ID); @@ -1264,7 +1281,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) if (view_ubo_location != -1) { drw_shgroup_uniform_create_ex( - shgroup, view_ubo_location, DRW_UNIFORM_BLOCK_PERSIST, G_draw.view_ubo, 0, 1); + shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, G_draw.view_ubo, 0, 1); } else { /* Only here to support builtin shaders. This should not be used by engines. */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 48e0115741f..25fdb8080a8 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -22,6 +22,7 @@ #include "draw_manager.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_math_bits.h" #include "BLI_memblock.h" @@ -744,107 +745,6 @@ BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup, DRWCommandsState *s } } -enum { - BIND_NONE = 0, - BIND_TEMP = 1, /* Release slot after this shading group. */ - BIND_PERSIST = 2, /* Release slot only after the next shader change. */ -}; - -static void set_bound_flags(uint64_t *slots, uint64_t *persist_slots, int slot_idx, char bind_type) -{ - uint64_t slot = 1llu << (unsigned long)slot_idx; - *slots |= slot; - if (bind_type == BIND_PERSIST) { - *persist_slots |= slot; - } -} - -static int get_empty_slot_index(uint64_t slots) -{ - uint64_t empty_slots = ~slots; - /* Find first empty slot using bitscan. */ - if (empty_slots != 0) { - if ((empty_slots & 0xFFFFFFFFlu) != 0) { - return (int)bitscan_forward_uint(empty_slots); - } - else { - return (int)bitscan_forward_uint(empty_slots >> 32) + 32; - } - } - else { - /* Greater than GPU_max_textures() */ - return 99999; - } -} - -static void bind_texture(GPUTexture *tex, char bind_type) -{ - int idx = GPU_texture_bound_number(tex); - if (idx == -1) { - /* Texture isn't bound yet. Find an empty slot and bind it. */ - idx = get_empty_slot_index(DST.RST.bound_tex_slots); - - if (idx < GPU_max_textures()) { - GPUTexture **gpu_tex_slot = &DST.RST.bound_texs[idx]; - /* Unbind any previous texture. */ - if (*gpu_tex_slot != NULL) { - GPU_texture_unbind(*gpu_tex_slot); - } - GPU_texture_bind(tex, idx); - *gpu_tex_slot = tex; - } - else { - printf("Not enough texture slots! Reduce number of textures used by your shader.\n"); - return; - } - } - else { - /* This texture slot was released but the tex - * is still bound. Just flag the slot again. */ - BLI_assert(DST.RST.bound_texs[idx] == tex); - } - set_bound_flags(&DST.RST.bound_tex_slots, &DST.RST.bound_tex_slots_persist, idx, bind_type); -} - -static void bind_ubo(GPUUniformBuffer *ubo, char bind_type) -{ - int idx = GPU_uniformbuffer_bindpoint(ubo); - if (idx == -1) { - /* UBO isn't bound yet. Find an empty slot and bind it. */ - idx = get_empty_slot_index(DST.RST.bound_ubo_slots); - - /* [0..1] are reserved ubo slots. */ - idx += 2; - - if (idx < GPU_max_ubo_binds()) { - GPUUniformBuffer **gpu_ubo_slot = &DST.RST.bound_ubos[idx]; - /* Unbind any previous UBO. */ - if (*gpu_ubo_slot != NULL) { - GPU_uniformbuffer_unbind(*gpu_ubo_slot); - } - GPU_uniformbuffer_bind(ubo, idx); - *gpu_ubo_slot = ubo; - } - else { - /* printf so user can report bad behavior */ - printf("Not enough ubo slots! This should not happen!\n"); - /* This is not depending on user input. - * It is our responsibility to make sure there is enough slots. */ - BLI_assert(0); - return; - } - } - else { - BLI_assert(idx < 64); - /* This UBO slot was released but the UBO is - * still bound here. Just flag the slot again. */ - BLI_assert(DST.RST.bound_ubos[idx] == ubo); - } - /* Remove offset for flag bitfield. */ - idx -= 2; - set_bound_flags(&DST.RST.bound_ubo_slots, &DST.RST.bound_ubo_slots_persist, idx, bind_type); -} - #ifndef NDEBUG /** * Opengl specification is strict on buffer binding. @@ -900,28 +800,6 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup) } #endif -static void release_texture_slots(bool with_persist) -{ - if (with_persist) { - DST.RST.bound_tex_slots = 0; - DST.RST.bound_tex_slots_persist = 0; - } - else { - DST.RST.bound_tex_slots &= DST.RST.bound_tex_slots_persist; - } -} - -static void release_ubo_slots(bool with_persist) -{ - if (with_persist) { - DST.RST.bound_ubo_slots = 0; - DST.RST.bound_ubo_slots_persist = 0; - } - else { - DST.RST.bound_ubo_slots &= DST.RST.bound_ubo_slots_persist; - } -} - static void draw_update_uniforms(DRWShadingGroup *shgroup, DRWCommandsState *state, bool *use_tfeedback) @@ -929,78 +807,42 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, for (DRWUniformChunk *unichunk = shgroup->uniforms; unichunk; unichunk = unichunk->next) { DRWUniform *uni = unichunk->uniforms; for (int i = 0; i < unichunk->uniform_used; i++, uni++) { - GPUTexture *tex; - GPUUniformBuffer *ubo; - const void *data = uni->pvalue; - if (ELEM(uni->type, DRW_UNIFORM_INT_COPY, DRW_UNIFORM_FLOAT_COPY)) { - data = uni->fvalue; - } switch (uni->type) { case DRW_UNIFORM_INT_COPY: + GPU_shader_uniform_vector_int( + shgroup->shader, uni->location, uni->length, uni->arraysize, uni->ivalue); + break; case DRW_UNIFORM_INT: GPU_shader_uniform_vector_int( - shgroup->shader, uni->location, uni->length, uni->arraysize, data); + shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue); break; case DRW_UNIFORM_FLOAT_COPY: + GPU_shader_uniform_vector( + shgroup->shader, uni->location, uni->length, uni->arraysize, uni->fvalue); + break; case DRW_UNIFORM_FLOAT: GPU_shader_uniform_vector( - shgroup->shader, uni->location, uni->length, uni->arraysize, data); + shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue); break; case DRW_UNIFORM_TEXTURE: - tex = (GPUTexture *)uni->pvalue; - BLI_assert(tex); - bind_texture(tex, BIND_TEMP); - GPU_shader_uniform_texture(shgroup->shader, uni->location, tex); - break; - case DRW_UNIFORM_TEXTURE_PERSIST: - tex = (GPUTexture *)uni->pvalue; - BLI_assert(tex); - bind_texture(tex, BIND_PERSIST); - GPU_shader_uniform_texture(shgroup->shader, uni->location, tex); + GPU_texture_bind_ex(uni->texture, uni->location, false); break; case DRW_UNIFORM_TEXTURE_REF: - tex = *((GPUTexture **)uni->pvalue); - BLI_assert(tex); - bind_texture(tex, BIND_TEMP); - GPU_shader_uniform_texture(shgroup->shader, uni->location, tex); - break; - case DRW_UNIFORM_TEXTURE_REF_PERSIST: - tex = *((GPUTexture **)uni->pvalue); - BLI_assert(tex); - bind_texture(tex, BIND_PERSIST); - GPU_shader_uniform_texture(shgroup->shader, uni->location, tex); + GPU_texture_bind_ex(*uni->texture_ref, uni->location, false); break; case DRW_UNIFORM_BLOCK: - ubo = (GPUUniformBuffer *)uni->pvalue; - bind_ubo(ubo, BIND_TEMP); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); - break; - case DRW_UNIFORM_BLOCK_PERSIST: - ubo = (GPUUniformBuffer *)uni->pvalue; - bind_ubo(ubo, BIND_PERSIST); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); + GPU_uniformbuffer_bind(uni->block, uni->location); break; case DRW_UNIFORM_BLOCK_REF: - ubo = *((GPUUniformBuffer **)uni->pvalue); - bind_ubo(ubo, BIND_TEMP); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); - break; - case DRW_UNIFORM_BLOCK_REF_PERSIST: - ubo = *((GPUUniformBuffer **)uni->pvalue); - bind_ubo(ubo, BIND_PERSIST); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); + GPU_uniformbuffer_bind(*uni->block_ref, uni->location); break; case DRW_UNIFORM_BLOCK_OBMATS: state->obmats_loc = uni->location; - ubo = DST.vmempool->matrices_ubo[0]; - GPU_uniformbuffer_bind(ubo, 0); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); + GPU_uniformbuffer_bind(DST.vmempool->matrices_ubo[0], uni->location); break; case DRW_UNIFORM_BLOCK_OBINFOS: state->obinfos_loc = uni->location; - ubo = DST.vmempool->obinfos_ubo[0]; - GPU_uniformbuffer_bind(ubo, 1); - GPU_shader_uniform_buffer(shgroup->shader, uni->location, ubo); + GPU_uniformbuffer_bind(DST.vmempool->obinfos_ubo[0], uni->location); break; case DRW_UNIFORM_RESOURCE_CHUNK: state->chunkid_loc = uni->location; @@ -1010,9 +852,9 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, state->resourceid_loc = uni->location; break; case DRW_UNIFORM_TFEEDBACK_TARGET: - BLI_assert(data && (*use_tfeedback == false)); - *use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader, - ((GPUVertBuf *)data)->vbo_id); + BLI_assert(uni->pvalue && (*use_tfeedback == false)); + *use_tfeedback = GPU_shader_transform_feedback_enable( + shgroup->shader, ((GPUVertBuf *)uni->pvalue)->vbo_id); break; /* Legacy/Fallback support. */ case DRW_UNIFORM_BASE_INSTANCE: @@ -1119,7 +961,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa } if (state->obmats_loc != -1) { GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]); - GPU_uniformbuffer_bind(DST.vmempool->matrices_ubo[chunk], 0); + GPU_uniformbuffer_bind(DST.vmempool->matrices_ubo[chunk], state->obmats_loc); } if (state->obinfos_loc != -1) { GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]); @@ -1282,6 +1124,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) if (shader_changed) { if (DST.shader) { GPU_shader_unbind(); + GPU_texture_unbind_all(); } GPU_shader_bind(shgroup->shader); DST.shader = shgroup->shader; @@ -1292,9 +1135,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) DST.batch = NULL; } - release_ubo_slots(shader_changed); - release_texture_slots(shader_changed); - draw_update_uniforms(shgroup, &state, &use_tfeedback); drw_state_set(pass_state); @@ -1476,24 +1316,9 @@ static void drw_draw_pass_ex(DRWPass *pass, } } - /* Clear Bound textures */ - for (int i = 0; i < DST_MAX_SLOTS; i++) { - if (DST.RST.bound_texs[i] != NULL) { - GPU_texture_unbind(DST.RST.bound_texs[i]); - DST.RST.bound_texs[i] = NULL; - } - } - - /* Clear Bound Ubos */ - for (int i = 0; i < DST_MAX_SLOTS; i++) { - if (DST.RST.bound_ubos[i] != NULL) { - GPU_uniformbuffer_unbind(DST.RST.bound_ubos[i]); - DST.RST.bound_ubos[i] = NULL; - } - } - if (DST.shader) { GPU_shader_unbind(); + GPU_texture_unbind_all(); DST.shader = NULL; } diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index baf3fb99974..40bae88f46d 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -94,13 +94,15 @@ void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface); int GPU_shader_get_uniform(GPUShader *shader, const char *name); int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); int GPU_shader_get_uniform_block(GPUShader *shader, const char *name); + +int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name); +int GPU_shader_get_texture_binding(GPUShader *shader, const char *name); + void GPU_shader_uniform_vector( GPUShader *shader, int location, int length, int arraysize, const float *value); void GPU_shader_uniform_vector_int( GPUShader *shader, int location, int length, int arraysize, const int *value); -void GPU_shader_uniform_buffer(GPUShader *shader, int location, struct GPUUniformBuffer *ubo); -void GPU_shader_uniform_texture(GPUShader *shader, int location, struct GPUTexture *tex); void GPU_shader_uniform_float(GPUShader *shader, int location, float value); void GPU_shader_uniform_int(GPUShader *shader, int location, int value); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index a1e00793857..01814b78641 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -261,8 +261,9 @@ void GPU_texture_free(GPUTexture *tex); void GPU_texture_ref(GPUTexture *tex); void GPU_texture_bind(GPUTexture *tex, int number); +void GPU_texture_bind_ex(GPUTexture *tex, int unit, const bool set_number); void GPU_texture_unbind(GPUTexture *tex); -int GPU_texture_bound_number(GPUTexture *tex); +void GPU_texture_unbind_all(void); void GPU_texture_copy(GPUTexture *dst, GPUTexture *src); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 97c2621de6b..66f98461047 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -746,6 +746,20 @@ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) return ubo ? ubo->location : -1; } +int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); + return ubo ? ubo->binding : -1; +} + +int GPU_shader_get_texture_binding(GPUShader *shader, const char *name) +{ + BLI_assert(shader && shader->program); + const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name); + return tex ? tex->binding : -1; +} + void *GPU_shader_get_interface(GPUShader *shader) { return shader->interface; @@ -833,34 +847,6 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value) glUniform1i(location, value); } -void GPU_shader_uniform_buffer(GPUShader *shader, int location, GPUUniformBuffer *ubo) -{ - int bindpoint = GPU_uniformbuffer_bindpoint(ubo); - - if (location == -1) { - return; - } - - glUniformBlockBinding(shader->program, location, bindpoint); -} - -void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex) -{ - int number = GPU_texture_bound_number(tex); - - if (number == -1) { - fprintf(stderr, "Texture is not bound.\n"); - BLI_assert(0); - return; - } - - if (location == -1) { - return; - } - - glUniform1i(location, number); -} - void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface) { const GPUShaderInput *srgb_uniform = GPU_shaderinterface_uniform_builtin( diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 69efd287218..95d33a03d93 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -1712,7 +1712,8 @@ void GPU_invalid_tex_free(void) } } -void GPU_texture_bind(GPUTexture *tex, int unit) +/* set_number is to save the the texture unit for setting texture parameters. */ +void GPU_texture_bind_ex(GPUTexture *tex, int unit, const bool set_number) { BLI_assert(unit >= 0); @@ -1721,7 +1722,7 @@ void GPU_texture_bind(GPUTexture *tex, int unit) return; } - if ((G.debug & G_DEBUG)) { + if (G.debug & G_DEBUG) { for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; i++) { if (tex->fb[i] && GPU_framebuffer_bound(tex->fb[i])) { fprintf(stderr, @@ -1733,7 +1734,10 @@ void GPU_texture_bind(GPUTexture *tex, int unit) } } - tex->number = unit; + if (set_number) { + tex->number = unit; + } + glActiveTexture(GL_TEXTURE0 + unit); if (tex->bindcode != 0) { @@ -1746,6 +1750,11 @@ void GPU_texture_bind(GPUTexture *tex, int unit) } } +void GPU_texture_bind(GPUTexture *tex, int unit) +{ + GPU_texture_bind_ex(tex, unit, true); +} + void GPU_texture_unbind(GPUTexture *tex) { if (tex->number == -1) { @@ -1758,10 +1767,25 @@ void GPU_texture_unbind(GPUTexture *tex) tex->number = -1; } -int GPU_texture_bound_number(GPUTexture *tex) +void GPU_texture_unbind_all(void) { - /* TODO remove. Makes no sense now. */ - return tex->number; + /* Unbinding can be costly. Skip in normal condition. */ + if (G.debug & G_DEBUG_GPU) { + for (int i = 0; i < GPU_max_textures(); i++) { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D_ARRAY, 0); + glBindTexture(GL_TEXTURE_1D, 0); + glBindTexture(GL_TEXTURE_1D_ARRAY, 0); + glBindTexture(GL_TEXTURE_3D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindTexture(GL_TEXTURE_BUFFER, 0); + if (GPU_arb_texture_cube_map_array_is_supported()) { + glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY_ARB, 0); + } + glBindSampler(i, 0); + } + } } #define WARN_NOT_BOUND(_tex) \ @@ -1785,8 +1809,8 @@ void GPU_texture_generate_mipmap(GPUTexture *tex) if (GPU_texture_depth(tex)) { /* Some drivers have bugs when using glGenerateMipmap with depth textures (see T56789). - * In this case we just create a complete texture with mipmaps manually without down-sampling. - * You must initialize the texture levels using other methods like + * In this case we just create a complete texture with mipmaps manually without + * down-sampling. You must initialize the texture levels using other methods like * GPU_framebuffer_recursive_downsample(). */ eGPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex->format); for (int i = 1; i < levels; i++) { |