Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 // must call this after creating the CommandPool | 130 // must call this after creating the CommandPool |
| 131 fResourceProvider.init(); | 131 fResourceProvider.init(); |
| 132 fCurrentCmdBuffer = fResourceProvider.createPrimaryCommandBuffer(); | 132 fCurrentCmdBuffer = fResourceProvider.createPrimaryCommandBuffer(); |
| 133 SkASSERT(fCurrentCmdBuffer); | 133 SkASSERT(fCurrentCmdBuffer); |
| 134 fCurrentCmdBuffer->begin(this); | 134 fCurrentCmdBuffer->begin(this); |
| 135 | 135 |
| 136 // set up our heaps | 136 // set up our heaps |
| 137 fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strat egy, 16*1024*1024)); | 137 fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strat egy, 16*1024*1024)); |
| 138 // We want the OptimalImage_Heap to use a SubAlloc_strategy but it occasiona lly causes the | 138 // We want the OptimalImage_Heap to use a SubAlloc_strategy but it occasiona lly causes the |
| 139 // device to run out of memory. Most likely this is caused by fragmentation in the device heap | 139 // device to run out of memory. Most likely this is caused by fragmentation in the device heap |
| 140 // and we can't allocate more. Until we get a fix moving this to SingleAlloc . | 140 // and we can't allocate more. Until we get a fix moving this to SingleAlloc . |
|
bsalomon
2016/06/22 15:41:15
I think this is from your other CL
egdaniel
2016/06/22 21:13:36
Yes it is only showing up here cause it is rebased
| |
| 141 fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_S trategy, 64*1024*1024)); | 141 fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_S trategy, 64*1024*1024)); |
| 142 fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc _Strategy, 2*1024*1024)); | 142 fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc _Strategy, 2*1024*1024)); |
| 143 fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_S trategy, 0)); | 143 fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_S trategy, 0)); |
| 144 fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_St rategy, 0)); | 144 fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_St rategy, 0)); |
| 145 fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Str ategy, 64*1024)); | 145 fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Str ategy, 64*1024)); |
| 146 fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc _Strategy, 0)); | 146 fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc _Strategy, 0)); |
| 147 fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_S trategy, 16*1024*1024)); | 147 fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_S trategy, 16*1024*1024)); |
| 148 } | 148 } |
| 149 | 149 |
| 150 GrVkGpu::~GrVkGpu() { | 150 GrVkGpu::~GrVkGpu() { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 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(GrRenderTarget* target, |
| 178 GrGpuCommandBuffer::LoadAndStor eOp colorOp, | 178 GrGpuCommandBuffer::LoadAndStor eOp colorOp, |
| 179 GrColor colorClear, | 179 GrColor colorClear, |
| 180 GrGpuCommandBuffer::LoadAndStor eOp stencilOp, | 180 GrGpuCommandBuffer::LoadAndStor eOp stencilOp, |
| 181 GrColor stencilClear) { | 181 GrColor stencilClear) { |
| 182 const GrVkRenderTarget& vkRT = static_cast<const GrVkRenderTarget&>(target); | 182 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); |
| 183 return new GrVkGpuCommandBuffer(this, vkRT, colorOp, colorClear, stencilOp, stencilClear); | 183 return new GrVkGpuCommandBuffer(this, vkRT, colorOp, colorClear, stencilOp, stencilClear); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void GrVkGpu::submitCommandBuffer(SyncQueue sync) { | 186 void GrVkGpu::submitCommandBuffer(SyncQueue sync) { |
| 187 SkASSERT(fCurrentCmdBuffer); | 187 SkASSERT(fCurrentCmdBuffer); |
| 188 fCurrentCmdBuffer->end(this); | 188 fCurrentCmdBuffer->end(this); |
| 189 | 189 |
| 190 fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); | 190 fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); |
| 191 fResourceProvider.checkCommandBuffers(); | 191 fResourceProvider.checkCommandBuffers(); |
| 192 | 192 |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 *tex, | 812 *tex, |
| 813 1, | 813 1, |
| 814 &blitRegion, | 814 &blitRegion, |
| 815 VK_FILTER_LINEAR); | 815 VK_FILTER_LINEAR); |
| 816 ++mipLevel; | 816 ++mipLevel; |
| 817 } | 817 } |
| 818 | 818 |
| 819 oldResource->unref(this); | 819 oldResource->unref(this); |
| 820 } | 820 } |
| 821 | 821 |
| 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 //////////////////////////////////////////////////////////////////////////////// | 822 //////////////////////////////////////////////////////////////////////////////// |
| 848 | 823 |
| 849 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, | 824 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen derTarget* rt, |
| 850 int width, | 825 int width, |
| 851 int height) { | 826 int height) { |
| 852 SkASSERT(width >= rt->width()); | 827 SkASSERT(width >= rt->width()); |
| 853 SkASSERT(height >= rt->height()); | 828 SkASSERT(height >= rt->height()); |
| 854 | 829 |
| 855 int samples = rt->numStencilSamples(); | 830 int samples = rt->numStencilSamples(); |
| 856 | 831 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1080 subRange.levelCount = 1; | 1055 subRange.levelCount = 1; |
| 1081 subRange.baseArrayLayer = 0; | 1056 subRange.baseArrayLayer = 0; |
| 1082 subRange.layerCount = 1; | 1057 subRange.layerCount = 1; |
| 1083 | 1058 |
| 1084 // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a | 1059 // 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 | 1060 // draw. Thus we should look into using the load op functions on the render pass to clear out |
| 1086 // the stencil there. | 1061 // the stencil there. |
| 1087 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); | 1062 fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); |
| 1088 } | 1063 } |
| 1089 | 1064 |
| 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, | 1065 inline bool can_copy_image(const GrSurface* dst, |
| 1242 const GrSurface* src, | 1066 const GrSurface* src, |
| 1243 const GrVkGpu* gpu) { | 1067 const GrVkGpu* gpu) { |
| 1244 // Currently we don't support msaa | 1068 // Currently we don't support msaa |
| 1245 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || | 1069 if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || |
| 1246 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) { | 1070 (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) { |
| 1247 return false; | 1071 return false; |
| 1248 } | 1072 } |
| 1249 | 1073 |
| 1250 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src | 1074 // 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 Loading... | |
| 1580 memcpy(top, bottom, tightRowBytes); | 1404 memcpy(top, bottom, tightRowBytes); |
| 1581 memcpy(bottom, tmpRow, tightRowBytes); | 1405 memcpy(bottom, tmpRow, tightRowBytes); |
| 1582 top += rowBytes; | 1406 top += rowBytes; |
| 1583 bottom -= rowBytes; | 1407 bottom -= rowBytes; |
| 1584 } | 1408 } |
| 1585 } | 1409 } |
| 1586 | 1410 |
| 1587 return true; | 1411 return true; |
| 1588 } | 1412 } |
| 1589 | 1413 |
| 1590 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer) { | 1414 void GrVkGpu::submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer* buf fer, |
| 1415 const GrVkRenderPass* renderPass, | |
| 1416 const VkClearValue* colorClear, | |
| 1417 GrVkRenderTarget* target, | |
| 1418 const SkIRect& bounds) { | |
| 1419 // Currently it is fine for us to always pass in 1 for the clear count even if no attachment | |
| 1420 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment | |
| 1421 // which is always at the first attachment. | |
| 1422 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, bounds, true); | |
| 1591 fCurrentCmdBuffer->executeCommands(this, buffer); | 1423 fCurrentCmdBuffer->executeCommands(this, buffer); |
| 1424 fCurrentCmdBuffer->endRenderPass(this); | |
| 1592 } | 1425 } |
| 1593 | 1426 |
| 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 } | |
| OLD | NEW |