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 "common/vulkan/vk_headers.h" 13 #include "libANGLE/formatutils.h" 14 #include "libANGLE/renderer/Format.h" 15 #include "libANGLE/renderer/copyvertex.h" 16 #include "libANGLE/renderer/renderer_utils.h" 17 #include "platform/FeaturesVk.h" 18 19 #include <array> 20 21 namespace gl 22 { 23 struct SwizzleState; 24 class TextureCapsMap; 25 } // namespace gl 26 27 namespace rx 28 { 29 class RendererVk; 30 class ContextVk; 31 32 namespace vk 33 { 34 // VkFormat values in range [0, kNumVkFormats) are used as indices in various tables. 35 constexpr uint32_t kNumVkFormats = 185; 36 37 struct ImageFormatInitInfo final 38 { 39 angle::FormatID format; 40 InitializeTextureDataFunction initializer; 41 }; 42 43 struct BufferFormatInitInfo final 44 { 45 angle::FormatID format; 46 bool vkFormatIsPacked; 47 VertexCopyFunction vertexLoadFunction; 48 bool vertexLoadRequiresConversion; 49 }; 50 51 VkFormat GetVkFormatFromFormatID(angle::FormatID formatID); 52 angle::FormatID GetFormatIDFromVkFormat(VkFormat vkFormat); 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 intendedGLFormat != 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 actualImageVkFormatfinal73 VkFormat actualImageVkFormat() const { return GetVkFormatFromFormatID(actualImageFormatID); } 74 75 // The actual Buffer format is used to implement the front-end format for Buffers. This format 76 // is used by vertex buffers as well as texture buffers. Note that all formats required for 77 // GL_EXT_texture_buffer have mandatory support for vertex buffers in Vulkan, so they won't be 78 // using an emulated format. actualBufferFormatfinal79 const angle::Format &actualBufferFormat(bool compressed) const 80 { 81 return angle::Format::Get(compressed ? actualCompressedBufferFormatID 82 : actualBufferFormatID); 83 } 84 actualBufferVkFormatfinal85 VkFormat actualBufferVkFormat(bool compressed) const 86 { 87 return GetVkFormatFromFormatID(compressed ? actualCompressedBufferFormatID 88 : actualBufferFormatID); 89 } 90 getVertexLoadFunctionfinal91 VertexCopyFunction getVertexLoadFunction(bool compressed) const 92 { 93 return compressed ? compressedVertexLoadFunction : vertexLoadFunction; 94 } 95 getVertexLoadRequiresConversionfinal96 bool getVertexLoadRequiresConversion(bool compressed) const 97 { 98 return compressed ? compressedVertexLoadRequiresConversion : vertexLoadRequiresConversion; 99 } 100 101 // |intendedGLFormat| always correponds to a valid GLenum type. For types that don't have a 102 // corresponding GLenum we do our best to specify a GLenum that is "close". getInternalFormatInfofinal103 const gl::InternalFormat &getInternalFormatInfo(GLenum type) const 104 { 105 return gl::GetInternalFormatInfo(intendedGLFormat, type); 106 } 107 108 // Returns buffer alignment for image-copy operations (to or from a buffer). 109 size_t getImageCopyBufferAlignment() const; 110 size_t getValidImageCopyBufferAlignment() const; 111 112 // Returns true if the image format has more channels than the ANGLE format. 113 bool hasEmulatedImageChannels() const; 114 115 // Returns true if the image has a different image format than intended. hasEmulatedImageFormatfinal116 bool hasEmulatedImageFormat() const { return actualImageFormatID != intendedFormatID; } 117 118 // This is an auto-generated method in vk_format_table_autogen.cpp. 119 void initialize(RendererVk *renderer, const angle::Format &angleFormat); 120 121 // These are used in the format table init. 122 void initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *info, int numInfo); 123 void initBufferFallback(RendererVk *renderer, 124 const BufferFormatInitInfo *fallbackInfo, 125 int numInfo, 126 int compressedStartIndex); 127 128 angle::FormatID intendedFormatID; 129 GLenum intendedGLFormat; 130 angle::FormatID actualImageFormatID; 131 angle::FormatID actualBufferFormatID; 132 angle::FormatID actualCompressedBufferFormatID; 133 134 InitializeTextureDataFunction imageInitializerFunction; 135 LoadFunctionMap textureLoadFunctions; 136 LoadTextureBorderFunctionMap textureBorderLoadFunctions; 137 VertexCopyFunction vertexLoadFunction; 138 VertexCopyFunction compressedVertexLoadFunction; 139 140 bool vertexLoadRequiresConversion; 141 bool compressedVertexLoadRequiresConversion; 142 bool vkBufferFormatIsPacked; 143 bool vkCompressedBufferFormatIsPacked; 144 bool vkFormatIsInt; 145 bool vkFormatIsUnsigned; 146 }; 147 148 bool operator==(const Format &lhs, const Format &rhs); 149 bool operator!=(const Format &lhs, const Format &rhs); 150 151 class FormatTable final : angle::NonCopyable 152 { 153 public: 154 FormatTable(); 155 ~FormatTable(); 156 157 // Also initializes the TextureCapsMap and the compressedTextureCaps in the Caps instance. 158 void initialize(RendererVk *renderer, 159 gl::TextureCapsMap *outTextureCapsMap, 160 std::vector<GLenum> *outCompressedTextureFormats); 161 162 ANGLE_INLINE const Format &operator[](GLenum internalFormat) const 163 { 164 angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); 165 return mFormatData[static_cast<size_t>(formatID)]; 166 } 167 168 ANGLE_INLINE const Format &operator[](angle::FormatID formatID) const 169 { 170 return mFormatData[static_cast<size_t>(formatID)]; 171 } 172 173 private: 174 // The table data is indexed by angle::FormatID. 175 std::array<Format, angle::kNumANGLEFormats> mFormatData; 176 }; 177 178 // This will return a reference to a VkFormatProperties with the feature flags supported 179 // if the format is a mandatory format described in section 31.3.3. Required Format Support 180 // of the Vulkan spec. If the vkFormat isn't mandatory, it will return a VkFormatProperties 181 // initialized to 0. 182 const VkFormatProperties &GetMandatoryFormatSupport(angle::FormatID formatID); 183 184 VkImageUsageFlags GetMaximalImageUsageFlags(RendererVk *renderer, angle::FormatID formatID); 185 186 } // namespace vk 187 188 // Checks if a Vulkan format supports all the features needed to use it as a GL texture format. 189 bool HasFullTextureFormatSupport(RendererVk *renderer, angle::FormatID formatID); 190 // Checks if a Vulkan format supports all the features except rendering. 191 bool HasNonRenderableTextureFormatSupport(RendererVk *renderer, angle::FormatID formatID); 192 193 // Returns the alignment for a buffer to be used with the vertex input stage in Vulkan. This 194 // calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'. 195 size_t GetVertexInputAlignment(const vk::Format &format, bool compressed); 196 197 // Get the swizzle state based on format's requirements and emulations. 198 gl::SwizzleState GetFormatSwizzle(const ContextVk *contextVk, 199 const vk::Format &format, 200 const bool sized); 201 202 // Apply application's swizzle to the swizzle implied by format as received from GetFormatSwizzle. 203 gl::SwizzleState ApplySwizzle(const gl::SwizzleState &formatSwizzle, 204 const gl::SwizzleState &toApply); 205 206 } // namespace rx 207 208 #endif // LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_ 209