| 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 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 return false; | 1695 return false; |
| 1696 } | 1696 } |
| 1697 | 1697 |
| 1698 // Change layout of our target so it can be used as copy | 1698 // Change layout of our target so it can be used as copy |
| 1699 image->setImageLayout(this, | 1699 image->setImageLayout(this, |
| 1700 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 1700 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 1701 VK_ACCESS_TRANSFER_READ_BIT, | 1701 VK_ACCESS_TRANSFER_READ_BIT, |
| 1702 VK_PIPELINE_STAGE_TRANSFER_BIT, | 1702 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 1703 false); | 1703 false); |
| 1704 | 1704 |
| 1705 size_t bpp = GrBytesPerPixel(config); |
| 1706 size_t tightRowBytes = bpp * width; |
| 1707 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); |
| 1708 |
| 1709 VkBufferImageCopy region; |
| 1710 memset(®ion, 0, sizeof(VkBufferImageCopy)); |
| 1711 |
| 1712 bool copyFromOrigin = this->vkCaps().mustDoCopiesFromOrigin(); |
| 1713 if (copyFromOrigin) { |
| 1714 region.imageOffset = { 0, 0, 0 }; |
| 1715 region.imageExtent = { (uint32_t)(left + width), |
| 1716 (uint32_t)(flipY ? surface->height() - top : top
+ height), |
| 1717 1 |
| 1718 }; |
| 1719 } else { |
| 1720 VkOffset3D offset = { |
| 1721 left, |
| 1722 flipY ? surface->height() - top - height : top, |
| 1723 0 |
| 1724 }; |
| 1725 region.imageOffset = offset; |
| 1726 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; |
| 1727 } |
| 1728 |
| 1729 size_t transBufferRowBytes = bpp * region.imageExtent.width; |
| 1705 GrVkTransferBuffer* transferBuffer = | 1730 GrVkTransferBuffer* transferBuffer = |
| 1706 static_cast<GrVkTransferBuffer*>(this->createBuffer(rowBytes * height, | 1731 static_cast<GrVkTransferBuffer*>(this->createBuffer(transBufferRowBy
tes * height, |
| 1707 kXferGpuToCpu_GrBuff
erType, | 1732 kXferGpuToCpu_Gr
BufferType, |
| 1708 kStream_GrAccessPatt
ern)); | 1733 kStream_GrAccess
Pattern)); |
| 1709 | |
| 1710 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); | |
| 1711 VkOffset3D offset = { | |
| 1712 left, | |
| 1713 flipY ? surface->height() - top - height : top, | |
| 1714 0 | |
| 1715 }; | |
| 1716 | 1734 |
| 1717 // Copy the image to a buffer so we can map it to cpu memory | 1735 // Copy the image to a buffer so we can map it to cpu memory |
| 1718 VkBufferImageCopy region; | |
| 1719 memset(®ion, 0, sizeof(VkBufferImageCopy)); | |
| 1720 region.bufferOffset = transferBuffer->offset(); | 1736 region.bufferOffset = transferBuffer->offset(); |
| 1721 region.bufferRowLength = 0; // Forces RowLength to be width. We handle the r
owBytes below. | 1737 region.bufferRowLength = 0; // Forces RowLength to be width. We handle the r
owBytes below. |
| 1722 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us
eful for 3d images. | 1738 region.bufferImageHeight = 0; // Forces height to be tightly packed. Only us
eful for 3d images. |
| 1723 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; | 1739 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 1724 region.imageOffset = offset; | |
| 1725 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; | |
| 1726 | 1740 |
| 1727 fCurrentCmdBuffer->copyImageToBuffer(this, | 1741 fCurrentCmdBuffer->copyImageToBuffer(this, |
| 1728 image, | 1742 image, |
| 1729 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, | 1743 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 1730 transferBuffer, | 1744 transferBuffer, |
| 1731 1, | 1745 1, |
| 1732 ®ion); | 1746 ®ion); |
| 1733 | 1747 |
| 1734 // make sure the copy to buffer has finished | 1748 // make sure the copy to buffer has finished |
| 1735 transferBuffer->addMemoryBarrier(this, | 1749 transferBuffer->addMemoryBarrier(this, |
| 1736 VK_ACCESS_TRANSFER_WRITE_BIT, | 1750 VK_ACCESS_TRANSFER_WRITE_BIT, |
| 1737 VK_ACCESS_HOST_READ_BIT, | 1751 VK_ACCESS_HOST_READ_BIT, |
| 1738 VK_PIPELINE_STAGE_TRANSFER_BIT, | 1752 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 1739 VK_PIPELINE_STAGE_HOST_BIT, | 1753 VK_PIPELINE_STAGE_HOST_BIT, |
| 1740 false); | 1754 false); |
| 1741 | 1755 |
| 1742 // We need to submit the current command buffer to the Queue and make sure i
t finishes before | 1756 // We need to submit the current command buffer to the Queue and make sure i
t finishes before |
| 1743 // we can copy the data out of the buffer. | 1757 // we can copy the data out of the buffer. |
| 1744 this->submitCommandBuffer(kForce_SyncQueue); | 1758 this->submitCommandBuffer(kForce_SyncQueue); |
| 1745 | 1759 |
| 1746 void* mappedMemory = transferBuffer->map(); | 1760 void* mappedMemory = transferBuffer->map(); |
| 1747 | 1761 |
| 1748 size_t tightRowBytes = GrBytesPerPixel(config) * width; | 1762 if (copyFromOrigin) { |
| 1763 uint32_t skipRows = region.imageExtent.height - height; |
| 1764 mappedMemory = (char*)mappedMemory + transBufferRowBytes * skipRows + bp
p * left; |
| 1765 } |
| 1766 |
| 1749 if (flipY) { | 1767 if (flipY) { |
| 1750 const char* srcRow = reinterpret_cast<const char*>(mappedMemory); | 1768 const char* srcRow = reinterpret_cast<const char*>(mappedMemory); |
| 1751 char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes; | 1769 char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes; |
| 1752 for (int y = 0; y < height; y++) { | 1770 for (int y = 0; y < height; y++) { |
| 1753 memcpy(dstRow, srcRow, tightRowBytes); | 1771 memcpy(dstRow, srcRow, tightRowBytes); |
| 1754 srcRow += tightRowBytes; | 1772 srcRow += transBufferRowBytes; |
| 1755 dstRow -= rowBytes; | 1773 dstRow -= rowBytes; |
| 1756 } | 1774 } |
| 1757 } else { | 1775 } else { |
| 1758 if (tightRowBytes == rowBytes) { | 1776 if (transBufferRowBytes == rowBytes) { |
| 1759 memcpy(buffer, mappedMemory, rowBytes*height); | 1777 memcpy(buffer, mappedMemory, rowBytes*height); |
| 1760 } else { | 1778 } else { |
| 1761 SkRectMemcpy(buffer, rowBytes, mappedMemory, tightRowBytes, tightRow
Bytes, height); | 1779 SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, ti
ghtRowBytes, |
| 1780 height); |
| 1762 } | 1781 } |
| 1763 } | 1782 } |
| 1764 | 1783 |
| 1765 transferBuffer->unmap(); | 1784 transferBuffer->unmap(); |
| 1766 transferBuffer->unref(); | 1785 transferBuffer->unref(); |
| 1767 | |
| 1768 return true; | 1786 return true; |
| 1769 } | 1787 } |
| 1770 | 1788 |
| 1771 // The RenderArea bounds we pass into BeginRenderPass must have a start x value
that is a multiple | 1789 // The RenderArea bounds we pass into BeginRenderPass must have a start x value
that is a multiple |
| 1772 // of the granularity. The width must also be a multiple of the granularity or e
aqual to the width | 1790 // of the granularity. The width must also be a multiple of the granularity or e
aqual to the width |
| 1773 // the the entire attachment. Similar requirements for the y and height componen
ts. | 1791 // the the entire attachment. Similar requirements for the y and height componen
ts. |
| 1774 void adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds, | 1792 void adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds, |
| 1775 const VkExtent2D& granularity, int maxWidth, i
nt maxHeight) { | 1793 const VkExtent2D& granularity, int maxWidth, i
nt maxHeight) { |
| 1776 // Adjust Width | 1794 // Adjust Width |
| 1777 // Start with the right side of rect so we know if we end up going pass the
maxWidth. | 1795 // Start with the right side of rect so we know if we end up going pass the
maxWidth. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1830 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment | 1848 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment |
| 1831 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment | 1849 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment |
| 1832 // which is always at the first attachment. | 1850 // which is always at the first attachment. |
| 1833 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); | 1851 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); |
| 1834 fCurrentCmdBuffer->executeCommands(this, buffer); | 1852 fCurrentCmdBuffer->executeCommands(this, buffer); |
| 1835 fCurrentCmdBuffer->endRenderPass(this); | 1853 fCurrentCmdBuffer->endRenderPass(this); |
| 1836 | 1854 |
| 1837 this->didWriteToSurface(target, &bounds); | 1855 this->didWriteToSurface(target, &bounds); |
| 1838 } | 1856 } |
| 1839 | 1857 |
| OLD | NEW |