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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « gm/imagefromyuvtextures.cpp ('k') | src/gpu/vk/GrVkImage.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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 width, 942 width,
943 height, 943 height,
944 samples, 944 samples,
945 sFmt)); 945 sFmt));
946 fStats.incStencilAttachmentCreates(); 946 fStats.incStencilAttachmentCreates();
947 return stencil; 947 return stencil;
948 } 948 }
949 949
950 //////////////////////////////////////////////////////////////////////////////// 950 ////////////////////////////////////////////////////////////////////////////////
951 951
952 bool copy_testing_data(GrVkGpu* gpu, void* srcData, GrVkAlloc* alloc,
953 size_t srcRowBytes, size_t dstRowBytes, int h) {
954 void* mapPtr;
955 VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(),
956 alloc->fMemory,
957 alloc->fOffset,
958 dstRowBytes * h,
959 0,
960 &mapPtr));
961 if (err) {
962 return false;
963 }
964
965 // If there is no padding on dst we can do a single memcopy.
966 // This assumes the srcData comes in with no padding.
967 if (srcRowBytes == dstRowBytes) {
968 memcpy(mapPtr, srcData, srcRowBytes * h);
969 } else {
970 SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes), srcData, srcRowBy tes,
971 srcRowBytes, h);
972 }
973 GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc->fMemory));
974 return true;
975 }
976
952 GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i nt h, 977 GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i nt h,
953 GrPixelConfig config, 978 GrPixelConfig config,
954 bool isRenderTarget) { 979 bool isRenderTarget) {
955 980
956 VkFormat pixelFormat; 981 VkFormat pixelFormat;
957 if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 982 if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
958 return 0; 983 return 0;
959 } 984 }
960 985
961 bool linearTiling = false; 986 bool linearTiling = false;
962 if (!fVkCaps->isConfigTexturable(config)) { 987 if (!fVkCaps->isConfigTexturable(config)) {
963 return 0; 988 return 0;
964 } 989 }
965 990
966 if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) { 991 if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) {
967 return 0; 992 return 0;
968 } 993 }
969 994
970 if (fVkCaps->isConfigTexurableLinearly(config) && 995 if (fVkCaps->isConfigTexurableLinearly(config) &&
971 (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) { 996 (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) {
972 linearTiling = true; 997 linearTiling = true;
973 } 998 }
974 999
975 // Currently this is not supported since it requires a copy which has not ye t been implemented.
976 if (srcData && !linearTiling) {
977 return 0;
978 }
979
980 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 1000 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
981 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1001 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
982 usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 1002 usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
983 if (isRenderTarget) { 1003 if (isRenderTarget) {
984 usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1004 usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
985 } 1005 }
986 1006
987 VkImage image = VK_NULL_HANDLE; 1007 VkImage image = VK_NULL_HANDLE;
988 GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0 }; 1008 GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0 };
989 1009
(...skipping 27 matching lines...) Expand all
1017 }; 1037 };
1018 1038
1019 GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageC reateInfo, nullptr, &image)); 1039 GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageC reateInfo, nullptr, &image));
1020 1040
1021 if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) { 1041 if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) {
1022 VK_CALL(DestroyImage(this->device(), image, nullptr)); 1042 VK_CALL(DestroyImage(this->device(), image, nullptr));
1023 return 0; 1043 return 0;
1024 } 1044 }
1025 1045
1026 if (srcData) { 1046 if (srcData) {
1047 size_t bpp = GrBytesPerPixel(config);
1048 size_t rowCopyBytes = bpp * w;
1027 if (linearTiling) { 1049 if (linearTiling) {
1028 const VkImageSubresource subres = { 1050 const VkImageSubresource subres = {
1029 VK_IMAGE_ASPECT_COLOR_BIT, 1051 VK_IMAGE_ASPECT_COLOR_BIT,
1030 0, // mipLevel 1052 0, // mipLevel
1031 0, // arraySlice 1053 0, // arraySlice
1032 }; 1054 };
1033 VkSubresourceLayout layout; 1055 VkSubresourceLayout layout;
1034 VkResult err;
1035 1056
1036 VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout)) ; 1057 VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout)) ;
1037 1058
1038 void* mapPtr; 1059 if (!copy_testing_data(this, srcData, &alloc, rowCopyBytes, layout.r owPitch, h)) {
1039 err = VK_CALL(MapMemory(fDevice, alloc.fMemory, alloc.fOffset, layou t.rowPitch * h, 1060 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1040 0, &mapPtr)); 1061 VK_CALL(DestroyImage(fDevice, image, nullptr));
1062 return 0;
1063 }
1064 } else {
1065 SkASSERT(w && h);
1066
1067 VkBuffer buffer;
1068 VkBufferCreateInfo bufInfo;
1069 memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
1070 bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1071 bufInfo.flags = 0;
1072 bufInfo.size = rowCopyBytes * h;
1073 bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1074 bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1075 bufInfo.queueFamilyIndexCount = 0;
1076 bufInfo.pQueueFamilyIndices = nullptr;
1077 VkResult err;
1078 err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer));
1079
1041 if (err) { 1080 if (err) {
1042 GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 1081 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1043 VK_CALL(DestroyImage(this->device(), image, nullptr)); 1082 VK_CALL(DestroyImage(fDevice, image, nullptr));
1044 return 0; 1083 return 0;
1045 } 1084 }
1046 1085
1047 size_t bpp = GrBytesPerPixel(config); 1086 GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0 };
1048 size_t rowCopyBytes = bpp * w; 1087 if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer:: kCopyRead_Type,
1049 // If there is no padding on dst (layout.rowPitch) we can do a singl e memcopy. 1088 true, &bufferAlloc)) {
1050 // This assumes the srcData comes in with no padding. 1089 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1051 if (rowCopyBytes == layout.rowPitch) { 1090 VK_CALL(DestroyImage(fDevice, image, nullptr));
1052 memcpy(mapPtr, srcData, rowCopyBytes * h); 1091 VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
1053 } else { 1092 return 0;
1054 SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcDa ta, rowCopyBytes,
1055 rowCopyBytes, h);
1056 } 1093 }
1057 VK_CALL(UnmapMemory(fDevice, alloc.fMemory)); 1094
1058 } else { 1095 if (!copy_testing_data(this, srcData, &bufferAlloc, rowCopyBytes, ro wCopyBytes, h)) {
1059 // TODO: Add support for copying to optimal tiling 1096 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1060 SkASSERT(false); 1097 VK_CALL(DestroyImage(fDevice, image, nullptr));
1098 GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, b ufferAlloc);
1099 VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
1100 return 0;
1101 }
1102
1103 const VkCommandBufferAllocateInfo cmdInfo = {
1104 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
1105 NULL, // pNext
1106 fCmdPool, // commandPool
1107 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1108 1 // bufferCount
1109 };
1110
1111 VkCommandBuffer cmdBuffer;
1112 err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer)) ;
1113 if (err) {
1114 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1115 VK_CALL(DestroyImage(fDevice, image, nullptr));
1116 GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, b ufferAlloc);
1117 VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
1118 return 0;
1119 }
1120
1121 VkCommandBufferBeginInfo cmdBufferBeginInfo;
1122 memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
1123 cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_IN FO;
1124 cmdBufferBeginInfo.pNext = nullptr;
1125 cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_B IT;
1126 cmdBufferBeginInfo.pInheritanceInfo = nullptr;
1127
1128 err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
1129 SkASSERT(!err);
1130
1131 // Set image layout and add barrier
1132 VkImageMemoryBarrier barrier;
1133 memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
1134 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1135 barrier.pNext = nullptr;
1136 barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLay out);
1137 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1138 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1139 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1140 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1141 barrier.image = image;
1142 barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1} ;
1143
1144 VK_CALL(CmdPipelineBarrier(cmdBuffer,
1145 GrVkMemory::LayoutToPipelineStageFlags(in itialLayout),
1146 VK_PIPELINE_STAGE_TRANSFER_BIT,
1147 0,
1148 0, nullptr,
1149 0, nullptr,
1150 1, &barrier));
1151 initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1152
1153 // Make sure buffer has finished the unmap
1154 VkBufferMemoryBarrier bufBarrier;
1155 memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
1156 bufBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
1157 bufBarrier.pNext = nullptr;
1158 bufBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
1159 bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1160 bufBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1161 bufBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1162 bufBarrier.buffer = buffer;
1163 bufBarrier.offset = 0;
1164 bufBarrier.size = bufInfo.size;
1165
1166 VK_CALL(CmdPipelineBarrier(cmdBuffer,
1167 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1168 VK_PIPELINE_STAGE_TRANSFER_BIT,
1169 0,
1170 0, nullptr,
1171 1, &bufBarrier,
1172 0, nullptr));
1173
1174 // Submit copy command
1175 VkBufferImageCopy region;
1176 memset(&region, 0, sizeof(VkBufferImageCopy));
1177 region.bufferOffset = 0;
1178 region.bufferRowLength = (uint32_t)rowCopyBytes;
1179 region.bufferImageHeight = h;
1180 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1181 region.imageOffset = { 0, 0, 0 };
1182 region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 };
1183
1184 VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout , 1, &region));
1185
1186 // End CommandBuffer
1187 err = VK_CALL(EndCommandBuffer(cmdBuffer));
1188 SkASSERT(!err);
1189
1190 // Create Fence for queue
1191 VkFence fence;
1192 VkFenceCreateInfo fenceInfo;
1193 memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
1194 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1195
1196 err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
1197 SkASSERT(!err);
1198
1199 VkSubmitInfo submitInfo;
1200 memset(&submitInfo, 0, sizeof(VkSubmitInfo));
1201 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1202 submitInfo.pNext = nullptr;
1203 submitInfo.waitSemaphoreCount = 0;
1204 submitInfo.pWaitSemaphores = nullptr;
1205 submitInfo.pWaitDstStageMask = 0;
1206 submitInfo.commandBufferCount = 1;
1207 submitInfo.pCommandBuffers = &cmdBuffer;
1208 submitInfo.signalSemaphoreCount = 0;
1209 submitInfo.pSignalSemaphores = nullptr;
1210 err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
1211 SkASSERT(!err);
1212
1213 err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
1214 if (VK_TIMEOUT == err) {
1215 GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
1216 VK_CALL(DestroyImage(fDevice, image, nullptr));
1217 GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, b ufferAlloc);
1218 VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
1219 VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
1220 VK_CALL(DestroyFence(fDevice, fence, nullptr));
1221 SkDebugf("Fence failed to signal: %d\n", err);
1222 SkFAIL("failing");
1223 }
1224 SkASSERT(!err);
1225
1226 // Clean up transfer resources
1227 GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, buffe rAlloc);
1228 VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
1229 VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
1230 VK_CALL(DestroyFence(fDevice, fence, nullptr));
1061 } 1231 }
1062 } 1232 }
1063 1233
1064 GrVkImageInfo* info = new GrVkImageInfo; 1234 GrVkImageInfo* info = new GrVkImageInfo;
1065 info->fImage = image; 1235 info->fImage = image;
1066 info->fAlloc = alloc; 1236 info->fAlloc = alloc;
1067 info->fImageTiling = imageTiling; 1237 info->fImageTiling = imageTiling;
1068 info->fImageLayout = initialLayout; 1238 info->fImageLayout = initialLayout;
1069 info->fFormat = pixelFormat; 1239 info->fFormat = pixelFormat;
1070 info->fLevelCount = 1; 1240 info->fLevelCount = 1;
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 } 1772 }
1603 1773
1604 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment 1774 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment
1605 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment 1775 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment
1606 // which is always at the first attachment. 1776 // which is always at the first attachment.
1607 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); 1777 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true);
1608 fCurrentCmdBuffer->executeCommands(this, buffer); 1778 fCurrentCmdBuffer->executeCommands(this, buffer);
1609 fCurrentCmdBuffer->endRenderPass(this); 1779 fCurrentCmdBuffer->endRenderPass(this);
1610 } 1780 }
1611 1781
OLDNEW
« 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