Flutter Impeller
texture_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
11 
12 namespace impeller {
13 
14 TextureVK::TextureVK(std::weak_ptr<Context> context,
15  std::shared_ptr<TextureSourceVK> source)
16  : Texture(source->GetTextureDescriptor()),
17  context_(std::move(context)),
18  source_(std::move(source)) {}
19 
20 TextureVK::~TextureVK() = default;
21 
22 void TextureVK::SetLabel(std::string_view label) {
23  auto context = context_.lock();
24  if (!context) {
25  // The context may have died.
26  return;
27  }
28  ContextVK::Cast(*context).SetDebugName(GetImage(), label);
29  ContextVK::Cast(*context).SetDebugName(GetImageView(), label);
30 }
31 
32 bool TextureVK::OnSetContents(const uint8_t* contents,
33  size_t length,
34  size_t slice) {
35  if (!IsValid() || !contents) {
36  return false;
37  }
38 
39  const auto& desc = GetTextureDescriptor();
40 
41  // Out of bounds access.
42  if (length != desc.GetByteSizeOfBaseMipLevel()) {
43  VALIDATION_LOG << "Illegal to set contents for invalid size.";
44  return false;
45  }
46 
47  auto context = context_.lock();
48  if (!context) {
49  VALIDATION_LOG << "Context died before setting contents on texture.";
50  return false;
51  }
52 
53  auto staging_buffer =
54  context->GetResourceAllocator()->CreateBufferWithCopy(contents, length);
55 
56  if (!staging_buffer) {
57  VALIDATION_LOG << "Could not create staging buffer.";
58  return false;
59  }
60 
61  auto cmd_buffer = context->CreateCommandBuffer();
62 
63  if (!cmd_buffer) {
64  return false;
65  }
66 
67  const auto encoder = CommandBufferVK::Cast(*cmd_buffer).GetEncoder();
68 
69  if (!encoder->Track(staging_buffer) || !encoder->Track(source_)) {
70  return false;
71  }
72 
73  const auto& vk_cmd_buffer = encoder->GetCommandBuffer();
74 
75  BarrierVK barrier;
76  barrier.cmd_buffer = vk_cmd_buffer;
77  barrier.new_layout = vk::ImageLayout::eTransferDstOptimal;
78  barrier.src_access = {};
79  barrier.src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
80  barrier.dst_access = vk::AccessFlagBits::eTransferWrite;
81  barrier.dst_stage = vk::PipelineStageFlagBits::eTransfer;
82 
83  if (!SetLayout(barrier)) {
84  return false;
85  }
86 
87  vk::BufferImageCopy copy;
88  copy.bufferOffset = 0u;
89  copy.bufferRowLength = 0u; // 0u means tightly packed per spec.
90  copy.bufferImageHeight = 0u; // 0u means tightly packed per spec.
91  copy.imageOffset.x = 0u;
92  copy.imageOffset.y = 0u;
93  copy.imageOffset.z = 0u;
94  copy.imageExtent.width = desc.size.width;
95  copy.imageExtent.height = desc.size.height;
96  copy.imageExtent.depth = 1u;
97  copy.imageSubresource.aspectMask =
99  copy.imageSubresource.mipLevel = 0u;
100  copy.imageSubresource.baseArrayLayer = slice;
101  copy.imageSubresource.layerCount = 1u;
102 
103  vk_cmd_buffer.copyBufferToImage(
104  DeviceBufferVK::Cast(*staging_buffer).GetBuffer(), // src buffer
105  GetImage(), // dst image
106  barrier.new_layout, // dst image layout
107  1u, // region count
108  &copy // regions
109  );
110 
111  // Transition to shader-read.
112  {
113  BarrierVK barrier;
114  barrier.cmd_buffer = vk_cmd_buffer;
115  barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite |
116  vk::AccessFlagBits::eTransferWrite;
117  barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput |
118  vk::PipelineStageFlagBits::eTransfer;
119  barrier.dst_access = vk::AccessFlagBits::eShaderRead;
120  barrier.dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
121 
122  barrier.new_layout = vk::ImageLayout::eShaderReadOnlyOptimal;
123 
124  if (!SetLayout(barrier)) {
125  return false;
126  }
127  }
128 
129  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
130 }
131 
132 bool TextureVK::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
133  size_t slice) {
134  // Vulkan has no threading restrictions. So we can pass this data along to the
135  // client rendering API immediately.
136  return OnSetContents(mapping->GetMapping(), mapping->GetSize(), slice);
137 }
138 
139 bool TextureVK::IsValid() const {
140  return !!source_;
141 }
142 
144  return GetTextureDescriptor().size;
145 }
146 
147 vk::Image TextureVK::GetImage() const {
148  return source_->GetImage();
149 }
150 
151 vk::ImageView TextureVK::GetImageView() const {
152  return source_->GetImageView();
153 }
154 
155 std::shared_ptr<const TextureSourceVK> TextureVK::GetTextureSource() const {
156  return source_;
157 }
158 
159 bool TextureVK::SetLayout(const BarrierVK& barrier) const {
160  return source_ ? source_->SetLayout(barrier).ok() : false;
161 }
162 
164  vk::ImageLayout layout) const {
165  return source_ ? source_->SetLayoutWithoutEncoding(layout)
166  : vk::ImageLayout::eUndefined;
167 }
168 
169 vk::ImageLayout TextureVK::GetLayout() const {
170  return source_ ? source_->GetLayout() : vk::ImageLayout::eUndefined;
171 }
172 
173 vk::ImageView TextureVK::GetRenderTargetView() const {
174  return source_->GetRenderTargetView();
175 }
176 
178  const SharedHandleVK<vk::Framebuffer>& framebuffer) {
179  source_->SetCachedFramebuffer(framebuffer);
180 }
181 
183  const SharedHandleVK<vk::RenderPass>& render_pass) {
184  source_->SetCachedRenderPass(render_pass);
185 }
186 
188  return source_->GetCachedFramebuffer();
189 }
190 
192  return source_->GetCachedRenderPass();
193 }
194 
196  mipmap_generated_ = true;
197 }
198 
200  return source_->IsSwapchainImage();
201 }
202 
203 std::shared_ptr<SamplerVK> TextureVK::GetImmutableSamplerVariant(
204  const SamplerVK& sampler) const {
205  if (!source_) {
206  return nullptr;
207  }
208  auto conversion = source_->GetYUVConversion();
209  if (!conversion) {
210  // Most textures don't need a sampler conversion and will go down this path.
211  // Only needed for YUV sampling from external textures.
212  return nullptr;
213  }
214  return sampler.CreateVariantForConversion(std::move(conversion));
215 }
216 
217 } // namespace impeller
impeller::DeviceBufferVK::GetBuffer
vk::Buffer GetBuffer() const
Definition: device_buffer_vk.cc:86
impeller::TextureVK::GetCachedFramebuffer
SharedHandleVK< vk::Framebuffer > GetCachedFramebuffer() const
Definition: texture_vk.cc:187
impeller::CommandBufferVK::GetEncoder
const std::shared_ptr< CommandEncoderVK > & GetEncoder()
Definition: command_buffer_vk.cc:45
impeller::SamplerVK::CreateVariantForConversion
std::shared_ptr< SamplerVK > CreateVariantForConversion(std::shared_ptr< YUVConversionVK > conversion) const
Definition: sampler_vk.cc:114
command_encoder_vk.h
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
impeller::TextureVK::SetMipMapGenerated
void SetMipMapGenerated()
Definition: texture_vk.cc:195
formats_vk.h
impeller::SamplerVK
Definition: sampler_vk.h:19
impeller::TextureVK::GetTextureSource
std::shared_ptr< const TextureSourceVK > GetTextureSource() const
Definition: texture_vk.cc:155
impeller::TextureVK::SetLayout
bool SetLayout(const BarrierVK &barrier) const
Definition: texture_vk.cc:159
command_buffer_vk.h
impeller::Texture
Definition: texture.h:17
impeller::TSize< int64_t >
impeller::TextureVK::GetImage
vk::Image GetImage() const
Definition: texture_vk.cc:147
impeller::BarrierVK
Defines an operations and memory access barrier on a resource.
Definition: barrier_vk.h:28
impeller::TextureVK::IsSwapchainImage
bool IsSwapchainImage() const
Definition: texture_vk.cc:199
impeller::TextureVK::GetImageView
vk::ImageView GetImageView() const
Definition: texture_vk.cc:151
impeller::TextureVK::GetRenderTargetView
vk::ImageView GetRenderTargetView() const
Definition: texture_vk.cc:173
impeller::TextureVK::SetCachedFramebuffer
void SetCachedFramebuffer(const SharedHandleVK< vk::Framebuffer > &framebuffer)
Definition: texture_vk.cc:177
impeller::TextureVK::~TextureVK
~TextureVK() override
impeller::TextureVK::GetLayout
vk::ImageLayout GetLayout() const
Definition: texture_vk.cc:169
impeller::Texture::mipmap_generated_
bool mipmap_generated_
Definition: texture.h:64
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:106
impeller::TextureVK::GetSize
ISize GetSize() const override
Definition: texture_vk.cc:143
texture_vk.h
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
std
Definition: comparable.h:95
impeller::SharedHandleVK
std::shared_ptr< SharedObjectVKT< T > > SharedHandleVK
Definition: shared_object_vk.h:52
impeller::BackendCast< ContextVK, Context >::Cast
static ContextVK & Cast(Context &base)
Definition: backend_cast.h:13
impeller::TextureVK::GetCachedRenderPass
SharedHandleVK< vk::RenderPass > GetCachedRenderPass() const
Definition: texture_vk.cc:191
sampler_vk.h
impeller::TextureVK::SetLayoutWithoutEncoding
vk::ImageLayout SetLayoutWithoutEncoding(vk::ImageLayout layout) const
Definition: texture_vk.cc:163
impeller::TextureVK::GetImmutableSamplerVariant
std::shared_ptr< SamplerVK > GetImmutableSamplerVariant(const SamplerVK &sampler) const
Definition: texture_vk.cc:203
impeller::TextureVK::TextureVK
TextureVK(std::weak_ptr< Context > context, std::shared_ptr< TextureSourceVK > source)
Definition: texture_vk.cc:14
impeller
Definition: aiks_blur_unittests.cc:20
impeller::ToImageAspectFlags
constexpr vk::ImageAspectFlags ToImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:564
impeller::TextureVK::SetCachedRenderPass
void SetCachedRenderPass(const SharedHandleVK< vk::RenderPass > &render_pass)
Definition: texture_vk.cc:182