Flutter Impeller
formats_vk.h
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 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_FORMATS_VK_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_FORMATS_VK_H_
7 
8 #include <cstdint>
9 #include <ostream>
10 
11 #include "fml/logging.h"
13 #include "impeller/core/formats.h"
16 #include "vulkan/vulkan_enums.hpp"
17 
18 namespace impeller {
19 
20 constexpr std::optional<PixelFormat> VkFormatToImpellerFormat(
21  vk::Format format) {
22  switch (format) {
23  case vk::Format::eR8G8B8A8Unorm:
25  case vk::Format::eB8G8R8A8Unorm:
27  default:
28  return std::nullopt;
29  }
30 }
31 
32 constexpr vk::SampleCountFlagBits ToVKSampleCountFlagBits(SampleCount count) {
33  switch (count) {
37  return vk::SampleCountFlagBits::e4;
38  }
39  FML_UNREACHABLE();
40 }
41 
43  switch (factor) {
44  case BlendFactor::kZero:
45  return vk::BlendFactor::eZero;
46  case BlendFactor::kOne:
47  return vk::BlendFactor::eOne;
49  return vk::BlendFactor::eSrcColor;
51  return vk::BlendFactor::eOneMinusSrcColor;
53  return vk::BlendFactor::eSrcAlpha;
55  return vk::BlendFactor::eOneMinusSrcAlpha;
57  return vk::BlendFactor::eDstColor;
59  return vk::BlendFactor::eOneMinusDstColor;
61  return vk::BlendFactor::eDstAlpha;
63  return vk::BlendFactor::eOneMinusDstAlpha;
65  return vk::BlendFactor::eSrcAlphaSaturate;
67  return vk::BlendFactor::eConstantColor;
69  return vk::BlendFactor::eOneMinusConstantColor;
71  return vk::BlendFactor::eConstantAlpha;
73  return vk::BlendFactor::eOneMinusConstantAlpha;
74  }
75  FML_UNREACHABLE();
76 }
77 
78 constexpr vk::BlendOp ToVKBlendOp(BlendOperation op) {
79  switch (op) {
81  return vk::BlendOp::eAdd;
83  return vk::BlendOp::eSubtract;
85  return vk::BlendOp::eReverseSubtract;
86  }
87  FML_UNREACHABLE();
88 }
89 
90 constexpr vk::ColorComponentFlags ToVKColorComponentFlags(ColorWriteMask type) {
91  vk::ColorComponentFlags mask;
92 
94  mask |= vk::ColorComponentFlagBits::eR;
95  }
96 
98  mask |= vk::ColorComponentFlagBits::eG;
99  }
100 
102  mask |= vk::ColorComponentFlagBits::eB;
103  }
104 
106  mask |= vk::ColorComponentFlagBits::eA;
107  }
108 
109  return mask;
110 }
111 
112 constexpr vk::PipelineColorBlendAttachmentState
114  vk::PipelineColorBlendAttachmentState res;
115 
116  res.setBlendEnable(desc.blending_enabled);
117 
118  res.setSrcColorBlendFactor(ToVKBlendFactor(desc.src_color_blend_factor));
119  res.setColorBlendOp(ToVKBlendOp(desc.color_blend_op));
120  res.setDstColorBlendFactor(ToVKBlendFactor(desc.dst_color_blend_factor));
121 
122  res.setSrcAlphaBlendFactor(ToVKBlendFactor(desc.src_alpha_blend_factor));
123  res.setAlphaBlendOp(ToVKBlendOp(desc.alpha_blend_op));
124  res.setDstAlphaBlendFactor(ToVKBlendFactor(desc.dst_alpha_blend_factor));
125 
126  res.setColorWriteMask(ToVKColorComponentFlags(desc.write_mask));
127 
128  return res;
129 }
130 
131 constexpr std::optional<vk::ShaderStageFlagBits> ToVKShaderStageFlagBits(
132  ShaderStage stage) {
133  switch (stage) {
135  return std::nullopt;
137  return vk::ShaderStageFlagBits::eVertex;
139  return vk::ShaderStageFlagBits::eFragment;
141  return vk::ShaderStageFlagBits::eCompute;
142  }
143  FML_UNREACHABLE();
144 }
145 
146 constexpr vk::Format ToVKImageFormat(PixelFormat format) {
147  switch (format) {
152  return vk::Format::eUndefined;
154  // TODO(csg): This is incorrect. Don't depend on swizzle support for GLES.
155  return vk::Format::eR8Unorm;
157  return vk::Format::eR8G8B8A8Unorm;
159  return vk::Format::eR8G8B8A8Srgb;
161  return vk::Format::eB8G8R8A8Unorm;
163  return vk::Format::eB8G8R8A8Srgb;
165  return vk::Format::eR32G32B32A32Sfloat;
167  return vk::Format::eR16G16B16A16Sfloat;
169  return vk::Format::eS8Uint;
171  return vk::Format::eD24UnormS8Uint;
173  return vk::Format::eD32SfloatS8Uint;
175  return vk::Format::eR8Unorm;
177  return vk::Format::eR8G8Unorm;
178  }
179 
180  FML_UNREACHABLE();
181 }
182 
183 constexpr PixelFormat ToPixelFormat(vk::Format format) {
184  switch (format) {
185  case vk::Format::eUndefined:
186  return PixelFormat::kUnknown;
187  case vk::Format::eR8G8B8A8Unorm:
189  case vk::Format::eR8G8B8A8Srgb:
191  case vk::Format::eB8G8R8A8Unorm:
193  case vk::Format::eB8G8R8A8Srgb:
195  case vk::Format::eR32G32B32A32Sfloat:
197  case vk::Format::eR16G16B16A16Sfloat:
199  case vk::Format::eS8Uint:
200  return PixelFormat::kS8UInt;
201  case vk::Format::eD24UnormS8Uint:
203  case vk::Format::eD32SfloatS8Uint:
205  case vk::Format::eR8Unorm:
207  case vk::Format::eR8G8Unorm:
209  default:
210  return PixelFormat::kUnknown;
211  }
212 }
213 
214 constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count) {
215  switch (sample_count) {
219  return vk::SampleCountFlagBits::e4;
220  }
221 
222  FML_UNREACHABLE();
223 }
224 
225 constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter) {
226  switch (filter) {
228  return vk::Filter::eNearest;
230  return vk::Filter::eLinear;
231  }
232 
233  FML_UNREACHABLE();
234 }
235 
236 constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter) {
237  switch (filter) {
238  case MipFilter::kBase:
239  case MipFilter::kNearest:
240  return vk::SamplerMipmapMode::eNearest;
241  case MipFilter::kLinear:
242  return vk::SamplerMipmapMode::eLinear;
243  }
244 
245  FML_UNREACHABLE();
246 }
247 
249  SamplerAddressMode mode) {
250  switch (mode) {
252  return vk::SamplerAddressMode::eRepeat;
254  return vk::SamplerAddressMode::eMirroredRepeat;
256  return vk::SamplerAddressMode::eClampToEdge;
258  return vk::SamplerAddressMode::eClampToBorder;
259  }
260 
261  FML_UNREACHABLE();
262 }
263 
264 constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage) {
265  switch (stage) {
267  return vk::ShaderStageFlagBits::eAll;
269  return vk::ShaderStageFlagBits::eFragment;
271  return vk::ShaderStageFlagBits::eCompute;
273  return vk::ShaderStageFlagBits::eVertex;
274  }
275 
276  FML_UNREACHABLE();
277 }
278 
279 static_assert(static_cast<int>(DescriptorType::kSampledImage) ==
280  static_cast<int>(vk::DescriptorType::eCombinedImageSampler));
281 static_assert(static_cast<int>(DescriptorType::kUniformBuffer) ==
282  static_cast<int>(vk::DescriptorType::eUniformBuffer));
283 static_assert(static_cast<int>(DescriptorType::kStorageBuffer) ==
284  static_cast<int>(vk::DescriptorType::eStorageBuffer));
285 static_assert(static_cast<int>(DescriptorType::kImage) ==
286  static_cast<int>(vk::DescriptorType::eSampledImage));
287 static_assert(static_cast<int>(DescriptorType::kSampler) ==
288  static_cast<int>(vk::DescriptorType::eSampler));
289 static_assert(static_cast<int>(DescriptorType::kInputAttachment) ==
290  static_cast<int>(vk::DescriptorType::eInputAttachment));
291 
293  return static_cast<vk::DescriptorType>(type);
294 }
295 
296 constexpr vk::DescriptorSetLayoutBinding ToVKDescriptorSetLayoutBinding(
297  const DescriptorSetLayout& layout) {
298  vk::DescriptorSetLayoutBinding binding;
299  binding.binding = layout.binding;
300  binding.descriptorCount = 1u;
301  binding.descriptorType = ToVKDescriptorType(layout.descriptor_type);
302  binding.stageFlags = ToVkShaderStage(layout.shader_stage);
303  return binding;
304 }
305 
306 constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action) {
307  switch (load_action) {
308  case LoadAction::kLoad:
309  return vk::AttachmentLoadOp::eLoad;
310  case LoadAction::kClear:
311  return vk::AttachmentLoadOp::eClear;
313  return vk::AttachmentLoadOp::eDontCare;
314  }
315 
316  FML_UNREACHABLE();
317 }
318 
319 constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action,
320  bool is_resolve_texture) {
321  switch (store_action) {
322  case StoreAction::kStore:
323  // Both MSAA and resolve textures need to be stored. A resolve is NOT
324  // performed.
325  return vk::AttachmentStoreOp::eStore;
327  // Both MSAA and resolve textures can be discarded. A resolve is NOT
328  // performed.
329  return vk::AttachmentStoreOp::eDontCare;
331  // The resolve texture is stored but the MSAA texture can be discarded. A
332  // resolve IS performed.
333  return is_resolve_texture ? vk::AttachmentStoreOp::eStore
334  : vk::AttachmentStoreOp::eDontCare;
336  // Both MSAA and resolve textures need to be stored. A resolve IS
337  // performed.
338  return vk::AttachmentStoreOp::eStore;
339  }
340  FML_UNREACHABLE();
341 }
342 
343 constexpr bool StoreActionPerformsResolve(StoreAction store_action) {
344  switch (store_action) {
346  case StoreAction::kStore:
347  return false;
350  return true;
351  }
352  FML_UNREACHABLE();
353 }
354 
355 constexpr vk::IndexType ToVKIndexType(IndexType index_type) {
356  switch (index_type) {
357  case IndexType::k16bit:
358  return vk::IndexType::eUint16;
359  case IndexType::k32bit:
360  return vk::IndexType::eUint32;
361  case IndexType::kUnknown:
362  return vk::IndexType::eUint32;
363  case IndexType::kNone:
364  FML_UNREACHABLE();
365  }
366 
367  FML_UNREACHABLE();
368 }
369 
371  switch (mode) {
372  case PolygonMode::kFill:
373  return vk::PolygonMode::eFill;
374  case PolygonMode::kLine:
375  return vk::PolygonMode::eLine;
376  }
377  FML_UNREACHABLE();
378 }
379 
381  PrimitiveType primitive) {
382  switch (primitive) {
387  return true;
390  return false;
391  }
392  FML_UNREACHABLE();
393 }
394 
395 constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive) {
396  switch (primitive) {
398  return vk::PrimitiveTopology::eTriangleList;
400  return vk::PrimitiveTopology::eTriangleStrip;
402  return vk::PrimitiveTopology::eLineList;
404  return vk::PrimitiveTopology::eLineStrip;
406  return vk::PrimitiveTopology::ePointList;
408  return vk::PrimitiveTopology::eTriangleFan;
409  }
410 
411  FML_UNREACHABLE();
412 }
413 
414 constexpr bool PixelFormatIsDepthStencil(PixelFormat format) {
415  switch (format) {
429  return false;
433  return true;
434  }
435  return false;
436 }
437 
438 static constexpr vk::AttachmentReference kUnusedAttachmentReference = {
439  VK_ATTACHMENT_UNUSED, vk::ImageLayout::eUndefined};
440 
441 constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode) {
442  switch (mode) {
443  case CullMode::kNone:
444  return vk::CullModeFlagBits::eNone;
446  return vk::CullModeFlagBits::eFront;
447  case CullMode::kBackFace:
448  return vk::CullModeFlagBits::eBack;
449  }
450  FML_UNREACHABLE();
451 }
452 
453 constexpr vk::CompareOp ToVKCompareOp(CompareFunction op) {
454  switch (op) {
456  return vk::CompareOp::eNever;
458  return vk::CompareOp::eAlways;
460  return vk::CompareOp::eLess;
462  return vk::CompareOp::eEqual;
464  return vk::CompareOp::eLessOrEqual;
466  return vk::CompareOp::eGreater;
468  return vk::CompareOp::eNotEqual;
470  return vk::CompareOp::eGreaterOrEqual;
471  }
472  FML_UNREACHABLE();
473 }
474 
475 constexpr vk::StencilOp ToVKStencilOp(StencilOperation op) {
476  switch (op) {
478  return vk::StencilOp::eKeep;
480  return vk::StencilOp::eZero;
482  return vk::StencilOp::eReplace;
484  return vk::StencilOp::eIncrementAndClamp;
486  return vk::StencilOp::eDecrementAndClamp;
488  return vk::StencilOp::eInvert;
490  return vk::StencilOp::eIncrementAndWrap;
492  return vk::StencilOp::eDecrementAndWrap;
493  break;
494  }
495  FML_UNREACHABLE();
496 }
497 
498 constexpr vk::StencilOpState ToVKStencilOpState(
499  const StencilAttachmentDescriptor& desc) {
500  vk::StencilOpState state;
501  state.failOp = ToVKStencilOp(desc.stencil_failure);
502  state.passOp = ToVKStencilOp(desc.depth_stencil_pass);
503  state.depthFailOp = ToVKStencilOp(desc.depth_failure);
504  state.compareOp = ToVKCompareOp(desc.stencil_compare);
505  state.compareMask = desc.read_mask;
506  state.writeMask = desc.write_mask;
507  // This is irrelevant as the stencil references are always dynamic state and
508  // will be set in the render pass.
509  state.reference = 1988;
510  return state;
511 }
512 
513 constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format) {
514  switch (format) {
528  return vk::ImageAspectFlagBits::eColor;
530  return vk::ImageAspectFlagBits::eStencil;
533  return vk::ImageAspectFlagBits::eDepth |
534  vk::ImageAspectFlagBits::eStencil;
535  }
536  FML_UNREACHABLE();
537 }
538 
539 constexpr uint32_t ToArrayLayerCount(TextureType type) {
540  switch (type) {
543  return 1u;
545  return 6u;
548  << "kTextureExternalOES can not be used with the Vulkan backend.";
549  }
550  FML_UNREACHABLE();
551 }
552 
553 constexpr vk::ImageViewType ToVKImageViewType(TextureType type) {
554  switch (type) {
557  return vk::ImageViewType::e2D;
559  return vk::ImageViewType::eCube;
562  << "kTextureExternalOES can not be used with the Vulkan backend.";
563  }
564  FML_UNREACHABLE();
565 }
566 
567 constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type) {
568  switch (type) {
571  return {};
573  return vk::ImageCreateFlagBits::eCubeCompatible;
576  << "kTextureExternalOES can not be used with the Vulkan backend.";
577  }
578  FML_UNREACHABLE();
579 }
580 
581 vk::PipelineDepthStencilStateCreateInfo ToVKPipelineDepthStencilStateCreateInfo(
582  std::optional<DepthAttachmentDescriptor> depth,
583  std::optional<StencilAttachmentDescriptor> front,
584  std::optional<StencilAttachmentDescriptor> back);
585 
586 constexpr vk::ImageAspectFlags ToImageAspectFlags(PixelFormat format) {
587  switch (format) {
589  return {};
602  return vk::ImageAspectFlagBits::eColor;
604  return vk::ImageAspectFlagBits::eStencil;
607  return vk::ImageAspectFlagBits::eDepth |
608  vk::ImageAspectFlagBits::eStencil;
609  }
610  FML_UNREACHABLE();
611 }
612 
613 } // namespace impeller
614 
615 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_FORMATS_VK_H_
GLenum type
Vector3 e1
@ kNone
Does not use the index buffer.
static constexpr vk::AttachmentReference kUnusedAttachmentReference
Definition: formats_vk.h:438
BlendFactor
Definition: formats.h:178
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:352
@ kPoint
Draws a point at each input vertex.
constexpr vk::SamplerAddressMode ToVKSamplerAddressMode(SamplerAddressMode mode)
Definition: formats_vk.h:248
constexpr vk::PipelineColorBlendAttachmentState ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor &desc)
Definition: formats_vk.h:113
constexpr PixelFormat ToPixelFormat(vk::Format format)
Definition: formats_vk.h:183
constexpr vk::CompareOp ToVKCompareOp(CompareFunction op)
Definition: formats_vk.h:453
constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter)
Definition: formats_vk.h:236
SamplerAddressMode
Definition: formats.h:441
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
constexpr bool StoreActionPerformsResolve(StoreAction store_action)
Definition: formats_vk.h:343
constexpr vk::IndexType ToVKIndexType(IndexType index_type)
Definition: formats_vk.h:355
constexpr vk::DescriptorSetLayoutBinding ToVKDescriptorSetLayoutBinding(const DescriptorSetLayout &layout)
Definition: formats_vk.h:296
constexpr uint32_t ToArrayLayerCount(TextureType type)
Definition: formats_vk.h:539
constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter)
Definition: formats_vk.h:225
constexpr vk::ImageAspectFlags ToImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:586
constexpr vk::SampleCountFlagBits ToVKSampleCountFlagBits(SampleCount count)
Definition: formats_vk.h:32
constexpr std::optional< vk::ShaderStageFlagBits > ToVKShaderStageFlagBits(ShaderStage stage)
Definition: formats_vk.h:131
constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action)
Definition: formats_vk.h:306
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
Definition: formats_vk.h:292
constexpr vk::PolygonMode ToVKPolygonMode(PolygonMode mode)
Definition: formats_vk.h:370
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
CompareFunction
Definition: formats.h:552
@ kEqual
Comparison test passes if new_value == current_value.
@ kLessEqual
Comparison test passes if new_value <= current_value.
@ kGreaterEqual
Comparison test passes if new_value >= current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kGreater
Comparison test passes if new_value > current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
@ kNever
Comparison test never passes.
constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action, bool is_resolve_texture)
Definition: formats_vk.h:319
constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode)
Definition: formats_vk.h:441
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:425
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
@ kNearest
The nearst mipmap level is selected.
constexpr vk::ColorComponentFlags ToVKColorComponentFlags(ColorWriteMask type)
Definition: formats_vk.h:90
StencilOperation
Definition: formats.h:571
@ kDecrementWrap
Decrement the current stencil value by 1. If at zero, set to maximum.
@ kSetToReferenceValue
Reset the stencil value to the reference value.
@ kDecrementClamp
Decrement the current stencil value by 1. Clamp it to zero.
@ kZero
Reset the stencil value to zero.
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
@ kIncrementWrap
Increment the current stencil value by 1. If at maximum, set to zero.
@ kInvert
Perform a logical bitwise invert on the current stencil value.
@ kKeep
Don't modify the current stencil value.
constexpr vk::BlendFactor ToVKBlendFactor(BlendFactor factor)
Definition: formats_vk.h:42
constexpr std::optional< PixelFormat > VkFormatToImpellerFormat(vk::Format format)
Definition: formats_vk.h:20
TextureType
Definition: formats.h:262
constexpr bool PixelFormatIsDepthStencil(PixelFormat format)
Definition: formats_vk.h:414
vk::PipelineDepthStencilStateCreateInfo ToVKPipelineDepthStencilStateCreateInfo(std::optional< DepthAttachmentDescriptor > depth, std::optional< StencilAttachmentDescriptor > front, std::optional< StencilAttachmentDescriptor > back)
Definition: formats_vk.cc:9
constexpr bool PrimitiveTopologySupportsPrimitiveRestart(PrimitiveType primitive)
Definition: formats_vk.h:380
constexpr vk::ImageViewType ToVKImageViewType(TextureType type)
Definition: formats_vk.h:553
LoadAction
Definition: formats.h:202
StoreAction
Definition: formats.h:208
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:214
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:146
constexpr vk::StencilOpState ToVKStencilOpState(const StencilAttachmentDescriptor &desc)
Definition: formats_vk.h:498
constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage)
Definition: formats_vk.h:264
constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive)
Definition: formats_vk.h:395
PolygonMode
Definition: formats.h:389
constexpr vk::BlendOp ToVKBlendOp(BlendOperation op)
Definition: formats_vk.h:78
constexpr vk::StencilOp ToVKStencilOp(StencilOperation op)
Definition: formats_vk.h:475
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:415
@ kNearest
Select nearest to the sample point. Most widely supported.
constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type)
Definition: formats_vk.h:567
constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:513
BlendOperation
Definition: formats.h:196
SampleCount
Definition: formats.h:295
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:518
StencilOperation depth_stencil_pass
Definition: formats.h:629
#define VALIDATION_LOG
Definition: validation.h:91