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

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

Powered by Google App Engine
This is Rietveld 408576698