diff --git a/source/blender/draw/engines/gpencil/gpencil_antialiasing.cc b/source/blender/draw/engines/gpencil/gpencil_antialiasing.cc index 132e5337c24..d4e8ff13e17 100644 --- a/source/blender/draw/engines/gpencil/gpencil_antialiasing.cc +++ b/source/blender/draw/engines/gpencil/gpencil_antialiasing.cc @@ -12,15 +12,11 @@ #include "BLI_smaa_textures.h" -void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) +void GPENCIL_antialiasing_init(GPENCIL_Instance *inst, GPENCIL_PrivateData *pd) { - GPENCIL_Instance *inst = vedata->instance; - GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; - - const float *size = DRW_viewport_size_get(); - const float *sizeinv = DRW_viewport_invert_size_get(); - const float4 metrics = {sizeinv[0], sizeinv[1], size[0], size[1]}; + const float *size_f = DRW_viewport_size_get(); + const int2 size(size_f[0], size_f[1]); + const float4 metrics = {1.0f / size[0], 1.0f / size[1], float(size[0]), float(size[1])}; if (pd->simplify_antialias) { /* No AA fallback. */ @@ -28,9 +24,9 @@ void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) pass.init(); pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM); pass.shader_set(GPENCIL_shader_antialiasing(2)); - pass.bind_texture("blendTex", pd->color_tx); - pass.bind_texture("colorTex", pd->color_tx); - pass.bind_texture("revealTex", pd->reveal_tx); + pass.bind_texture("blendTex", inst->color_tx); + pass.bind_texture("colorTex", inst->color_tx); + pass.bind_texture("revealTex", inst->reveal_tx); pass.push_constant("doAntiAliasing", false); pass.push_constant("onlyAlpha", pd->draw_wireframe); pass.push_constant("viewportMetrics", metrics); @@ -52,22 +48,11 @@ void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) { eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT; - pd->smaa_edge_tx = DRW_texture_pool_query_2d_ex( - size[0], size[1], GPU_RG8, usage, &draw_engine_gpencil_type); - pd->smaa_weight_tx = DRW_texture_pool_query_2d_ex( - size[0], size[1], GPU_RGBA8, usage, &draw_engine_gpencil_type); + inst->smaa_edge_tx.acquire(size, GPU_RG8, usage); + inst->smaa_weight_tx.acquire(size, GPU_RGBA8, usage); - GPU_framebuffer_ensure_config(&fbl->smaa_edge_fb, - { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(pd->smaa_edge_tx), - }); - - GPU_framebuffer_ensure_config(&fbl->smaa_weight_fb, - { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(pd->smaa_weight_tx), - }); + inst->smaa_edge_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(inst->smaa_edge_tx)); + inst->smaa_weight_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(inst->smaa_weight_tx)); } { @@ -76,8 +61,8 @@ void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) pass.init(); pass.state_set(DRW_STATE_WRITE_COLOR); pass.shader_set(GPENCIL_shader_antialiasing(0)); - pass.bind_texture("colorTex", pd->color_tx); - pass.bind_texture("revealTex", pd->reveal_tx); + pass.bind_texture("colorTex", &inst->color_tx); + pass.bind_texture("revealTex", &inst->reveal_tx); pass.push_constant("viewportMetrics", metrics); pass.push_constant("lumaWeight", pd->scene->grease_pencil_settings.smaa_threshold); pass.clear_color(float4(0.0f)); @@ -89,9 +74,9 @@ void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) pass.init(); pass.state_set(DRW_STATE_WRITE_COLOR); pass.shader_set(GPENCIL_shader_antialiasing(1)); - pass.bind_texture("edgesTex", pd->smaa_edge_tx); - pass.bind_texture("areaTex", inst->smaa_area_tx); - pass.bind_texture("searchTex", inst->smaa_search_tx); + pass.bind_texture("edgesTex", &inst->smaa_edge_tx); + pass.bind_texture("areaTex", &inst->smaa_area_tx); + pass.bind_texture("searchTex", &inst->smaa_search_tx); pass.push_constant("viewportMetrics", metrics); pass.clear_color(float4(0.0f)); pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); @@ -102,9 +87,9 @@ void GPENCIL_antialiasing_init(GPENCIL_Data *vedata) pass.init(); pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM); pass.shader_set(GPENCIL_shader_antialiasing(2)); - pass.bind_texture("blendTex", pd->smaa_weight_tx); - pass.bind_texture("colorTex", pd->color_tx); - pass.bind_texture("revealTex", pd->reveal_tx); + pass.bind_texture("blendTex", &inst->smaa_weight_tx); + pass.bind_texture("colorTex", &inst->color_tx); + pass.bind_texture("revealTex", &inst->reveal_tx); pass.push_constant("doAntiAliasing", true); pass.push_constant("onlyAlpha", pd->draw_wireframe); pass.push_constant("viewportMetrics", metrics); @@ -118,14 +103,13 @@ void GPENCIL_antialiasing_draw(GPENCIL_Data *vedata) blender::draw::Manager *manager = DRW_manager_get(); - GPENCIL_FramebufferList *fbl = vedata->fbl; GPENCIL_PrivateData *pd = vedata->stl->pd; if (!pd->simplify_antialias) { - GPU_framebuffer_bind(fbl->smaa_edge_fb); + GPU_framebuffer_bind(inst->smaa_edge_fb); manager->submit(inst->smaa_edge_ps); - GPU_framebuffer_bind(fbl->smaa_weight_fb); + GPU_framebuffer_bind(inst->smaa_weight_fb); manager->submit(inst->smaa_weight_ps); } diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc b/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc index a63a9a5ddfc..fe8f4cf0f86 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc @@ -287,7 +287,8 @@ GPENCIL_tLayer *grease_pencil_layer_cache_get(GPENCIL_tObject *tgp_ob, return nullptr; } -GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, +GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_Instance *inst, + GPENCIL_PrivateData *pd, const Object *ob, const blender::bke::greasepencil::Layer &layer, const int onion_id, @@ -414,9 +415,9 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, pass.shader_set(GPENCIL_shader_layer_blend_get()); pass.push_constant("blendMode", int(layer.blend_mode)); pass.push_constant("blendOpacity", layer_opacity); - pass.bind_texture("colorBuf", &pd->color_layer_tx); - pass.bind_texture("revealBuf", &pd->reveal_layer_tx); - pass.bind_texture("maskBuf", (is_masked) ? &pd->mask_tx : &pd->dummy_tx); + pass.bind_texture("colorBuf", &inst->color_layer_tx); + pass.bind_texture("revealBuf", &inst->reveal_layer_tx); + pass.bind_texture("maskBuf", (is_masked) ? &inst->mask_tx : &pd->dummy_tx); pass.state_stencil(0xFF, 0xFF, 0xFF); pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); @@ -440,7 +441,7 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, PassSimple &pass = *tgp_layer->geom_ps; GPUTexture *depth_tex = (is_in_front) ? pd->dummy_depth : pd->scene_depth_tx; - GPUTexture **mask_tex = (is_masked) ? &pd->mask_tx : &pd->dummy_tx; + GPUTexture **mask_tex = (is_masked) ? &inst->mask_tx : &pd->dummy_tx; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND_ALPHA_PREMUL; /* For 2D mode, we render all strokes with uniform depth (increasing with stroke id). */ diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 7e64f2c0a09..26ed7bef3bc 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -53,6 +53,8 @@ struct GPENCIL_tLayer; using PassSimple = blender::draw::PassSimple; using Texture = blender::draw::Texture; +using TextureFromPool = blender::draw::TextureFromPool; +using Framebuffer = blender::draw::Framebuffer; /* NOTE: These do not preserve the PassSimple memory across frames. * If that becomes a bottleneck, these containers can be improved. */ using GPENCIL_tVfx_Pool = blender::draw::detail::SubPassVector; @@ -156,17 +158,6 @@ typedef struct GPENCIL_StorageList { struct GPENCIL_PrivateData *pd; } GPENCIL_StorageList; -typedef struct GPENCIL_FramebufferList { - struct GPUFrameBuffer *render_fb; - struct GPUFrameBuffer *gpencil_fb; - struct GPUFrameBuffer *snapshot_fb; - struct GPUFrameBuffer *layer_fb; - struct GPUFrameBuffer *object_fb; - struct GPUFrameBuffer *mask_fb; - struct GPUFrameBuffer *smaa_edge_fb; - struct GPUFrameBuffer *smaa_weight_fb; -} GPENCIL_FramebufferList; - struct GPENCIL_Instance { PassSimple smaa_edge_ps = {"smaa_edge"}; PassSimple smaa_weight_ps = {"smaa_weight"}; @@ -191,11 +182,40 @@ struct GPENCIL_Instance { /* Textures used by Antialiasing. */ Texture smaa_area_tx = {"smaa_area_tx"}; Texture smaa_search_tx = {"smaa_search_tx"}; + + /* Temp Textures (shared with other engines). */ + TextureFromPool depth_tx = {"depth_tx"}; + TextureFromPool color_tx = {"color_tx"}; + TextureFromPool color_layer_tx = {"color_layer_tx"}; + TextureFromPool color_object_tx = {"color_object_tx"}; + /* Revealage is 1 - alpha */ + TextureFromPool reveal_tx = {"reveal_tx"}; + TextureFromPool reveal_layer_tx = {"reveal_layer_tx"}; + TextureFromPool reveal_object_tx = {"reveal_object_tx"}; + /* Mask texture */ + TextureFromPool mask_depth_tx = {"mask_depth_tx"}; + TextureFromPool mask_color_tx = {"mask_color_tx"}; + TextureFromPool mask_tx = {"mask_tx"}; + /* Anti-Aliasing. */ + TextureFromPool smaa_edge_tx = {"smaa_edge_tx"}; + TextureFromPool smaa_weight_tx = {"smaa_weight_tx"}; + + Framebuffer render_fb = {"render_fb"}; + Framebuffer gpencil_fb = {"gpencil_fb"}; + Framebuffer snapshot_fb = {"snapshot_fb"}; + Framebuffer layer_fb = {"layer_fb"}; + Framebuffer object_fb = {"object_fb"}; + Framebuffer mask_fb = {"mask_fb"}; + Framebuffer smaa_edge_fb = {"smaa_edge_fb"}; + Framebuffer smaa_weight_fb = {"smaa_weight_fb"}; + + void acquire_resources(GPENCIL_PrivateData *pd); + void release_resources(); }; struct GPENCIL_Data { void *engine_type; /* Required */ - struct GPENCIL_FramebufferList *fbl; + DRWViewportEmptyList *fbl; DRWViewportEmptyList *txl; DRWViewportEmptyList *psl; struct GPENCIL_StorageList *stl; @@ -225,20 +245,6 @@ typedef struct GPENCIL_PrivateData { struct { GPENCIL_tObject *first, *last; } tobjects, tobjects_infront; - /* Temp Textures (shared with other engines). */ - GPUTexture *depth_tx; - GPUTexture *color_tx; - GPUTexture *color_layer_tx; - GPUTexture *color_object_tx; - /* Revealage is 1 - alpha */ - GPUTexture *reveal_tx; - GPUTexture *reveal_layer_tx; - GPUTexture *reveal_object_tx; - /* Mask texture */ - GPUTexture *mask_tx; - /* Anti-Aliasing. */ - GPUTexture *smaa_edge_tx; - GPUTexture *smaa_weight_tx; /* Pointer to dtxl->depth */ GPUTexture *scene_depth_tx; GPUFrameBuffer *scene_fb; @@ -337,7 +343,8 @@ GPENCIL_tLayer *grease_pencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int layer_id, bool skip_onion); -GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, +GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_Instance *inst, + GPENCIL_PrivateData *pd, const Object *ob, const blender::bke::greasepencil::Layer &layer, int onion_id, @@ -390,7 +397,7 @@ struct GPUShader *GPENCIL_shader_fx_shadow_get(void); void GPENCIL_shader_free(void); /* Antialiasing */ -void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata); +void GPENCIL_antialiasing_init(GPENCIL_Instance *inst, GPENCIL_PrivateData *pd); void GPENCIL_antialiasing_draw(struct GPENCIL_Data *vedata); /* main functions */ diff --git a/source/blender/draw/engines/gpencil/gpencil_engine_c.cc b/source/blender/draw/engines/gpencil/gpencil_engine_c.cc index 54a4ac15233..0e62ad796bf 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine_c.cc +++ b/source/blender/draw/engines/gpencil/gpencil_engine_c.cc @@ -54,7 +54,6 @@ void GPENCIL_engine_init(void *ved) { GPENCIL_Data *vedata = (GPENCIL_Data *)ved; GPENCIL_StorageList *stl = vedata->stl; - GPENCIL_FramebufferList *fbl = vedata->fbl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); const DRWContextState *ctx = DRW_context_state_get(); @@ -159,7 +158,7 @@ void GPENCIL_engine_init(void *ved) if (inst.render_depth_tx.is_valid()) { stl->pd->scene_depth_tx = inst.render_depth_tx; - stl->pd->scene_fb = fbl->render_fb; + stl->pd->scene_fb = inst.render_fb; } gpencil_light_ambient_add(stl->pd->shadeless_light_pool, blender::float3{1.0f, 1.0f, 1.0f}); @@ -192,7 +191,6 @@ void GPENCIL_cache_init(void *ved) using namespace blender::draw; GPENCIL_Data *vedata = (GPENCIL_Data *)ved; GPENCIL_Instance *inst = vedata->instance; - GPENCIL_FramebufferList *fbl = vedata->fbl; GPENCIL_PrivateData *pd = vedata->stl->pd; const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -261,16 +259,12 @@ void GPENCIL_cache_init(void *ved) inst->snapshot_color_tx.ensure_2d(GPU_R11F_G11F_B10F, int2(size), usage); inst->snapshot_reveal_tx.ensure_2d(GPU_R11F_G11F_B10F, int2(size), usage); - GPU_framebuffer_ensure_config(&fbl->snapshot_fb, - { - GPU_ATTACHMENT_TEXTURE(inst->snapshot_depth_tx), - GPU_ATTACHMENT_TEXTURE(inst->snapshot_color_tx), - GPU_ATTACHMENT_TEXTURE(inst->snapshot_reveal_tx), - }); + inst->snapshot_fb.ensure(GPU_ATTACHMENT_TEXTURE(inst->snapshot_depth_tx), + GPU_ATTACHMENT_TEXTURE(inst->snapshot_color_tx), + GPU_ATTACHMENT_TEXTURE(inst->snapshot_reveal_tx)); } else { /* Free unneeded buffers. */ - GPU_FRAMEBUFFER_FREE_SAFE(fbl->snapshot_fb); inst->snapshot_depth_tx.free(); inst->snapshot_color_tx.free(); inst->snapshot_reveal_tx.free(); @@ -281,7 +275,7 @@ void GPENCIL_cache_init(void *ved) pass.init(); pass.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); pass.shader_set(GPENCIL_shader_depth_merge_get()); - pass.bind_texture("depthBuf", &pd->depth_tx); + pass.bind_texture("depthBuf", &inst->depth_tx); pass.push_constant("strokeOrder3d", &pd->is_stroke_order_3d); pass.push_constant("gpModelMatrix", &inst->object_bound_mat); pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); @@ -375,7 +369,10 @@ static bool use_layer_in_render(const GreasePencil &grease_pencil, } static GPENCIL_tObject *grease_pencil_object_cache_populate( - GPENCIL_PrivateData *pd, Object *ob, blender::draw::ResourceHandle res_handle) + GPENCIL_Instance *inst, + GPENCIL_PrivateData *pd, + Object *ob, + blender::draw::ResourceHandle res_handle) { using namespace blender; using namespace blender::ed::greasepencil; @@ -483,7 +480,7 @@ static GPENCIL_tObject *grease_pencil_object_cache_populate( } GPENCIL_tLayer *tgp_layer = grease_pencil_layer_cache_add( - pd, ob, layer, info.onion_id, is_layer_used_as_mask, tgp_ob); + inst, pd, ob, layer, info.onion_id, is_layer_used_as_mask, tgp_ob); PassSimple &pass = *tgp_layer->geom_ps; last_pass = &pass; @@ -608,6 +605,7 @@ static GPENCIL_tObject *grease_pencil_object_cache_populate( void GPENCIL_cache_populate(void *ved, Object *ob) { GPENCIL_Data *vedata = (GPENCIL_Data *)ved; + GPENCIL_Instance *inst = vedata->instance; GPENCIL_PrivateData *pd = vedata->stl->pd; /* object must be visible */ @@ -620,7 +618,7 @@ void GPENCIL_cache_populate(void *ved, Object *ob) blender::draw::ObjectRef ob_ref = DRW_object_ref_get(ob); blender::draw::ResourceHandle res_handle = manager->unique_handle(ob_ref); - GPENCIL_tObject *tgp_ob = grease_pencil_object_cache_populate(pd, ob, res_handle); + GPENCIL_tObject *tgp_ob = grease_pencil_object_cache_populate(inst, pd, ob, res_handle); gpencil_vfx_cache_populate( vedata, ob, @@ -637,7 +635,6 @@ void GPENCIL_cache_finish(void *ved) { GPENCIL_Data *vedata = (GPENCIL_Data *)ved; GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; /* Upload UBO data. */ BLI_memblock_iter iter; @@ -652,77 +649,75 @@ void GPENCIL_cache_finish(void *ved) while ((lpool = (GPENCIL_LightPool *)BLI_memblock_iterstep(&iter))) { GPU_uniformbuf_update(lpool->ubo, lpool->light_data); } +} - /* Sort object by decreasing Z to avoid most of alpha ordering issues. */ - gpencil_object_cache_sort(pd); - +void GPENCIL_Instance::acquire_resources(GPENCIL_PrivateData *pd) +{ /* Create frame-buffers only if needed. */ - if (pd->tobjects.first) { - eGPUTextureFormat format = pd->use_signed_fb ? GPU_RGBA16F : GPU_R11F_G11F_B10F; - - const float *size = DRW_viewport_size_get(); - pd->depth_tx = DRW_texture_pool_query_2d( - size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type); - pd->color_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type); - pd->reveal_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type); - - GPU_framebuffer_ensure_config(&fbl->gpencil_fb, - { - GPU_ATTACHMENT_TEXTURE(pd->depth_tx), - GPU_ATTACHMENT_TEXTURE(pd->color_tx), - GPU_ATTACHMENT_TEXTURE(pd->reveal_tx), - }); - - if (pd->use_layer_fb) { - pd->color_layer_tx = DRW_texture_pool_query_2d( - size[0], size[1], format, &draw_engine_gpencil_type); - pd->reveal_layer_tx = DRW_texture_pool_query_2d( - size[0], size[1], format, &draw_engine_gpencil_type); - - GPU_framebuffer_ensure_config(&fbl->layer_fb, - { - GPU_ATTACHMENT_TEXTURE(pd->depth_tx), - GPU_ATTACHMENT_TEXTURE(pd->color_layer_tx), - GPU_ATTACHMENT_TEXTURE(pd->reveal_layer_tx), - }); - } - - if (pd->use_object_fb) { - pd->color_object_tx = DRW_texture_pool_query_2d( - size[0], size[1], format, &draw_engine_gpencil_type); - pd->reveal_object_tx = DRW_texture_pool_query_2d( - size[0], size[1], format, &draw_engine_gpencil_type); - - GPU_framebuffer_ensure_config(&fbl->object_fb, - { - GPU_ATTACHMENT_TEXTURE(pd->depth_tx), - GPU_ATTACHMENT_TEXTURE(pd->color_object_tx), - GPU_ATTACHMENT_TEXTURE(pd->reveal_object_tx), - }); - } - - if (pd->use_mask_fb) { - /* We need an extra depth to not disturb the normal drawing. - * The color_tx is needed for frame-buffer completeness. */ - GPUTexture *color_tx, *depth_tx; - depth_tx = DRW_texture_pool_query_2d( - size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type); - color_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_R8, &draw_engine_gpencil_type); - /* Use high quality format for render. */ - eGPUTextureFormat mask_format = pd->is_render ? GPU_R16 : GPU_R8; - pd->mask_tx = DRW_texture_pool_query_2d( - size[0], size[1], mask_format, &draw_engine_gpencil_type); - - GPU_framebuffer_ensure_config(&fbl->mask_fb, - { - GPU_ATTACHMENT_TEXTURE(depth_tx), - GPU_ATTACHMENT_TEXTURE(color_tx), - GPU_ATTACHMENT_TEXTURE(pd->mask_tx), - }); - } - - GPENCIL_antialiasing_init(vedata); + if (pd->tobjects.first == nullptr) { + return; } + + const float *size_f = DRW_viewport_size_get(); + const int2 size(size_f[0], size_f[1]); + + eGPUTextureFormat format = pd->use_signed_fb ? GPU_RGBA16F : GPU_R11F_G11F_B10F; + + this->depth_tx.acquire(size, GPU_DEPTH24_STENCIL8); + this->color_tx.acquire(size, format); + this->reveal_tx.acquire(size, format); + + this->gpencil_fb.ensure(GPU_ATTACHMENT_TEXTURE(this->depth_tx), + GPU_ATTACHMENT_TEXTURE(this->color_tx), + GPU_ATTACHMENT_TEXTURE(this->reveal_tx)); + + if (pd->use_layer_fb) { + this->color_layer_tx.acquire(size, format); + this->reveal_layer_tx.acquire(size, format); + + this->layer_fb.ensure(GPU_ATTACHMENT_TEXTURE(this->depth_tx), + GPU_ATTACHMENT_TEXTURE(this->color_layer_tx), + GPU_ATTACHMENT_TEXTURE(this->reveal_layer_tx)); + } + + if (pd->use_object_fb) { + this->color_object_tx.acquire(size, format); + this->reveal_object_tx.acquire(size, format); + + this->object_fb.ensure(GPU_ATTACHMENT_TEXTURE(this->depth_tx), + GPU_ATTACHMENT_TEXTURE(this->color_object_tx), + GPU_ATTACHMENT_TEXTURE(this->reveal_object_tx)); + } + + if (pd->use_mask_fb) { + /* Use high quality format for render. */ + eGPUTextureFormat mask_format = pd->is_render ? GPU_R16 : GPU_R8; + /* We need an extra depth to not disturb the normal drawing. */ + this->mask_depth_tx.acquire(size, GPU_DEPTH24_STENCIL8); + /* The mask_color_tx is needed for frame-buffer completeness. */ + this->mask_color_tx.acquire(size, GPU_R8); + this->mask_tx.acquire(size, mask_format); + + this->mask_fb.ensure(GPU_ATTACHMENT_TEXTURE(this->depth_tx), + GPU_ATTACHMENT_TEXTURE(this->color_object_tx), + GPU_ATTACHMENT_TEXTURE(this->reveal_object_tx)); + } +} + +void GPENCIL_Instance::release_resources() +{ + this->depth_tx.release(); + this->color_tx.release(); + this->reveal_tx.release(); + this->color_layer_tx.release(); + this->reveal_layer_tx.release(); + this->color_object_tx.release(); + this->reveal_object_tx.release(); + this->mask_depth_tx.release(); + this->mask_color_tx.release(); + this->mask_tx.release(); + this->smaa_edge_tx.release(); + this->smaa_weight_tx.release(); } static void gpencil_draw_mask(GPENCIL_Data *vedata, @@ -733,7 +728,6 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_Instance *inst = vedata->instance; blender::draw::Manager *manager = DRW_manager_get(); - GPENCIL_FramebufferList *fbl = vedata->fbl; const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f; bool inverted = false; @@ -743,7 +737,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, DRW_stats_group_start("GPencil Mask"); - GPU_framebuffer_bind(fbl->mask_fb); + GPU_framebuffer_bind(inst->mask_fb); for (int i = 0; i < GP_MAX_MASKBITS; i++) { if (!BLI_BITMAP_TEST(layer->mask_bits, i)) { @@ -759,7 +753,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, if (!cleared) { cleared = true; - GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth); + GPU_framebuffer_clear_color_depth(inst->mask_fb, clear_col, clear_depth); } GPENCIL_tLayer *mask_layer = grease_pencil_layer_cache_get(ob, i, true); @@ -787,12 +781,11 @@ static void GPENCIL_draw_object(GPENCIL_Data *vedata, blender::draw::Manager *manager = DRW_manager_get(); GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}; DRW_stats_group_start("GPencil Object"); - GPUFrameBuffer *fb_object = (ob->vfx.first) ? fbl->object_fb : fbl->gpencil_fb; + GPUFrameBuffer *fb_object = (ob->vfx.first) ? inst->object_fb : inst->gpencil_fb; GPU_framebuffer_bind(fb_object); GPU_framebuffer_clear_depth_stencil(fb_object, ob->is_drawmode3d ? 1.0f : 0.0f, 0x00); @@ -807,8 +800,8 @@ static void GPENCIL_draw_object(GPENCIL_Data *vedata, } if (layer->blend_ps) { - GPU_framebuffer_bind(fbl->layer_fb); - GPU_framebuffer_multi_clear(fbl->layer_fb, clear_cols); + GPU_framebuffer_bind(inst->layer_fb); + GPU_framebuffer_multi_clear(inst->layer_fb, clear_cols); } else { GPU_framebuffer_bind(fb_object); @@ -840,15 +833,15 @@ static void GPENCIL_draw_object(GPENCIL_Data *vedata, static void GPENCIL_fast_draw_start(GPENCIL_Data *vedata) { + GPENCIL_Instance *inst = vedata->instance; GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (!pd->snapshot_buffer_dirty) { /* Copy back cached render. */ - GPU_framebuffer_blit(fbl->snapshot_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT); - GPU_framebuffer_blit(fbl->snapshot_fb, 0, fbl->gpencil_fb, 0, GPU_COLOR_BIT); - GPU_framebuffer_blit(fbl->snapshot_fb, 1, fbl->gpencil_fb, 1, GPU_COLOR_BIT); + GPU_framebuffer_blit(inst->snapshot_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT); + GPU_framebuffer_blit(inst->snapshot_fb, 0, inst->gpencil_fb, 0, GPU_COLOR_BIT); + GPU_framebuffer_blit(inst->snapshot_fb, 1, inst->gpencil_fb, 1, GPU_COLOR_BIT); /* Bypass drawing. */ pd->tobjects.first = pd->tobjects.last = nullptr; } @@ -856,15 +849,15 @@ static void GPENCIL_fast_draw_start(GPENCIL_Data *vedata) static void GPENCIL_fast_draw_end(GPENCIL_Data *vedata, blender::draw::View &view) { + GPENCIL_Instance *inst = vedata->instance; GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (pd->snapshot_buffer_dirty) { /* Save to snapshot buffer. */ - GPU_framebuffer_blit(dfbl->default_fb, 0, fbl->snapshot_fb, 0, GPU_DEPTH_BIT); - GPU_framebuffer_blit(fbl->gpencil_fb, 0, fbl->snapshot_fb, 0, GPU_COLOR_BIT); - GPU_framebuffer_blit(fbl->gpencil_fb, 1, fbl->snapshot_fb, 1, GPU_COLOR_BIT); + GPU_framebuffer_blit(dfbl->default_fb, 0, inst->snapshot_fb, 0, GPU_DEPTH_BIT); + GPU_framebuffer_blit(inst->gpencil_fb, 0, inst->snapshot_fb, 0, GPU_COLOR_BIT); + GPU_framebuffer_blit(inst->gpencil_fb, 1, inst->snapshot_fb, 1, GPU_COLOR_BIT); pd->snapshot_buffer_dirty = false; } /* Draw the sbuffer stroke(s). */ @@ -877,8 +870,8 @@ void GPENCIL_draw_scene(void *ved) { using namespace blender::draw; GPENCIL_Data *vedata = (GPENCIL_Data *)ved; + GPENCIL_Instance &inst = *vedata->instance; GPENCIL_PrivateData *pd = vedata->stl->pd; - GPENCIL_FramebufferList *fbl = vedata->fbl; float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}; /* Fade 3D objects. */ @@ -897,17 +890,24 @@ void GPENCIL_draw_scene(void *ved) return; } + GPENCIL_antialiasing_init(&inst, pd); + + inst.acquire_resources(pd); + if (pd->do_fast_drawing) { GPENCIL_fast_draw_start(vedata); } if (pd->tobjects.first) { - GPU_framebuffer_bind(fbl->gpencil_fb); - GPU_framebuffer_multi_clear(fbl->gpencil_fb, clear_cols); + GPU_framebuffer_bind(inst.gpencil_fb); + GPU_framebuffer_multi_clear(inst.gpencil_fb, clear_cols); } blender::draw::View &view = blender::draw::View::default_get(); + /* Sort object by decreasing Z to avoid most of alpha ordering issues. */ + gpencil_object_cache_sort(pd); + LISTBASE_FOREACH (GPENCIL_tObject *, ob, &pd->tobjects) { GPENCIL_draw_object(vedata, view, ob); } @@ -923,6 +923,8 @@ void GPENCIL_draw_scene(void *ved) pd->gp_object_pool = pd->gp_maskbit_pool = nullptr; pd->gp_vfx_pool = nullptr; pd->gp_layer_pool = nullptr; + + inst.release_resources(); } static void GPENCIL_engine_free() diff --git a/source/blender/draw/engines/gpencil/gpencil_render.cc b/source/blender/draw/engines/gpencil/gpencil_render.cc index adcd3e86a25..968b0b3c044 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.cc +++ b/source/blender/draw/engines/gpencil/gpencil_render.cc @@ -27,8 +27,6 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, const Depsgraph *depsgraph, const rcti *rect) { - GPENCIL_FramebufferList *fbl = vedata->fbl; - if (vedata->instance == nullptr) { vedata->instance = new GPENCIL_Instance(); } @@ -112,21 +110,18 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, inst.render_color_tx.ensure_2d(GPU_RGBA16F, int2(size), usage, do_region ? nullptr : pix_col); } - GPU_framebuffer_ensure_config(&fbl->render_fb, - { - GPU_ATTACHMENT_TEXTURE(inst.render_depth_tx), - GPU_ATTACHMENT_TEXTURE(inst.render_color_tx), - }); + inst.render_fb.ensure(GPU_ATTACHMENT_TEXTURE(inst.render_depth_tx), + GPU_ATTACHMENT_TEXTURE(inst.render_color_tx)); if (do_clear_z || do_clear_col) { /* To avoid unpredictable result, clear buffers that have not be initialized. */ - GPU_framebuffer_bind(fbl->render_fb); + GPU_framebuffer_bind(inst.render_fb); if (do_clear_col) { const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_clear_color(fbl->render_fb, clear_col); + GPU_framebuffer_clear_color(inst.render_fb, clear_col); } if (do_clear_z) { - GPU_framebuffer_clear_depth(fbl->render_fb, 1.0f); + GPU_framebuffer_clear_depth(inst.render_fb, 1.0f); } } @@ -176,7 +171,7 @@ static void GPENCIL_render_result_z(RenderLayer *rl, float *ro_buffer_data = rp->ibuf->float_buffer.data; - GPU_framebuffer_read_depth(vedata->fbl->render_fb, + GPU_framebuffer_read_depth(vedata->instance->render_fb, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), @@ -223,10 +218,9 @@ static void GPENCIL_render_result_combined(RenderLayer *rl, const rcti *rect) { RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); - GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; - GPU_framebuffer_bind(fbl->render_fb); - GPU_framebuffer_read_color(vedata->fbl->render_fb, + GPU_framebuffer_bind(vedata->instance->render_fb); + GPU_framebuffer_read_color(vedata->instance->render_fb, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.cc b/source/blender/draw/engines/gpencil/gpencil_shader_fx.cc index 5e1af94d512..e4bbda4410f 100644 --- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.cc +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.cc @@ -588,19 +588,19 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, GPENCIL_tObject *tgp_ob, const bool is_edit_mode) { - GPENCIL_FramebufferList *fbl = vedata->fbl; + GPENCIL_Instance *inst = vedata->instance; GPENCIL_PrivateData *pd = vedata->stl->pd; /* These may not be allocated yet, use address of future pointer. */ gpIterVfxData iter{}; iter.pd = pd; iter.tgp_ob = tgp_ob; - iter.target_fb = &fbl->layer_fb; - iter.source_fb = &fbl->object_fb; - iter.target_color_tx = &pd->color_layer_tx; - iter.source_color_tx = &pd->color_object_tx; - iter.target_reveal_tx = &pd->reveal_layer_tx; - iter.source_reveal_tx = &pd->reveal_object_tx; + iter.target_fb = &inst->layer_fb; + iter.source_fb = &inst->object_fb; + iter.target_color_tx = &inst->color_layer_tx; + iter.source_color_tx = &inst->color_object_tx; + iter.target_reveal_tx = &inst->reveal_layer_tx; + iter.source_reveal_tx = &inst->reveal_object_tx; /* If simplify enabled, nothing more to do. */ if (!pd->simplify_fx) { @@ -643,7 +643,7 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, if ((!pd->simplify_fx && tgp_ob->vfx.first != nullptr) || tgp_ob->do_mat_holdout) { /* We need an extra pass to combine result to main buffer. */ - iter.target_fb = &fbl->gpencil_fb; + iter.target_fb = &inst->gpencil_fb; GPUShader *sh = GPENCIL_shader_fx_composite_get();