aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-10-23 09:37:36 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-23 15:32:15 +0000
commit261b8aa1de8562f79c1a7c515d968787e027a2c8 (patch)
tree738bada2d198062d8ed72d5fdbe6f5b9f1b3b7f4 /src/gpu/vk
parent1cb41717bc4a44272eab48bd47ca7579425dc22e (diff)
Revert "Revert "Support creation/use of mipped proxy in GrBackendTextureImageGenerator""
This reverts commit 7477d9693869982a4b0b18d20fee32d2f3eaedbf. Reason for revert: Putting in fixes in tests Original change's description: > Revert "Support creation/use of mipped proxy in GrBackendTextureImageGenerator" > > This reverts commit b8ad00b5a68975cafd68d6df0d66f0a01f5c07c2. > > Reason for revert: Some various test failures > > Original change's description: > > Support creation/use of mipped proxy in GrBackendTextureImageGenerator > > > > Bug: skia: > > Change-Id: I9d06780ccb2db0865100b67041c03408f2445c62 > > Reviewed-on: https://skia-review.googlesource.com/61241 > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Commit-Queue: Greg Daniel <egdaniel@google.com> > > TBR=egdaniel@google.com,bsalomon@google.com,brianosman@google.com > > Change-Id: I28e625776352ee6f9f27e66cd5d4b149ef50a22a > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia: > Reviewed-on: https://skia-review.googlesource.com/61941 > Reviewed-by: Greg Daniel <egdaniel@google.com> > Commit-Queue: Greg Daniel <egdaniel@google.com> TBR=egdaniel@google.com,bsalomon@google.com,brianosman@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: skia: Change-Id: Ibfbca5101b06d9ff8f8a5d33bc6f2114806db552 Reviewed-on: https://skia-review.googlesource.com/62561 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/gpu/vk')
-rw-r--r--src/gpu/vk/GrVkGpu.cpp268
1 files changed, 171 insertions, 97 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 1a9bd2f254..3b40f27480 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1138,12 +1138,12 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen
////////////////////////////////////////////////////////////////////////////////
-bool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc,
+bool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, size_t bufferOffset,
size_t srcRowBytes, size_t dstRowBytes, int h) {
void* mapPtr;
VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(),
alloc.fMemory,
- alloc.fOffset,
+ alloc.fOffset + bufferOffset,
dstRowBytes * h,
0,
&mapPtr));
@@ -1255,6 +1255,37 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
return 0;
}
+ // We need to declare these early so that we can delete them at the end outside of the if block.
+ GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
+ VkBuffer buffer = VK_NULL_HANDLE;
+
+ VkResult err;
+ const VkCommandBufferAllocateInfo cmdInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
+ nullptr, // pNext
+ fCmdPool, // commandPool
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
+ 1 // bufferCount
+ };
+
+ VkCommandBuffer cmdBuffer;
+ err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer));
+ if (err) {
+ GrVkMemory::FreeImageMemory(this, false, alloc);
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
+ return 0;
+ }
+
+ VkCommandBufferBeginInfo cmdBufferBeginInfo;
+ memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
+ cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdBufferBeginInfo.pNext = nullptr;
+ cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
+ SkASSERT(!err);
+
size_t bpp = GrBytesPerPixel(config);
size_t rowCopyBytes = bpp * w;
if (linearTiling) {
@@ -1267,79 +1298,89 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout));
- if (!copy_testing_data(this, srcData, alloc, rowCopyBytes,
+ if (!copy_testing_data(this, srcData, alloc, 0, rowCopyBytes,
static_cast<size_t>(layout.rowPitch), h)) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
+ GrVkMemory::FreeImageMemory(this, true, alloc);
VK_CALL(DestroyImage(fDevice, image, nullptr));
+ VK_CALL(EndCommandBuffer(cmdBuffer));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return 0;
}
} else {
SkASSERT(w && h);
- VkBuffer buffer;
+ SkTArray<size_t> individualMipOffsets(mipLevels);
+ individualMipOffsets.push_back(0);
+ size_t combinedBufferSize = w * bpp * h;
+ int currentWidth = w;
+ int currentHeight = h;
+ // The alignment must be at least 4 bytes and a multiple of the bytes per pixel of the image
+ // config. This works with the assumption that the bytes in pixel config is always a power
+ // of 2.
+ SkASSERT((bpp & (bpp - 1)) == 0);
+ const size_t alignmentMask = 0x3 | (bpp - 1);
+ for (uint32_t currentMipLevel = 1; currentMipLevel < mipLevels; currentMipLevel++) {
+ currentWidth = SkTMax(1, currentWidth/2);
+ currentHeight = SkTMax(1, currentHeight/2);
+
+ const size_t trimmedSize = currentWidth * bpp * currentHeight;
+ const size_t alignmentDiff = combinedBufferSize & alignmentMask;
+ if (alignmentDiff != 0) {
+ combinedBufferSize += alignmentMask - alignmentDiff + 1;
+ }
+ individualMipOffsets.push_back(combinedBufferSize);
+ combinedBufferSize += trimmedSize;
+ }
+
VkBufferCreateInfo bufInfo;
memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufInfo.flags = 0;
- bufInfo.size = rowCopyBytes * h;
+ bufInfo.size = combinedBufferSize;
bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bufInfo.queueFamilyIndexCount = 0;
bufInfo.pQueueFamilyIndices = nullptr;
- VkResult err;
err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer));
if (err) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
+ GrVkMemory::FreeImageMemory(this, false, alloc);
VK_CALL(DestroyImage(fDevice, image, nullptr));
+ VK_CALL(EndCommandBuffer(cmdBuffer));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return 0;
}
- GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type,
true, &bufferAlloc)) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
+ GrVkMemory::FreeImageMemory(this, false, alloc);
VK_CALL(DestroyImage(fDevice, image, nullptr));
VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+ VK_CALL(EndCommandBuffer(cmdBuffer));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return 0;
}
- if (!copy_testing_data(this, srcData, bufferAlloc, rowCopyBytes, rowCopyBytes, h)) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
- VK_CALL(DestroyImage(fDevice, image, nullptr));
- GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
- VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
- return 0;
- }
-
- const VkCommandBufferAllocateInfo cmdInfo = {
- VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
- nullptr, // pNext
- fCmdPool, // commandPool
- VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
- 1 // bufferCount
- };
-
- VkCommandBuffer cmdBuffer;
- err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer));
- if (err) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
- VK_CALL(DestroyImage(fDevice, image, nullptr));
- GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
- VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
- return 0;
+ currentWidth = w;
+ currentHeight = h;
+ for (uint32_t currentMipLevel = 0; currentMipLevel < mipLevels; currentMipLevel++) {
+ SkASSERT(0 == currentMipLevel || !srcData);
+ size_t currentRowBytes = bpp * currentWidth;
+ size_t bufferOffset = individualMipOffsets[currentMipLevel];
+ if (!copy_testing_data(this, srcData, bufferAlloc, bufferOffset,
+ currentRowBytes, currentRowBytes, currentHeight)) {
+ GrVkMemory::FreeImageMemory(this, false, alloc);
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
+ GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
+ VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+ VK_CALL(EndCommandBuffer(cmdBuffer));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
+ return 0;
+ }
+ currentWidth = SkTMax(1, currentWidth/2);
+ currentHeight = SkTMax(1, currentHeight/2);
}
- VkCommandBufferBeginInfo cmdBufferBeginInfo;
- memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
- cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdBufferBeginInfo.pNext = nullptr;
- cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- cmdBufferBeginInfo.pInheritanceInfo = nullptr;
-
- err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
- SkASSERT(!err);
-
// Set image layout and add barrier
VkImageMemoryBarrier barrier;
memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
@@ -1347,11 +1388,12 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
barrier.pNext = nullptr;
barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ barrier.oldLayout = initialLayout;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
- barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1};
+ barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0 , 1};
VK_CALL(CmdPipelineBarrier(cmdBuffer,
GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
@@ -1362,70 +1404,102 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
1, &barrier));
initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- // Submit copy command
- VkBufferImageCopy region;
- memset(&region, 0, sizeof(VkBufferImageCopy));
- region.bufferOffset = 0;
- region.bufferRowLength = w;
- region.bufferImageHeight = h;
- region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- region.imageOffset = { 0, 0, 0 };
- region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 };
-
- VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, 1, &region));
-
- // End CommandBuffer
- err = VK_CALL(EndCommandBuffer(cmdBuffer));
- SkASSERT(!err);
-
- // Create Fence for queue
- VkFence fence;
- VkFenceCreateInfo fenceInfo;
- memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
- fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-
- err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
- SkASSERT(!err);
-
- VkSubmitInfo submitInfo;
- memset(&submitInfo, 0, sizeof(VkSubmitInfo));
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.pWaitDstStageMask = 0;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &cmdBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
- SkASSERT(!err);
-
- err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
- if (VK_TIMEOUT == err) {
- GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
- VK_CALL(DestroyImage(fDevice, image, nullptr));
- GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
- VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
- VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
- VK_CALL(DestroyFence(fDevice, fence, nullptr));
- SkDebugf("Fence failed to signal: %d\n", err);
- SK_ABORT("failing");
+ SkTArray<VkBufferImageCopy> regions(mipLevels);
+
+ currentWidth = w;
+ currentHeight = h;
+ for (uint32_t currentMipLevel = 0; currentMipLevel < mipLevels; currentMipLevel++) {
+ // Submit copy command
+ VkBufferImageCopy& region = regions.push_back();
+ memset(&region, 0, sizeof(VkBufferImageCopy));
+ region.bufferOffset = individualMipOffsets[currentMipLevel];
+ region.bufferRowLength = currentWidth;
+ region.bufferImageHeight = currentHeight;
+ region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
+ region.imageOffset = { 0, 0, 0 };
+ region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 };
+ currentWidth = SkTMax(1, currentWidth/2);
+ currentHeight = SkTMax(1, currentHeight/2);
}
- SkASSERT(!err);
- // Clean up transfer resources
+ VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, regions.count(),
+ regions.begin()));
+ }
+ // Change Image layout to shader read since if we use this texture as a borrowed textures within
+ // Ganesh we require that its layout be set to that
+ VkImageMemoryBarrier barrier;
+ memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ barrier.oldLayout = initialLayout;
+ barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image;
+ barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0 , 1};
+
+ VK_CALL(CmdPipelineBarrier(cmdBuffer,
+ GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
+ VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+ 0,
+ 0, nullptr,
+ 0, nullptr,
+ 1, &barrier));
+
+ // End CommandBuffer
+ err = VK_CALL(EndCommandBuffer(cmdBuffer));
+ SkASSERT(!err);
+
+ // Create Fence for queue
+ VkFence fence;
+ VkFenceCreateInfo fenceInfo;
+ memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
+ fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+
+ err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
+ SkASSERT(!err);
+
+ VkSubmitInfo submitInfo;
+ memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = 0;
+ submitInfo.pWaitSemaphores = nullptr;
+ submitInfo.pWaitDstStageMask = 0;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &cmdBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
+ SkASSERT(!err);
+
+ err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
+ if (VK_TIMEOUT == err) {
+ GrVkMemory::FreeImageMemory(this, false, alloc);
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
VK_CALL(DestroyFence(fDevice, fence, nullptr));
+ SkDebugf("Fence failed to signal: %d\n", err);
+ SK_ABORT("failing");
}
+ SkASSERT(!err);
+
+ // Clean up transfer resources
+ GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
+ VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
+ VK_CALL(DestroyFence(fDevice, fence, nullptr));
+
GrVkImageInfo* info = new GrVkImageInfo;
info->fImage = image;
info->fAlloc = alloc;
info->fImageTiling = imageTiling;
- info->fImageLayout = initialLayout;
+ info->fImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
info->fFormat = pixelFormat;
info->fLevelCount = mipLevels;