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