Add support for finding/creating general GrVkRenderPass from the VkResourceProvider.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2035853002
Review-Url: https://codereview.chromium.org/2035853002
diff --git a/src/gpu/vk/GrVkRenderPass.cpp b/src/gpu/vk/GrVkRenderPass.cpp
index c56bafa..6a0f953 100644
--- a/src/gpu/vk/GrVkRenderPass.cpp
+++ b/src/gpu/vk/GrVkRenderPass.cpp
@@ -23,16 +23,16 @@
SkAssertResult(GrSampleCountToVkSampleCount(desc.fSamples, &attachment->samples));
switch (layout) {
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- attachment->loadOp = desc.fLoadOp;
- attachment->storeOp = desc.fStoreOp;
+ attachment->loadOp = desc.fLoadStoreOps.fLoadOp;
+ attachment->storeOp = desc.fLoadStoreOps.fStoreOp;
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachment->stencilLoadOp = desc.fLoadOp;
- attachment->stencilStoreOp = desc.fStoreOp;
+ attachment->stencilLoadOp = desc.fLoadStoreOps.fLoadOp;
+ attachment->stencilStoreOp = desc.fLoadStoreOps.fStoreOp;
break;
default:
SkFAIL("Unexpected attachment layout");
@@ -43,15 +43,21 @@
}
void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) {
- // Get attachment information from render target. This includes which attachments the render
- // target has (color, resolve, stencil) and the attachments format and sample count.
- target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
+ static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
+ VK_ATTACHMENT_STORE_OP_STORE);
+ this->init(gpu, target, kBasicLoadStoreOps, kBasicLoadStoreOps, kBasicLoadStoreOps);
+}
+
+void GrVkRenderPass::init(const GrVkGpu* gpu,
+ const LoadStoreOps& colorOp,
+ const LoadStoreOps& resolveOp,
+ const LoadStoreOps& stencilOp) {
uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
// Attachment descriptions to be set on the render pass
SkTArray<VkAttachmentDescription> attachments(numAttachments);
attachments.reset(numAttachments);
- memset(attachments.begin(), 0, numAttachments*sizeof(VkAttachmentDescription));
+ memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));
// Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
// that are used by the subpass.
@@ -70,6 +76,7 @@
subpassDesc.pInputAttachments = nullptr;
if (fAttachmentFlags & kColor_AttachmentFlag) {
// set up color attachment
+ fAttachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
setup_vk_attachment_description(&attachments[currentAttachment],
fAttachmentsDescriptor.fColor,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
@@ -88,6 +95,7 @@
if (fAttachmentFlags & kResolve_AttachmentFlag) {
// set up resolve attachment
+ fAttachmentsDescriptor.fResolve.fLoadStoreOps = resolveOp;
setup_vk_attachment_description(&attachments[currentAttachment],
fAttachmentsDescriptor.fResolve,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
@@ -102,6 +110,7 @@
if (fAttachmentFlags & kStencil_AttachmentFlag) {
// set up stencil attachment
+ fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
setup_vk_attachment_description(&attachments[currentAttachment],
fAttachmentsDescriptor.fStencil,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@@ -138,6 +147,27 @@
&fRenderPass));
}
+void GrVkRenderPass::init(const GrVkGpu* gpu,
+ const GrVkRenderPass& compatibleRenderPass,
+ const LoadStoreOps& colorOp,
+ const LoadStoreOps& resolveOp,
+ const LoadStoreOps& stencilOp) {
+ fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
+ fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
+ this->init(gpu, colorOp, resolveOp, stencilOp);
+}
+
+void GrVkRenderPass::init(const GrVkGpu* gpu,
+ const GrVkRenderTarget& target,
+ const LoadStoreOps& colorOp,
+ const LoadStoreOps& resolveOp,
+ const LoadStoreOps& stencilOp) {
+ // Get attachment information from render target. This includes which attachments the render
+ // target has (color, resolve, stencil) and the attachments format and sample count.
+ target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
+ this->init(gpu, colorOp, resolveOp, stencilOp);
+}
+
void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
}
@@ -231,6 +261,27 @@
return true;
}
+bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
+ const LoadStoreOps& resolveOps,
+ const LoadStoreOps& stencilOps) const {
+ if (fAttachmentFlags & kColor_AttachmentFlag) {
+ if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
+ return false;
+ }
+ }
+ if (fAttachmentFlags & kResolve_AttachmentFlag) {
+ if (fAttachmentsDescriptor.fResolve.fLoadStoreOps != resolveOps) {
+ return false;
+ }
+ }
+ if (fAttachmentFlags & kStencil_AttachmentFlag) {
+ if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
+ return false;
+ }
+ }
+ return true;
+}
+
void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
b->add32(fAttachmentFlags);
if (fAttachmentFlags & kColor_AttachmentFlag) {
diff --git a/src/gpu/vk/GrVkRenderPass.h b/src/gpu/vk/GrVkRenderPass.h
index 082cccd..b4f4b2b 100644
--- a/src/gpu/vk/GrVkRenderPass.h
+++ b/src/gpu/vk/GrVkRenderPass.h
@@ -21,25 +21,51 @@
class GrVkRenderPass : public GrVkResource {
public:
GrVkRenderPass() : INHERITED(), fRenderPass(VK_NULL_HANDLE) {}
+
+ struct LoadStoreOps {
+ VkAttachmentLoadOp fLoadOp;
+ VkAttachmentStoreOp fStoreOp;
+
+ LoadStoreOps(VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp)
+ : fLoadOp(loadOp)
+ , fStoreOp(storeOp) {}
+
+ bool operator==(const LoadStoreOps& right) const {
+ return fLoadOp == right.fLoadOp && fStoreOp == right.fStoreOp;
+ }
+
+ bool operator!=(const LoadStoreOps& right) const {
+ return !(*this == right);
+ }
+ };
+
void initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target);
+ void init(const GrVkGpu* gpu,
+ const GrVkRenderTarget& target,
+ const LoadStoreOps& colorOp,
+ const LoadStoreOps& resolveOp,
+ const LoadStoreOps& stencilOp);
+
+ void init(const GrVkGpu* gpu,
+ const GrVkRenderPass& compatibleRenderPass,
+ const LoadStoreOps& colorOp,
+ const LoadStoreOps& resolveOp,
+ const LoadStoreOps& stencilOp);
struct AttachmentsDescriptor {
struct AttachmentDesc {
VkFormat fFormat;
int fSamples;
- VkAttachmentLoadOp fLoadOp;
- VkAttachmentStoreOp fStoreOp;
+ LoadStoreOps fLoadStoreOps;
AttachmentDesc()
: fFormat(VK_FORMAT_UNDEFINED)
, fSamples(0)
- , fLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD)
- , fStoreOp(VK_ATTACHMENT_STORE_OP_STORE) {}
+ , fLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE) {}
bool operator==(const AttachmentDesc& right) const {
return (fFormat == right.fFormat &&
fSamples == right.fSamples &&
- fLoadOp == right.fLoadOp &&
- fStoreOp == right.fStoreOp);
+ fLoadStoreOps == right.fLoadStoreOps);
}
bool operator!=(const AttachmentDesc& right) const {
return !(*this == right);
@@ -84,6 +110,10 @@
// basic RenderPasses that can be used when creating a VkFrameBuffer object.
bool isCompatible(const GrVkRenderTarget& target) const;
+ bool equalLoadStoreOps(const LoadStoreOps& colorOps,
+ const LoadStoreOps& resolveOps,
+ const LoadStoreOps& stencilOps) const;
+
VkRenderPass vkRenderPass() const { return fRenderPass; }
void genKey(GrProcessorKeyBuilder* b) const;
@@ -91,6 +121,11 @@
private:
GrVkRenderPass(const GrVkRenderPass&);
+ void init(const GrVkGpu* gpu,
+ const LoadStoreOps& colorOps,
+ const LoadStoreOps& resolveOps,
+ const LoadStoreOps& stencilOps);
+
void freeGPUData(const GrVkGpu* gpu) const override;
VkRenderPass fRenderPass;
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index 0467371..735f5cd 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -65,7 +65,6 @@
GrBackendObject getRenderTargetHandle() const override;
- // Returns the total number of attachments
void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags* flags) const;
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index fdc9e90..cd3ba47 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -10,7 +10,6 @@
#include "GrTextureParams.h"
#include "GrVkCommandBuffer.h"
#include "GrVkPipeline.h"
-#include "GrVkRenderPass.h"
#include "GrVkSampler.h"
#include "GrVkUtil.h"
@@ -134,6 +133,33 @@
return renderPass;
}
+const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
+ const GrVkRenderTarget& target,
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps,
+ CompatibleRPHandle* compatibleHandle) {
+ // This will get us the handle to (and possible create) the compatible set for the specific
+ // GrVkRenderPass we are looking for.
+ this->findCompatibleRenderPass(target, compatibleHandle);
+ return this->findRenderPass(*compatibleHandle, colorOps, resolveOps, stencilOps);
+}
+
+const GrVkRenderPass*
+GrVkResourceProvider::findRenderPass(const CompatibleRPHandle& compatibleHandle,
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps) {
+ SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.count());
+ CompatibleRenderPassSet& compatibleSet = fRenderPassArray[compatibleHandle.toIndex()];
+ const GrVkRenderPass* renderPass = compatibleSet.getRenderPass(fGpu,
+ colorOps,
+ resolveOps,
+ stencilOps);
+ renderPass->ref();
+ return renderPass;
+}
+
GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
VkDescriptorType type, uint32_t count) {
return new GrVkDescriptorPool(fGpu, type, count);
@@ -295,6 +321,24 @@
return fRenderPasses[0]->isCompatible(target);
}
+GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(
+ const GrVkGpu* gpu,
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps) {
+ for (int i = 0; i < fRenderPasses.count(); ++i) {
+ int idx = (i + fLastReturnedIndex) % fRenderPasses.count();
+ if (fRenderPasses[idx]->equalLoadStoreOps(colorOps, resolveOps, stencilOps)) {
+ fLastReturnedIndex = idx;
+ return fRenderPasses[idx];
+ }
+ }
+ GrVkRenderPass* renderPass = fRenderPasses.push_back();
+ renderPass->init(gpu, *this->getCompatibleRenderPass(), colorOps, resolveOps, stencilOps);
+ fLastReturnedIndex = fRenderPasses.count() - 1;
+ return renderPass;
+}
+
void GrVkResourceProvider::CompatibleRenderPassSet::releaseResources(const GrVkGpu* gpu) {
for (int i = 0; i < fRenderPasses.count(); ++i) {
if (fRenderPasses[i]) {
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 5368a21..e754501 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -12,6 +12,7 @@
#include "GrResourceHandle.h"
#include "GrVkDescriptorPool.h"
#include "GrVkPipelineState.h"
+#include "GrVkRenderPass.h"
#include "GrVkResource.h"
#include "GrVkUtil.h"
#include "SkTArray.h"
@@ -27,7 +28,6 @@
class GrVkCommandBuffer;
class GrVkGpu;
class GrVkPipeline;
-class GrVkRenderPass;
class GrVkRenderTarget;
class GrVkSampler;
@@ -59,21 +59,23 @@
// findCompatibleRenderPass(GrVkRenderTarget&, CompatibleRPHandle*).
const GrVkRenderPass* findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle);
-#if 0
- // TODO:
+ // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
+ // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
+ // If this is non null it will be set to a handle that can be used in the furutre to quickly
+ // return a GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
const GrVkRenderPass* findRenderPass(const GrVkRenderTarget& target,
- VkAttachmentLoadOp colorLoad,
- VkAttachmentStoreOp colorStore,
- VkAttachmentLoadOp stencilLoad,
- VkAttachmentStoreOp stencilStore,
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle = nullptr);
+ // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
+ // findCompatibleRenderPass.
const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
- VkAttachmentLoadOp colorLoad,
- VkAttachmentStoreOp colorStore,
- VkAttachmentLoadOp stencilLoad,
- VkAttachmentStoreOp stencilStore);
-#endif
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps);
+
GrVkCommandBuffer* createCommandBuffer();
void checkCommandBuffers();
@@ -175,6 +177,11 @@
return fRenderPasses[0];
}
+ GrVkRenderPass* getRenderPass(const GrVkGpu* gpu,
+ const GrVkRenderPass::LoadStoreOps& colorOps,
+ const GrVkRenderPass::LoadStoreOps& resolveOps,
+ const GrVkRenderPass::LoadStoreOps& stencilOps);
+
void releaseResources(const GrVkGpu* gpu);
void abandonResources();