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;
179  return vk::Format::eR32Sfloat;
180  }
181 
182  FML_UNREACHABLE();
183 }
184 
185 constexpr PixelFormat ToPixelFormat(vk::Format format) {
186  switch (format) {
187  case vk::Format::eUndefined:
188  return PixelFormat::kUnknown;
189  case vk::Format::eR8G8B8A8Unorm:
191  case vk::Format::eR8G8B8A8Srgb:
193  case vk::Format::eB8G8R8A8Unorm:
195  case vk::Format::eB8G8R8A8Srgb:
197  case vk::Format::eR32G32B32A32Sfloat:
199  case vk::Format::eR16G16B16A16Sfloat:
201  case vk::Format::eS8Uint:
202  return PixelFormat::kS8UInt;
203  case vk::Format::eD24UnormS8Uint:
205  case vk::Format::eD32SfloatS8Uint:
207  case vk::Format::eR8Unorm:
209  case vk::Format::eR8G8Unorm:
211  default:
212  return PixelFormat::kUnknown;
213  }
214 }
215 
216 constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count) {
217  switch (sample_count) {
221  return vk::SampleCountFlagBits::e4;
222  }
223 
224  FML_UNREACHABLE();
225 }
226 
227 constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter) {
228  switch (filter) {
230  return vk::Filter::eNearest;
232  return vk::Filter::eLinear;
233  }
234 
235  FML_UNREACHABLE();
236 }
237 
238 constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter) {
239  switch (filter) {
240  case MipFilter::kBase:
241  case MipFilter::kNearest:
242  return vk::SamplerMipmapMode::eNearest;
243  case MipFilter::kLinear:
244  return vk::SamplerMipmapMode::eLinear;
245  }
246 
247  FML_UNREACHABLE();
248 }
249 
251  SamplerAddressMode mode) {
252  switch (mode) {
254  return vk::SamplerAddressMode::eRepeat;
256  return vk::SamplerAddressMode::eMirroredRepeat;
258  return vk::SamplerAddressMode::eClampToEdge;
260  return vk::SamplerAddressMode::eClampToBorder;
261  }
262 
263  FML_UNREACHABLE();
264 }
265 
266 constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage) {
267  switch (stage) {
269  return vk::ShaderStageFlagBits::eAll;
271  return vk::ShaderStageFlagBits::eFragment;
273  return vk::ShaderStageFlagBits::eCompute;
275  return vk::ShaderStageFlagBits::eVertex;
276  }
277 
278  FML_UNREACHABLE();
279 }
280 
281 static_assert(static_cast<int>(DescriptorType::kSampledImage) ==
282  static_cast<int>(vk::DescriptorType::eCombinedImageSampler));
283 static_assert(static_cast<int>(DescriptorType::kUniformBuffer) ==
284  static_cast<int>(vk::DescriptorType::eUniformBuffer));
285 static_assert(static_cast<int>(DescriptorType::kStorageBuffer) ==
286  static_cast<int>(vk::DescriptorType::eStorageBuffer));
287 static_assert(static_cast<int>(DescriptorType::kImage) ==
288  static_cast<int>(vk::DescriptorType::eSampledImage));
289 static_assert(static_cast<int>(DescriptorType::kSampler) ==
290  static_cast<int>(vk::DescriptorType::eSampler));
291 static_assert(static_cast<int>(DescriptorType::kInputAttachment) ==
292  static_cast<int>(vk::DescriptorType::eInputAttachment));
293 
295  return static_cast<vk::DescriptorType>(type);
296 }
297 
298 constexpr vk::DescriptorSetLayoutBinding ToVKDescriptorSetLayoutBinding(
299  const DescriptorSetLayout& layout) {
300  vk::DescriptorSetLayoutBinding binding;
301  binding.binding = layout.binding;
302  binding.descriptorCount = 1u;
303  binding.descriptorType = ToVKDescriptorType(layout.descriptor_type);
304  binding.stageFlags = ToVkShaderStage(layout.shader_stage);
305  return binding;
306 }
307 
308 constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action) {
309  switch (load_action) {
310  case LoadAction::kLoad:
311  return vk::AttachmentLoadOp::eLoad;
312  case LoadAction::kClear:
313  return vk::AttachmentLoadOp::eClear;
315  return vk::AttachmentLoadOp::eDontCare;
316  }
317 
318  FML_UNREACHABLE();
319 }
320 
321 constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action,
322  bool is_resolve_texture) {
323  switch (store_action) {
324  case StoreAction::kStore:
325  // Both MSAA and resolve textures need to be stored. A resolve is NOT
326  // performed.
327  return vk::AttachmentStoreOp::eStore;
329  // Both MSAA and resolve textures can be discarded. A resolve is NOT
330  // performed.
331  return vk::AttachmentStoreOp::eDontCare;
333  // The resolve texture is stored but the MSAA texture can be discarded. A
334  // resolve IS performed.
335  return is_resolve_texture ? vk::AttachmentStoreOp::eStore
336  : vk::AttachmentStoreOp::eDontCare;
338  // Both MSAA and resolve textures need to be stored. A resolve IS
339  // performed.
340  return vk::AttachmentStoreOp::eStore;
341  }
342  FML_UNREACHABLE();
343 }
344 
345 constexpr bool StoreActionPerformsResolve(StoreAction store_action) {
346  switch (store_action) {
348  case StoreAction::kStore:
349  return false;
352  return true;
353  }
354  FML_UNREACHABLE();
355 }
356 
357 constexpr vk::IndexType ToVKIndexType(IndexType index_type) {
358  switch (index_type) {
359  case IndexType::k16bit:
360  return vk::IndexType::eUint16;
361  case IndexType::k32bit:
362  return vk::IndexType::eUint32;
363  case IndexType::kUnknown:
364  return vk::IndexType::eUint32;
365  case IndexType::kNone:
366  FML_UNREACHABLE();
367  }
368 
369  FML_UNREACHABLE();
370 }
371 
373  switch (mode) {
374  case PolygonMode::kFill:
375  return vk::PolygonMode::eFill;
376  case PolygonMode::kLine:
377  return vk::PolygonMode::eLine;
378  }
379  FML_UNREACHABLE();
380 }
381 
383  PrimitiveType primitive) {
384  switch (primitive) {
389  return true;
392  return false;
393  }
394  FML_UNREACHABLE();
395 }
396 
397 constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive) {
398  switch (primitive) {
400  return vk::PrimitiveTopology::eTriangleList;
402  return vk::PrimitiveTopology::eTriangleStrip;
404  return vk::PrimitiveTopology::eLineList;
406  return vk::PrimitiveTopology::eLineStrip;
408  return vk::PrimitiveTopology::ePointList;
410  return vk::PrimitiveTopology::eTriangleFan;
411  }
412 
413  FML_UNREACHABLE();
414 }
415 
416 constexpr bool PixelFormatIsDepthStencil(PixelFormat format) {
417  switch (format) {
432  return false;
436  return true;
437  }
438  return false;
439 }
440 
441 static constexpr vk::AttachmentReference kUnusedAttachmentReference = {
442  VK_ATTACHMENT_UNUSED, vk::ImageLayout::eUndefined};
443 
444 constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode) {
445  switch (mode) {
446  case CullMode::kNone:
447  return vk::CullModeFlagBits::eNone;
449  return vk::CullModeFlagBits::eFront;
450  case CullMode::kBackFace:
451  return vk::CullModeFlagBits::eBack;
452  }
453  FML_UNREACHABLE();
454 }
455 
456 constexpr vk::CompareOp ToVKCompareOp(CompareFunction op) {
457  switch (op) {
459  return vk::CompareOp::eNever;
461  return vk::CompareOp::eAlways;
463  return vk::CompareOp::eLess;
465  return vk::CompareOp::eEqual;
467  return vk::CompareOp::eLessOrEqual;
469  return vk::CompareOp::eGreater;
471  return vk::CompareOp::eNotEqual;
473  return vk::CompareOp::eGreaterOrEqual;
474  }
475  FML_UNREACHABLE();
476 }
477 
478 constexpr vk::StencilOp ToVKStencilOp(StencilOperation op) {
479  switch (op) {
481  return vk::StencilOp::eKeep;
483  return vk::StencilOp::eZero;
485  return vk::StencilOp::eReplace;
487  return vk::StencilOp::eIncrementAndClamp;
489  return vk::StencilOp::eDecrementAndClamp;
491  return vk::StencilOp::eInvert;
493  return vk::StencilOp::eIncrementAndWrap;
495  return vk::StencilOp::eDecrementAndWrap;
496  break;
497  }
498  FML_UNREACHABLE();
499 }
500 
501 constexpr vk::StencilOpState ToVKStencilOpState(
502  const StencilAttachmentDescriptor& desc) {
503  vk::StencilOpState state;
504  state.failOp = ToVKStencilOp(desc.stencil_failure);
505  state.passOp = ToVKStencilOp(desc.depth_stencil_pass);
506  state.depthFailOp = ToVKStencilOp(desc.depth_failure);
507  state.compareOp = ToVKCompareOp(desc.stencil_compare);
508  state.compareMask = desc.read_mask;
509  state.writeMask = desc.write_mask;
510  // This is irrelevant as the stencil references are always dynamic state and
511  // will be set in the render pass.
512  state.reference = 1988;
513  return state;
514 }
515 
516 constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format) {
517  switch (format) {
532  return vk::ImageAspectFlagBits::eColor;
534  return vk::ImageAspectFlagBits::eStencil;
537  return vk::ImageAspectFlagBits::eDepth |
538  vk::ImageAspectFlagBits::eStencil;
539  }
540  FML_UNREACHABLE();
541 }
542 
543 constexpr uint32_t ToArrayLayerCount(TextureType type) {
544  switch (type) {
547  return 1u;
549  return 6u;
552  << "kTextureExternalOES can not be used with the Vulkan backend.";
553  }
554  FML_UNREACHABLE();
555 }
556 
557 constexpr vk::ImageViewType ToVKImageViewType(TextureType type) {
558  switch (type) {
561  return vk::ImageViewType::e2D;
563  return vk::ImageViewType::eCube;
566  << "kTextureExternalOES can not be used with the Vulkan backend.";
567  }
568  FML_UNREACHABLE();
569 }
570 
571 constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type) {
572  switch (type) {
575  return {};
577  return vk::ImageCreateFlagBits::eCubeCompatible;
580  << "kTextureExternalOES can not be used with the Vulkan backend.";
581  }
582  FML_UNREACHABLE();
583 }
584 
585 vk::PipelineDepthStencilStateCreateInfo ToVKPipelineDepthStencilStateCreateInfo(
586  std::optional<DepthAttachmentDescriptor> depth,
587  std::optional<StencilAttachmentDescriptor> front,
588  std::optional<StencilAttachmentDescriptor> back);
589 
590 constexpr vk::ImageAspectFlags ToImageAspectFlags(PixelFormat format) {
591  switch (format) {
593  return {};
607  return vk::ImageAspectFlagBits::eColor;
609  return vk::ImageAspectFlagBits::eStencil;
612  return vk::ImageAspectFlagBits::eDepth |
613  vk::ImageAspectFlagBits::eStencil;
614  }
615  FML_UNREACHABLE();
616 }
617 
618 } // namespace impeller
619 
620 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_FORMATS_VK_H_
GLenum type
Vector3 e1
static constexpr vk::AttachmentReference kUnusedAttachmentReference
Definition: formats_vk.h:441
BlendFactor
Definition: formats.h:181
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:355
@ kPoint
Draws a point at each input vertex.
constexpr vk::SamplerAddressMode ToVKSamplerAddressMode(SamplerAddressMode mode)
Definition: formats_vk.h:250
@ kNone
Does not use the index buffer.
constexpr vk::PipelineColorBlendAttachmentState ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor &desc)
Definition: formats_vk.h:113
constexpr PixelFormat ToPixelFormat(vk::Format format)
Definition: formats_vk.h:185
constexpr vk::CompareOp ToVKCompareOp(CompareFunction op)
Definition: formats_vk.h:456
constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter)
Definition: formats_vk.h:238
SamplerAddressMode
Definition: formats.h:444
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
constexpr bool StoreActionPerformsResolve(StoreAction store_action)
Definition: formats_vk.h:345
constexpr vk::IndexType ToVKIndexType(IndexType index_type)
Definition: formats_vk.h:357
constexpr vk::DescriptorSetLayoutBinding ToVKDescriptorSetLayoutBinding(const DescriptorSetLayout &layout)
Definition: formats_vk.h:298
constexpr uint32_t ToArrayLayerCount(TextureType type)
Definition: formats_vk.h:543
constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter)
Definition: formats_vk.h:227
constexpr vk::ImageAspectFlags ToImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:590
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:308
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
Definition: formats_vk.h:294
constexpr vk::PolygonMode ToVKPolygonMode(PolygonMode mode)
Definition: formats_vk.h:372
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
CompareFunction
Definition: formats.h:556
@ 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:321
constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode)
Definition: formats_vk.h:444
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:428
@ 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:575
@ 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:265
constexpr bool PixelFormatIsDepthStencil(PixelFormat format)
Definition: formats_vk.h:416
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:382
constexpr vk::ImageViewType ToVKImageViewType(TextureType type)
Definition: formats_vk.h:557
LoadAction
Definition: formats.h:205
StoreAction
Definition: formats.h:211
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:216
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:146
constexpr vk::StencilOpState ToVKStencilOpState(const StencilAttachmentDescriptor &desc)
Definition: formats_vk.h:501
constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage)
Definition: formats_vk.h:266
constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive)
Definition: formats_vk.h:397
PolygonMode
Definition: formats.h:392
constexpr vk::BlendOp ToVKBlendOp(BlendOperation op)
Definition: formats_vk.h:78
constexpr vk::StencilOp ToVKStencilOp(StencilOperation op)
Definition: formats_vk.h:478
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:418
@ kNearest
Select nearest to the sample point. Most widely supported.
constexpr vk::ImageCreateFlags ToVKImageCreateFlags(TextureType type)
Definition: formats_vk.h:571
constexpr vk::ImageAspectFlags ToVKImageAspectFlags(PixelFormat format)
Definition: formats_vk.h:516
BlendOperation
Definition: formats.h:199
SampleCount
Definition: formats.h:298
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:522
StencilOperation depth_stencil_pass
Definition: formats.h:633
#define VALIDATION_LOG
Definition: validation.h:91