Handle failure to create VkRenderPasses in vulkan backend.
Bug: skia:9603 Change-Id: I8c56f399d58b109d163ff69b654d07edbc44dde0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253497 Reviewed-by: Chris Dalton <csmartdalton@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
4d0fe38f29
commit
ed98476cf2
@ -112,7 +112,9 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
|
||||
vkColorOps,
|
||||
vkStencilOps);
|
||||
}
|
||||
SkASSERT(fCurrentRenderPass);
|
||||
if (!fCurrentRenderPass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VkClearValue vkClearColor;
|
||||
vkClearColor.color.float32[0] = clearColor[0];
|
||||
@ -380,7 +382,9 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
|
||||
vkColorOps,
|
||||
vkStencilOps);
|
||||
}
|
||||
SkASSERT(fCurrentRenderPass);
|
||||
if (!fCurrentRenderPass) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkClearValue vkClearColor;
|
||||
memset(&vkClearColor, 0, sizeof(VkClearValue));
|
||||
|
@ -42,17 +42,34 @@ void setup_vk_attachment_description(VkAttachmentDescription* attachment,
|
||||
attachment->finalLayout = layout;
|
||||
}
|
||||
|
||||
void GrVkRenderPass::initSimple(GrVkGpu* gpu, const GrVkRenderTarget& target) {
|
||||
GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu, const GrVkRenderTarget& target) {
|
||||
static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE);
|
||||
|
||||
this->init(gpu, target, kBasicLoadStoreOps, kBasicLoadStoreOps);
|
||||
AttachmentFlags attachmentFlags;
|
||||
AttachmentsDescriptor attachmentsDescriptor;
|
||||
// Get attachment information from render target. This includes which attachments the render
|
||||
// target has (color, stencil) and the attachments format and sample count.
|
||||
target.getAttachmentsDescriptor(&attachmentsDescriptor, &attachmentFlags);
|
||||
return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps,
|
||||
kBasicLoadStoreOps);
|
||||
}
|
||||
|
||||
void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp) {
|
||||
uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
|
||||
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
|
||||
const GrVkRenderPass& compatibleRenderPass,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp) {
|
||||
AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags;
|
||||
AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
|
||||
return Create(gpu, attachmentFlags, attachmentsDescriptor, colorOp, stencilOp);
|
||||
}
|
||||
|
||||
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
|
||||
AttachmentFlags attachmentFlags,
|
||||
AttachmentsDescriptor& attachmentsDescriptor,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp) {
|
||||
uint32_t numAttachments = attachmentsDescriptor.fAttachmentCount;
|
||||
// Attachment descriptions to be set on the render pass
|
||||
SkTArray<VkAttachmentDescription> attachments(numAttachments);
|
||||
attachments.reset(numAttachments);
|
||||
@ -74,11 +91,13 @@ void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
subpassDesc.pInputAttachments = nullptr;
|
||||
subpassDesc.pResolveAttachments = nullptr;
|
||||
|
||||
if (fAttachmentFlags & kColor_AttachmentFlag) {
|
||||
uint32_t clearValueCount = 0;
|
||||
|
||||
if (attachmentFlags & kColor_AttachmentFlag) {
|
||||
// set up color attachment
|
||||
fAttachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
|
||||
attachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
|
||||
setup_vk_attachment_description(&attachments[currentAttachment],
|
||||
fAttachmentsDescriptor.fColor,
|
||||
attachmentsDescriptor.fColor,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
// setup subpass use of attachment
|
||||
colorRef.attachment = currentAttachment++;
|
||||
@ -86,7 +105,7 @@ void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
subpassDesc.colorAttachmentCount = 1;
|
||||
|
||||
if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
|
||||
fClearValueCount = colorRef.attachment + 1;
|
||||
clearValueCount = colorRef.attachment + 1;
|
||||
}
|
||||
} else {
|
||||
// I don't think there should ever be a time where we don't have a color attachment
|
||||
@ -97,17 +116,17 @@ void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
}
|
||||
subpassDesc.pColorAttachments = &colorRef;
|
||||
|
||||
if (fAttachmentFlags & kStencil_AttachmentFlag) {
|
||||
if (attachmentFlags & kStencil_AttachmentFlag) {
|
||||
// set up stencil attachment
|
||||
fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
|
||||
attachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
|
||||
setup_vk_attachment_description(&attachments[currentAttachment],
|
||||
fAttachmentsDescriptor.fStencil,
|
||||
attachmentsDescriptor.fStencil,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
// setup subpass use of attachment
|
||||
stencilRef.attachment = currentAttachment++;
|
||||
stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
if (VK_ATTACHMENT_LOAD_OP_CLEAR == stencilOp.fLoadOp) {
|
||||
fClearValueCount = SkTMax(fClearValueCount, stencilRef.attachment + 1);
|
||||
clearValueCount = SkTMax(clearValueCount, stencilRef.attachment + 1);
|
||||
}
|
||||
} else {
|
||||
stencilRef.attachment = VK_ATTACHMENT_UNUSED;
|
||||
@ -133,31 +152,34 @@ void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
createInfo.dependencyCount = 0;
|
||||
createInfo.pDependencies = nullptr;
|
||||
|
||||
GR_VK_CALL_ERRCHECK(gpu, CreateRenderPass(gpu->device(), &createInfo, nullptr, &fRenderPass));
|
||||
VkResult result;
|
||||
VkRenderPass renderPass;
|
||||
GR_VK_CALL_RESULT(gpu, result, CreateRenderPass(gpu->device(),
|
||||
&createInfo,
|
||||
nullptr,
|
||||
&renderPass));
|
||||
if (result != VK_SUCCESS) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VkExtent2D granularity;
|
||||
// Get granularity for this render pass
|
||||
GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
|
||||
fRenderPass,
|
||||
&fGranularity));
|
||||
renderPass,
|
||||
&granularity));
|
||||
|
||||
return new GrVkRenderPass(renderPass, attachmentFlags, attachmentsDescriptor, granularity,
|
||||
clearValueCount);
|
||||
}
|
||||
|
||||
void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
const GrVkRenderPass& compatibleRenderPass,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp) {
|
||||
fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
|
||||
fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
|
||||
this->init(gpu, colorOp, stencilOp);
|
||||
}
|
||||
|
||||
void GrVkRenderPass::init(GrVkGpu* gpu,
|
||||
const GrVkRenderTarget& target,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp) {
|
||||
// Get attachment information from render target. This includes which attachments the render
|
||||
// target has (color, stencil) and the attachments format and sample count.
|
||||
target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
|
||||
this->init(gpu, colorOp, stencilOp);
|
||||
GrVkRenderPass::GrVkRenderPass(VkRenderPass renderPass, AttachmentFlags flags,
|
||||
const AttachmentsDescriptor& descriptor,
|
||||
const VkExtent2D& granularity, uint32_t clearValueCount)
|
||||
: fRenderPass(renderPass)
|
||||
, fAttachmentFlags(flags)
|
||||
, fAttachmentsDescriptor(descriptor)
|
||||
, fGranularity(granularity)
|
||||
, fClearValueCount(clearValueCount) {
|
||||
}
|
||||
|
||||
void GrVkRenderPass::freeGPUData(GrVkGpu* gpu) const {
|
||||
|
@ -18,17 +18,6 @@ class GrVkRenderTarget;
|
||||
|
||||
class GrVkRenderPass : public GrVkResource {
|
||||
public:
|
||||
GrVkRenderPass() : INHERITED(), fRenderPass(VK_NULL_HANDLE), fClearValueCount(0) {}
|
||||
|
||||
// Used when importing an external render pass. In this case we have to explicitly be told the
|
||||
// color attachment index
|
||||
explicit GrVkRenderPass(VkRenderPass renderPass, uint32_t colorAttachmentIndex)
|
||||
: INHERITED()
|
||||
, fRenderPass(renderPass)
|
||||
, fAttachmentFlags(kExternal_AttachmentFlag)
|
||||
, fClearValueCount(0)
|
||||
, fColorAttachmentIndex(colorAttachmentIndex) {}
|
||||
|
||||
struct LoadStoreOps {
|
||||
VkAttachmentLoadOp fLoadOp;
|
||||
VkAttachmentStoreOp fStoreOp;
|
||||
@ -46,16 +35,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void initSimple(GrVkGpu* gpu, const GrVkRenderTarget& target);
|
||||
void init(GrVkGpu* gpu,
|
||||
const GrVkRenderTarget& target,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp);
|
||||
static GrVkRenderPass* CreateSimple(GrVkGpu* gpu, const GrVkRenderTarget& target);
|
||||
static GrVkRenderPass* Create(GrVkGpu* gpu,
|
||||
const GrVkRenderPass& compatibleRenderPass,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp);
|
||||
|
||||
void init(GrVkGpu* gpu,
|
||||
const GrVkRenderPass& compatibleRenderPass,
|
||||
const LoadStoreOps& colorOp,
|
||||
const LoadStoreOps& stencilOp);
|
||||
// Used when importing an external render pass. In this case we have to explicitly be told the
|
||||
// color attachment index
|
||||
explicit GrVkRenderPass(VkRenderPass renderPass, uint32_t colorAttachmentIndex)
|
||||
: INHERITED()
|
||||
, fRenderPass(renderPass)
|
||||
, fAttachmentFlags(kExternal_AttachmentFlag)
|
||||
, fClearValueCount(0)
|
||||
, fColorAttachmentIndex(colorAttachmentIndex) {}
|
||||
|
||||
struct AttachmentsDescriptor {
|
||||
struct AttachmentDesc {
|
||||
@ -132,11 +125,14 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
GrVkRenderPass(const GrVkRenderPass&);
|
||||
GrVkRenderPass(VkRenderPass, AttachmentFlags, const AttachmentsDescriptor&,
|
||||
const VkExtent2D& granularity, uint32_t clearValueCount);
|
||||
|
||||
void init(GrVkGpu* gpu,
|
||||
const LoadStoreOps& colorOps,
|
||||
const LoadStoreOps& stencilOps);
|
||||
static GrVkRenderPass* Create(GrVkGpu* gpu,
|
||||
AttachmentFlags,
|
||||
AttachmentsDescriptor&,
|
||||
const LoadStoreOps& colorOps,
|
||||
const LoadStoreOps& stencilOps);
|
||||
|
||||
bool isCompatible(const AttachmentsDescriptor&, const AttachmentFlags&) const;
|
||||
|
||||
|
@ -259,8 +259,6 @@ const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass() {
|
||||
|
||||
fCachedSimpleRenderPass =
|
||||
this->getVkGpu()->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
|
||||
// TODO: allow for the above call to fail and handle returning null from getSimpleRenderPass
|
||||
SkASSERT(fCachedSimpleRenderPass);
|
||||
return fCachedSimpleRenderPass;
|
||||
}
|
||||
|
||||
@ -278,8 +276,11 @@ const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer() {
|
||||
GrVkGpu* gpu = this->getVkGpu();
|
||||
// Stencil attachment view is stored in the base RT stencil attachment
|
||||
const GrVkImageView* stencilView = this->stencilAttachmentView();
|
||||
fCachedFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
|
||||
this->getSimpleRenderPass(),
|
||||
const GrVkRenderPass* renderPass = this->getSimpleRenderPass();
|
||||
if (!renderPass) {
|
||||
return nullptr;
|
||||
}
|
||||
fCachedFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(), renderPass,
|
||||
fColorAttachmentView, stencilView);
|
||||
return fCachedFramebuffer;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
SkASSERT(!fCachedSimpleRenderPass);
|
||||
this->createSimpleRenderPass();
|
||||
}
|
||||
SkASSERT(fCompatibleRPHandle.isValid() == SkToBool(fCachedSimpleRenderPass));
|
||||
return fCompatibleRPHandle;
|
||||
}
|
||||
const GrVkRenderPass* externalRenderPass() const {
|
||||
|
@ -119,9 +119,11 @@ GrVkResourceProvider::findCompatibleRenderPass(const GrVkRenderTarget& target,
|
||||
}
|
||||
}
|
||||
|
||||
const GrVkRenderPass* renderPass =
|
||||
fRenderPassArray.emplace_back(fGpu, target).getCompatibleRenderPass();
|
||||
renderPass->ref();
|
||||
GrVkRenderPass* renderPass = GrVkRenderPass::CreateSimple(fGpu, target);
|
||||
if (!renderPass) {
|
||||
return nullptr;
|
||||
}
|
||||
fRenderPassArray.emplace_back(renderPass);
|
||||
|
||||
if (compatibleHandle) {
|
||||
*compatibleHandle = CompatibleRPHandle(fRenderPassArray.count() - 1);
|
||||
@ -134,6 +136,7 @@ GrVkResourceProvider::findCompatibleRenderPass(const CompatibleRPHandle& compati
|
||||
SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.count());
|
||||
int index = compatibleHandle.toIndex();
|
||||
const GrVkRenderPass* renderPass = fRenderPassArray[index].getCompatibleRenderPass();
|
||||
SkASSERT(renderPass);
|
||||
renderPass->ref();
|
||||
return renderPass;
|
||||
}
|
||||
@ -167,10 +170,10 @@ const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
|
||||
GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
|
||||
: &tempRPHandle;
|
||||
*pRPHandle = target->compatibleRenderPassHandle();
|
||||
if (!pRPHandle->isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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(*pRPHandle, colorOps, stencilOps);
|
||||
}
|
||||
|
||||
@ -183,6 +186,9 @@ GrVkResourceProvider::findRenderPass(const CompatibleRPHandle& compatibleHandle,
|
||||
const GrVkRenderPass* renderPass = compatibleSet.getRenderPass(fGpu,
|
||||
colorOps,
|
||||
stencilOps);
|
||||
if (!renderPass) {
|
||||
return nullptr;
|
||||
}
|
||||
renderPass->ref();
|
||||
return renderPass;
|
||||
}
|
||||
@ -533,10 +539,10 @@ void GrVkResourceProvider::storePipelineCacheData() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(
|
||||
GrVkGpu* gpu, const GrVkRenderTarget& target) : fLastReturnedIndex(0) {
|
||||
fRenderPasses.emplace_back(new GrVkRenderPass());
|
||||
fRenderPasses[0]->initSimple(gpu, target);
|
||||
GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(GrVkRenderPass* renderPass)
|
||||
: fLastReturnedIndex(0) {
|
||||
renderPass->ref();
|
||||
fRenderPasses.push_back(renderPass);
|
||||
}
|
||||
|
||||
bool GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(
|
||||
@ -558,8 +564,12 @@ GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(
|
||||
return fRenderPasses[idx];
|
||||
}
|
||||
}
|
||||
GrVkRenderPass* renderPass = fRenderPasses.emplace_back(new GrVkRenderPass());
|
||||
renderPass->init(gpu, *this->getCompatibleRenderPass(), colorOps, stencilOps);
|
||||
GrVkRenderPass* renderPass = GrVkRenderPass::Create(gpu, *this->getCompatibleRenderPass(),
|
||||
colorOps, stencilOps);
|
||||
if (!renderPass) {
|
||||
return nullptr;
|
||||
}
|
||||
fRenderPasses.push_back(renderPass);
|
||||
fLastReturnedIndex = fRenderPasses.count() - 1;
|
||||
return renderPass;
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ private:
|
||||
// This will always construct the basic load store render pass (all attachments load and
|
||||
// store their data) so that there is at least one compatible VkRenderPass that can be used
|
||||
// with this set.
|
||||
CompatibleRenderPassSet(GrVkGpu* gpu, const GrVkRenderTarget& target);
|
||||
CompatibleRenderPassSet(GrVkRenderPass* renderPass);
|
||||
|
||||
bool isCompatible(const GrVkRenderTarget& target) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user