Add program pre-compilation to Vulkan backend
This CL fills out the GrVkGpu::compile method and updates GrVkCaps::makeDesc to both reconstruct the GrVkRenderPass AttachmentsDescriptor and AttachmentFlags from the GrProgramDesc. In the 'compile' case, the renderPass info is used to get a renderpass and then a pipeline state. In the 'makeDesc' case, the renderPass info is used to create the ProgramDesc. Bug: skia:9455 Change-Id: I3810651232c95c3d837d96655853ea54056c70cb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288462 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
f63713518c
commit
24e2f6e25e
@ -71,11 +71,10 @@ private:
|
||||
|
||||
const GrCaps* caps = this->caps();
|
||||
|
||||
if (this->backend() == GrBackendApi::kVulkan ||
|
||||
this->backend() == GrBackendApi::kMetal ||
|
||||
if (this->backend() == GrBackendApi::kMetal ||
|
||||
this->backend() == GrBackendApi::kDirect3D ||
|
||||
this->backend() == GrBackendApi::kDawn) {
|
||||
// Currently Vulkan, Metal, Direct3D, and Dawn require a live renderTarget to
|
||||
// Currently Metal, Direct3D, and Dawn require a live renderTarget to
|
||||
// compute the key
|
||||
return;
|
||||
}
|
||||
|
@ -975,8 +975,7 @@ int GrRenderTargetContextPriv::maxWindowRectangles() const {
|
||||
*fRenderTargetContext->caps());
|
||||
}
|
||||
|
||||
GrOpsTask::CanDiscardPreviousOps GrRenderTargetContext::canDiscardPreviousOpsOnFullClear(
|
||||
) const {
|
||||
GrOpsTask::CanDiscardPreviousOps GrRenderTargetContext::canDiscardPreviousOpsOnFullClear() const {
|
||||
#if GR_TEST_UTILS
|
||||
if (fPreserveOpsOnFullClear_TestingOnly) {
|
||||
return GrOpsTask::CanDiscardPreviousOps::kNo;
|
||||
|
@ -1701,13 +1701,39 @@ GrProgramDesc GrVkCaps::makeDesc(const GrRenderTarget* rt, const GrProgramInfo&
|
||||
// GrVkPipelineStateBuilder.cpp).
|
||||
b.add32(GrVkGpu::kShader_PersistentCacheKeyType);
|
||||
|
||||
GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
|
||||
if (rt) {
|
||||
GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
|
||||
|
||||
bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
|
||||
// TODO: support failure in getSimpleRenderPass
|
||||
const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil);
|
||||
SkASSERT(rp);
|
||||
rp->genKey(&b);
|
||||
bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
|
||||
// TODO: support failure in getSimpleRenderPass
|
||||
const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil);
|
||||
SkASSERT(rp);
|
||||
rp->genKey(&b);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (!rp->isExternal()) {
|
||||
// This is to ensure ReconstructAttachmentsDescriptor keeps matching
|
||||
// getSimpleRenderPass' result
|
||||
GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
|
||||
GrVkRenderPass::AttachmentFlags attachmentFlags;
|
||||
GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
|
||||
&attachmentsDescriptor,
|
||||
&attachmentFlags);
|
||||
SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
|
||||
GrVkRenderPass::AttachmentFlags attachmentFlags;
|
||||
GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
|
||||
&attachmentsDescriptor,
|
||||
&attachmentFlags);
|
||||
|
||||
// kExternal_AttachmentFlag is only set for wrapped secondary command buffers - which
|
||||
// will always go through the above 'rt' path (i.e., we can always pass 0 as the final
|
||||
// parameter to GenKey).
|
||||
GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, 0);
|
||||
}
|
||||
|
||||
GrStencilSettings stencil = programInfo.nonGLStencilSettings();
|
||||
stencil.genKey(&b, true);
|
||||
|
@ -1896,8 +1896,33 @@ void GrVkGpu::deleteBackendTexture(const GrBackendTexture& tex) {
|
||||
}
|
||||
}
|
||||
|
||||
bool GrVkGpu::compile(const GrProgramDesc&, const GrProgramInfo&) {
|
||||
return false;
|
||||
bool GrVkGpu::compile(const GrProgramDesc& desc, const GrProgramInfo& programInfo) {
|
||||
SkASSERT(!(GrProcessor::CustomFeatures::kSampleLocations & programInfo.requestedFeatures()));
|
||||
|
||||
GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
|
||||
GrVkRenderPass::AttachmentFlags attachmentFlags;
|
||||
GrVkRenderTarget::ReconstructAttachmentsDescriptor(this->vkCaps(), programInfo,
|
||||
&attachmentsDescriptor, &attachmentFlags);
|
||||
|
||||
sk_sp<const GrVkRenderPass> renderPass(this->resourceProvider().findCompatibleRenderPass(
|
||||
&attachmentsDescriptor,
|
||||
attachmentFlags));
|
||||
if (!renderPass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Stats::ProgramCacheResult stat;
|
||||
|
||||
auto pipelineState = this->resourceProvider().findOrCreateCompatiblePipelineState(
|
||||
desc,
|
||||
programInfo,
|
||||
renderPass->vkRenderPass(),
|
||||
&stat);
|
||||
if (!pipelineState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stat != Stats::ProgramCacheResult::kHit;
|
||||
}
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
|
@ -266,19 +266,25 @@ bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
|
||||
}
|
||||
|
||||
void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
|
||||
b->add32(fAttachmentFlags);
|
||||
if (fAttachmentFlags & kColor_AttachmentFlag) {
|
||||
b->add32(fAttachmentsDescriptor.fColor.fFormat);
|
||||
b->add32(fAttachmentsDescriptor.fColor.fSamples);
|
||||
GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, (uint64_t)fRenderPass);
|
||||
}
|
||||
|
||||
void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b,
|
||||
AttachmentFlags attachmentFlags,
|
||||
const AttachmentsDescriptor& attachmentsDescriptor,
|
||||
uint64_t externalRenderPass) {
|
||||
b->add32(attachmentFlags);
|
||||
if (attachmentFlags & kColor_AttachmentFlag) {
|
||||
b->add32(attachmentsDescriptor.fColor.fFormat);
|
||||
b->add32(attachmentsDescriptor.fColor.fSamples);
|
||||
}
|
||||
if (fAttachmentFlags & kStencil_AttachmentFlag) {
|
||||
b->add32(fAttachmentsDescriptor.fStencil.fFormat);
|
||||
b->add32(fAttachmentsDescriptor.fStencil.fSamples);
|
||||
if (attachmentFlags & kStencil_AttachmentFlag) {
|
||||
b->add32(attachmentsDescriptor.fStencil.fFormat);
|
||||
b->add32(attachmentsDescriptor.fStencil.fSamples);
|
||||
}
|
||||
if (fAttachmentFlags & kExternal_AttachmentFlag) {
|
||||
SkASSERT(!(fAttachmentFlags & ~kExternal_AttachmentFlag));
|
||||
uint64_t handle = (uint64_t)fRenderPass;
|
||||
b->add32((uint32_t)(handle & 0xFFFFFFFF));
|
||||
b->add32((uint32_t)(handle>>32));
|
||||
if (attachmentFlags & kExternal_AttachmentFlag) {
|
||||
SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag));
|
||||
b->add32((uint32_t)(externalRenderPass & 0xFFFFFFFF));
|
||||
b->add32((uint32_t)(externalRenderPass>>32));
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,8 @@ public:
|
||||
|
||||
bool isCompatibleExternalRP(VkRenderPass) const;
|
||||
|
||||
SkDEBUGCODE(bool isExternal() const { return fAttachmentFlags & kExternal_AttachmentFlag; })
|
||||
|
||||
bool equalLoadStoreOps(const LoadStoreOps& colorOps,
|
||||
const LoadStoreOps& stencilOps) const;
|
||||
|
||||
@ -120,7 +122,12 @@ public:
|
||||
uint32_t clearValueCount() const { return fClearValueCount; }
|
||||
|
||||
|
||||
void genKey(GrProcessorKeyBuilder* b) const;
|
||||
void genKey(GrProcessorKeyBuilder*) const;
|
||||
|
||||
static void GenKey(GrProcessorKeyBuilder*,
|
||||
AttachmentFlags,
|
||||
const AttachmentsDescriptor&,
|
||||
uint64_t externalRenderPass);
|
||||
|
||||
#ifdef SK_TRACE_MANAGED_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
|
@ -343,6 +343,36 @@ void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescr
|
||||
desc->fAttachmentCount = attachmentCount;
|
||||
}
|
||||
|
||||
void GrVkRenderTarget::ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrVkRenderPass::AttachmentsDescriptor* desc,
|
||||
GrVkRenderPass::AttachmentFlags* flags) {
|
||||
VkFormat format;
|
||||
SkAssertResult(programInfo.backendFormat().asVkFormat(&format));
|
||||
|
||||
desc->fColor.fFormat = format;
|
||||
desc->fColor.fSamples = programInfo.numSamples();
|
||||
*flags = GrVkRenderPass::kColor_AttachmentFlag;
|
||||
uint32_t attachmentCount = 1;
|
||||
|
||||
SkASSERT(!programInfo.isStencilEnabled() || programInfo.numStencilSamples());
|
||||
if (programInfo.numStencilSamples()) {
|
||||
const GrVkCaps::StencilFormat& stencilFormat = vkCaps.preferredStencilFormat();
|
||||
desc->fStencil.fFormat = stencilFormat.fInternalFormat;
|
||||
desc->fStencil.fSamples = programInfo.numStencilSamples();
|
||||
#ifdef SK_DEBUG
|
||||
if (vkCaps.mixedSamplesSupport()) {
|
||||
SkASSERT(desc->fStencil.fSamples >= desc->fColor.fSamples);
|
||||
} else {
|
||||
SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
|
||||
}
|
||||
#endif
|
||||
*flags |= GrVkRenderPass::kStencil_AttachmentFlag;
|
||||
++attachmentCount;
|
||||
}
|
||||
desc->fAttachmentCount = attachmentCount;
|
||||
}
|
||||
|
||||
GrVkRenderTarget::~GrVkRenderTarget() {
|
||||
// either release or abandon should have been called by the owner of this object.
|
||||
SkASSERT(!fMSAAImage);
|
||||
|
@ -100,6 +100,14 @@ public:
|
||||
GrVkRenderPass::AttachmentFlags* flags,
|
||||
bool withStencil) const;
|
||||
|
||||
// Reconstruct the render target attachment information from the programInfo. This includes
|
||||
// which attachments the render target will have (color, stencil) and the attachments' formats
|
||||
// and sample counts - cf. getAttachmentsDescriptor.
|
||||
static void ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps,
|
||||
const GrProgramInfo& programInfo,
|
||||
GrVkRenderPass::AttachmentsDescriptor* desc,
|
||||
GrVkRenderPass::AttachmentFlags* flags);
|
||||
|
||||
void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil);
|
||||
|
||||
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
|
||||
|
Loading…
Reference in New Issue
Block a user