xref: /aosp_15_r20/external/skia/tests/MtlBackendAllocationTest.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/gpu/ganesh/GrDirectContext.h"
9#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
10#include "src/gpu/ganesh/GrDirectContextPriv.h"
11#include "src/gpu/ganesh/mtl/GrMtlCaps.h"
12#include "tests/Test.h"
13#include "tools/gpu/ManagedBackendTexture.h"
14
15#import <Metal/Metal.h>
16
17using sk_gpu_test::ManagedBackendTexture;
18
19// In BackendAllocationTest.cpp
20void test_wrapping(GrDirectContext*,
21                   skiatest::Reporter*,
22                   const std::function<sk_sp<ManagedBackendTexture>(
23                           GrDirectContext*, skgpu::Mipmapped, GrRenderable)>& create,
24                   GrColorType,
25                   skgpu::Mipmapped,
26                   GrRenderable);
27
28void test_color_init(
29        GrDirectContext*,
30        skiatest::Reporter*,
31        const std::function<sk_sp<ManagedBackendTexture>(
32                GrDirectContext*, const SkColor4f&, skgpu::Mipmapped, GrRenderable)>& create,
33        GrColorType,
34        const SkColor4f&,
35        skgpu::Mipmapped,
36        GrRenderable);
37
38void test_pixmap_init(GrDirectContext*,
39                      skiatest::Reporter*,
40                      const std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
41                                                                       const SkPixmap srcData[],
42                                                                       int numLevels,
43                                                                       GrSurfaceOrigin,
44                                                                       GrRenderable)>& create,
45                      SkColorType,
46                      GrSurfaceOrigin,
47                      skgpu::Mipmapped,
48                      GrRenderable);
49
50DEF_GANESH_TEST_FOR_METAL_CONTEXT(MtlBackendAllocationTest, reporter, ctxInfo) {
51    auto dContext = ctxInfo.directContext();
52    const GrMtlCaps* mtlCaps = static_cast<const GrMtlCaps*>(dContext->priv().caps());
53
54    constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
55    constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
56
57    struct {
58        GrColorType      fColorType;
59        MTLPixelFormat   fFormat;
60        SkColor4f        fColor;
61    } combinations[] = {
62        { GrColorType::kRGBA_8888,        MTLPixelFormatRGBA8Unorm,      SkColors::kRed       },
63        { GrColorType::kRGBA_8888_SRGB,   MTLPixelFormatRGBA8Unorm_sRGB, SkColors::kRed       },
64
65        // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
66        // there is nothing to tell Skia to make the provided color opaque. Clients will need
67        // to provide an opaque initialization color in this case.
68        { GrColorType::kRGB_888x,         MTLPixelFormatRGBA8Unorm,      SkColors::kYellow    },
69
70        { GrColorType::kBGRA_8888,        MTLPixelFormatBGRA8Unorm,      SkColors::kBlue      },
71
72        { GrColorType::kRGBA_1010102,     MTLPixelFormatRGB10A2Unorm,
73                                                                    { 0.25f, 0.5f, 0.75f, 1.0f } },
74        { GrColorType::kRGB_101010x,      MTLPixelFormatRGB10A2Unorm,
75                                                                    { 0.25f, 0.5f, 0.75f, 1.0f } },
76#ifdef SK_BUILD_FOR_MAC
77        { GrColorType::kBGRA_1010102,     MTLPixelFormatBGR10A2Unorm,
78                                                                    { 0.25f, 0.5f, 0.75f, 1.0f } },
79#endif
80#ifdef SK_BUILD_FOR_IOS
81        { GrColorType::kBGR_565,          MTLPixelFormatB5G6R5Unorm,     SkColors::kRed       },
82        { GrColorType::kABGR_4444,        MTLPixelFormatABGR4Unorm,      SkColors::kGreen     },
83#endif
84
85        { GrColorType::kAlpha_8,          MTLPixelFormatA8Unorm,         kTransCol            },
86        { GrColorType::kAlpha_8,          MTLPixelFormatR8Unorm,         kTransCol            },
87        { GrColorType::kGray_8,           MTLPixelFormatR8Unorm,         kGrayCol             },
88
89        { GrColorType::kRGBA_F16_Clamped, MTLPixelFormatRGBA16Float,     SkColors::kLtGray    },
90        { GrColorType::kRGBA_F16,         MTLPixelFormatRGBA16Float,     SkColors::kYellow    },
91        { GrColorType::kRGB_F16F16F16x,   MTLPixelFormatRGBA16Float,     SkColors::kYellow    },
92
93        { GrColorType::kRG_88,            MTLPixelFormatRG8Unorm,        { 0.5f, 0.5f, 0, 1 } },
94        { GrColorType::kAlpha_F16,        MTLPixelFormatR16Float,        { 1.0f, 0, 0, 0.5f } },
95
96        { GrColorType::kAlpha_16,         MTLPixelFormatR16Unorm,        kTransCol            },
97        { GrColorType::kRG_1616,          MTLPixelFormatRG16Unorm,       SkColors::kYellow    },
98
99        { GrColorType::kRGBA_16161616,    MTLPixelFormatRGBA16Unorm,     SkColors::kLtGray    },
100        { GrColorType::kRG_F16,           MTLPixelFormatRG16Float,       SkColors::kYellow    },
101    };
102
103    for (auto combo : combinations) {
104        GrBackendFormat format = GrBackendFormats::MakeMtl(combo.fFormat);
105
106        if (!mtlCaps->isFormatTexturable(combo.fFormat)) {
107            continue;
108        }
109
110        // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
111        if (GrColorType::kRGBA_F32 == combo.fColorType) {
112            continue;
113        }
114
115        for (auto mipmapped : {skgpu::Mipmapped::kNo, skgpu::Mipmapped::kYes}) {
116            if (skgpu::Mipmapped::kYes == mipmapped && !mtlCaps->mipmapSupport()) {
117                continue;
118            }
119
120            for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
121
122                if (GrRenderable::kYes == renderable) {
123                    // We must also check whether we allow rendering to the format using the
124                    // color type.
125                    if (!mtlCaps->isFormatAsColorTypeRenderable(
126                                combo.fColorType, GrBackendFormats::MakeMtl(combo.fFormat), 1)) {
127                        continue;
128                    }
129                }
130
131                {
132                    auto uninitCreateMtd = [format](GrDirectContext* dContext,
133                                                    skgpu::Mipmapped mipmapped,
134                                                    GrRenderable renderable) {
135                        return ManagedBackendTexture::MakeWithoutData(dContext,
136                                                                      32, 32,
137                                                                      format,
138                                                                      mipmapped,
139                                                                      renderable,
140                                                                      GrProtected::kNo);
141                    };
142
143                    test_wrapping(dContext, reporter, uninitCreateMtd, combo.fColorType, mipmapped,
144                                  renderable);
145                }
146
147                {
148                    // We're creating backend textures without specifying a color type "view" of
149                    // them at the public API level. Therefore, Ganesh will not apply any swizzles
150                    // before writing the color to the texture. However, our validation code does
151                    // rely on interpreting the texture contents via a SkColorType and therefore
152                    // swizzles may be applied during the read step.
153                    // Ideally we'd update our validation code to use a "raw" read that doesn't
154                    // impose a color type but for now we just munge the data we upload to match the
155                    // expectation.
156                    skgpu::Swizzle swizzle;
157                    switch (combo.fColorType) {
158                        case GrColorType::kAlpha_8:
159                            swizzle = skgpu::Swizzle("aaaa");
160                            break;
161                        case GrColorType::kAlpha_16:
162                            swizzle = skgpu::Swizzle("aaaa");
163                            break;
164                        case GrColorType::kAlpha_F16:
165                            swizzle = skgpu::Swizzle("aaaa");
166                            break;
167                        default:
168                            break;
169                    }
170
171                    auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
172                                                                const SkColor4f& color,
173                                                                skgpu::Mipmapped mipmapped,
174                                                                GrRenderable renderable) {
175                        auto swizzledColor = swizzle.applyTo(color);
176                        return ManagedBackendTexture::MakeWithData(dContext,
177                                                                   32, 32,
178                                                                   format,
179                                                                   swizzledColor,
180                                                                   mipmapped,
181                                                                   renderable,
182                                                                   GrProtected::kNo);
183                    };
184                    test_color_init(dContext, reporter, createWithColorMtd, combo.fColorType,
185                                    combo.fColor, mipmapped, renderable);
186                }
187
188                for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
189                    SkColorType skColorType = GrColorTypeToSkColorType(combo.fColorType);
190                    if (skColorType == kUnknown_SkColorType) {
191                        break;
192                    }
193
194                    auto createWithSrcDataMtd = [](GrDirectContext* dContext,
195                                                   const SkPixmap srcData[],
196                                                   int numLevels,
197                                                   GrSurfaceOrigin origin,
198                                                   GrRenderable renderable) {
199                        SkASSERT(srcData && numLevels);
200                        return ManagedBackendTexture::MakeWithData(dContext,
201                                                                   srcData,
202                                                                   numLevels,
203                                                                   origin,
204                                                                   renderable,
205                                                                   GrProtected::kNo);
206                    };
207
208                    test_pixmap_init(dContext,
209                                     reporter,
210                                     createWithSrcDataMtd,
211                                     skColorType,
212                                     origin,
213                                     mipmapped,
214                                     renderable);
215
216                }
217            }
218        }
219    }
220}
221