• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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