OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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(®ion, 0, sizeof(VkBufferImageCopy)); | 1427 memset(®ion, 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 ®ion); | 1440 ®ion); |
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 |
OLD | NEW |