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