From cd64615425248eaf8dc80653626fe5f2dbb084a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 13 Nov 2022 16:23:22 +0100 Subject: DRW: Manager: Add `ClearMulti` command Allows to record `GPU_framebuffer_multi_clear` inside `draw::Pass`. --- source/blender/draw/intern/draw_command.cc | 15 +++++++++++++++ source/blender/draw/intern/draw_command.hh | 9 +++++++++ source/blender/draw/intern/draw_pass.hh | 16 ++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 848d13083d0..3ef33f13c4a 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -158,6 +158,12 @@ void Clear::execute() const GPU_framebuffer_clear(fb, (eGPUFrameBufferBits)clear_channels, color, depth, stencil); } +void ClearMulti::execute() const +{ + GPUFrameBuffer *fb = GPU_framebuffer_active_get(); + GPU_framebuffer_multi_clear(fb, (const float(*)[4])colors.data()); +} + void StateSet::execute(RecordingState &recording_state) const { /** @@ -471,6 +477,15 @@ std::string Clear::serialize() const return std::string(".clear(") + ss.str() + ")"; } +std::string ClearMulti::serialize() const +{ + std::stringstream ss; + for (float4 color : colors) { + ss << color << ", "; + } + return std::string(".clear_multi(colors={") + ss.str() + "})"; +} + std::string StateSet::serialize() const { /* TODO(@fclem): Better serialization... */ diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh index 03499d07041..ea92b54d2ec 100644 --- a/source/blender/draw/intern/draw_command.hh +++ b/source/blender/draw/intern/draw_command.hh @@ -84,6 +84,7 @@ enum class Type : uint8_t { /** Commands stored as Undetermined in regular command buffer. */ Barrier, Clear, + ClearMulti, Dispatch, DispatchIndirect, Draw, @@ -323,6 +324,13 @@ struct Clear { std::string serialize() const; }; +struct ClearMulti { + Span colors; + + void execute() const; + std::string serialize() const; +}; + struct StateSet { DRWState new_state; int clip_plane_count; @@ -352,6 +360,7 @@ union Undetermined { DispatchIndirect dispatch_indirect; Barrier barrier; Clear clear; + ClearMulti clear_multi; StateSet state_set; StencilSet stencil_set; }; diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 3675a8fb6d9..a9c1d776091 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -172,6 +172,11 @@ class PassBase { void clear_stencil(uint8_t stencil); void clear_depth_stencil(float depth, uint8_t stencil); void clear_color_depth_stencil(float4 color, float depth, uint8_t stencil); + /** + * Clear each color attachment with different values. Span needs to be appropriately sized. + * IMPORTANT: The source is dereference on pass submission. + */ + void clear_multi(Span colors); /** * Reminders: @@ -469,6 +474,11 @@ inline void PassBase::clear(eGPUFrameBufferBits planes, create_command(command::Type::Clear).clear = {uint8_t(planes), stencil, depth, color}; } +template inline void PassBase::clear_multi(Span colors) +{ + create_command(command::Type::ClearMulti).clear_multi = {colors}; +} + template inline GPUBatch *PassBase::procedural_batch_get(GPUPrimType primitive) { switch (primitive) { @@ -540,6 +550,9 @@ template void PassBase::submit(command::RecordingState &state) const case command::Type::Clear: commands_[header.index].clear.execute(); break; + case command::Type::ClearMulti: + commands_[header.index].clear_multi.execute(); + break; case command::Type::StateSet: commands_[header.index].state_set.execute(state); break; @@ -598,6 +611,9 @@ template std::string PassBase::serialize(std::string line_prefix) co case Type::Clear: ss << line_prefix << commands_[header.index].clear.serialize() << std::endl; break; + case Type::ClearMulti: + ss << line_prefix << commands_[header.index].clear_multi.serialize() << std::endl; + break; case Type::StateSet: ss << line_prefix << commands_[header.index].state_set.serialize() << std::endl; break; -- cgit v1.2.3