blob: ada040de8c5ffb8fdd213e2c70deb81e03a5ff18 [file] [log] [blame]
Robert Phillips0c6daf02019-05-16 12:43:11 -04001/*
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
Mike Kleinfe0aeb32019-05-20 10:55:11 -05008#include "include/core/SkSurface.h"
Robert Phillips02dc0302019-07-02 17:58:27 -04009#include "include/core/SkSurfaceCharacterization.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050010#include "include/gpu/GrContext.h"
Robert Phillips459b2952019-05-23 09:38:27 -040011#include "src/core/SkAutoPixmapStorage.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050012#include "src/gpu/GrContextPriv.h"
Robert Phillipsefb9f142019-05-17 14:19:44 -040013#include "src/image/SkImage_Base.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040014#include "tests/Test.h"
Robert Phillipse3b6fe42019-09-11 11:26:46 -040015#include "tests/TestUtils.h"
16#include "tools/ToolUtils.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040017
Robert Phillips27eb5252019-06-03 12:59:40 -040018#ifdef SK_GL
19#include "src/gpu/gl/GrGLGpu.h"
20#include "src/gpu/gl/GrGLUtil.h"
21#endif
22
Robert Phillips7f367982019-09-26 14:01:36 -040023#ifdef SK_METAL
24#include "include/gpu/mtl/GrMtlTypes.h"
25#include "src/gpu/mtl/GrMtlCppUtil.h"
26#endif
27
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040028// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillips0c6daf02019-05-16 12:43:11 -040029void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040030 std::function<GrBackendTexture (GrContext*,
31 GrMipMapped,
32 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040033 GrColorType grColorType, GrMipMapped mipMapped, GrRenderable renderable) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040034 GrResourceCache* cache = context->priv().getResourceCache();
35
36 const int initialCount = cache->getResourceCount();
37
Robert Phillipsefb9f142019-05-17 14:19:44 -040038 GrBackendTexture backendTex = create(context, mipMapped, renderable);
39 if (!backendTex.isValid()) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040040 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
41 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040042 GrRenderable::kYes == renderable ? "yes" : "no");
43 return;
44 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040045
Robert Phillips0c6daf02019-05-16 12:43:11 -040046 // Skia proper should know nothing about the new backend object
47 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
48
Robert Phillipsb7f95d12019-07-26 11:13:19 -040049 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
50
51 // Wrapping a backendTexture in an image requires an SkColorType
52 if (kUnknown_SkColorType == skColorType) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040053 context->deleteBackendTexture(backendTex);
54 return;
55 }
56
Robert Phillipsd470e1b2019-09-04 15:05:35 -040057 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040058 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040059 backendTex,
60 kTopLeft_GrSurfaceOrigin,
61 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040062 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040063 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040064 if (!surf) {
65 ERRORF(reporter, "Couldn't make surface from backendTexture for colorType %d\n",
Robert Phillipsb7f95d12019-07-26 11:13:19 -040066 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040067 } else {
68 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040069 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040070 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040071
Robert Phillipsb04b6942019-05-21 17:24:31 -040072 {
73 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040074 backendTex,
75 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040076 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040077 kPremul_SkAlphaType,
78 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040079 if (!img) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040080 ERRORF(reporter, "Couldn't make image from backendTexture for skColorType %d\n",
81 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040082 } else {
83 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -040084
Robert Phillipsb04b6942019-05-21 17:24:31 -040085 GrTextureProxy* proxy = ib->peekProxy();
86 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -040087
Robert Phillipsb04b6942019-05-21 17:24:31 -040088 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
89 REPORTER_ASSERT(reporter, proxy->isInstantiated());
90 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -040091
Robert Phillipsb04b6942019-05-21 17:24:31 -040092 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040093 }
94 }
95
96 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
97
Robert Phillips5c7a25b2019-05-20 08:38:07 -040098 context->deleteBackendTexture(backendTex);
Robert Phillips0c6daf02019-05-16 12:43:11 -040099}
100
Robert Phillips7f367982019-09-26 14:01:36 -0400101static bool isBGRA(const GrBackendFormat& format) {
102 switch (format.backend()) {
103 case GrBackendApi::kMetal:
104#ifdef SK_METAL
105 return GrMtlFormatIsBGRA(format.asMtlFormat());
106#else
107 return false;
108#endif
109 case GrBackendApi::kDawn:
110 return false;
111 case GrBackendApi::kOpenGL:
112#ifdef SK_GL
113 return format.asGLFormat() == GrGLFormat::kBGRA8;
114#else
115 return false;
116#endif
117 case GrBackendApi::kVulkan: {
118#ifdef SK_VULKAN
119 VkFormat vkFormat;
120 format.asVkFormat(&vkFormat);
121 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
122#else
123 return false;
124#endif
125 }
126 case GrBackendApi::kMock:
127 return format.asMockColorType() == GrColorType::kBGRA_8888;
128 }
129 SkUNREACHABLE;
130}
131
132static bool isRGB(const GrBackendFormat& format) {
133 switch (format.backend()) {
134 case GrBackendApi::kMetal:
135 return false; // Metal doesn't even pretend to support this
136 case GrBackendApi::kDawn:
137 return false;
138 case GrBackendApi::kOpenGL:
139#ifdef SK_GL
140 return format.asGLFormat() == GrGLFormat::kRGB8;
141#else
142 return false;
143#endif
144 case GrBackendApi::kVulkan: {
145#ifdef SK_VULKAN
146 VkFormat vkFormat;
147 format.asVkFormat(&vkFormat);
148 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
149#else
150 return false;
151#endif
152 }
153 case GrBackendApi::kMock:
154 return false; // No GrColorType::kRGB_888
155 }
156 SkUNREACHABLE;
157}
158
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400159static void check_solid_pixmap(skiatest::Reporter* reporter,
160 const SkColor4f& expected, const SkPixmap& actual,
Robert Phillips7f367982019-09-26 14:01:36 -0400161 SkColorType ct, const char* label1, const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400162 // we need 0.001f across the board just for noise
163 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400164 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400165
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400166 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400167 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400168 SkASSERT(x >= 0 && y >= 0);
Robert Phillips7f367982019-09-26 14:01:36 -0400169 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
170 ToolUtils::colortype_name(ct), label1, label2, x, y,
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400171 diffs[0], diffs[1], diffs[2], diffs[3]);
172 });
173
174 check_solid_pixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400175}
176
Robert Phillips7f367982019-09-26 14:01:36 -0400177// What would raster do?
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400178static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
Robert Phillips7f367982019-09-26 14:01:36 -0400179 if (ct == kGray_8_SkColorType) {
180 // Prevent the premul raster graciously applies in this case
181 orig.fA = 1.0;
Robert Phillips459b2952019-05-23 09:38:27 -0400182 }
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400183
Robert Phillips7f367982019-09-26 14:01:36 -0400184 SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
185 : kPremul_SkAlphaType;
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400186
Robert Phillips7f367982019-09-26 14:01:36 -0400187 SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
188 SkAutoPixmapStorage pm;
189 pm.alloc(ii);
190 pm.erase(orig);
191 SkColor tmp = pm.getColor(0, 0);
192 return SkColor4f::FromColor(tmp);
Robert Phillips459b2952019-05-23 09:38:27 -0400193}
194
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400195static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
196 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400197 skiatest::Reporter* reporter, const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400198
Robert Phillips0ee10342019-09-25 09:55:16 -0400199static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
200 SkColorType skColorType, GrRenderable renderable,
Robert Phillips7f367982019-09-26 14:01:36 -0400201 const SkColor4f& color, skiatest::Reporter* reporter,
202 const char* label) {
203 if (isRGB(backendTex.getBackendFormat())) {
204 // readPixels is busted for the RGB backend format (skbug.com/8862)
205 // TODO: add a GrColorType::kRGB_888 to fix the situation
206 return;
207 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400208
209 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
210 : kPremul_SkAlphaType;
211
212 SkColor4f expectedColor = get_expected_color(color, skColorType);
213
214 SkAutoPixmapStorage actual;
215
216 {
217 SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400218 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400219
220 SkAssertResult(actual.tryAlloc(readBackII));
221 }
222
Robert Phillips0ee10342019-09-25 09:55:16 -0400223 {
224 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
225 backendTex,
226 kTopLeft_GrSurfaceOrigin,
227 skColorType,
228 at,
229 nullptr);
230 if (img) {
231 actual.erase(SkColors::kTransparent);
232 bool result = img->readPixels(actual, 0, 0);
233 if (!result) {
234 // TODO: we need a better way to tell a priori if readPixels will work for an
235 // arbitrary colorType
236#if 0
237 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n", colorType);
238#endif
239 } else {
240 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400241 label, "SkImage::readPixels");
Robert Phillips0ee10342019-09-25 09:55:16 -0400242 }
243 }
244 }
Robert Phillips7f367982019-09-26 14:01:36 -0400245
246 // This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
247 // backend texture) so it must be done last!
248 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
249 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
250 backendTex,
251 kTopLeft_GrSurfaceOrigin,
252 0,
253 skColorType,
254 nullptr, nullptr);
255 if (surf) {
256 actual.erase(SkColors::kTransparent);
257 bool result = surf->readPixels(actual, 0, 0);
258 REPORTER_ASSERT(reporter, result);
259
260 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
261 label, "SkSurface::readPixels");
262 }
263 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400264}
265
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400266// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillips459b2952019-05-23 09:38:27 -0400267void test_color_init(GrContext* context, skiatest::Reporter* reporter,
268 std::function<GrBackendTexture (GrContext*,
269 const SkColor4f&,
270 GrMipMapped,
271 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400272 GrColorType grColorType, const SkColor4f& color,
Robert Phillips459b2952019-05-23 09:38:27 -0400273 GrMipMapped mipMapped, GrRenderable renderable) {
274 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
275 if (!backendTex.isValid()) {
276 // errors here should be reported by the test_wrapping test
277 return;
278 }
279
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400280 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
281
282 // Can't wrap backend textures in images and surfaces w/o an SkColorType
283 if (kUnknown_SkColorType == skColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400284 // TODO: burrow in and scrappily check that data was uploaded!
285 context->deleteBackendTexture(backendTex);
286 return;
287 }
288
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400289 if (mipMapped == GrMipMapped::kYes) {
290 SkColor4f expectedColor = get_expected_color(color, skColorType);
291 SkColor4f expectedColors[6] = { expectedColor, expectedColor, expectedColor,
292 expectedColor, expectedColor, expectedColor };
Robert Phillips7f367982019-09-26 14:01:36 -0400293 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400294 }
295
Robert Phillips7f367982019-09-26 14:01:36 -0400296 // The last step in this test will dirty the mipmaps so do it last
297 check_base_readbacks(context, backendTex, skColorType, renderable, color,
298 reporter, "colorinit");
Robert Phillips459b2952019-05-23 09:38:27 -0400299 context->deleteBackendTexture(backendTex);
300}
301
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400302// Draw the backend texture (wrapped in an SkImage) into an RGBA surface, attempting to access
303// all the mipMap levels.
304static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
305 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400306 skiatest::Reporter* reporter, const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400307
308#ifdef SK_GL
309 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
310 if (GrBackendApi::kOpenGL == context->backend()) {
311 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
312
313 if (kRGBA_F32_SkColorType == skColorType &&
314 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
315 return;
316 }
317 }
318#endif
319
Robert Phillips7f367982019-09-26 14:01:36 -0400320 if (isRGB(backendTex.getBackendFormat())) {
321 // readPixels is busted for the RGB backend format (skbug.com/8862)
322 // TODO: add a GrColorType::kRGB_888 to fix the situation
323 return;
324 }
325
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400326 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
327 : kPremul_SkAlphaType;
Robert Phillips7f367982019-09-26 14:01:36 -0400328
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400329 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
330 backendTex,
331 kTopLeft_GrSurfaceOrigin,
332 skColorType,
333 at,
334 nullptr);
335 if (!img) {
336 return;
337 }
338
Robert Phillips7f367982019-09-26 14:01:36 -0400339 SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
340 kPremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400341
342 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
343 SkBudgeted::kNo,
Robert Phillips7f367982019-09-26 14:01:36 -0400344 readbackSurfaceII, 1,
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400345 kTopLeft_GrSurfaceOrigin,
346 nullptr);
347 if (!surf) {
348 return;
349 }
350
351 SkCanvas* canvas = surf->getCanvas();
352
353 SkPaint p;
354 p.setFilterQuality(kHigh_SkFilterQuality);
355
356 int numMipLevels = 6;
357
358 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
359 SkASSERT(rectSize >= 1);
360
361 SkRect r = SkRect::MakeWH(rectSize, rectSize);
362 canvas->clear(SK_ColorTRANSPARENT);
363 canvas->drawImageRect(img, r, &p);
364
365 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
366 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400367 kUnpremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400368 SkAutoPixmapStorage actual2;
369 SkAssertResult(actual2.tryAlloc(readbackII));
370 actual2.erase(SkColors::kTransparent);
371
372 bool result = surf->readPixels(actual2, 0, 0);
373 REPORTER_ASSERT(reporter, result);
374
Robert Phillips7f367982019-09-26 14:01:36 -0400375 check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
376 label, "mip-level failure");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400377 }
378}
379
Robert Phillips7f367982019-09-26 14:01:36 -0400380static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
381 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
382 int levelSize = 32;
383 int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
384 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
385 : kPremul_SkAlphaType;
386 for (int level = 0; level < numMipLevels; ++level) {
387 SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
388 pixmaps[level].alloc(ii);
389 pixmaps[level].erase(colors[level]);
390 levelSize /= 2;
391 }
392 return numMipLevels;
393}
394
395// Test initialization of GrBackendObjects using SkPixmaps
396static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
397 std::function<GrBackendTexture (GrContext*,
398 const SkPixmap srcData[],
399 int numLevels,
400 GrRenderable)> create,
401 SkColorType skColorType, GrMipMapped mipMapped,
402 GrRenderable renderable) {
403 SkAutoPixmapStorage pixmapMem[6];
404 SkColor4f colors[6] = {
405 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
406 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
407 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
408 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
409 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
410 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
411 };
412
413 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
414 SkASSERT(numMipLevels);
415
416 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
417 SkPixmap pixmaps[6];
418 for (int i = 0; i < numMipLevels; ++i) {
419 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
420 }
421
422 GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
423 if (!backendTex.isValid()) {
424 // errors here should be reported by the test_wrapping test
425 return;
426 }
427
428 if (skColorType == kBGRA_8888_SkColorType && !isBGRA(backendTex.getBackendFormat())) {
429 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
430 return;
431 }
432
433 if (mipMapped == GrMipMapped::kYes) {
434 SkColor4f expectedColors[6] = {
435 get_expected_color(colors[0], skColorType),
436 get_expected_color(colors[1], skColorType),
437 get_expected_color(colors[2], skColorType),
438 get_expected_color(colors[3], skColorType),
439 get_expected_color(colors[4], skColorType),
440 get_expected_color(colors[5], skColorType),
441 };
442
443 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
444 }
445
446 // The last step in this test will dirty the mipmaps so do it last
447 check_base_readbacks(context, backendTex, skColorType, renderable, colors[0],
448 reporter, "pixmap");
449 context->deleteBackendTexture(backendTex);
450}
451
Robert Phillips02dc0302019-07-02 17:58:27 -0400452enum class VkLayout {
453 kUndefined,
454 kReadOnlyOptimal,
455 kColorAttachmentOptimal
456};
457
458void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
459#if defined(SK_VULKAN) && defined(SK_DEBUG)
460 VkImageLayout expected;
461
462 switch (layout) {
463 case VkLayout::kUndefined:
464 expected = VK_IMAGE_LAYOUT_UNDEFINED;
465 break;
466 case VkLayout::kReadOnlyOptimal:
467 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
468 break;
469 case VkLayout::kColorAttachmentOptimal:
470 expected = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
471 break;
472 default:
473 SkUNREACHABLE;
474 }
475
476 GrVkImageInfo vkII;
477
478 if (backendTex.getVkImageInfo(&vkII)) {
479 SkASSERT(expected == vkII.fImageLayout);
480 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
481 }
482#endif
483}
484
485///////////////////////////////////////////////////////////////////////////////
486// This test is a bit different from the others in this file. It is mainly checking that, for any
487// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
488// its characterization and then create a new surface that wraps that backend texture.
489DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
490 GrContext* context = ctxInfo.grContext();
491
492 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
493 SkColorType colorType = static_cast<SkColorType>(ct);
494
495 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
496
497 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
498 for (bool mipMaps : { true, false } ) {
499 for (int sampleCount : {1, 2}) {
500 SkSurfaceCharacterization c;
501
502 // Get a characterization, if possible
503 {
504 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
505 ii, sampleCount,
506 origin, nullptr, mipMaps);
507 if (!s) {
508 continue;
509 }
510
511 if (!s->characterize(&c)) {
512 continue;
513 }
514
515 REPORTER_ASSERT(reporter, s->isCompatible(c));
516 }
517
518 // Test out uninitialized path
519 {
520 GrBackendTexture backendTex = context->createBackendTexture(c);
521 check_vk_layout(backendTex, VkLayout::kUndefined);
522 REPORTER_ASSERT(reporter, backendTex.isValid());
523 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
524
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400525 {
526 GrBackendFormat format = context->defaultBackendFormat(
527 c.imageInfo().colorType(),
528 GrRenderable::kYes);
529 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
530 }
531
Robert Phillips02dc0302019-07-02 17:58:27 -0400532 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
533 backendTex);
534 REPORTER_ASSERT(reporter, s2);
535 REPORTER_ASSERT(reporter, s2->isCompatible(c));
536
537 s2 = nullptr;
538 context->deleteBackendTexture(backendTex);
539 }
540
541 // Test out color-initialized path
542 {
543 GrBackendTexture backendTex = context->createBackendTexture(c,
544 SkColors::kRed);
545 check_vk_layout(backendTex, VkLayout::kColorAttachmentOptimal);
546 REPORTER_ASSERT(reporter, backendTex.isValid());
547 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
548
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400549 {
550 GrBackendFormat format = context->defaultBackendFormat(
551 c.imageInfo().colorType(),
552 GrRenderable::kYes);
553 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
554 }
555
Robert Phillips02dc0302019-07-02 17:58:27 -0400556 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
557 backendTex);
558 REPORTER_ASSERT(reporter, s2);
559 REPORTER_ASSERT(reporter, s2->isCompatible(c));
560
561 s2 = nullptr;
562 context->deleteBackendTexture(backendTex);
563 }
564 }
565 }
566 }
567 }
568}
569
Robert Phillipsefb9f142019-05-17 14:19:44 -0400570///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400571DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
572 GrContext* context = ctxInfo.grContext();
573 const GrCaps* caps = context->priv().caps();
574
Robert Phillips459b2952019-05-23 09:38:27 -0400575 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400576 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400577
Robert Phillips0c6daf02019-05-16 12:43:11 -0400578 struct {
579 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400580 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400581 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400582 { kAlpha_8_SkColorType, kTransCol },
583 { kRGB_565_SkColorType, SkColors::kRed },
584 { kARGB_4444_SkColorType, SkColors::kGreen },
585 { kRGBA_8888_SkColorType, SkColors::kBlue },
586 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400587 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400588 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips459b2952019-05-23 09:38:27 -0400589 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400590 { kRGBA_1010102_SkColorType, { .25f, .5f, .75f, 1.0f }},
Robert Phillipsb04b6942019-05-21 17:24:31 -0400591 // The kRGB_101010x_SkColorType has no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400592 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
593 { kGray_8_SkColorType, kGrayCol },
594 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
595 { kRGBA_F16_SkColorType, SkColors::kYellow },
596 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400597 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400598 { kR16G16_unorm_SkColorType, SkColors::kGreen },
599 { kA16_unorm_SkColorType, kTransCol },
600 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400601 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400602 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400603 };
604
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400605 GR_STATIC_ASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400606
607 for (auto combo : combinations) {
608 SkColorType colorType = combo.fColorType;
609
Robert Phillips0c6daf02019-05-16 12:43:11 -0400610 if (GrBackendApi::kMetal == context->backend()) {
611 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
612 if (kRGBA_F32_SkColorType == combo.fColorType) {
613 continue;
614 }
615 }
616
Robert Phillipsefb9f142019-05-17 14:19:44 -0400617 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
618 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
619 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400620 }
621
Robert Phillipsefb9f142019-05-17 14:19:44 -0400622 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400623 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
624 renderable).isValid()) {
625 continue;
626 }
Robert Phillips7f367982019-09-26 14:01:36 -0400627
Robert Phillipsefb9f142019-05-17 14:19:44 -0400628 if (GrRenderable::kYes == renderable) {
629 if (kRGB_888x_SkColorType == combo.fColorType) {
630 // Ganesh can't perform the blends correctly when rendering this format
631 continue;
632 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400633 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400634
Robert Phillipsb04b6942019-05-21 17:24:31 -0400635 {
636 auto uninitCreateMtd = [colorType](GrContext* context,
637 GrMipMapped mipMapped,
638 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400639 auto result = context->createBackendTexture(32, 32, colorType,
640 mipMapped, renderable,
641 GrProtected::kNo);
642 check_vk_layout(result, VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400643
644#ifdef SK_DEBUG
645 {
646 GrBackendFormat format = context->defaultBackendFormat(colorType,
647 renderable);
648 SkASSERT(format == result.getBackendFormat());
649 }
650#endif
651
Robert Phillips02dc0302019-07-02 17:58:27 -0400652 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400653 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400654
Robert Phillipsb04b6942019-05-21 17:24:31 -0400655 test_wrapping(context, reporter, uninitCreateMtd,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400656 SkColorTypeToGrColorType(colorType), mipMapped, renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400657 }
Robert Phillips459b2952019-05-23 09:38:27 -0400658
659 {
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400660 // GL has difficulties reading back from these combinations. In particular,
661 // reading back kGray_8 is a mess.
Robert Phillips459b2952019-05-23 09:38:27 -0400662 if (GrBackendApi::kOpenGL == context->backend()) {
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400663 if (kAlpha_8_SkColorType == combo.fColorType ||
664 kGray_8_SkColorType == combo.fColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400665 continue;
666 }
Robert Phillips459b2952019-05-23 09:38:27 -0400667 }
668
669 auto createWithColorMtd = [colorType](GrContext* context,
670 const SkColor4f& color,
671 GrMipMapped mipMapped,
672 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400673 auto result = context->createBackendTexture(32, 32, colorType, color,
674 mipMapped, renderable,
675 GrProtected::kNo);
676 check_vk_layout(result, GrRenderable::kYes == renderable
677 ? VkLayout::kColorAttachmentOptimal
678 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400679
680#ifdef SK_DEBUG
681 {
682 GrBackendFormat format = context->defaultBackendFormat(colorType,
683 renderable);
684 SkASSERT(format == result.getBackendFormat());
685 }
686#endif
687
Robert Phillips02dc0302019-07-02 17:58:27 -0400688 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400689 };
690
691 test_color_init(context, reporter, createWithColorMtd,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400692 SkColorTypeToGrColorType(colorType),
693 combo.fColor, mipMapped, renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400694 }
Robert Phillips7f367982019-09-26 14:01:36 -0400695
696 // Gray_8 is problematic. In the colorInit tests there is ambiguity when
697 // mapping from format to colorType (since R8 or A8 could be either Alpha_8
698 // or Gray_8). To compensate for this ambiguity we feed in colors with
699 // R==G==B==A. If we actually do know the colorType (as is the case
700 // in the SkPixmap case, there is no ambiguity but the two test expectations
701 // now collide.
702 // For now, skip the SkPixmap tests. The real answer is to plumb the
703 // SkColorType down further in the color-init case.
704 if (colorType != kGray_8_SkColorType) {
705 auto createWithSrcDataMtd = [](GrContext* context,
706 const SkPixmap srcData[],
707 int numLevels,
708 GrRenderable renderable) {
709 SkASSERT(srcData && numLevels);
Robert Phillips66944402019-09-30 13:21:25 -0400710 auto result = context->createBackendTexture(srcData, numLevels,
711 renderable, GrProtected::kNo);
Robert Phillips7f367982019-09-26 14:01:36 -0400712 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
713#ifdef SK_DEBUG
714 {
715 auto format = context->defaultBackendFormat(srcData[0].colorType(),
716 renderable);
717 SkASSERT(format == result.getBackendFormat());
718 }
719#endif
720 return result;
721 };
722
723 test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType,
724 mipMapped, renderable);
725 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400726 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400727 }
728 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400729}
730
Robert Phillipsefb9f142019-05-17 14:19:44 -0400731///////////////////////////////////////////////////////////////////////////////
732#ifdef SK_GL
733
734#include "src/gpu/gl/GrGLCaps.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -0400735#include "src/gpu/gl/GrGLDefines.h"
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400736#include "src/gpu/gl/GrGLUtil.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -0400737
738DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
739 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
740 GrGLStandard standard = glCtx->gl()->fStandard;
741 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400742 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400743
Robert Phillips459b2952019-05-23 09:38:27 -0400744 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400745 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400746
Robert Phillips0c6daf02019-05-16 12:43:11 -0400747 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400748 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400749 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400750 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400751 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400752 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
753 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400754
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400755 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
756 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400757
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400758 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
759 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
760 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
761 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.5f, 0, 0, 1.0f } },
762 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
763 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400764
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400765 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
766 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400767
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400768 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
769 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400770
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400771 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400772
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400773 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
774 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400775
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400776 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400777 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
778 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400779
Robert Phillips429f0d32019-09-11 17:03:28 -0400780 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400781 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400782
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400783 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
784 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400785 };
786
787 for (auto combo : combinations) {
788 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
789
Greg Daniel7bfc9132019-08-14 14:23:53 -0400790 if (!glCaps->isFormatTexturable(format)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400791 continue;
792 }
Greg Daniele877dce2019-07-11 10:52:43 -0400793
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400794 if (GrColorType::kBGRA_8888 == combo.fColorType) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400795 if (GR_GL_RGBA8 == combo.fFormat && kGL_GrGLStandard != standard) {
796 continue;
797 }
798 if (GR_GL_BGRA8 == combo.fFormat && kGL_GrGLStandard == standard) {
799 continue;
800 }
801 }
802
Robert Phillipsefb9f142019-05-17 14:19:44 -0400803 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
804 if (GrMipMapped::kYes == mipMapped && !glCaps->mipMapSupport()) {
805 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400806 }
807
Robert Phillipsefb9f142019-05-17 14:19:44 -0400808 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400809
Robert Phillipsefb9f142019-05-17 14:19:44 -0400810 if (GrRenderable::kYes == renderable) {
Greg Daniel900583a2019-08-06 12:05:31 -0400811 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400812 continue;
813 }
814 }
815
Robert Phillipsd34691b2019-09-24 13:38:43 -0400816 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400817 auto uninitCreateMtd = [format](GrContext* context,
818 GrMipMapped mipMapped,
819 GrRenderable renderable) {
820 return context->createBackendTexture(32, 32, format,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400821 mipMapped, renderable,
822 GrProtected::kNo);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400823 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400824
Robert Phillipsb04b6942019-05-21 17:24:31 -0400825 test_wrapping(context, reporter, uninitCreateMtd,
826 combo.fColorType, mipMapped, renderable);
827 }
Robert Phillips459b2952019-05-23 09:38:27 -0400828
829 {
830 // GL has difficulties reading back from these combinations
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400831 if (GrColorType::kAlpha_8 == combo.fColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400832 continue;
833 }
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400834 if (GrRenderable::kYes != renderable) {
Robert Phillips459b2952019-05-23 09:38:27 -0400835 continue;
836 }
837
838 auto createWithColorMtd = [format](GrContext* context,
839 const SkColor4f& color,
840 GrMipMapped mipMapped,
841 GrRenderable renderable) {
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400842 return context->createBackendTexture(32, 32, format, color,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400843 mipMapped, renderable,
844 GrProtected::kNo);
Robert Phillips459b2952019-05-23 09:38:27 -0400845 };
846
847 test_color_init(context, reporter, createWithColorMtd,
848 combo.fColorType, combo.fColor, mipMapped, renderable);
849 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400850 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400851 }
852 }
853}
854
Robert Phillipsefb9f142019-05-17 14:19:44 -0400855#endif
856
857///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400858
859#ifdef SK_VULKAN
860
861#include "src/gpu/vk/GrVkCaps.h"
862
863DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
864 GrContext* context = ctxInfo.grContext();
865 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
866
Robert Phillips459b2952019-05-23 09:38:27 -0400867 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400868 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400869
Robert Phillips0c6daf02019-05-16 12:43:11 -0400870 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400871 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400872 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400873 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400874 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400875 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
876 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400877
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400878 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
879 // there is nothing to tell Skia to make the provided color opaque. Clients will need
880 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400881 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
882 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400883
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400884 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400885
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400886 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32, { 0.5f, 0, 0, 1.0f }},
887 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400888
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400889 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
890 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400891
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400892 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400893 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
894 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
895 // the alpha channel of the color). Clients should, in general, fill all the channels
896 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400897 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400898
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400899 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
900 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400901
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400902 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400903 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
904
Robert Phillips429f0d32019-09-11 17:03:28 -0400905 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400906 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400907 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
908 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400909 };
910
911 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400912 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400913 continue;
914 }
915
916 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
917
Robert Phillipsefb9f142019-05-17 14:19:44 -0400918 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
919 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
920 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400921 }
922
Robert Phillipsefb9f142019-05-17 14:19:44 -0400923 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400924
Robert Phillipsefb9f142019-05-17 14:19:44 -0400925 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400926 // We must also check whether we allow rendering to the format using the
927 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -0400928 if (!vkCaps->isFormatAsColorTypeRenderable(
929 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400930 continue;
931 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400932 }
933
Robert Phillipsd34691b2019-09-24 13:38:43 -0400934 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400935 auto uninitCreateMtd = [format](GrContext* context,
Robert Phillips459b2952019-05-23 09:38:27 -0400936 GrMipMapped mipMapped,
937 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400938 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
939 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400940 renderable,
941 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400942 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400943 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400944 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400945
Robert Phillipsb04b6942019-05-21 17:24:31 -0400946 test_wrapping(context, reporter, uninitCreateMtd,
947 combo.fColorType, mipMapped, renderable);
948 }
Robert Phillips459b2952019-05-23 09:38:27 -0400949
Robert Phillips459b2952019-05-23 09:38:27 -0400950 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400951 // We're creating backend textures without specifying a color type "view" of
952 // them at the public API level. Therefore, Ganesh will not apply any swizzles
953 // before writing the color to the texture. However, our validation code does
954 // rely on interpreting the texture contents via a SkColorType and therefore
955 // swizzles may be applied during the read step.
956 // Ideally we'd update our validation code to use a "raw" read that doesn't
957 // impose a color type but for now we just munge the data we upload to match the
958 // expectation.
959 GrSwizzle swizzle;
960 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400961 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400962 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
963 swizzle = GrSwizzle("aaaa");
964 break;
Robert Phillips429f0d32019-09-11 17:03:28 -0400965 case GrColorType::kAlpha_16:
966 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
967 swizzle = GrSwizzle("aaaa");
968 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -0400969 case GrColorType::kAlpha_F16:
970 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
971 swizzle = GrSwizzle("aaaa");
972 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400973 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400974 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
975 swizzle = GrSwizzle("bgra");
976 }
977 break;
978 default:
979 swizzle = GrSwizzle("rgba");
980 break;
981 }
982 auto createWithColorMtd = [format, swizzle](GrContext* context,
983 const SkColor4f& color,
984 GrMipMapped mipMapped,
985 GrRenderable renderable) {
986 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400987 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -0400988 swizzledColor,
989 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400990 renderable,
991 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400992 check_vk_layout(beTex, GrRenderable::kYes == renderable
993 ? VkLayout::kColorAttachmentOptimal
994 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400995 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -0400996 };
Robert Phillips459b2952019-05-23 09:38:27 -0400997 test_color_init(context, reporter, createWithColorMtd,
998 combo.fColorType, combo.fColor, mipMapped, renderable);
999 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001000 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001001 }
1002 }
1003}
1004
1005#endif