GrVkGpuCommandBuffer.cpp revision ab015efc48c462ffdffebb45c02cd19efb254983
1066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel/* 2066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* Copyright 2016 Google Inc. 3066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* 4066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* Use of this source code is governed by a BSD-style license that can be 5066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* found in the LICENSE file. 6066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel*/ 7066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 8066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpuCommandBuffer.h" 9066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 1029df76096fd30941086324902a82656df2d8becdcsmartdalton#include "GrFixedClip.h" 119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrMesh.h" 12742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h" 139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrPipeline.h" 149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrRenderTargetPriv.h" 159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrTexturePriv.h" 16066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkCommandBuffer.h" 17066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpu.h" 189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrVkPipeline.h" 19066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkRenderPass.h" 20066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkRenderTarget.h" 21066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkResourceProvider.h" 229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrVkTexture.h" 2336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel#include "SkRect.h" 24066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 259cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid get_vk_load_store_ops(const GrGpuCommandBuffer::LoadAndStoreInfo& info, 26066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) { 279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel switch (info.fLoadOp) { 289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel case GrGpuCommandBuffer::LoadOp::kLoad: 29066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 30066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel break; 319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel case GrGpuCommandBuffer::LoadOp::kClear: 32066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 33066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel break; 349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel case GrGpuCommandBuffer::LoadOp::kDiscard: 35066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel break; 379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel default: 389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SK_ABORT("Invalid LoadOp"); 399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel switch (info.fStoreOp) { 439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel case GrGpuCommandBuffer::StoreOp::kStore: 44066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel *storeOp = VK_ATTACHMENT_STORE_OP_STORE; 45066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel break; 469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel case GrGpuCommandBuffer::StoreOp::kDiscard: 47066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 48066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel break; 490bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman default: 509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SK_ABORT("Invalid StoreOp"); 510bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman *storeOp = VK_ATTACHMENT_STORE_OP_STORE; 52066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel } 53066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 54066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 55066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::GrVkGpuCommandBuffer(GrVkGpu* gpu, 569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const LoadAndStoreInfo& colorInfo, 579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const LoadAndStoreInfo& stencilInfo) 589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel : fGpu(gpu) 59c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon , fRenderTarget(nullptr) 6022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel , fClearColor(GrColor4f::FromGrColor(colorInfo.fClearColor)) 6122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel , fLastPipelineState(nullptr) { 62066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 63c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon get_vk_load_store_ops(colorInfo, &fVkColorLoadOp, &fVkColorStoreOp); 64066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 65c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon get_vk_load_store_ops(stencilInfo, &fVkStencilLoadOp, &fVkStencilStoreOp); 66c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 6722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCurrentCmdInfo = -1; 68c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon} 69c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 70c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::init(GrVkRenderTarget* target) { 71c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(!fRenderTarget); 72c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon fRenderTarget = target; 73c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 74c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp); 75c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp); 769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 7736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back(); 78c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(fCommandBufferInfos.count() == 1); 7922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCurrentCmdInfo = 0; 8036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrVkResourceProvider::CompatibleRPHandle& rpHandle = target->compatibleRenderPassHandle(); 82066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel if (rpHandle.isValid()) { 8336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, 8436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 8536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 86066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel } else { 8736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*target, 8836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 8936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 90066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel } 91066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 92c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon cbInfo.fColorClearValue.color.float32[0] = fClearColor.fRGBA[0]; 93c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon cbInfo.fColorClearValue.color.float32[1] = fClearColor.fRGBA[1]; 94c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon cbInfo.fColorClearValue.color.float32[2] = fClearColor.fRGBA[2]; 95c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon cbInfo.fColorClearValue.color.float32[3] = fClearColor.fRGBA[3]; 9636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 9736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.setEmpty(); 9877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fIsEmpty = true; 9977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fStartsWithClear = false; 1009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 10122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer()); 10222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->begin(fGpu, target->framebuffer(), cbInfo.fRenderPass); 103066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 104066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 105c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 106066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::~GrVkGpuCommandBuffer() { 10736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel for (int i = 0; i < fCommandBufferInfos.count(); ++i) { 10836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[i]; 10922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) { 11022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.fCommandBuffers[j]->unref(fGpu); 11122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel } 11236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass->unref(fGpu); 11336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } 114066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 115066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 1169cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpu* GrVkGpuCommandBuffer::gpu() { return fGpu; } 11765a09274184ffd25d446352a96d3890ea7e625faGreg DanielGrRenderTarget* GrVkGpuCommandBuffer::renderTarget() { return fRenderTarget; } 1189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 119066df7ca911b65d416783f3bec6f4f1662948ad5egdanielvoid GrVkGpuCommandBuffer::end() { 12022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel if (fCurrentCmdInfo >= 0) { 12122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu); 122c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 123066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 124066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 12536a77ee494791989548b717515e3621b9c4ffe4eGreg Danielvoid GrVkGpuCommandBuffer::onSubmit() { 126c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon if (!fRenderTarget) { 127c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon return; 128c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 129ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel // Change layout of our render target so it can be used as the color attachment. Currently 130ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel // we don't attach the resolve to the framebuffer so no need to change its layout. 1318d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel GrVkImage* targetImage = fRenderTarget->msaaImage() ? fRenderTarget->msaaImage() 132ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel : fRenderTarget; 133bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 134bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel // Change layout of our render target so it can be used as the color attachment 135ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel targetImage->setImageLayout(fGpu, 136ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 137ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 138bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 139ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel false); 1409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 1419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // If we are using a stencil attachment we also need to update its layout 1429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) { 1439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 1449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel vkStencil->setImageLayout(fGpu, 1459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 1479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, 148bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 1499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel false); 1509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 1519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 15236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel for (int i = 0; i < fCommandBufferInfos.count(); ++i) { 15336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[i]; 15436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 15577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel for (int j = 0; j < cbInfo.fPreDrawUploads.count(); ++j) { 15677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel InlineUploadInfo& iuInfo = cbInfo.fPreDrawUploads[j]; 15777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel iuInfo.fFlushState->doUpload(iuInfo.fUpload); 15877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel } 15977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 16077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // TODO: We can't add this optimization yet since many things create a scratch texture which 16177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // adds the discard immediately, but then don't draw to it right away. This causes the 16277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // discard to be ignored and we get yelled at for loading uninitialized data. However, once 16377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // MDP lands, the discard will get reordered with the rest of the draw commands and we can 16477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // re-enable this. 16577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel#if 0 16677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel if (cbInfo.fIsEmpty && !cbInfo.fStartsWithClear) { 16777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // We have sumbitted no actual draw commands to the command buffer and we are not using 16877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // the render pass to do a clear so there is no need to submit anything. 16977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel continue; 17077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel } 17177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel#endif 17236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel if (cbInfo.fBounds.intersect(0, 0, 17336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkIntToScalar(fRenderTarget->width()), 17436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkIntToScalar(fRenderTarget->height()))) { 17536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkIRect iBounds; 17636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.roundOut(&iBounds); 17736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 17822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass, 17936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel &cbInfo.fColorClearValue, fRenderTarget, iBounds); 18036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } 18136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } 1829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 1839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 184c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::discard(GrRenderTarget* rt) { 185c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt); 186c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon if (!fRenderTarget) { 187c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon this->init(target); 188c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 189c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(target == fRenderTarget); 190c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 19122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 19277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel if (cbInfo.fIsEmpty) { 19337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel // We will change the render pass to do a clear load instead 19437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE, 19537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel VK_ATTACHMENT_STORE_OP_STORE); 19637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE, 19737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel VK_ATTACHMENT_STORE_OP_STORE); 19837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel 19936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel const GrVkRenderPass* oldRP = cbInfo.fRenderPass; 20037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel 20137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel const GrVkResourceProvider::CompatibleRPHandle& rpHandle = 20265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel fRenderTarget->compatibleRenderPassHandle(); 20337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel if (rpHandle.isValid()) { 20436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, 20536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 20636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 20737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel } else { 20836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget, 20936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 21036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 21137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel } 21237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel 21336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP)); 21437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel oldRP->unref(fGpu); 2155011f8547c6de936f20bc954d5fd131a52106f33Greg Daniel cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); 21677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fStartsWithClear = false; 21737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel } 21837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel} 21937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel 220c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* rt, const GrFixedClip& clip, 22129df76096fd30941086324902a82656df2d8becdcsmartdalton bool insideStencilMask) { 222bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton SkASSERT(!clip.hasWindowRectangles()); 2239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 224c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt); 225c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon if (!fRenderTarget) { 226c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon this->init(target); 227c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 228c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(target == fRenderTarget); 229c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 23022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 23136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 23265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment(); 2339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // this should only be called internally when we know we have a 2349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // stencil buffer. 2359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(sb); 2369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel int stencilBitCount = sb->bits(); 2379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // The contract with the callers does not guarantee that we preserve all bits in the stencil 2399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // during this clear. Thus we will clear the entire stencil to the desired value. 2409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearDepthStencilValue vkStencilColor; 2429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); 24329df76096fd30941086324902a82656df2d8becdcsmartdalton if (insideStencilMask) { 2449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel vkStencilColor.stencil = (1 << (stencilBitCount - 1)); 2459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } else { 2469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel vkStencilColor.stencil = 0; 2479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 2489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearRect clearRect; 2509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // Flip rect if necessary 25129df76096fd30941086324902a82656df2d8becdcsmartdalton SkIRect vkRect; 25229df76096fd30941086324902a82656df2d8becdcsmartdalton if (!clip.scissorEnabled()) { 25365a09274184ffd25d446352a96d3890ea7e625faGreg Daniel vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); 25465a09274184ffd25d446352a96d3890ea7e625faGreg Daniel } else if (kBottomLeft_GrSurfaceOrigin != fRenderTarget->origin()) { 25529df76096fd30941086324902a82656df2d8becdcsmartdalton vkRect = clip.scissorRect(); 25629df76096fd30941086324902a82656df2d8becdcsmartdalton } else { 25729df76096fd30941086324902a82656df2d8becdcsmartdalton const SkIRect& scissor = clip.scissorRect(); 25865a09274184ffd25d446352a96d3890ea7e625faGreg Daniel vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, 25965a09274184ffd25d446352a96d3890ea7e625faGreg Daniel scissor.fRight, fRenderTarget->height() - scissor.fTop); 2609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 2619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; 2639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; 2649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.baseArrayLayer = 0; 2669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.layerCount = 1; 2679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel uint32_t stencilIndex; 26936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex)); 2709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 2719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearAttachment attachment; 2729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 2739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.colorAttachment = 0; // this value shouldn't matter 2749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.clearValue.depthStencil = vkStencilColor; 2759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 27622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); 27777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fIsEmpty = false; 27836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 27936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel // Update command buffer bounds 28036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel if (!clip.scissorEnabled()) { 28136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); 28236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } else { 28336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); 28436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } 2859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 2869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 287c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::onClear(GrRenderTarget* rt, const GrFixedClip& clip, GrColor color) { 2889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // parent class should never let us get here with no RT 289bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton SkASSERT(!clip.hasWindowRectangles()); 2909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 291c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt); 292c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon if (!fRenderTarget) { 293c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon this->init(target); 294c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 295c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(target == fRenderTarget); 296c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 29722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 29836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 2999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearColorValue vkColor; 3009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrColorToRGBAFloat(color, vkColor.float32); 3019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 30277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel if (cbInfo.fIsEmpty && !clip.scissorEnabled()) { 3039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // We will change the render pass to do a clear load instead 3049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR, 3059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VK_ATTACHMENT_STORE_OP_STORE); 3069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD, 3079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VK_ATTACHMENT_STORE_OP_STORE); 3089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 30936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel const GrVkRenderPass* oldRP = cbInfo.fRenderPass; 3109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 3119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrVkResourceProvider::CompatibleRPHandle& rpHandle = 31265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel fRenderTarget->compatibleRenderPassHandle(); 3139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (rpHandle.isValid()) { 31436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, 31536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 31636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 3179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } else { 31836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget, 31936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkColorOps, 32036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel vkStencilOps); 3219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 3229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 32336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP)); 3249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel oldRP->unref(fGpu); 3259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 32636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel GrColorToRGBAFloat(color, cbInfo.fColorClearValue.color.float32); 32777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fStartsWithClear = true; 32836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 32936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel // Update command buffer bounds 33036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); 3319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return; 3329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 3339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 3349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // We always do a sub rect clear with clearAttachments since we are inside a render pass 3359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearRect clearRect; 3369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // Flip rect if necessary 33729df76096fd30941086324902a82656df2d8becdcsmartdalton SkIRect vkRect; 33829df76096fd30941086324902a82656df2d8becdcsmartdalton if (!clip.scissorEnabled()) { 33965a09274184ffd25d446352a96d3890ea7e625faGreg Daniel vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height()); 34065a09274184ffd25d446352a96d3890ea7e625faGreg Daniel } else if (kBottomLeft_GrSurfaceOrigin != fRenderTarget->origin()) { 34129df76096fd30941086324902a82656df2d8becdcsmartdalton vkRect = clip.scissorRect(); 34229df76096fd30941086324902a82656df2d8becdcsmartdalton } else { 34329df76096fd30941086324902a82656df2d8becdcsmartdalton const SkIRect& scissor = clip.scissorRect(); 34465a09274184ffd25d446352a96d3890ea7e625faGreg Daniel vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom, 34565a09274184ffd25d446352a96d3890ea7e625faGreg Daniel scissor.fRight, fRenderTarget->height() - scissor.fTop); 3469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 3479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; 3489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; 3499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.baseArrayLayer = 0; 3509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel clearRect.layerCount = 1; 3519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 3529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel uint32_t colorIndex; 35336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex)); 3549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 3559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel VkClearAttachment attachment; 3569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.colorAttachment = colorIndex; 3589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel attachment.clearValue.color = vkColor; 3599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 36022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect); 36177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fIsEmpty = false; 36236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 36336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel // Update command buffer bounds 36436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel if (!clip.scissorEnabled()) { 36536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(fRenderTarget->getBoundsRect()); 36636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } else { 36736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(SkRect::Make(clip.scissorRect())); 36836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } 3699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return; 3709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 3719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 37277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Danielvoid GrVkGpuCommandBuffer::addAdditionalCommandBuffer() { 37322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 37422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->end(fGpu); 37522bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer()); 37622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->begin(fGpu, fRenderTarget->framebuffer(), cbInfo.fRenderPass); 37722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel} 37822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel 37922bc8653d704584e13f35844dafb5ddeb9989127Greg Danielvoid GrVkGpuCommandBuffer::addAdditionalRenderPass() { 38022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu); 38177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 38277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back(); 38322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCurrentCmdInfo++; 38477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 38577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD, 38677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel VK_ATTACHMENT_STORE_OP_STORE); 38777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD, 38877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel VK_ATTACHMENT_STORE_OP_STORE); 38977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 39077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel const GrVkResourceProvider::CompatibleRPHandle& rpHandle = 39177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel fRenderTarget->compatibleRenderPassHandle(); 39277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel if (rpHandle.isValid()) { 39377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, 39477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel vkColorOps, 39577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel vkStencilOps); 39677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel } else { 39777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget, 39877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel vkColorOps, 39977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel vkStencilOps); 40077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel } 40177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 40222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer()); 40377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // It shouldn't matter what we set the clear color to here since we will assume loading of the 40477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel // attachment. 40577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue)); 40677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fBounds.setEmpty(); 40777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fIsEmpty = true; 40877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fStartsWithClear = false; 40977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 41022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->begin(fGpu, fRenderTarget->framebuffer(), cbInfo.fRenderPass); 41177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel} 41277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 413dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Danielvoid GrVkGpuCommandBuffer::inlineUpload(GrOpFlushState* state, GrDrawOp::DeferredUploadFn& upload, 414dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel GrRenderTarget* rt) { 415dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt); 416dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel if (!fRenderTarget) { 417dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel this->init(target); 418dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel } 41922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) { 42022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel this->addAdditionalRenderPass(); 42177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel } 42222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCommandBufferInfos[fCurrentCmdInfo].fPreDrawUploads.emplace_back(state, upload); 42377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel} 42477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel 4259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel//////////////////////////////////////////////////////////////////////////////// 4269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 4279cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc, 4289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrNonInstancedMesh& mesh) { 42922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 4309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // There is no need to put any memory barriers to make sure host writes have finished here. 4319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // When a command buffer is submitted to a queue, there is an implicit memory barrier that 4329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of 4339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // an active RenderPass. 434485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton SkASSERT(!mesh.vertexBuffer()->isCPUBacked()); 4359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkVertexBuffer* vbuf; 4369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer(); 4379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(vbuf); 4389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(!vbuf->isMapped()); 4399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 44022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->bindVertexBuffer(fGpu, vbuf); 4419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 4429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (mesh.isIndexed()) { 443485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton SkASSERT(!mesh.indexBuffer()->isCPUBacked()); 4449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer(); 4459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(ibuf); 4469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(!ibuf->isMapped()); 4479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 44822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->bindIndexBuffer(fGpu, ibuf); 4499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 4509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 4519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 4529cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielsk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState( 4539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrPipeline& pipeline, 4549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrPrimitiveProcessor& primProc, 45536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel GrPrimitiveType primitiveType) { 45622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 45722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel SkASSERT(cbInfo.fRenderPass); 45836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 4599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel sk_sp<GrVkPipelineState> pipelineState = 4609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline, 4619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel primProc, 4629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel primitiveType, 46336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel *cbInfo.fRenderPass); 4649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (!pipelineState) { 4659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return pipelineState; 4669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 4679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 46822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel if (!cbInfo.fIsEmpty && 46922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fLastPipelineState && fLastPipelineState != pipelineState.get() && 47022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fGpu->vkCaps().newSecondaryCBOnPipelineChange()) { 47122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel this->addAdditionalCommandBuffer(); 47222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel } 47322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fLastPipelineState = pipelineState.get(); 47422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel 4759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel pipelineState->setData(fGpu, primProc, pipeline); 4769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 47722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel pipelineState->bind(fGpu, cbInfo.currentCmdBuf()); 4789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 47922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel GrVkPipeline::SetDynamicState(fGpu, cbInfo.currentCmdBuf(), pipeline); 4809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 4819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return pipelineState; 4829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 4839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 48418dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomonstatic void set_texture_layout(GrVkTexture* vkTexture, GrVkGpu* gpu) { 48518dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon // TODO: If we ever decide to create the secondary command buffers ahead of time before we 48618dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon // are actually going to submit them, we will need to track the sampled images and delay 48718dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon // adding the layout change/barrier until we are ready to submit. 48818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon vkTexture->setImageLayout(gpu, 48918dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 49018dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon VK_ACCESS_SHADER_READ_BIT, 49118dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 49218dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon false); 49318dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon} 49418dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon 495ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomonstatic void prepare_sampled_images(const GrResourceIOProcessor& processor, GrVkGpu* gpu) { 4960bbecb21ab82b3d742c491780bcc2e74be03efedBrian Salomon for (int i = 0; i < processor.numTextureSamplers(); ++i) { 497ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i); 498db4183d227b764b219e9e314dd5387ded4c38797Brian Salomon GrVkTexture* vkTexture = static_cast<GrVkTexture*>(sampler.texture()); 4998d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel SkASSERT(vkTexture); 50066933552f1723c4a2b248711ab3d43921401e8e6egdaniel 5018d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel // We may need to resolve the texture first if it is also a render target 5028d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget()); 5038d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel if (texRT) { 5048d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel gpu->onResolveRenderTarget(texRT); 5058d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel } 5069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 507514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon const GrSamplerParams& params = sampler.params(); 5088d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel // Check if we need to regenerate any mip maps 509514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon if (GrSamplerParams::kMipMap_FilterMode == params.filterMode()) { 5108d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel if (vkTexture->texturePriv().mipMapsAreDirty()) { 5118d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel gpu->generateMipmap(vkTexture); 5128d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel vkTexture->texturePriv().dirtyMipMaps(false); 5138d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel } 5148d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel } 51518dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon set_texture_layout(vkTexture, gpu); 5169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel} 5189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 5199cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline, 5209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrPrimitiveProcessor& primProc, 5219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrMesh* meshes, 52236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel int meshCount, 52336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel const SkRect& bounds) { 524c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(pipeline.getRenderTarget()); 525c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon if (!fRenderTarget) { 526c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon this->init(target); 527c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon } 528c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon SkASSERT(target == fRenderTarget); 529c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon 5309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (!meshCount) { 5319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return; 5329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5338d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel prepare_sampled_images(primProc, fGpu); 534b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon GrFragmentProcessor::Iter iter(pipeline); 535b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon while (const GrFragmentProcessor* fp = iter.next()) { 536b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon prepare_sampled_images(*fp, fGpu); 5372f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel } 53818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon if (GrVkTexture* dstTexture = static_cast<GrVkTexture*>(pipeline.dstTexture())) { 53918dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon set_texture_layout(dstTexture, fGpu); 54018dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon } 5412f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel 5429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrPrimitiveType primitiveType = meshes[0].primitiveType(); 5439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline, 5449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel primProc, 54536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel primitiveType); 5469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (!pipelineState) { 5479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return; 5489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 55022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; 55122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel 5529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel for (int i = 0; i < meshCount; ++i) { 5539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrMesh& mesh = meshes[i]; 5549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrMesh::Iterator iter; 5559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh); 5569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel do { 5579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (nonIdxMesh->primitiveType() != primitiveType) { 5589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // Technically we don't have to call this here (since there is a safety check in 5599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // pipelineState:setData but this will allow for quicker freeing of resources if the 5609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // pipelineState sits in a cache for a while. 5619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel pipelineState->freeTempResources(fGpu); 5629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkDEBUGCODE(pipelineState = nullptr); 5639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel primitiveType = nonIdxMesh->primitiveType(); 5649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel pipelineState = this->prepareDrawState(pipeline, 5659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel primProc, 56636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel primitiveType); 5679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (!pipelineState) { 5689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel return; 5699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel SkASSERT(pipelineState); 5729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel this->bindGeometry(primProc, *nonIdxMesh); 5739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 5749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel if (nonIdxMesh->isIndexed()) { 57522bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->drawIndexed(fGpu, 57636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel nonIdxMesh->indexCount(), 57736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 1, 57836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel nonIdxMesh->startIndex(), 57936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel nonIdxMesh->startVertex(), 58036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 0); 58136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel } else { 58222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel cbInfo.currentCmdBuf()->draw(fGpu, 58336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel nonIdxMesh->vertexCount(), 5849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 1, 5859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel nonIdxMesh->startVertex(), 5869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 0); 5879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 58877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel cbInfo.fIsEmpty = false; 5899cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 5909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel fGpu->stats()->incNumDraws(); 5919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } while ((nonIdxMesh = iter.next())); 5929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel } 5939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 59436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel // Update command buffer bounds 59536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel cbInfo.fBounds.join(bounds); 59636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel 5979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // Technically we don't have to call this here (since there is a safety check in 5989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // pipelineState:setData but this will allow for quicker freeing of resources if the 5999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // pipelineState sits in a cache for a while. 6009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel pipelineState->freeTempResources(fGpu); 601066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 602066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 603