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

Unified Diff: src/gpu/vk/GrVkGpu.cpp

Issue 2242553002: Allow vulkan to upload data to testing textures with optimal layouts (Closed) Base URL: https://skia.googlesource.com/skia.git@yuv
Patch Set: fix cast Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/imagefromyuvtextures.cpp ('k') | src/gpu/vk/GrVkImage.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/vk/GrVkGpu.cpp
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 85bfce87679c696ba720e6ff84f6747a5207b6d2..55fb533a53237797bc56af5e38b6d4e3d4e46b24 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -949,6 +949,31 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen
////////////////////////////////////////////////////////////////////////////////
+bool copy_testing_data(GrVkGpu* gpu, void* srcData, GrVkAlloc* alloc,
+ size_t srcRowBytes, size_t dstRowBytes, int h) {
+ void* mapPtr;
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(),
+ alloc->fMemory,
+ alloc->fOffset,
+ dstRowBytes * h,
+ 0,
+ &mapPtr));
+ if (err) {
+ return false;
+ }
+
+ // If there is no padding on dst we can do a single memcopy.
+ // This assumes the srcData comes in with no padding.
+ if (srcRowBytes == dstRowBytes) {
+ memcpy(mapPtr, srcData, srcRowBytes * h);
+ } else {
+ SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes), srcData, srcRowBytes,
+ srcRowBytes, h);
+ }
+ GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc->fMemory));
+ return true;
+}
+
GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h,
GrPixelConfig config,
bool isRenderTarget) {
@@ -972,11 +997,6 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
linearTiling = true;
}
- // Currently this is not supported since it requires a copy which has not yet been implemented.
- if (srcData && !linearTiling) {
- return 0;
- }
-
VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
@@ -1024,6 +1044,8 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
}
if (srcData) {
+ size_t bpp = GrBytesPerPixel(config);
+ size_t rowCopyBytes = bpp * w;
if (linearTiling) {
const VkImageSubresource subres = {
VK_IMAGE_ASPECT_COLOR_BIT,
@@ -1031,33 +1053,181 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
0, // arraySlice
};
VkSubresourceLayout layout;
- VkResult err;
VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout));
- void* mapPtr;
- err = VK_CALL(MapMemory(fDevice, alloc.fMemory, alloc.fOffset, layout.rowPitch * h,
- 0, &mapPtr));
+ if (!copy_testing_data(this, srcData, &alloc, rowCopyBytes, layout.rowPitch, h)) {
+ GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
+ return 0;
+ }
+ } else {
+ SkASSERT(w && h);
+
+ VkBuffer buffer;
+ VkBufferCreateInfo bufInfo;
+ memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
+ bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ bufInfo.flags = 0;
+ bufInfo.size = rowCopyBytes * h;
+ 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);
- VK_CALL(DestroyImage(this->device(), image, nullptr));
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
return 0;
}
- size_t bpp = GrBytesPerPixel(config);
- size_t rowCopyBytes = bpp * w;
- // If there is no padding on dst (layout.rowPitch) we can do a single memcopy.
- // This assumes the srcData comes in with no padding.
- if (rowCopyBytes == layout.rowPitch) {
- memcpy(mapPtr, srcData, rowCopyBytes * h);
- } else {
- SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcData, rowCopyBytes,
- rowCopyBytes, h);
+ GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0 };
+ if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type,
+ true, &bufferAlloc)) {
+ GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
+ VK_CALL(DestroyImage(fDevice, image, nullptr));
+ VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+ return 0;
}
- VK_CALL(UnmapMemory(fDevice, alloc.fMemory));
- } else {
- // TODO: Add support for copying to optimal tiling
- SkASSERT(false);
+
+ 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
+ NULL, // 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;
+ }
+
+ 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));
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ 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};
+
+ VK_CALL(CmdPipelineBarrier(cmdBuffer,
+ GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0,
+ 0, nullptr,
+ 0, nullptr,
+ 1, &barrier));
+ initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+
+ // Make sure buffer has finished the unmap
+ VkBufferMemoryBarrier bufBarrier;
+ memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
+ bufBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+ bufBarrier.pNext = nullptr;
+ bufBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+ bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ bufBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ bufBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ bufBarrier.buffer = buffer;
+ bufBarrier.offset = 0;
+ bufBarrier.size = bufInfo.size;
+
+ VK_CALL(CmdPipelineBarrier(cmdBuffer,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0,
+ 0, nullptr,
+ 1, &bufBarrier,
+ 0, nullptr));
+
+ // Submit copy command
+ VkBufferImageCopy region;
+ memset(&region, 0, sizeof(VkBufferImageCopy));
+ region.bufferOffset = 0;
+ region.bufferRowLength = (uint32_t)rowCopyBytes;
+ 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);
+ SkFAIL("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));
}
}
« no previous file with comments | « gm/imagefromyuvtextures.cpp ('k') | src/gpu/vk/GrVkImage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698