From e826ab9ba90595007b698df36622b725697ec26c Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Fri, 20 Sep 2024 15:11:08 +1000 Subject: [PATCH] [2D,Metal]: Fix subpixel blending; fix inconsistent blend state in Metal --- drivers/metal/metal_objects.h | 7 +++++++ drivers/metal/metal_objects.mm | 4 ++++ .../rendering/renderer_rd/renderer_canvas_render_rd.cpp | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h index 97f33bb1e84..030b353ee82 100644 --- a/drivers/metal/metal_objects.h +++ b/drivers/metal/metal_objects.h @@ -318,6 +318,13 @@ public: dirty.set_flag(DirtyFlag::DIRTY_UNIFORMS); } + _FORCE_INLINE_ void mark_blend_dirty() { + if (!blend_constants.has_value()) { + return; + } + dirty.set_flag(DirtyFlag::DIRTY_BLEND); + } + MTLScissorRect clip_to_render_area(MTLScissorRect p_rect) const { uint32_t raLeft = render_area.position.x; uint32_t raRight = raLeft + render_area.size.width; diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm index d3c3d2b2327..1d08a10781d 100644 --- a/drivers/metal/metal_objects.mm +++ b/drivers/metal/metal_objects.mm @@ -143,6 +143,9 @@ void MDCommandBuffer::bind_pipeline(RDD::PipelineID p_pipeline) { if (render.pipeline != nullptr && render.pipeline->depth_stencil != rp->depth_stencil) { render.dirty.set_flag(RenderState::DIRTY_DEPTH); } + if (rp->raster_state.blend.enabled) { + render.dirty.set_flag(RenderState::DIRTY_BLEND); + } render.pipeline = rp; } } else if (p->type == MDPipelineType::Compute) { @@ -301,6 +304,7 @@ void MDCommandBuffer::render_clear_attachments(VectorView render.mark_viewport_dirty(); render.mark_scissors_dirty(); render.mark_vertex_dirty(); + render.mark_blend_dirty(); } void MDCommandBuffer::_render_set_dirty_state() { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 738bcd48329..57497eb2070 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2479,6 +2479,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar r_current_batch = _new_batch(r_batch_broken); r_current_batch->command_type = Item::Command::TYPE_NINEPATCH; r_current_batch->command = c; + r_current_batch->has_blend = false; r_current_batch->pipeline_variant = PipelineVariant::PIPELINE_VARIANT_NINEPATCH; } @@ -2548,6 +2549,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar r_current_batch = _new_batch(r_batch_broken); r_current_batch->command_type = Item::Command::TYPE_POLYGON; + r_current_batch->has_blend = false; r_current_batch->command = c; TextureState tex_state(polygon->texture, texture_filter, texture_repeat, false, use_linear_colors); @@ -2585,6 +2587,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar if (primitive->point_count != r_current_batch->primitive_points || r_current_batch->command_type != Item::Command::TYPE_PRIMITIVE) { r_current_batch = _new_batch(r_batch_broken); r_current_batch->command_type = Item::Command::TYPE_PRIMITIVE; + r_current_batch->has_blend = false; r_current_batch->command = c; r_current_batch->primitive_points = primitive->point_count; @@ -2646,6 +2649,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar r_current_batch = _new_batch(r_batch_broken); r_current_batch->command = c; r_current_batch->command_type = c->type; + r_current_batch->has_blend = false; InstanceData *instance_data = nullptr; @@ -2799,6 +2803,7 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, PipelineV RID pipeline = p_pipeline_variants->variants[p_batch->light_mode][p_batch->pipeline_variant].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); if (p_batch->has_blend) { + DEV_ASSERT(p_batch->pipeline_variant == PIPELINE_VARIANT_QUAD_LCD_BLEND); RD::get_singleton()->draw_list_set_blend_constants(p_draw_list, p_batch->modulate); }