1 2 /* 3 * Copyright 2015 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 // This is a GPU-backend specific test. It relies on static intializers to work 10 11 #include "SkTypes.h" 12 13 #if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS && defined(SK_VULKAN) 14 15 #include "GrContextFactory.h" 16 #include "GrTest.h" 17 #include "Test.h" 18 #include "vk/GrVkGpu.h" 19 20 21 void fill_pixel_data(int width, int height, GrColor* data) { 22 23 // build red-green gradient 24 for (int j = 0; j < height; ++j) { 25 for (int i = 0; i < width; ++i) { 26 unsigned int red = (unsigned int)(256.f*(i / (float)width)); 27 unsigned int green = (unsigned int)(256.f*(j / (float)height)); 28 data[i + j*width] = GrColorPackRGBA(red - (red>>8), green - (green>>8), 0xff, 0xff); 29 } 30 } 31 } 32 33 bool does_full_buffer_contain_correct_color(GrColor* srcBuffer, 34 GrColor* dstBuffer, 35 GrPixelConfig config, 36 int width, 37 int height) { 38 GrColor* srcPtr = srcBuffer; 39 GrColor* dstPtr = dstBuffer; 40 for (int j = 0; j < height; ++j) { 41 for (int i = 0; i < width; ++i) { 42 if (srcPtr[i] != dstPtr[i]) { 43 return false; 44 } 45 } 46 srcPtr += width; 47 dstPtr += width; 48 } 49 return true; 50 } 51 52 void basic_texture_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config, 53 bool renderTarget, bool linearTiling) { 54 GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu()); 55 gpu->discard(NULL); 56 57 const int kWidth = 16; 58 const int kHeight = 16; 59 SkAutoTMalloc<GrColor> srcBuffer(kWidth*kHeight); 60 SkAutoTMalloc<GrColor> dstBuffer(kWidth*kHeight); 61 62 fill_pixel_data(kWidth, kHeight, srcBuffer.get()); 63 64 const GrVkCaps* caps = reinterpret_cast<const GrVkCaps*>(context->caps()); 65 66 bool canCreate = true; 67 // the expectation is that the given config is texturable/renderable with optimal tiling 68 // but may not be with linear tiling 69 if (linearTiling) { 70 if (!caps->isConfigTexurableLinearly(config) || 71 (renderTarget && !caps->isConfigRenderableLinearly(config, false))) { 72 canCreate = false; 73 } 74 } 75 76 GrSurfaceDesc surfDesc; 77 surfDesc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; 78 if (linearTiling) { 79 surfDesc.fFlags |= kZeroCopy_GrSurfaceFlag; 80 } 81 surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin; 82 surfDesc.fWidth = kWidth; 83 surfDesc.fHeight = kHeight; 84 surfDesc.fConfig = config; 85 surfDesc.fSampleCnt = 0; 86 GrTexture* tex0 = gpu->createTexture(surfDesc, SkBudgeted::kNo, srcBuffer, 0); 87 if (tex0) { 88 REPORTER_ASSERT(reporter, canCreate); 89 gpu->readPixels(tex0, 0, 0, kWidth, kHeight, config, dstBuffer, 0); 90 REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(srcBuffer, 91 dstBuffer, 92 config, 93 kWidth, 94 kHeight)); 95 96 tex0->writePixels(2, 10, 10, 2, config, srcBuffer); 97 memset(dstBuffer, 0, kWidth*kHeight*sizeof(GrColor)); 98 gpu->readPixels(tex0, 2, 10, 10, 2, config, dstBuffer, 0); 99 REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(srcBuffer, 100 dstBuffer, 101 config, 102 10, 103 2)); 104 105 tex0->unref(); 106 } else { 107 REPORTER_ASSERT(reporter, !canCreate); 108 } 109 110 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; 111 GrTexture* tex1 = gpu->createTexture(surfDesc, SkBudgeted::kNo, srcBuffer, 0); 112 if (tex1) { 113 REPORTER_ASSERT(reporter, canCreate); 114 gpu->readPixels(tex1, 0, 0, kWidth, kHeight, config, dstBuffer, 0); 115 REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(srcBuffer, 116 dstBuffer, 117 config, 118 kWidth, 119 kHeight)); 120 121 tex1->writePixels(5, 4, 4, 5, config, srcBuffer); 122 memset(dstBuffer, 0, kWidth*kHeight*sizeof(GrColor)); 123 gpu->readPixels(tex1, 5, 4, 4, 5, config, dstBuffer, 0); 124 REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_color(srcBuffer, 125 dstBuffer, 126 config, 127 4, 128 5)); 129 130 tex1->unref(); 131 } else { 132 REPORTER_ASSERT(reporter, !canCreate); 133 } 134 } 135 136 DEF_GPUTEST(VkUploadPixelsTests, reporter, factory) { 137 GrContextOptions opts; 138 opts.fSuppressPrints = true; 139 GrContextFactory debugFactory(opts); 140 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 141 if (static_cast<GrContextFactory::GLContextType>(type) != 142 GrContextFactory::kNative_GLContextType) { 143 continue; 144 } 145 GrContext* context = debugFactory.get(static_cast<GrContextFactory::GLContextType>(type)); 146 if (context) { 147 basic_texture_test(reporter, context, kRGBA_8888_GrPixelConfig, false, false); 148 basic_texture_test(reporter, context, kRGBA_8888_GrPixelConfig, true, false); 149 basic_texture_test(reporter, context, kRGBA_8888_GrPixelConfig, false, true); 150 basic_texture_test(reporter, context, kRGBA_8888_GrPixelConfig, true, true); 151 basic_texture_test(reporter, context, kBGRA_8888_GrPixelConfig, false, false); 152 basic_texture_test(reporter, context, kBGRA_8888_GrPixelConfig, true, false); 153 basic_texture_test(reporter, context, kBGRA_8888_GrPixelConfig, false, true); 154 basic_texture_test(reporter, context, kBGRA_8888_GrPixelConfig, true, true); 155 } 156 157 } 158 } 159 160 #endif 161