Home | History | Annotate | Download | only in tests
      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