• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // vk_format_utils:
7 //   Helper for Vulkan format code.
8 
9 #ifndef LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_
10 #define LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_
11 
12 #include "volk.h"
13 
14 #include "libANGLE/formatutils.h"
15 #include "libANGLE/renderer/Format.h"
16 #include "libANGLE/renderer/copyvertex.h"
17 #include "libANGLE/renderer/renderer_utils.h"
18 #include "platform/FeaturesVk.h"
19 
20 #include <array>
21 
22 namespace gl
23 {
24 struct SwizzleState;
25 class TextureCapsMap;
26 }  // namespace gl
27 
28 namespace rx
29 {
30 class RendererVk;
31 class ContextVk;
32 
33 namespace vk
34 {
35 // VkFormat values in range [0, kNumVkFormats) are used as indices in various tables.
36 constexpr uint32_t kNumVkFormats = 185;
37 
38 struct ImageFormatInitInfo final
39 {
40     angle::FormatID format;
41     VkFormat vkFormat;
42     InitializeTextureDataFunction initializer;
43 };
44 
45 struct BufferFormatInitInfo final
46 {
47     angle::FormatID format;
48     VkFormat vkFormat;
49     bool vkFormatIsPacked;
50     VertexCopyFunction vertexLoadFunction;
51     bool vertexLoadRequiresConversion;
52 };
53 
54 // Describes a Vulkan format. For more information on formats in the Vulkan back-end please see
55 // https://chromium.googlesource.com/angle/angle/+/master/src/libANGLE/renderer/vulkan/doc/FormatTablesAndEmulation.md
56 struct Format final : private angle::NonCopyable
57 {
58     Format();
59 
validfinal60     bool valid() const { return internalFormat != 0; }
61 
62     // The intended format is the front-end format. For Textures this usually correponds to a
63     // GLenum in the headers. Buffer formats don't always have a corresponding GLenum type.
64     // Some Surface formats and unsized types also don't have a corresponding GLenum.
intendedFormatfinal65     const angle::Format &intendedFormat() const { return angle::Format::Get(intendedFormatID); }
66 
67     // The actual Image format is used to implement the front-end format for Texture/Renderbuffers.
actualImageFormatfinal68     const angle::Format &actualImageFormat() const
69     {
70         return angle::Format::Get(actualImageFormatID);
71     }
72 
73     // The actual Buffer format is used to implement the front-end format for Buffers.
actualBufferFormatfinal74     const angle::Format &actualBufferFormat() const
75     {
76         return angle::Format::Get(actualBufferFormatID);
77     }
78 
79     // The |internalFormat| always correponds to a valid GLenum type. For types that don't have a
80     // corresponding GLenum we do our best to specify a GLenum that is "close".
getInternalFormatInfofinal81     const gl::InternalFormat &getInternalFormatInfo(GLenum type) const
82     {
83         return gl::GetInternalFormatInfo(internalFormat, type);
84     }
85 
86     // Returns buffer alignment for image-copy operations (to or from a buffer).
87     size_t getImageCopyBufferAlignment() const;
88 
89     // Returns true if the Image format has more channels than the ANGLE format.
90     bool hasEmulatedImageChannels() const;
91 
92     // This is an auto-generated method in vk_format_table_autogen.cpp.
93     void initialize(RendererVk *renderer, const angle::Format &angleFormat);
94 
95     // These are used in the format table init.
96     void initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *info, int numInfo);
97     void initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo *info, int numInfo);
98 
99     angle::FormatID intendedFormatID;
100     GLenum internalFormat;
101     angle::FormatID actualImageFormatID;
102     VkFormat vkImageFormat;
103     angle::FormatID actualBufferFormatID;
104     VkFormat vkBufferFormat;
105 
106     InitializeTextureDataFunction imageInitializerFunction;
107     LoadFunctionMap textureLoadFunctions;
108     VertexCopyFunction vertexLoadFunction;
109 
110     bool vertexLoadRequiresConversion;
111     bool vkBufferFormatIsPacked;
112     bool vkFormatIsInt;
113     bool vkFormatIsUnsigned;
114 };
115 
116 bool operator==(const Format &lhs, const Format &rhs);
117 bool operator!=(const Format &lhs, const Format &rhs);
118 
119 class FormatTable final : angle::NonCopyable
120 {
121   public:
122     FormatTable();
123     ~FormatTable();
124 
125     // Also initializes the TextureCapsMap and the compressedTextureCaps in the Caps instance.
126     void initialize(RendererVk *renderer,
127                     gl::TextureCapsMap *outTextureCapsMap,
128                     std::vector<GLenum> *outCompressedTextureFormats);
129 
130     ANGLE_INLINE const Format &operator[](GLenum internalFormat) const
131     {
132         angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
133         return mFormatData[static_cast<size_t>(formatID)];
134     }
135 
136     ANGLE_INLINE const Format &operator[](angle::FormatID formatID) const
137     {
138         return mFormatData[static_cast<size_t>(formatID)];
139     }
140 
141   private:
142     // The table data is indexed by angle::FormatID.
143     std::array<Format, angle::kNumANGLEFormats> mFormatData;
144 };
145 
146 // This will return a reference to a VkFormatProperties with the feature flags supported
147 // if the format is a mandatory format described in section 31.3.3. Required Format Support
148 // of the Vulkan spec. If the vkFormat isn't mandatory, it will return a VkFormatProperties
149 // initialized to 0.
150 const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat);
151 
152 VkImageUsageFlags GetMaximalImageUsageFlags(RendererVk *renderer, VkFormat format);
153 
154 }  // namespace vk
155 
156 // Checks if a vkFormat supports all the features needed to use it as a GL texture format
157 bool HasFullTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat);
158 // Checks if a vkFormat supports all the features except texture filtering
159 bool HasNonFilterableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat);
160 // Checks if a vkFormat supports all the features except rendering
161 bool HasNonRenderableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat);
162 
163 // Returns the alignment for a buffer to be used with the vertex input stage in Vulkan. This
164 // calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'.
165 size_t GetVertexInputAlignment(const vk::Format &format);
166 
167 void MapSwizzleState(const ContextVk *contextVk,
168                      const vk::Format &format,
169                      const bool sized,
170                      const gl::SwizzleState &swizzleState,
171                      gl::SwizzleState *swizzleStateOut);
172 }  // namespace rx
173 
174 #endif  // LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_
175