Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-11-13 18:23:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-11-13 18:23:22 +0300
commitcd64615425248eaf8dc80653626fe5f2dbb084a2 (patch)
tree36f87add4266767cc5eeea37a32de3acf3a65c22
parent930d14cc6203bf52f7a4f122336994bf47d2765b (diff)
DRW: Manager: Add `ClearMulti` command
Allows to record `GPU_framebuffer_multi_clear` inside `draw::Pass`.
-rw-r--r--source/blender/draw/intern/draw_command.cc15
-rw-r--r--source/blender/draw/intern/draw_command.hh9
-rw-r--r--source/blender/draw/intern/draw_pass.hh16
3 files changed, 40 insertions, 0 deletions
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<float4> 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<float4> colors);
/**
* Reminders:
@@ -469,6 +474,11 @@ inline void PassBase<T>::clear(eGPUFrameBufferBits planes,
create_command(command::Type::Clear).clear = {uint8_t(planes), stencil, depth, color};
}
+template<class T> inline void PassBase<T>::clear_multi(Span<float4> colors)
+{
+ create_command(command::Type::ClearMulti).clear_multi = {colors};
+}
+
template<class T> inline GPUBatch *PassBase<T>::procedural_batch_get(GPUPrimType primitive)
{
switch (primitive) {
@@ -540,6 +550,9 @@ template<class T> void PassBase<T>::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<class T> std::string PassBase<T>::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;