Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(686)

Side by Side Diff: src/gpu/vk/GrVkGpu.cpp

Issue 2102633003: Fix Vulkan readPixels (Closed) Base URL: https://skia.googlesource.com/skia.git@unitTests2
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/ReadPixelsTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrVkGpu.h" 8 #include "GrVkGpu.h"
9 9
10 #include "GrContextOptions.h" 10 #include "GrContextOptions.h"
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 for (int y = 0; y < height; y++) { 407 for (int y = 0; y < height; y++) {
408 memcpy(dstRow, srcRow, trimRowBytes); 408 memcpy(dstRow, srcRow, trimRowBytes);
409 srcRow += rowBytes; 409 srcRow += rowBytes;
410 dstRow -= layout.rowPitch; 410 dstRow -= layout.rowPitch;
411 } 411 }
412 } else { 412 } else {
413 // If there is no padding on the src (rowBytes) or dst (layout.rowPitch) we can memcpy 413 // If there is no padding on the src (rowBytes) or dst (layout.rowPitch) we can memcpy
414 if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) { 414 if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) {
415 memcpy(mapPtr, data, trimRowBytes * height); 415 memcpy(mapPtr, data, trimRowBytes * height);
416 } else { 416 } else {
417 SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, row Bytes, 417 SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, row Bytes, trimRowBytes,
418 trimRowBytes, height); 418 height);
419 } 419 }
420 } 420 }
421 421
422 GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory)); 422 GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory));
423 423
424 return true; 424 return true;
425 } 425 }
426 426
427 bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, 427 bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
428 int left, int top, int width, int height, 428 int left, int top, int width, int height,
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& , 1349 void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& ,
1350 int* effectiveSampleCnt, SkAutoTDeleteArray< SkPoint>*) { 1350 int* effectiveSampleCnt, SkAutoTDeleteArray< SkPoint>*) {
1351 // TODO: stub. 1351 // TODO: stub.
1352 SkASSERT(!this->caps()->sampleLocationsSupport()); 1352 SkASSERT(!this->caps()->sampleLocationsSupport());
1353 *effectiveSampleCnt = rt->desc().fSampleCnt; 1353 *effectiveSampleCnt = rt->desc().fSampleCnt;
1354 } 1354 }
1355 1355
1356 bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1356 bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
1357 GrPixelConfig readConfig, DrawPreference* draw Preference, 1357 GrPixelConfig readConfig, DrawPreference* draw Preference,
1358 ReadPixelTempDrawInfo* tempDrawInfo) { 1358 ReadPixelTempDrawInfo* tempDrawInfo) {
1359 // These settings we will always want if a temp draw is performed.
1360 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
1361 tempDrawInfo->fTempSurfaceDesc.fWidth = width;
1362 tempDrawInfo->fTempSurfaceDesc.fHeight = height;
1363 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
1364 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
1365 tempDrawInfo->fUseExactScratch = false;
1366
1367 // For now assume no swizzling, we may change that below.
1368 tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
1369
1370 // Depends on why we need/want a temp draw. Start off assuming no change, th e surface we read
1371 // from will be srcConfig and we will read readConfig pixels from it.
1372 // Not that if we require a draw and return a non-renderable format for the temp surface the
1373 // base class will fail for us.
1374 tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config();
1375 tempDrawInfo->fReadConfig = readConfig;
1376
1359 if (srcSurface->config() == readConfig) { 1377 if (srcSurface->config() == readConfig) {
1360 return true; 1378 return true;
1361 } 1379 }
1362 1380
1363 if (this->vkCaps().isConfigRenderable(readConfig, false)) { 1381 if (this->vkCaps().isConfigRenderable(readConfig, false)) {
1364 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 1382 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
1365 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 1383 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
1366 tempDrawInfo->fReadConfig = readConfig; 1384 tempDrawInfo->fReadConfig = readConfig;
1367 return true; 1385 return true;
1368 } 1386 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 VkOffset3D offset = { 1419 VkOffset3D offset = {
1402 left, 1420 left,
1403 flipY ? surface->height() - top - height : top, 1421 flipY ? surface->height() - top - height : top,
1404 0 1422 0
1405 }; 1423 };
1406 1424
1407 // Copy the image to a buffer so we can map it to cpu memory 1425 // Copy the image to a buffer so we can map it to cpu memory
1408 VkBufferImageCopy region; 1426 VkBufferImageCopy region;
1409 memset(&region, 0, sizeof(VkBufferImageCopy)); 1427 memset(&region, 0, sizeof(VkBufferImageCopy));
1410 region.bufferOffset = 0; 1428 region.bufferOffset = 0;
1411 region.bufferRowLength = 0; // Forces RowLength to be imageExtent.width 1429 region.bufferRowLength = 0; // Forces RowLength to be width. We handle the r owBytes below.
1412 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us eful for 3d images. 1430 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us eful for 3d images.
1413 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1431 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1414 region.imageOffset = offset; 1432 region.imageOffset = offset;
1415 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 1433 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
1416 1434
1417 fCurrentCmdBuffer->copyImageToBuffer(this, 1435 fCurrentCmdBuffer->copyImageToBuffer(this,
1418 tgt, 1436 tgt,
1419 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1437 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1420 transferBuffer, 1438 transferBuffer,
1421 1, 1439 1,
1422 &region); 1440 &region);
1423 1441
1424 // make sure the copy to buffer has finished 1442 // make sure the copy to buffer has finished
1425 transferBuffer->addMemoryBarrier(this, 1443 transferBuffer->addMemoryBarrier(this,
1426 VK_ACCESS_TRANSFER_WRITE_BIT, 1444 VK_ACCESS_TRANSFER_WRITE_BIT,
1427 VK_ACCESS_HOST_READ_BIT, 1445 VK_ACCESS_HOST_READ_BIT,
1428 VK_PIPELINE_STAGE_TRANSFER_BIT, 1446 VK_PIPELINE_STAGE_TRANSFER_BIT,
1429 VK_PIPELINE_STAGE_HOST_BIT, 1447 VK_PIPELINE_STAGE_HOST_BIT,
1430 false); 1448 false);
1431 1449
1432 // We need to submit the current command buffer to the Queue and make sure i t finishes before 1450 // We need to submit the current command buffer to the Queue and make sure i t finishes before
1433 // we can copy the data out of the buffer. 1451 // we can copy the data out of the buffer.
1434 this->submitCommandBuffer(kForce_SyncQueue); 1452 this->submitCommandBuffer(kForce_SyncQueue);
1435 1453
1436 void* mappedMemory = transferBuffer->map(); 1454 void* mappedMemory = transferBuffer->map();
1437 1455
1438 memcpy(buffer, mappedMemory, rowBytes*height); 1456 size_t tightRowBytes = GrBytesPerPixel(config) * width;
1457 if (flipY) {
1458 const char* srcRow = reinterpret_cast<const char*>(mappedMemory);
1459 char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes;
1460 for (int y = 0; y < height; y++) {
1461 memcpy(dstRow, srcRow, tightRowBytes);
1462 srcRow += tightRowBytes;
1463 dstRow -= rowBytes;
1464 }
1465 } else {
1466 if (tightRowBytes == rowBytes) {
1467 memcpy(buffer, mappedMemory, rowBytes*height);
1468 } else {
1469 SkRectMemcpy(buffer, rowBytes, mappedMemory, tightRowBytes, tightRow Bytes, height);
1470 }
1471 }
1439 1472
1440 transferBuffer->unmap(); 1473 transferBuffer->unmap();
1441 transferBuffer->unref(); 1474 transferBuffer->unref();
1442 1475
1443 if (flipY) {
1444 SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
1445 size_t tightRowBytes = GrBytesPerPixel(config) * width;
1446 scratch.reset(tightRowBytes);
1447 void* tmpRow = scratch.get();
1448 // flip y in-place by rows
1449 const int halfY = height >> 1;
1450 char* top = reinterpret_cast<char*>(buffer);
1451 char* bottom = top + (height - 1) * rowBytes;
1452 for (int y = 0; y < halfY; y++) {
1453 memcpy(tmpRow, top, tightRowBytes);
1454 memcpy(top, bottom, tightRowBytes);
1455 memcpy(bottom, tmpRow, tightRowBytes);
1456 top += rowBytes;
1457 bottom -= rowBytes;
1458 }
1459 }
1460
1461 return true; 1476 return true;
1462 } 1477 }
1463 1478
1464 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer, 1479 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer,
1465 const GrVkRenderPass* renderPass, 1480 const GrVkRenderPass* renderPass,
1466 const VkClearValue* colorClear, 1481 const VkClearValue* colorClear,
1467 GrVkRenderTarget* target, 1482 GrVkRenderTarget* target,
1468 const SkIRect& bounds) { 1483 const SkIRect& bounds) {
1469 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment 1484 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment
1470 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment 1485 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment
1471 // which is always at the first attachment. 1486 // which is always at the first attachment.
1472 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, bounds, true); 1487 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, bounds, true);
1473 fCurrentCmdBuffer->executeCommands(this, buffer); 1488 fCurrentCmdBuffer->executeCommands(this, buffer);
1474 fCurrentCmdBuffer->endRenderPass(this); 1489 fCurrentCmdBuffer->endRenderPass(this);
1475 } 1490 }
1476 1491
OLDNEW
« no previous file with comments | « no previous file | tests/ReadPixelsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698