26 uint32_t shift = std::min(mip_level, 31u);
27 return ISize{std::max<int64_t>(1, size.width >> shift),
28 std::max<int64_t>(1, size.height >> shift)};
39 <<
"Render target does not have color attachment at index 0.";
46 std::optional<ISize> size;
47 bool sizes_are_same =
true;
48 auto iterator = [&](
const Attachment& attachment) ->
bool {
49 ISize attachment_size =
51 if (!size.has_value()) {
52 size = attachment_size;
54 if (size != attachment_size) {
55 sizes_are_same =
false;
61 if (!sizes_are_same) {
63 <<
"Sizes of all render target attachments are not the same.";
70 std::optional<TextureType> texture_type;
71 std::optional<SampleCount> sample_count;
72 bool passes_type_validation =
true;
73 auto iterator = [&](
const Attachment& attachment) ->
bool {
74 if (!texture_type.has_value() || !sample_count.has_value()) {
75 texture_type = attachment.texture->GetTextureDescriptor().type;
76 sample_count = attachment.texture->GetTextureDescriptor().sample_count;
79 if (texture_type != attachment.texture->GetTextureDescriptor().type) {
80 passes_type_validation =
false;
84 attachment.texture->GetTextureDescriptor().type)
90 attachment.texture->GetTextureDescriptor().sample_count) {
91 passes_type_validation =
false;
93 <<
") has incompatible sample counts.";
101 if (!passes_type_validation) {
111 const std::function<
bool(
size_t index,
const ColorAttachment& attachment)>&
113 if (color0_.has_value()) {
114 if (!iterator(0, color0_.value())) {
118 for (
const auto& [index, attachment] : colors_) {
119 if (!iterator(index, attachment)) {
127 const std::function<
bool(
const Attachment& attachment)>& iterator)
const {
128 if (color0_.has_value()) {
129 if (!iterator(color0_.value())) {
133 for (
const auto& color : colors_) {
134 if (!iterator(color.second)) {
139 if (depth_.has_value()) {
140 if (!iterator(depth_.value())) {
145 if (stencil_.has_value()) {
146 if (!iterator(stencil_.value())) {
153 if (color0_.has_value()) {
154 return color0_.value().texture->GetTextureDescriptor().sample_count;
161 return color0_.has_value();
163 if (
auto found = colors_.find(index); found != colors_.end()) {
171 if (color0_.has_value()) {
173 color0_.value().mip_level);
177 auto found = colors_.find(index);
179 if (found == colors_.end()) {
183 return SizeForMipLevel(found->second.texture, found->second.mip_level);
188 return size.has_value() ? size.value() :
ISize{};
192 if (!color0_.has_value()) {
195 return color0_->resolve_texture ? color0_->resolve_texture : color0_->texture;
200 return texture->GetTextureDescriptor().format;
208 for (
const auto& color : colors_) {
209 max = std::max(color.first, max);
221 color0_ = attachment;
223 colors_[index] = attachment;
229 std::optional<DepthAttachment> attachment) {
230 if (!attachment.has_value()) {
231 depth_ = std::nullopt;
232 }
else if (attachment->IsValid()) {
233 depth_ = std::move(attachment);
239 std::optional<StencilAttachment> attachment) {
240 if (!attachment.has_value()) {
241 stencil_ = std::nullopt;
242 }
else if (attachment->IsValid()) {
243 stencil_ = std::move(attachment);
250 if (color0_.has_value()) {
251 return color0_.value();
255 std::map<size_t, ColorAttachment>::const_iterator it = colors_.find(index);
256 if (it != colors_.end()) {
273 for (
const auto& [_, color] : colors_) {
277 if (color.resolve_texture) {
281 if (color0_.has_value()) {
284 if (depth_.has_value()) {
287 if (stencil_.has_value()) {
294 std::stringstream stream;
296 if (color0_.has_value()) {
297 stream << std::format(
"Color[{}]=({})", 0,
300 for (
const auto& [index, color] : colors_) {
301 stream << std::format(
"Color[{}]=({})", index,
306 stream << std::format(
"Depth=({})",
311 stream << std::format(
"Stencil=({})",
318 if (!color0_.has_value()) {
321 const auto& color_attachment = color0_.value();
323 .
size = color_attachment.texture->GetSize(),
324 .mip_count = color_attachment.texture->GetMipCount(),
325 .has_msaa = color_attachment.resolve_texture !=
nullptr,
326 .has_depth_stencil = depth_.has_value() && stencil_.has_value()};
341 std::string_view label,
343 std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
344 const std::shared_ptr<Texture>& existing_color_texture,
345 const std::shared_ptr<Texture>& existing_depth_stencil_texture,
346 std::optional<PixelFormat> target_pixel_format) {
347 if (size.IsEmpty()) {
353 std::shared_ptr<Texture> color0_tex;
354 if (existing_color_texture) {
355 color0_tex = existing_color_texture;
360 target_pixel_format.has_value()
361 ? target_pixel_format.value()
362 :
context.GetCapabilities()->GetDefaultColorFormat();
363 color0_tex_desc.
size = size;
365 color0_tex_desc.
usage =
367 color0_tex = allocator_->CreateTexture(color0_tex_desc);
372 color0_tex->SetLabel(label,
"Color Texture");
379 target.SetColorAttachment(color0, 0u);
381 if (stencil_attachment_config.has_value()) {
382 target.SetupDepthStencilAttachments(
383 context, *allocator_, size,
false, label,
384 stencil_attachment_config.value(), existing_depth_stencil_texture);
386 target.SetStencilAttachment(std::nullopt);
387 target.SetDepthAttachment(std::nullopt);
397 std::string_view label,
399 std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
400 const std::shared_ptr<Texture>& existing_color_msaa_texture,
401 const std::shared_ptr<Texture>& existing_color_resolve_texture,
402 const std::shared_ptr<Texture>& existing_depth_stencil_texture,
403 std::optional<PixelFormat> target_pixel_format) {
404 if (size.IsEmpty()) {
410 target_pixel_format.has_value()
411 ? target_pixel_format.value()
412 :
context.GetCapabilities()->GetDefaultColorFormat();
415 std::shared_ptr<Texture> color0_msaa_tex;
416 if (existing_color_msaa_texture) {
417 color0_msaa_tex = existing_color_msaa_texture;
423 color0_tex_desc.
format = pixel_format;
424 color0_tex_desc.
size = size;
426 if (
context.GetCapabilities()->SupportsImplicitResolvingMSAA()) {
430 color0_msaa_tex = allocator_->CreateTexture(color0_tex_desc);
431 if (!color0_msaa_tex) {
436 color0_msaa_tex->SetLabel(label,
"Color Texture (Multisample)");
439 std::shared_ptr<Texture> color0_resolve_tex;
440 if (existing_color_resolve_texture) {
441 color0_resolve_tex = existing_color_resolve_texture;
446 color0_resolve_tex_desc.
format = pixel_format;
447 color0_resolve_tex_desc.
size = size;
449 color0_resolve_tex_desc.
usage =
451 color0_resolve_tex_desc.
mip_count = mip_count;
452 color0_resolve_tex = allocator_->CreateTexture(color0_resolve_tex_desc);
453 if (!color0_resolve_tex) {
458 color0_resolve_tex->SetLabel(label,
"Color Texture");
466 color0.
texture = color0_msaa_tex;
469 if (
context.GetCapabilities()->SupportsImplicitResolvingMSAA()) {
480 target.SetColorAttachment(color0, 0u);
484 if (stencil_attachment_config.has_value()) {
485 target.SetupDepthStencilAttachments(
context, *allocator_, size,
true, label,
486 stencil_attachment_config.value(),
487 existing_depth_stencil_texture);
489 target.SetDepthAttachment(std::nullopt);
490 target.SetStencilAttachment(std::nullopt);
501 std::string_view label,
503 const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
504 std::shared_ptr<Texture> depth_stencil_texture;
505 if (existing_depth_stencil_texture) {
506 depth_stencil_texture = existing_depth_stencil_texture;
515 depth_stencil_texture_desc.
format =
516 context.GetCapabilities()->GetDefaultDepthStencilFormat();
517 depth_stencil_texture_desc.
size = size;
519 depth_stencil_texture =
allocator.CreateTexture(depth_stencil_texture_desc);
520 if (!depth_stencil_texture) {
529 depth0.
texture = depth_stencil_texture;
535 stencil0.
texture = std::move(depth_stencil_texture);
536 stencil0.
texture->SetLabel(label,
"Depth+Stencil Texture");
An object that allocates device memory.
To do anything rendering related with Impeller, you need a context.
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, std::optional< PixelFormat > target_pixel_format=std::nullopt)
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, std::optional< PixelFormat > target_pixel_format=std::nullopt)
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
std::string ToString() const
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
size_t GetMaxColorAttachmentBindIndex() const
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::shared_ptr< ImpellerAllocator > allocator
std::string DepthAttachmentToString(const DepthAttachment &depth)
std::string ColorAttachmentToString(const ColorAttachment &color)
std::string StencilAttachmentToString(const StencilAttachment &stencil)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
static ISize SizeForMipLevel(const std::shared_ptr< Texture > &texture, uint32_t mip_level)
constexpr const char * TextureTypeToString(TextureType type)
std::shared_ptr< ContextGLES > context
std::shared_ptr< Texture > resolve_texture
std::shared_ptr< Texture > texture
StorageMode resolve_storage_mode
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
CompressionType compression_type