blob: f0bc6c66c856683b1ecfff1a69dac20cbe4b5a70 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrVkRenderTarget_DEFINED
#define GrVkRenderTarget_DEFINED
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/vk/GrVkImage.h"
#include "include/gpu/vk/GrVkTypes.h"
#include "src/gpu/vk/GrVkRenderPass.h"
#include "src/gpu/vk/GrVkResourceProvider.h"
class GrVkFramebuffer;
class GrVkGpu;
class GrVkImageView;
struct GrVkImageInfo;
class GrVkRenderTarget : public GrRenderTarget {
public:
static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*,
SkISize,
int sampleCnt,
const GrVkImageInfo&,
sk_sp<GrBackendSurfaceMutableStateImpl>);
static sk_sp<GrVkRenderTarget> MakeSecondaryCBRenderTarget(GrVkGpu*,
SkISize,
const GrVkDrawableInfo& vkInfo);
~GrVkRenderTarget() override;
GrBackendFormat backendFormat() const override;
using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
using LoadFromResolve = GrVkRenderPass::LoadFromResolve;
const GrVkFramebuffer* getFramebuffer(bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve);
const GrVkFramebuffer* getFramebuffer(const GrVkRenderPass& renderPass) {
return this->getFramebuffer(renderPass.hasResolveAttachment(),
renderPass.hasStencilAttachment(),
renderPass.selfDependencyFlags(),
renderPass.loadFromResolve());
}
GrVkImage* colorAttachment() const {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
return fColorAttachment.get();
}
const GrVkImageView* colorAttachmentView() const {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
return this->colorAttachment()->framebufferView();
}
GrVkImage* resolveAttachment() const {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
return fResolveAttachment.get();
}
const GrVkImageView* resolveAttachmentView() const {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
return fResolveAttachment->framebufferView();
}
// Returns the GrVkImage of the non-msaa attachment. If the color attachment has 1 sample,
// then the color attachment will be returned. Otherwise, the resolve attachment is returned.
// Note that in this second case the resolve attachment may be null if this was created by
// wrapping an msaa VkImage.
GrVkImage* nonMSAAAttachment() const;
// Returns the attachment that is used for all external client facing operations. This will be
// either a wrapped color attachment or the resolve attachment for created VkImages.
GrVkImage* externalAttachment() const {
return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
}
const GrVkRenderPass* getSimpleRenderPass(
bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve);
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(
bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve);
bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); }
sk_sp<GrVkFramebuffer> externalFramebuffer() const;
bool canAttemptStencilAttachment(bool useMSAASurface) const override;
GrBackendRenderTarget getBackendRenderTarget() const override;
void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags* flags,
bool withResolve,
bool withStencil);
// 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);
protected:
enum class CreateType {
kDirectlyWrapped, // We need to register this in the ctor
kFromTextureRT, // Skip registering this to cache since TexRT will handle it
};
GrVkRenderTarget(GrVkGpu* gpu,
SkISize dimensions,
sk_sp<GrVkImage> colorAttachment,
sk_sp<GrVkImage> resolveImage,
CreateType createType);
void onAbandon() override;
void onRelease() override;
// This returns zero since the memory should all be handled by the attachments
size_t onGpuMemorySize() const override { return 0; }
private:
// For external framebuffers that wrap a secondary command buffer
GrVkRenderTarget(GrVkGpu* gpu,
SkISize dimensions,
sk_sp<GrVkFramebuffer> externalFramebuffer);
void setFlags();
GrVkGpu* getVkGpu() const;
GrVkImage* dynamicMSAAAttachment();
GrVkImage* msaaAttachment();
std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
createSimpleRenderPass(bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve);
void createFramebuffer(bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve);
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
// In Vulkan we call the release proc after we are finished with the underlying
// GrVkImage::Resource object (which occurs after the GPU has finished all work on it).
void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override {
// Forward the release proc on to the GrVkImage of the release attachment if we have one,
// otherwise the color attachment.
GrVkImage* attachment =
fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
attachment->setResourceRelease(std::move(releaseHelper));
}
void releaseInternalObjects();
sk_sp<GrVkImage> fColorAttachment;
sk_sp<GrVkImage> fResolveAttachment;
sk_sp<GrVkImage> fDynamicMSAAAttachment;
// We can have a renderpass with and without resolve attachment, stencil attachment,
// input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of
// these being completely orthogonal. Thus we have a total of 32 types of render passes. We then
// cache a framebuffer for each type of these render passes.
static constexpr int kNumCachedFramebuffers = 32;
sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers];
const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr;
sk_sp<GrVkFramebuffer> fExternalFramebuffer;
};
#endif