Update RT views and framebuffer in vulkan after mipmaping

I've also changed it so all attachment views (texture, color, and resolve) are created separately and not shared with each other. This just added a lot more complexity than we were probably even saving in time.

A quick fix to make sure we don't reuse keys in resource tracking also
got merged into this change.

BUG=skia:5223
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2146103002

Review-Url: https://codereview.chromium.org/2146103002
This commit is contained in:
egdaniel 2016-07-13 14:23:26 -07:00 committed by Commit bot
parent 990dbc8879
commit 50ead53ac9
12 changed files with 83 additions and 55 deletions

View File

@ -68,7 +68,7 @@ protected:
Type fType;
private:
void freeGPUData(const GrVkGpu* gpu) const;
void freeGPUData(const GrVkGpu* gpu) const override;
typedef GrVkResource INHERITED;
};

View File

@ -770,7 +770,7 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
return tgt;
}
void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
void GrVkGpu::generateMipmap(GrVkTexture* tex) {
// don't do anything for linearly tiled textures (can't have mipmaps)
if (tex->isLinearTiled()) {
SkDebugf("Trying to create mipmap for linear tiled texture");

View File

@ -136,7 +136,7 @@ public:
void finishDrawTarget() override;
void generateMipmap(GrVkTexture* tex) const;
void generateMipmap(GrVkTexture* tex);
bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size);

View File

@ -337,7 +337,7 @@ sk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
}
static void append_sampled_images(const GrProcessor& processor,
const GrVkGpu* gpu,
GrVkGpu* gpu,
SkTArray<GrVkImage*>* sampledImages) {
if (int numTextures = processor.numTextures()) {
GrVkImage** images = sampledImages->push_back_n(numTextures);

View File

@ -33,10 +33,10 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, GrVkImage(info, wrapped)
// for the moment we only support 1:1 color to stencil
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
, fResolveAttachmentView(resolveAttachmentView)
, fFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(desc.fSampleCnt);
// The plus 1 is to account for the resolve texture.
@ -58,10 +58,10 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, GrVkImage(info, wrapped)
// for the moment we only support 1:1 color to stencil
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
, fResolveAttachmentView(resolveAttachmentView)
, fFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(desc.fSampleCnt);
// The plus 1 is to account for the resolve texture.
@ -80,10 +80,10 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
: GrSurface(gpu, desc)
, GrVkImage(info, wrapped)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(!desc.fSampleCnt);
fColorValuesPerPixel = 1;
@ -101,10 +101,10 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
: GrSurface(gpu, desc)
, GrVkImage(info, wrapped)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(!desc.fSampleCnt);
fColorValuesPerPixel = 1;
@ -117,6 +117,7 @@ GrVkRenderTarget::Create(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
GrVkImage::Wrapped wrapped) {
SkASSERT(1 == info.fLevelCount);
VkFormat pixelFormat;
GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);

View File

@ -103,6 +103,12 @@ protected:
return fColorValuesPerPixel * fDesc.fWidth * fDesc.fHeight * colorBytes;
}
void createFramebuffer(GrVkGpu* gpu);
const GrVkImageView* fColorAttachmentView;
GrVkImage* fMSAAImage;
const GrVkImageView* fResolveAttachmentView;
private:
GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted,
@ -125,15 +131,10 @@ private:
bool completeStencilAttachment() override;
void createFramebuffer(GrVkGpu* gpu);
void releaseInternalObjects();
void abandonInternalObjects();
const GrVkFramebuffer* fFramebuffer;
const GrVkImageView* fColorAttachmentView;
GrVkImage* fMSAAImage;
const GrVkImageView* fResolveAttachmentView;
int fColorValuesPerPixel;
// This is a cached pointer to a simple render pass. The render target should unref it

View File

@ -60,14 +60,14 @@ public:
};
static Trace fTrace;
static SkRandom fRandom;
static uint32_t fKeyCounter;
#endif
/** Default construct, initializing the reference count to 1.
*/
GrVkResource() : fRefCnt(1) {
#ifdef SK_TRACE_VK_RESOURCES
fKey = fRandom.nextU();
fKey = sk_atomic_fetch_add(&fKeyCounter, 1u, sk_memory_order_relaxed);
fTrace.add(this);
#endif
}

View File

@ -16,7 +16,7 @@
#ifdef SK_TRACE_VK_RESOURCES
GrVkResource::Trace GrVkResource::fTrace;
SkRandom GrVkResource::fRandom;
uint32_t GrVkResource::fKeyCounter = 0;
#endif
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)

View File

@ -9,6 +9,7 @@
#include "GrVkGpu.h"
#include "GrVkImageView.h"
#include "GrTexturePriv.h"
#include "GrVkTextureRenderTarget.h"
#include "GrVkUtil.h"
#include "vk/GrVkTypes.h"
@ -161,7 +162,7 @@ const GrVkImageView* GrVkTexture::textureView(bool allowSRGB) {
return fLinearTextureView;
}
bool GrVkTexture::reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels) {
bool GrVkTexture::reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels) {
if (mipLevels == 1) {
// don't need to do anything for a 1x1 texture
return false;
@ -174,7 +175,6 @@ bool GrVkTexture::reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels) {
return false;
}
// Does this even make sense for rendertargets?
bool renderTarget = SkToBool(fDesc.fFlags & kRenderTarget_GrSurfaceFlag);
VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
@ -209,6 +209,14 @@ bool GrVkTexture::reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels) {
return false;
}
if (renderTarget) {
GrVkTextureRenderTarget* texRT = static_cast<GrVkTextureRenderTarget*>(this);
if (!texRT->updateForMipmap(gpu, info)) {
GrVkImage::DestroyImageInfo(gpu, &info);
return false;
}
}
oldResource->unref(gpu);
oldView->unref(gpu);
if (fLinearTextureView) {

View File

@ -32,7 +32,7 @@ public:
const GrVkImageView* textureView(bool allowSRGB);
bool reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels);
bool reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels);
protected:
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, const GrVkImageView*,

View File

@ -25,13 +25,9 @@ GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
GrVkImage::Wrapped wrapped) {
VkImage image = info.fImage;
// Create the texture ImageView
uint32_t mipLevels = 1;
//TODO: does a mipmapped textureRenderTarget make sense?
//if (desc.fIsMipMapped) {
// mipLevels = SkMipMap::ComputeLevelCount(this->width(), this->height()) + 1;
//}
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
GrVkImageView::kColor_Type, mipLevels);
GrVkImageView::kColor_Type,
info.fLevelCount);
if (!imageView) {
return nullptr;
}
@ -63,34 +59,21 @@ GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
// Set color attachment image
colorImage = msInfo.fImage;
// Create resolve attachment view if necessary.
// If the format matches, this is the same as the texture imageView.
if (pixelFormat == info.fFormat) {
resolveAttachmentView = imageView;
resolveAttachmentView->ref();
} else {
// Create resolve attachment view.
resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
GrVkImageView::kColor_Type, 1);
GrVkImageView::kColor_Type,
info.fLevelCount);
if (!resolveAttachmentView) {
GrVkImage::DestroyImageInfo(gpu, &msInfo);
imageView->unref(gpu);
return nullptr;
}
}
} else {
// Set color attachment image
colorImage = info.fImage;
}
const GrVkImageView* colorAttachmentView;
// Get color attachment view.
// If the format matches and there's no multisampling,
// this is the same as the texture imageView
if (pixelFormat == info.fFormat && !resolveAttachmentView) {
colorAttachmentView = imageView;
colorAttachmentView->ref();
} else {
colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
GrVkImageView::kColor_Type, 1);
if (!colorAttachmentView) {
if (desc.fSampleCnt) {
@ -100,7 +83,7 @@ GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
imageView->unref(gpu);
return nullptr;
}
}
GrVkTextureRenderTarget* texRT;
if (desc.fSampleCnt) {
if (GrVkImage::kNot_Wrapped == wrapped) {
@ -165,3 +148,36 @@ GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
return trt;
}
bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) {
VkFormat pixelFormat;
GrPixelConfigToVkFormat(fDesc.fConfig, &pixelFormat);
if (fDesc.fSampleCnt) {
const GrVkImageView* resolveAttachmentView =
GrVkImageView::Create(gpu,
newInfo.fImage,
pixelFormat,
GrVkImageView::kColor_Type,
newInfo.fLevelCount);
if (!resolveAttachmentView) {
return false;
}
fResolveAttachmentView->unref(gpu);
fResolveAttachmentView = resolveAttachmentView;
} else {
const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu,
newInfo.fImage,
pixelFormat,
GrVkImageView::kColor_Type,
1);
if (!colorAttachmentView) {
return false;
}
fColorAttachmentView->unref(gpu);
fColorAttachmentView = colorAttachmentView;
}
this->createFramebuffer(gpu);
return true;
}

View File

@ -33,6 +33,8 @@ public:
GrWrapOwnership,
const GrVkImageInfo*);
bool updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo);
protected:
void onAbandon() override {
GrVkRenderTarget::onAbandon();