1 // 2 // Copyright 2019 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 // mtl_format_utils.h: 7 // Declares Format conversion utilities classes that convert from angle formats 8 // to respective MTLPixelFormat and MTLVertexFormat. 9 // 10 11 #ifndef LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_ 12 #define LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_ 13 14 #import <Metal/Metal.h> 15 16 #include "common/angleutils.h" 17 #include "libANGLE/Caps.h" 18 #include "libANGLE/formatutils.h" 19 #include "libANGLE/renderer/copyvertex.h" 20 21 namespace rx 22 { 23 class DisplayMtl; 24 25 namespace mtl 26 { 27 28 struct FormatBase 29 { 30 inline bool operator==(const FormatBase &rhs) const 31 { 32 return intendedFormatId == rhs.intendedFormatId && actualFormatId == rhs.actualFormatId; 33 } 34 35 inline bool operator!=(const FormatBase &rhs) const { return !((*this) == rhs); } 36 37 const angle::Format &actualAngleFormat() const; 38 const angle::Format &intendedAngleFormat() const; 39 40 angle::FormatID actualFormatId = angle::FormatID::NONE; 41 angle::FormatID intendedFormatId = angle::FormatID::NONE; 42 }; 43 44 // Pixel format 45 struct Format : public FormatBase 46 { 47 Format() = default; 48 49 const gl::InternalFormat &intendedInternalFormat() const; 50 validFormat51 bool valid() const { return metalFormat != MTLPixelFormatInvalid; } 52 53 static bool FormatRenderable(MTLPixelFormat format); 54 static bool FormatCPUReadable(MTLPixelFormat format); 55 56 MTLPixelFormat metalFormat = MTLPixelFormatInvalid; 57 58 private: 59 void init(const DisplayMtl *display, angle::FormatID intendedFormatId); 60 61 friend class FormatTable; 62 }; 63 64 // Vertex format 65 struct VertexFormat : public FormatBase 66 { 67 VertexFormat() = default; 68 69 MTLVertexFormat metalFormat = MTLVertexFormatInvalid; 70 71 VertexCopyFunction vertexLoadFunction = nullptr; 72 73 private: 74 void init(angle::FormatID angleFormatId, bool tightlyPacked = false); 75 76 friend class FormatTable; 77 }; 78 79 class FormatTable final : angle::NonCopyable 80 { 81 public: 82 FormatTable() = default; 83 ~FormatTable() = default; 84 85 angle::Result initialize(const DisplayMtl *display); 86 87 void generateTextureCaps(const DisplayMtl *display, 88 gl::TextureCapsMap *capsMapOut, 89 std::vector<GLenum> *compressedFormatsOut) const; 90 91 const Format &getPixelFormat(angle::FormatID angleFormatId) const; 92 93 // tightlyPacked means this format will be used in a tightly packed vertex buffer. 94 // In that case, it's easier to just convert everything to float to ensure 95 // Metal alignment requirements between 2 elements inside the buffer will be met regardless 96 // of how many components each element has. 97 const VertexFormat &getVertexFormat(angle::FormatID angleFormatId, bool tightlyPacked) const; 98 99 private: 100 std::array<Format, angle::kNumANGLEFormats> mPixelFormatTable; 101 // One for tightly packed buffers, one for general cases. 102 std::array<VertexFormat, angle::kNumANGLEFormats> mVertexFormatTables[2]; 103 }; 104 105 } // namespace mtl 106 } // namespace rx 107 108 #endif /* LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_ */ 109