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 <vulkan/vulkan.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 struct Format final : private angle::NonCopyable 55 { 56 Format(); 57 validfinal58 bool valid() const { return internalFormat != 0; } 59 60 // The ANGLE format is the front-end format. angleFormatfinal61 const angle::Format &angleFormat() const { return angle::Format::Get(angleFormatID); } 62 63 // The Image format is the VkFormat used to implement the front-end format for VkImages. imageFormatfinal64 const angle::Format &imageFormat() const { return angle::Format::Get(imageFormatID); } 65 66 // The Buffer format is the VkFormat used to implement the front-end format for VkBuffers. bufferFormatfinal67 const angle::Format &bufferFormat() const { return angle::Format::Get(bufferFormatID); } 68 69 // Returns OpenGL format information for the front-end format. getInternalFormatInfofinal70 const gl::InternalFormat &getInternalFormatInfo(GLenum type) const 71 { 72 return gl::GetInternalFormatInfo(internalFormat, type); 73 } 74 75 // Get buffer alignment for image-copy operations (to or from a buffer). 76 size_t getImageCopyBufferAlignment() const; 77 78 // Returns true if the Image format has more channels than the ANGLE format. 79 bool hasEmulatedImageChannels() const; 80 81 // This is an auto-generated method in vk_format_table_autogen.cpp. 82 void initialize(RendererVk *renderer, const angle::Format &angleFormat); 83 84 // These are used in the format table init. 85 void initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *info, int numInfo); 86 void initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo *info, int numInfo); 87 88 angle::FormatID angleFormatID; 89 GLenum internalFormat; 90 angle::FormatID imageFormatID; 91 VkFormat vkImageFormat; 92 angle::FormatID bufferFormatID; 93 VkFormat vkBufferFormat; 94 95 InitializeTextureDataFunction imageInitializerFunction; 96 LoadFunctionMap textureLoadFunctions; 97 VertexCopyFunction vertexLoadFunction; 98 99 bool vertexLoadRequiresConversion; 100 bool vkBufferFormatIsPacked; 101 bool vkFormatIsInt; 102 bool vkFormatIsUnsigned; 103 }; 104 105 bool operator==(const Format &lhs, const Format &rhs); 106 bool operator!=(const Format &lhs, const Format &rhs); 107 108 class FormatTable final : angle::NonCopyable 109 { 110 public: 111 FormatTable(); 112 ~FormatTable(); 113 114 // Also initializes the TextureCapsMap and the compressedTextureCaps in the Caps instance. 115 void initialize(RendererVk *renderer, 116 gl::TextureCapsMap *outTextureCapsMap, 117 std::vector<GLenum> *outCompressedTextureFormats); 118 119 ANGLE_INLINE const Format &operator[](GLenum internalFormat) const 120 { 121 angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat); 122 return mFormatData[static_cast<size_t>(formatID)]; 123 } 124 125 ANGLE_INLINE const Format &operator[](angle::FormatID formatID) const 126 { 127 return mFormatData[static_cast<size_t>(formatID)]; 128 } 129 130 private: 131 // The table data is indexed by angle::FormatID. 132 std::array<Format, angle::kNumANGLEFormats> mFormatData; 133 }; 134 135 // This will return a reference to a VkFormatProperties with the feature flags supported 136 // if the format is a mandatory format described in section 31.3.3. Required Format Support 137 // of the Vulkan spec. If the vkFormat isn't mandatory, it will return a VkFormatProperties 138 // initialized to 0. 139 const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat); 140 141 VkImageUsageFlags GetMaximalImageUsageFlags(RendererVk *renderer, VkFormat format); 142 143 } // namespace vk 144 145 // Checks if a vkFormat supports all the features needed to use it as a GL texture format 146 bool HasFullTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat); 147 // Checks if a vkFormat supports all the features except texture filtering 148 bool HasNonFilterableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat); 149 // Checks if a vkFormat supports all the features except rendering 150 bool HasNonRenderableTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat); 151 152 // Returns the alignment for a buffer to be used with the vertex input stage in Vulkan. This 153 // calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'. 154 size_t GetVertexInputAlignment(const vk::Format &format); 155 156 void MapSwizzleState(const ContextVk *contextVk, 157 const vk::Format &format, 158 const gl::SwizzleState &swizzleState, 159 gl::SwizzleState *swizzleStateOut); 160 } // namespace rx 161 162 #endif // LIBANGLE_RENDERER_VULKAN_VK_FORMAT_UTILS_H_ 163