27 <<
"Render target does not have color attachment at index 0.";
34 std::optional<ISize> size;
35 bool sizes_are_same =
true;
36 auto iterator = [&](
const Attachment& attachment) ->
bool {
37 if (!size.has_value()) {
38 size = attachment.texture->GetSize();
40 if (size != attachment.texture->GetSize()) {
41 sizes_are_same =
false;
47 if (!sizes_are_same) {
49 <<
"Sizes of all render target attachments are not the same.";
56 std::optional<TextureType> texture_type;
57 std::optional<SampleCount> sample_count;
58 bool passes_type_validation =
true;
59 auto iterator = [&](
const Attachment& attachment) ->
bool {
60 if (!texture_type.has_value() || !sample_count.has_value()) {
61 texture_type = attachment.texture->GetTextureDescriptor().type;
62 sample_count = attachment.texture->GetTextureDescriptor().sample_count;
65 if (texture_type != attachment.texture->GetTextureDescriptor().type) {
66 passes_type_validation =
false;
70 attachment.texture->GetTextureDescriptor().type)
76 attachment.texture->GetTextureDescriptor().sample_count) {
77 passes_type_validation =
false;
79 <<
") has incompatible sample counts.";
87 if (!passes_type_validation) {
97 const std::function<
bool(
size_t index,
const ColorAttachment& attachment)>&
99 if (color0_.has_value()) {
100 if (!iterator(0, color0_.value())) {
104 for (
const auto& [index, attachment] : colors_) {
105 if (!iterator(index, attachment)) {
113 const std::function<
bool(
const Attachment& attachment)>& iterator)
const {
114 if (color0_.has_value()) {
115 if (!iterator(color0_.value())) {
119 for (
const auto& color : colors_) {
120 if (!iterator(color.second)) {
125 if (depth_.has_value()) {
126 if (!iterator(depth_.value())) {
131 if (stencil_.has_value()) {
132 if (!iterator(stencil_.value())) {
139 if (color0_.has_value()) {
140 return color0_.value().texture->GetTextureDescriptor().sample_count;
147 return color0_.has_value();
149 if (
auto found = colors_.find(index); found != colors_.end()) {
157 if (color0_.has_value()) {
158 return color0_.value().texture->GetSize();
162 auto found = colors_.find(index);
164 if (found == colors_.end()) {
168 return found->second.texture->GetSize();
173 return size.has_value() ? size.value() :
ISize{};
177 if (!color0_.has_value()) {
180 return color0_->resolve_texture ? color0_->resolve_texture : color0_->texture;
185 return texture->GetTextureDescriptor().format;
193 for (
const auto& color : colors_) {
194 max = std::max(color.first, max);
206 color0_ = attachment;
208 colors_[index] = attachment;
214 std::optional<DepthAttachment> attachment) {
215 if (!attachment.has_value()) {
216 depth_ = std::nullopt;
217 }
else if (attachment->IsValid()) {
218 depth_ = std::move(attachment);
224 std::optional<StencilAttachment> attachment) {
225 if (!attachment.has_value()) {
226 stencil_ = std::nullopt;
227 }
else if (attachment->IsValid()) {
228 stencil_ = std::move(attachment);
235 if (color0_.has_value()) {
236 return color0_.value();
240 std::map<size_t, ColorAttachment>::const_iterator it = colors_.find(index);
241 if (it != colors_.end()) {
258 for (
const auto& [_, color] : colors_) {
262 if (color.resolve_texture) {
266 if (color0_.has_value()) {
269 if (depth_.has_value()) {
272 if (stencil_.has_value()) {
279 std::stringstream stream;
281 if (color0_.has_value()) {
282 stream <<
SPrintF(
"Color[%d]=(%s)", 0,
285 for (
const auto& [index, color] : colors_) {
286 stream <<
SPrintF(
"Color[%zu]=(%s)", index,
291 stream <<
SPrintF(
"Depth=(%s)",
296 stream <<
SPrintF(
"Stencil=(%s)",
303 if (!color0_.has_value()) {
306 const auto& color_attachment = color0_.value();
308 .
size = color_attachment.texture->GetSize(),
309 .mip_count = color_attachment.texture->GetMipCount(),
310 .has_msaa = color_attachment.resolve_texture !=
nullptr,
311 .has_depth_stencil = depth_.has_value() && stencil_.has_value()};
315 std::shared_ptr<Allocator> allocator)
316 : allocator_(
std::move(allocator)) {}
326 std::string_view label,
328 std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
329 const std::shared_ptr<Texture>& existing_color_texture,
330 const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
337 std::shared_ptr<Texture> color0_tex;
338 if (existing_color_texture) {
339 color0_tex = existing_color_texture;
345 color0_tex_desc.
format = pixel_format;
346 color0_tex_desc.
size = size;
348 color0_tex_desc.
usage =
350 color0_tex = allocator_->CreateTexture(color0_tex_desc);
355 color0_tex->SetLabel(label,
"Color Texture");
364 if (stencil_attachment_config.has_value()) {
366 context, *allocator_, size,
false, label,
367 stencil_attachment_config.value(), existing_depth_stencil_texture);
380 std::string_view label,
382 std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
383 const std::shared_ptr<Texture>& existing_color_msaa_texture,
384 const std::shared_ptr<Texture>& existing_color_resolve_texture,
385 const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
394 std::shared_ptr<Texture> color0_msaa_tex;
395 if (existing_color_msaa_texture) {
396 color0_msaa_tex = existing_color_msaa_texture;
402 color0_tex_desc.
format = pixel_format;
403 color0_tex_desc.
size = size;
409 color0_msaa_tex = allocator_->CreateTexture(color0_tex_desc);
410 if (!color0_msaa_tex) {
415 color0_msaa_tex->SetLabel(label,
"Color Texture (Multisample)");
418 std::shared_ptr<Texture> color0_resolve_tex;
419 if (existing_color_resolve_texture) {
420 color0_resolve_tex = existing_color_resolve_texture;
425 color0_resolve_tex_desc.
format = pixel_format;
426 color0_resolve_tex_desc.
size = size;
428 color0_resolve_tex_desc.
usage =
430 color0_resolve_tex_desc.
mip_count = mip_count;
431 color0_resolve_tex = allocator_->CreateTexture(color0_resolve_tex_desc);
432 if (!color0_resolve_tex) {
437 color0_resolve_tex->SetLabel(label,
"Color Texture");
445 color0.
texture = color0_msaa_tex;
463 if (stencil_attachment_config.has_value()) {
465 stencil_attachment_config.value(),
466 existing_depth_stencil_texture);
480 std::string_view label,
482 const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
483 std::shared_ptr<Texture> depth_stencil_texture;
484 if (existing_depth_stencil_texture) {
485 depth_stencil_texture = existing_depth_stencil_texture;
494 depth_stencil_texture_desc.
format =
496 depth_stencil_texture_desc.
size = size;
498 depth_stencil_texture = allocator.
CreateTexture(depth_stencil_texture_desc);
499 if (!depth_stencil_texture) {
508 depth0.
texture = depth_stencil_texture;
514 stencil0.
texture = std::move(depth_stencil_texture);
515 stencil0.
texture->SetLabel(label,
"Depth+Stencil Texture");
An object that allocates device memory.
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &desc)
To do anything rendering related with Impeller, you need a context.
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
RenderTargetAllocator(std::shared_ptr< Allocator > allocator)
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config=RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_msaa_texture=nullptr, const std::shared_ptr< Texture > &existing_color_resolve_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen", RenderTarget::AttachmentConfig color_attachment_config=RenderTarget::kDefaultColorAttachmentConfig, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
virtual void Start()
Mark the beginning of a frame workload.
virtual void End()
Mark the end of a frame workload.
ColorAttachment GetColorAttachment(size_t index) const
Get the color attachment at [index].
std::shared_ptr< Texture > GetRenderTargetTexture() const
SampleCount GetSampleCount() const
void IterateAllAttachments(const std::function< bool(const Attachment &attachment)> &iterator) const
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
bool HasColorAttachment(size_t index) const
size_t GetMaxColorAttacmentBindIndex() const
std::string ToString() const
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
PixelFormat GetRenderTargetPixelFormat() const
size_t GetTotalAttachmentCount() const
ISize GetRenderTargetSize() const
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
bool IterateAllColorAttachments(const std::function< bool(size_t index, const ColorAttachment &attachment)> &iterator) const
std::optional< ISize > GetColorAttachmentSize(size_t index) const
const std::optional< DepthAttachment > & GetDepthAttachment() const
const std::optional< StencilAttachment > & GetStencilAttachment() const
void SetupDepthStencilAttachments(const Context &context, Allocator &allocator, ISize size, bool msaa, std::string_view label="Offscreen", RenderTarget::AttachmentConfig stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &depth_stencil_texture=nullptr)
RenderTargetConfig ToConfig() const
std::string DepthAttachmentToString(const DepthAttachment &depth)
std::string ColorAttachmentToString(const ColorAttachment &color)
std::string StencilAttachmentToString(const StencilAttachment &stencil)
std::string SPrintF(const char *format,...)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
constexpr const char * TextureTypeToString(TextureType type)
std::shared_ptr< Texture > resolve_texture
std::shared_ptr< Texture > texture
StorageMode resolve_storage_mode
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
CompressionType compression_type