/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrVkStencilAttachment.h" #include "GrVkGpu.h" #include "GrVkImage.h" #include "GrVkImageView.h" #include "GrVkUtil.h" #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) GrVkStencilAttachment::GrVkStencilAttachment(GrVkGpu* gpu, const Format& format, const GrVkImage::ImageDesc& desc, const GrVkImageInfo& info, sk_sp layout, const GrVkImageView* stencilView) : GrStencilAttachment(gpu, desc.fWidth, desc.fHeight, format.fStencilBits, desc.fSamples) , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kOwned) , fFormat(format) , fStencilView(stencilView) { this->registerWithCache(SkBudgeted::kYes); stencilView->ref(); } GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu, int width, int height, int sampleCnt, const Format& format) { GrVkImage::ImageDesc imageDesc; imageDesc.fImageType = VK_IMAGE_TYPE_2D; imageDesc.fFormat = format.fInternalFormat; imageDesc.fWidth = width; imageDesc.fHeight = height; imageDesc.fLevels = 1; imageDesc.fSamples = sampleCnt; imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; imageDesc.fUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; GrVkImageInfo info; if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) { return nullptr; } const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage, format.fInternalFormat, GrVkImageView::kStencil_Type, 1); if (!imageView) { GrVkImage::DestroyImageInfo(gpu, &info); return nullptr; } sk_sp layout(new GrVkImageLayout(info.fImageLayout)); GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, format, imageDesc, info, std::move(layout), imageView); imageView->unref(gpu); return stencil; } GrVkStencilAttachment::~GrVkStencilAttachment() { // should have been released or abandoned first SkASSERT(!fStencilView); } size_t GrVkStencilAttachment::onGpuMemorySize() const { uint64_t size = this->width(); size *= this->height(); size *= fFormat.fTotalBits; size *= this->numSamples(); return static_cast(size / 8); } void GrVkStencilAttachment::onRelease() { GrVkGpu* gpu = this->getVkGpu(); this->releaseImage(gpu); fStencilView->unref(gpu); fStencilView = nullptr; GrStencilAttachment::onRelease(); } void GrVkStencilAttachment::onAbandon() { this->abandonImage(); fStencilView->unrefAndAbandon(); fStencilView = nullptr; GrStencilAttachment::onAbandon(); } GrVkGpu* GrVkStencilAttachment::getVkGpu() const { SkASSERT(!this->wasDestroyed()); return static_cast(this->getGpu()); }