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