From 854c999d827cfb78938c3b4605707b891092d001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 9 Aug 2020 00:52:45 +0200 Subject: GPUShader: Change shader state tracking to be part of the GPUContext This remove the use of batch->program and replace it with batch->shader. This will allow GL abstraction latter. --- source/blender/gpu/GPU_batch.h | 11 ++---- source/blender/gpu/intern/gpu_batch.cc | 45 ++++-------------------- source/blender/gpu/intern/gpu_context_private.hh | 1 + source/blender/gpu/intern/gpu_immediate.cc | 8 ++--- source/blender/gpu/intern/gpu_shader.cc | 16 +++++++-- source/blender/gpu/opengl/gl_drawlist.cc | 3 +- 6 files changed, 27 insertions(+), 57 deletions(-) (limited to 'source/blender/gpu') diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index fb273847a9c..d37fc923a67 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -57,11 +57,13 @@ typedef struct GPUBatch { GPUVertBuf *inst[GPU_BATCH_INST_VBO_MAX_LEN]; /** NULL if element list not needed */ GPUIndexBuf *elem; + + GPUShader *shader; + GPUPrimType prim_type; /* cached values (avoid dereferencing later) */ uint32_t vao_id; - uint32_t program; const struct GPUShaderInterface *interface; /* book-keeping */ @@ -69,7 +71,6 @@ typedef struct GPUBatch { /** used to free all vaos. this implies all vaos were created under the same context. */ struct GPUContext *context; GPUBatchPhase phase; - bool program_in_use; /* Vao management: remembers all geometry state (vertex attribute bindings & element buffer) * for each shader interface. Start with a static number of vaos and fallback to dynamic count @@ -128,17 +129,11 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); #define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false) void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader); -void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader); void GPU_batch_program_set_imm_shader(GPUBatch *batch); void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id); void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig sh_cfg); -/* Entire batch draws with one shader program, but can be redrawn later with another program. */ -/* Vertex shader's inputs must be compatible with the batch's vertex format. */ - -void GPU_batch_program_use_begin(GPUBatch *); /* call before Batch_Uniform (temp hack?) */ -void GPU_batch_program_use_end(GPUBatch *); void GPU_batch_uniform_1ui(GPUBatch *, const char *name, uint value); void GPU_batch_uniform_1i(GPUBatch *, const char *name, int value); diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 0c82279fe6e..e71ebec1a3b 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -376,21 +376,13 @@ static GLuint batch_vao_get(GPUBatch *batch) return new_vao; } -void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader) +void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) { -#if TRUST_NO_ONE - assert(glIsProgram(shader->program)); - assert(batch->program_in_use == 0); -#endif batch->interface = shader->interface; - batch->program = shader->program; + batch->shader = shader; batch->vao_id = batch_vao_get(batch); -} - -void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader) -{ - GPU_batch_set_shader_no_bind(batch, shader); - GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ + GPU_shader_bind(batch->shader); /* hack! to make Batch_Uniform* simpler */ + GPU_batch_bind(batch); } void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface) @@ -523,29 +515,6 @@ static void batch_update_program_bindings(GPUBatch *batch, uint i_first) } } -void GPU_batch_program_use_begin(GPUBatch *batch) -{ - /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with - * the GL context's active program. - * use_program doesn't mark other programs as "not used". */ - /* TODO: make not fragile (somehow) */ - - if (!batch->program_in_use) { - glUseProgram(batch->program); - batch->program_in_use = true; - } -} - -void GPU_batch_program_use_end(GPUBatch *batch) -{ - if (batch->program_in_use) { -#if PROGRAM_NO_OPTI - glUseProgram(0); -#endif - batch->program_in_use = false; - } -} - #if TRUST_NO_ONE # define GET_UNIFORM \ const GPUShaderInput *uniform = GPU_shaderinterface_uniform(batch->interface, name); \ @@ -670,14 +639,14 @@ void GPU_batch_draw(GPUBatch *batch) assert(batch->phase == GPU_BATCH_READY_TO_DRAW); assert(batch->verts[0]->vbo_id != 0); #endif - GPU_batch_program_use_begin(batch); + GPU_shader_bind(batch->shader); GPU_matrix_bind(batch->interface); // external call. GPU_shader_set_srgb_uniform(batch->interface); GPU_batch_bind(batch); GPU_batch_draw_advanced(batch, 0, 0, 0, 0); - GPU_batch_program_use_end(batch); + GPU_shader_unbind(); } #if GPU_TRACK_INDEX_RANGE @@ -690,7 +659,7 @@ void GPU_batch_draw(GPUBatch *batch) void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_first, int i_count) { - BLI_assert(batch->program_in_use); + BLI_assert(GPU_context_active_get()->shader != NULL); /* TODO could assert that VAO is bound. */ if (v_count == 0) { diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index d369dbe7402..9d3b5c3fc85 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -41,6 +41,7 @@ struct GPUMatrixState; struct GPUContext { public: /** State managment */ + GPUShader *shader = NULL; GPUFrameBuffer *current_fbo = NULL; GPUMatrixState *matrix_state = NULL; diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index 9cededa54f7..08adefc9f12 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -171,12 +171,8 @@ void immBindBuiltinProgram(eGPUBuiltinShader shader_id) void immUnbindProgram(void) { -#if TRUST_NO_ONE - assert(imm.bound_program != NULL); -#endif -#if PROGRAM_NO_OPTI - glUseProgram(0); -#endif + BLI_assert(imm.bound_program != NULL); + GPU_shader_unbind(); imm.bound_program = NULL; } diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 03b7d5402f5..07b4139eadc 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -42,6 +42,7 @@ #include "GPU_texture.h" #include "GPU_uniformbuffer.h" +#include "gpu_context_private.hh" #include "gpu_shader_private.h" extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[]; @@ -598,14 +599,23 @@ void GPU_shader_bind(GPUShader *shader) { BLI_assert(shader && shader->program); - glUseProgram(shader->program); - GPU_matrix_bind(shader->interface); - GPU_shader_set_srgb_uniform(shader->interface); + GPUContext *ctx = GPU_context_active_get(); + + if (ctx->shader != shader) { + ctx->shader = shader; + glUseProgram(shader->program); + GPU_matrix_bind(shader->interface); + GPU_shader_set_srgb_uniform(shader->interface); + } } void GPU_shader_unbind(void) { +#ifndef NDEBUG + GPUContext *ctx = GPU_context_active_get(); + ctx->shader = NULL; glUseProgram(0); +#endif } /** \} */ diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc index f24bfdc8751..e801a28ec52 100644 --- a/source/blender/gpu/opengl/gl_drawlist.cc +++ b/source/blender/gpu/opengl/gl_drawlist.cc @@ -184,8 +184,7 @@ void GLDrawList::submit(void) /* Something's wrong if we get here without MDI support. */ BLI_assert(MDI_ENABLED); BLI_assert(data_); - /* TODO fix this assert */ - // BLI_assert(batch_->program_in_use); + BLI_assert(GPU_context_active_get()->shader != NULL); /* TODO could assert that VAO is bound. */ /* Only do multi-draw indirect if doing more than 2 drawcall. This avoids the overhead of -- cgit v1.2.3