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

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

Issue 2078483002: Start using GrGpuCommandBuffer in GrDrawTarget. (Closed) Base URL: https://skia.googlesource.com/skia.git@memoryWAR
Patch Set: review nits Created 4 years, 6 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
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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 #ifdef ENABLE_VK_LAYERS 164 #ifdef ENABLE_VK_LAYERS
165 if (fCallback) { 165 if (fCallback) {
166 VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallb ack, nullptr)); 166 VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallb ack, nullptr));
167 fCallback = VK_NULL_HANDLE; 167 fCallback = VK_NULL_HANDLE;
168 } 168 }
169 #endif 169 #endif
170 } 170 }
171 171
172 /////////////////////////////////////////////////////////////////////////////// 172 ///////////////////////////////////////////////////////////////////////////////
173 173
174 GrGpuCommandBuffer* GrVkGpu::createCommandBuffer(const GrRenderTarget& target, 174 GrGpuCommandBuffer* GrVkGpu::createCommandBuffer(GrRenderTarget* target,
175 GrGpuCommandBuffer::LoadAndStor eOp colorOp, 175 GrGpuCommandBuffer::LoadAndStor eOp colorOp,
176 GrColor colorClear, 176 GrColor colorClear,
177 GrGpuCommandBuffer::LoadAndStor eOp stencilOp, 177 GrGpuCommandBuffer::LoadAndStor eOp stencilOp,
178 GrColor stencilClear) { 178 GrColor stencilClear) {
179 const GrVkRenderTarget& vkRT = static_cast<const GrVkRenderTarget&>(target); 179 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
180 return new GrVkGpuCommandBuffer(this, vkRT, colorOp, colorClear, stencilOp, stencilClear); 180 return new GrVkGpuCommandBuffer(this, vkRT, colorOp, colorClear, stencilOp, stencilClear);
181 } 181 }
182 182
183 void GrVkGpu::submitCommandBuffer(SyncQueue sync) { 183 void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
184 SkASSERT(fCurrentCmdBuffer); 184 SkASSERT(fCurrentCmdBuffer);
185 fCurrentCmdBuffer->end(this); 185 fCurrentCmdBuffer->end(this);
186 186
187 fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); 187 fCurrentCmdBuffer->submitToQueue(this, fQueue, sync);
188 fResourceProvider.checkCommandBuffers(); 188 fResourceProvider.checkCommandBuffers();
189 189
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 *tex, 809 *tex,
810 1, 810 1,
811 &blitRegion, 811 &blitRegion,
812 VK_FILTER_LINEAR); 812 VK_FILTER_LINEAR);
813 ++mipLevel; 813 ++mipLevel;
814 } 814 }
815 815
816 oldResource->unref(this); 816 oldResource->unref(this);
817 } 817 }
818 818
819
820 ////////////////////////////////////////////////////////////////////////////////
821
822 void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
823 const GrNonInstancedMesh& mesh) {
824 // There is no need to put any memory barriers to make sure host writes have finished here.
825 // When a command buffer is submitted to a queue, there is an implicit memor y barrier that
826 // occurs for all host writes. Additionally, BufferMemoryBarriers are not al lowed inside of
827 // an active RenderPass.
828 GrVkVertexBuffer* vbuf;
829 vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
830 SkASSERT(vbuf);
831 SkASSERT(!vbuf->isMapped());
832
833 fCurrentCmdBuffer->bindVertexBuffer(this, vbuf);
834
835 if (mesh.isIndexed()) {
836 GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
837 SkASSERT(ibuf);
838 SkASSERT(!ibuf->isMapped());
839
840 fCurrentCmdBuffer->bindIndexBuffer(this, ibuf);
841 }
842 }
843
844 //////////////////////////////////////////////////////////////////////////////// 819 ////////////////////////////////////////////////////////////////////////////////
845 820
846 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, 821 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt,
847 int width, 822 int width,
848 int height) { 823 int height) {
849 SkASSERT(width >= rt->width()); 824 SkASSERT(width >= rt->width());
850 SkASSERT(height >= rt->height()); 825 SkASSERT(height >= rt->height());
851 826
852 int samples = rt->numStencilSamples(); 827 int samples = rt->numStencilSamples();
853 828
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 subRange.levelCount = 1; 1052 subRange.levelCount = 1;
1078 subRange.baseArrayLayer = 0; 1053 subRange.baseArrayLayer = 0;
1079 subRange.layerCount = 1; 1054 subRange.layerCount = 1;
1080 1055
1081 // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a 1056 // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a
1082 // draw. Thus we should look into using the load op functions on the render pass to clear out 1057 // draw. Thus we should look into using the load op functions on the render pass to clear out
1083 // the stencil there. 1058 // the stencil there.
1084 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); 1059 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange);
1085 } 1060 }
1086 1061
1087 void GrVkGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo ol insideClip) {
1088 SkASSERT(target);
1089
1090 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
1091 GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
1092 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)sb;
1093
1094 // this should only be called internally when we know we have a
1095 // stencil buffer.
1096 SkASSERT(sb);
1097 int stencilBitCount = sb->bits();
1098
1099 // The contract with the callers does not guarantee that we preserve all bit s in the stencil
1100 // during this clear. Thus we will clear the entire stencil to the desired v alue.
1101
1102 VkClearDepthStencilValue vkStencilColor;
1103 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
1104 if (insideClip) {
1105 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
1106 } else {
1107 vkStencilColor.stencil = 0;
1108 }
1109
1110 vkStencil->setImageLayout(this,
1111 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1112 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1113 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1114 false);
1115
1116 // Change layout of our render target so it can be used as the color attachm ent. This is what
1117 // the render pass expects when it begins.
1118 vkRT->setImageLayout(this,
1119 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1120 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1121 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1122 false);
1123
1124 VkClearRect clearRect;
1125 // Flip rect if necessary
1126 SkIRect vkRect = rect;
1127
1128 if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
1129 vkRect.fTop = vkRT->height() - rect.fBottom;
1130 vkRect.fBottom = vkRT->height() - rect.fTop;
1131 }
1132
1133 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
1134 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height( ) };
1135
1136 clearRect.baseArrayLayer = 0;
1137 clearRect.layerCount = 1;
1138
1139 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
1140 SkASSERT(renderPass);
1141 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
1142
1143 uint32_t stencilIndex;
1144 SkAssertResult(renderPass->stencilAttachmentIndex(&stencilIndex));
1145
1146 VkClearAttachment attachment;
1147 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1148 attachment.colorAttachment = 0; // this value shouldn't matter
1149 attachment.clearValue.depthStencil = vkStencilColor;
1150
1151 fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect);
1152 fCurrentCmdBuffer->endRenderPass(this);
1153
1154 return;
1155 }
1156
1157 void GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color ) {
1158 // parent class should never let us get here with no RT
1159 SkASSERT(target);
1160
1161 VkClearColorValue vkColor;
1162 GrColorToRGBAFloat(color, vkColor.float32);
1163
1164 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
1165
1166 if (rect.width() != target->width() || rect.height() != target->height()) {
1167 vkRT->setImageLayout(this,
1168 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1169 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1170 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1171 false);
1172
1173 // If we are using a stencil attachment we also need to change its layou t to what the render
1174 // pass is expecting.
1175 if (GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAt tachment()) {
1176 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1177 vkStencil->setImageLayout(this,
1178 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_O PTIMAL,
1179 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_B IT |
1180 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BI T,
1181 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1182 false);
1183 }
1184
1185 VkClearRect clearRect;
1186 // Flip rect if necessary
1187 SkIRect vkRect = rect;
1188 if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) {
1189 vkRect.fTop = vkRT->height() - rect.fBottom;
1190 vkRect.fBottom = vkRT->height() - rect.fTop;
1191 }
1192 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
1193 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.hei ght() };
1194 clearRect.baseArrayLayer = 0;
1195 clearRect.layerCount = 1;
1196
1197 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
1198 SkASSERT(renderPass);
1199 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
1200
1201 uint32_t colorIndex;
1202 SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex));
1203
1204 VkClearAttachment attachment;
1205 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1206 attachment.colorAttachment = colorIndex;
1207 attachment.clearValue.color = vkColor;
1208
1209 fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect) ;
1210 fCurrentCmdBuffer->endRenderPass(this);
1211 return;
1212 }
1213
1214 vkRT->setImageLayout(this,
1215 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1216 VK_ACCESS_TRANSFER_WRITE_BIT,
1217 VK_PIPELINE_STAGE_TRANSFER_BIT,
1218 false);
1219
1220 VkImageSubresourceRange subRange;
1221 memset(&subRange, 0, sizeof(VkImageSubresourceRange));
1222 subRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1223 subRange.baseMipLevel = 0;
1224 subRange.levelCount = 1;
1225 subRange.baseArrayLayer = 0;
1226 subRange.layerCount = 1;
1227
1228 // In the future we may not actually be doing this type of clear at all. If we are inside a
1229 // render pass or doing a non full clear then we will use CmdClearColorAttac hment. The more
1230 // common use case will be clearing an attachment at the start of a render p ass, in which case
1231 // we will use the clear load ops.
1232 fCurrentCmdBuffer->clearColorImage(this,
1233 vkRT,
1234 &vkColor,
1235 1, &subRange);
1236 }
1237
1238 inline bool can_copy_image(const GrSurface* dst, 1062 inline bool can_copy_image(const GrSurface* dst,
1239 const GrSurface* src, 1063 const GrSurface* src,
1240 const GrVkGpu* gpu) { 1064 const GrVkGpu* gpu) {
1241 // Currently we don't support msaa 1065 // Currently we don't support msaa
1242 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || 1066 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) ||
1243 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) { 1067 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) {
1244 return false; 1068 return false;
1245 } 1069 }
1246 1070
1247 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src 1071 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 memcpy(top, bottom, tightRowBytes); 1401 memcpy(top, bottom, tightRowBytes);
1578 memcpy(bottom, tmpRow, tightRowBytes); 1402 memcpy(bottom, tmpRow, tightRowBytes);
1579 top += rowBytes; 1403 top += rowBytes;
1580 bottom -= rowBytes; 1404 bottom -= rowBytes;
1581 } 1405 }
1582 } 1406 }
1583 1407
1584 return true; 1408 return true;
1585 } 1409 }
1586 1410
1587 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer) { 1411 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer,
1412 const GrVkRenderPass* renderPass,
1413 GrVkRenderTarget* target,
1414 const SkIRect& bounds) {
1415 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *target, bounds, true);
1588 fCurrentCmdBuffer->executeCommands(this, buffer); 1416 fCurrentCmdBuffer->executeCommands(this, buffer);
1417 fCurrentCmdBuffer->endRenderPass(this);
1589 } 1418 }
1590 1419
1591 sk_sp<GrVkPipelineState> GrVkGpu::prepareDrawState(const GrPipeline& pipeline,
1592 const GrPrimitiveProcessor& p rimProc,
1593 GrPrimitiveType primitiveType ,
1594 const GrVkRenderPass& renderP ass) {
1595 sk_sp<GrVkPipelineState> pipelineState =
1596 fResourceProvider.findOrCreateCompatiblePipelineState(pipeline,
1597 primProc,
1598 primitiveType,
1599 renderPass);
1600 if (!pipelineState) {
1601 return pipelineState;
1602 }
1603
1604 pipelineState->setData(this, primProc, pipeline);
1605
1606 pipelineState->bind(this, fCurrentCmdBuffer);
1607
1608 GrVkPipeline::SetDynamicState(this, fCurrentCmdBuffer, pipeline);
1609
1610 return pipelineState;
1611 }
1612
1613 void GrVkGpu::onDraw(const GrPipeline& pipeline,
1614 const GrPrimitiveProcessor& primProc,
1615 const GrMesh* meshes,
1616 int meshCount) {
1617 if (!meshCount) {
1618 return;
1619 }
1620 GrRenderTarget* rt = pipeline.getRenderTarget();
1621 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
1622 const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
1623 SkASSERT(renderPass);
1624
1625 GrPrimitiveType primitiveType = meshes[0].primitiveType();
1626 sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
1627 primProc,
1628 primitiveTyp e,
1629 *renderPass) ;
1630 if (!pipelineState) {
1631 return;
1632 }
1633
1634 // Change layout of our render target so it can be used as the color attachm ent
1635 vkRT->setImageLayout(this,
1636 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1637 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1638 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1639 false);
1640
1641 // If we are using a stencil attachment we also need to update its layout
1642 if (GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttach ment()) {
1643 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1644 vkStencil->setImageLayout(this,
1645 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIM AL,
1646 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
1647 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1648 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1649 false);
1650 }
1651
1652 fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT);
1653
1654 for (int i = 0; i < meshCount; ++i) {
1655 const GrMesh& mesh = meshes[i];
1656 GrMesh::Iterator iter;
1657 const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
1658 do {
1659 if (nonIdxMesh->primitiveType() != primitiveType) {
1660 // Technically we don't have to call this here (since there is a safety check in
1661 // pipelineState:setData but this will allow for quicker freeing of resources if the
1662 // pipelineState sits in a cache for a while.
1663 pipelineState->freeTempResources(this);
1664 SkDEBUGCODE(pipelineState = nullptr);
1665 primitiveType = nonIdxMesh->primitiveType();
1666 pipelineState = this->prepareDrawState(pipeline,
1667 primProc,
1668 primitiveType,
1669 *renderPass);
1670 if (!pipelineState) {
1671 return;
1672 }
1673 }
1674 SkASSERT(pipelineState);
1675 this->bindGeometry(primProc, *nonIdxMesh);
1676
1677 if (nonIdxMesh->isIndexed()) {
1678 fCurrentCmdBuffer->drawIndexed(this,
1679 nonIdxMesh->indexCount(),
1680 1,
1681 nonIdxMesh->startIndex(),
1682 nonIdxMesh->startVertex(),
1683 0);
1684 } else {
1685 fCurrentCmdBuffer->draw(this,
1686 nonIdxMesh->vertexCount(),
1687 1,
1688 nonIdxMesh->startVertex(),
1689 0);
1690 }
1691
1692 fStats.incNumDraws();
1693 } while ((nonIdxMesh = iter.next()));
1694 }
1695
1696 fCurrentCmdBuffer->endRenderPass(this);
1697
1698 // Technically we don't have to call this here (since there is a safety chec k in
1699 // pipelineState:setData but this will allow for quicker freeing of resource s if the
1700 // pipelineState sits in a cache for a while.
1701 pipelineState->freeTempResources(this);
1702
1703 #if SWAP_PER_DRAW
1704 glFlush();
1705 #if defined(SK_BUILD_FOR_MAC)
1706 aglSwapBuffers(aglGetCurrentContext());
1707 int set_a_break_pt_here = 9;
1708 aglSwapBuffers(aglGetCurrentContext());
1709 #elif defined(SK_BUILD_FOR_WIN32)
1710 SwapBuf();
1711 int set_a_break_pt_here = 9;
1712 SwapBuf();
1713 #endif
1714 #endif
1715 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698