Add support for draws in vulkan read and write pixels
authoregdaniel <egdaniel@google.com>
Mon, 27 Jun 2016 19:57:00 +0000 (12:57 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 27 Jun 2016 19:57:00 +0000 (12:57 -0700)
GL has a lot more optimizations checks here to make sure we do the most
effecient and correct draw here, but for now as long as the features
are support we just do basic draws for both reads and writes when we
need certain conversions.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2105433002

Review-Url: https://codereview.chromium.org/2105433002

src/gpu/vk/GrVkGpu.cpp
tests/WritePixelsTest.cpp

index ee5d324dc8930701607d7cc4f5b08a901822f9ba..bfda30a0338030928eab74b79b4576b719a1d150 100644 (file)
@@ -252,18 +252,42 @@ bool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
         return false;
     }
 
-    // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail
-    if (kNoDraw_DrawPreference != *drawPreference) {
-        return false;
+    if (dstSurface->config() == srcConfig) {
+        return true;
     }
 
-    if (dstSurface->config() != srcConfig) {
-        // TODO: This should fall back to drawing or copying to change config of dstSurface to
-        // match that of srcConfig.
-        return false;
+    GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
+
+    // Start off assuming no swizzling
+    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
+    tempDrawInfo->fWriteConfig = srcConfig;
+
+    // These settings we will always want if a temp draw is performed. Initially set the config
+    // to srcConfig, though that may be modified if we decide to do a R/B swap
+    tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
+    tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
+    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
+    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
+    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
+    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
+
+    if (renderTarget && this->vkCaps().isConfigRenderable(renderTarget->config(), false)) {
+        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+
+        bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
+
+        if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) {
+            if (!this->vkCaps().isConfigTexturable(dstSurface->config())) {
+                return false;
+            }
+            tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
+            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
+            tempDrawInfo->fWriteConfig = dstSurface->config();
+        }
+        return true;
     }
 
-    return true;
+    return false;
 }
 
 bool GrVkGpu::onWritePixels(GrSurface* surface,
@@ -324,7 +348,7 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
             success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config, texels);
         }
     }
-    
+
     return success;
 }
 
@@ -502,7 +526,7 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
         region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 };
         region.imageOffset = { left, flipY ? tex->height() - top - currentHeight : top, 0 };
         region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 };
-        
+
         currentWidth = SkTMax(1, currentWidth/2);
         currentHeight = SkTMax(1, currentHeight/2);
     }
@@ -1332,18 +1356,18 @@ void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&
 bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
                                   GrPixelConfig readConfig, DrawPreference* drawPreference,
                                   ReadPixelTempDrawInfo* tempDrawInfo) {
-    // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail
-    if (kNoDraw_DrawPreference != *drawPreference) {
-        return false;
+    if (srcSurface->config() == readConfig) {
+        return true;
     }
 
-    if (srcSurface->config() != readConfig) {
-        // TODO: This should fall back to drawing or copying to change config of srcSurface to match
-        // that of readConfig.
-        return false;
+    if (this->vkCaps().isConfigRenderable(readConfig, false)) {
+        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+        tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
+        tempDrawInfo->fReadConfig = readConfig;
+        return true;
     }
 
-    return true;
+    return false;
 }
 
 bool GrVkGpu::onReadPixels(GrSurface* surface,
index 8ad84510c98938bdb98af1890e1eb8a04a4c8094..90f5d805f1071cc91c8adcf61ed7eefae30bf00a 100644 (file)
@@ -406,7 +406,7 @@ DEF_TEST(WritePixels, reporter) {
     }
 }
 #if SK_SUPPORT_GPU
-DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(WritePixels_Gpu, reporter, ctxInfo) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WritePixels_Gpu, reporter, ctxInfo) {
     for (auto& origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
         GrSurfaceDesc desc;
         desc.fFlags = kRenderTarget_GrSurfaceFlag;