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