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

Side by Side Diff: src/gpu/vk/GrVkGpu.cpp

Issue 1755753002: Implement various vulkan stencil clears and fix various stenciling bugs. (Closed) Base URL: https://skia.googlesource.com/skia.git@stencilImage
Patch Set: Review Nits Created 4 years, 9 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 | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkPipeline.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 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 imageDesc.fLevels = 1; 513 imageDesc.fLevels = 1;
514 imageDesc.fSamples = 1; 514 imageDesc.fSamples = 1;
515 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI LING_OPTIMAL; 515 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI LING_OPTIMAL;
516 imageDesc.fUsageFlags = usageFlags; 516 imageDesc.fUsageFlags = usageFlags;
517 imageDesc.fMemProps = memProps; 517 imageDesc.fMemProps = memProps;
518 518
519 GrVkTexture* tex; 519 GrVkTexture* tex;
520 if (renderTarget) { 520 if (renderTarget) {
521 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc, lifeCycle, 521 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc, lifeCycle,
522 imageDesc); 522 imageDesc);
523 #if 0
524 // This clear can be included to fix warning described in htttps://bugs. skia.org/5045
525 // Obviously we do not want to be clearling needlessly every time we cre ate a render target.
526 SkIRect rect = SkIRect::MakeWH(tex->width(), tex->height());
527 this->clear(rect, GrColor_TRANSPARENT_BLACK, tex->asRenderTarget());
528 #endif
523 } else { 529 } else {
524 tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc); 530 tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc);
525 } 531 }
526 532
527 if (!tex) { 533 if (!tex) {
528 return nullptr; 534 return nullptr;
529 } 535 }
530 536
531 if (srcData) { 537 if (srcData) {
532 if (!this->uploadTexData(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fCon fig, srcData, 538 if (!this->uploadTexData(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fCon fig, srcData,
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 byRegion, 881 byRegion,
876 GrVkCommandBuffer::kImageMemory_BarrierTy pe, 882 GrVkCommandBuffer::kImageMemory_BarrierTy pe,
877 barrier); 883 barrier);
878 } 884 }
879 885
880 void GrVkGpu::finishDrawTarget() { 886 void GrVkGpu::finishDrawTarget() {
881 // Submit the current command buffer to the Queue 887 // Submit the current command buffer to the Queue
882 this->submitCommandBuffer(kSkip_SyncQueue); 888 this->submitCommandBuffer(kSkip_SyncQueue);
883 } 889 }
884 890
891 void GrVkGpu::clearStencil(GrRenderTarget* target) {
892 if (nullptr == target) {
893 return;
894 }
895 GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachme nt();
896 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
897
898
899 VkClearDepthStencilValue vkStencilColor;
900 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
901
902 VkImageLayout origDstLayout = vkStencil->currentLayout();
903
904 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(o rigDstLayout);
905 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
906
907 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayou t);;
908 VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
909
910 vkStencil->setImageLayout(this,
911 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
912 srcAccessMask,
913 dstAccessMask,
914 srcStageMask,
915 dstStageMask,
916 false);
917
918
919 VkImageSubresourceRange subRange;
920 memset(&subRange, 0, sizeof(VkImageSubresourceRange));
921 subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
922 subRange.baseMipLevel = 0;
923 subRange.levelCount = 1;
924 subRange.baseArrayLayer = 0;
925 subRange.layerCount = 1;
926
927 // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a
928 // draw. Thus we should look into using the load op functions on the render pass to clear out
929 // the stencil there.
930 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange);
931 }
932
933 void GrVkGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo ol insideClip) {
934 SkASSERT(target);
935
936 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
937 GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
938 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)sb;
939
940 // this should only be called internally when we know we have a
941 // stencil buffer.
942 SkASSERT(sb);
943 int stencilBitCount = sb->bits();
944
945 // The contract with the callers does not guarantee that we preserve all bit s in the stencil
946 // during this clear. Thus we will clear the entire stencil to the desired v alue.
947
948 VkClearDepthStencilValue vkStencilColor;
949 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
950 if (insideClip) {
951 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
952 } else {
953 vkStencilColor.stencil = 0;
954 }
955
956 VkImageLayout origDstLayout = vkStencil->currentLayout();
957 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayou t);
958 VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
959 VkPipelineStageFlags srcStageMask =
960 GrVkMemory::LayoutToPipelineStageFlags(origDstLayout);
961 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
962 vkStencil->setImageLayout(this,
963 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
964 srcAccessMask,
965 dstAccessMask,
966 srcStageMask,
967 dstStageMask,
968 false);
969
970 VkClearRect clearRect;
971 // Flip rect if necessary
972 SkIRect vkRect = rect;
973
974 if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
975 vkRect.fTop = vkRT->height() - rect.fBottom;
976 vkRect.fBottom = vkRT->height() - rect.fTop;
977 }
978
979 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
980 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height( ) };
981
982 clearRect.baseArrayLayer = 0;
983 clearRect.layerCount = 1;
984
985 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
986 SkASSERT(renderPass);
987 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
988
989 uint32_t stencilIndex;
990 SkAssertResult(renderPass->stencilAttachmentIndex(&stencilIndex));
991
992 VkClearAttachment attachment;
993 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
994 attachment.colorAttachment = 0; // this value shouldn't matter
995 attachment.clearValue.depthStencil = vkStencilColor;
996
997 fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect);
998 fCurrentCmdBuffer->endRenderPass(this);
999
1000 return;
1001 }
1002
885 void GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color ) { 1003 void GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color ) {
886 // parent class should never let us get here with no RT 1004 // parent class should never let us get here with no RT
887 SkASSERT(target); 1005 SkASSERT(target);
888 1006
889 VkClearColorValue vkColor; 1007 VkClearColorValue vkColor;
890 GrColorToRGBAFloat(color, vkColor.float32); 1008 GrColorToRGBAFloat(color, vkColor.float32);
891 1009
892 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); 1010 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
893 VkImageLayout origDstLayout = vkRT->currentLayout(); 1011 VkImageLayout origDstLayout = vkRT->currentLayout();
894 1012
895 if (rect.width() != target->width() || rect.height() != target->height()) { 1013 if (rect.width() != target->width() || rect.height() != target->height()) {
896 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstL ayout); 1014 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstL ayout);
897 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1015 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
898 VkPipelineStageFlags srcStageMask = 1016 VkPipelineStageFlags srcStageMask =
899 GrVkMemory::LayoutToPipelineStageFlags(vkRT->currentLayout()); 1017 GrVkMemory::LayoutToPipelineStageFlags(origDstLayout);
900 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1018 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
901 vkRT->setImageLayout(this, 1019 vkRT->setImageLayout(this,
902 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1020 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
903 srcAccessMask, 1021 srcAccessMask,
904 dstAccessMask, 1022 dstAccessMask,
905 srcStageMask, 1023 srcStageMask,
906 dstStageMask, 1024 dstStageMask,
907 false); 1025 false);
908 1026
909 VkClearRect clearRect; 1027 VkClearRect clearRect;
910 clearRect.rect.offset = { rect.fLeft, rect.fTop }; 1028 // Flip rect if necessary
911 clearRect.rect.extent = { (uint32_t)rect.width(), (uint32_t)rect.height( ) }; 1029 SkIRect vkRect = rect;
912 clearRect.baseArrayLayer = 0; 1030 if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
913 clearRect.layerCount = 1; 1031 vkRect.fTop = vkRT->height() - rect.fBottom;
914 1032 vkRect.fBottom = vkRT->height() - rect.fTop;
915 1033 }
1034 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
1035 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.hei ght() };
916 1036
917 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 1037 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
918 SkASSERT(renderPass); 1038 SkASSERT(renderPass);
919 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 1039 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
920 1040
921 uint32_t colorIndex; 1041 uint32_t colorIndex;
922 SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex)); 1042 SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex));
923 1043
924 VkClearAttachment attachment; 1044 VkClearAttachment attachment;
925 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1045 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 1314
1195 return true; 1315 return true;
1196 } 1316 }
1197 1317
1198 void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice s) { 1318 void GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice s) {
1199 GrRenderTarget* rt = args.fPipeline->getRenderTarget(); 1319 GrRenderTarget* rt = args.fPipeline->getRenderTarget();
1200 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); 1320 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
1201 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 1321 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
1202 SkASSERT(renderPass); 1322 SkASSERT(renderPass);
1203 1323
1204
1205 GrVkProgram* program = GrVkProgramBuilder::CreateProgram(this, args, 1324 GrVkProgram* program = GrVkProgramBuilder::CreateProgram(this, args,
1206 vertices.primitiveT ype(), 1325 vertices.primitiveT ype(),
1207 *renderPass); 1326 *renderPass);
1208 1327
1209 if (!program) { 1328 if (!program) {
1210 return; 1329 return;
1211 } 1330 }
1212 1331
1213 program->setData(this, *args.fPrimitiveProcessor, *args.fPipeline); 1332 program->setData(this, *args.fPrimitiveProcessor, *args.fPipeline);
1214 1333
(...skipping 12 matching lines...) Expand all
1227 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1346 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout);
1228 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1347 VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1229 vkRT->setImageLayout(this, 1348 vkRT->setImageLayout(this,
1230 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1349 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1231 srcAccessMask, 1350 srcAccessMask,
1232 dstAccessMask, 1351 dstAccessMask,
1233 srcStageMask, 1352 srcStageMask,
1234 dstStageMask, 1353 dstStageMask,
1235 false); 1354 false);
1236 1355
1356 // If we are using a stencil attachment we also need to update its layout
1357 if (!args.fPipeline->getStencil().isDisabled()) {
1358 GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttach ment();
1359 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1360 VkImageLayout origDstLayout = vkStencil->currentLayout();
1361 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstL ayout);
1362 VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_B IT |
1363 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BI T;
1364 VkPipelineStageFlags srcStageMask =
1365 GrVkMemory::LayoutToPipelineStageFlags(origDstLayout);
1366 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1367 vkStencil->setImageLayout(this,
1368 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIM AL,
1369 srcAccessMask,
1370 dstAccessMask,
1371 srcStageMask,
1372 dstStageMask,
1373 false);
1374 }
1375
1237 if (vertices.isIndexed()) { 1376 if (vertices.isIndexed()) {
1238 fCurrentCmdBuffer->drawIndexed(this, 1377 fCurrentCmdBuffer->drawIndexed(this,
1239 vertices.indexCount(), 1378 vertices.indexCount(),
1240 1, 1379 1,
1241 vertices.startIndex(), 1380 vertices.startIndex(),
1242 vertices.startVertex(), 1381 vertices.startVertex(),
1243 0); 1382 0);
1244 } else { 1383 } else {
1245 fCurrentCmdBuffer->draw(this, vertices.vertexCount(), 1, vertices.startV ertex(), 0); 1384 fCurrentCmdBuffer->draw(this, vertices.vertexCount(), 1, vertices.startV ertex(), 0);
1246 } 1385 }
(...skipping 16 matching lines...) Expand all
1263 int set_a_break_pt_here = 9; 1402 int set_a_break_pt_here = 9;
1264 aglSwapBuffers(aglGetCurrentContext()); 1403 aglSwapBuffers(aglGetCurrentContext());
1265 #elif defined(SK_BUILD_FOR_WIN32) 1404 #elif defined(SK_BUILD_FOR_WIN32)
1266 SwapBuf(); 1405 SwapBuf();
1267 int set_a_break_pt_here = 9; 1406 int set_a_break_pt_here = 9;
1268 SwapBuf(); 1407 SwapBuf();
1269 #endif 1408 #endif
1270 #endif 1409 #endif
1271 } 1410 }
1272 1411
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkPipeline.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698