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