blob: 43e213fc5002255ba9e0a68fd3c96471c6aaf82f [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.
*/
#include "GrVkTextureRenderTarget.h"
#include "GrRenderTargetPriv.h"
#include "GrVkGpu.h"
#include "GrVkImageView.h"
#include "GrVkUtil.h"
#include "vk/GrVkTypes.h"
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
const GrVkImage::Resource* imageResource) {
VkImage image = imageResource->fImage;
// Create the texture ImageView
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
GrVkImageView::kColor_Type);
if (!imageView) {
return nullptr;
}
VkFormat pixelFormat;
GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
VkImage colorImage;
// create msaa surface if necessary
const GrVkImage::Resource* msaaImageResource = nullptr;
const GrVkImageView* resolveAttachmentView = nullptr;
if (desc.fSampleCnt) {
GrVkImage::ImageDesc msImageDesc;
msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
msImageDesc.fFormat = pixelFormat;
msImageDesc.fWidth = desc.fWidth;
msImageDesc.fHeight = desc.fHeight;
msImageDesc.fLevels = 1;
msImageDesc.fSamples = desc.fSampleCnt;
msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc);
if (!msaaImageResource) {
imageView->unref(gpu);
return nullptr;
}
// Set color attachment image
colorImage = msaaImageResource->fImage;
// Create resolve attachment view if necessary.
// If the format matches, this is the same as the texture imageView.
if (pixelFormat == format) {
resolveAttachmentView = imageView;
resolveAttachmentView->ref();
} else {
resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
GrVkImageView::kColor_Type);
if (!resolveAttachmentView) {
msaaImageResource->unref(gpu);
imageView->unref(gpu);
return nullptr;
}
}
} else {
// Set color attachment image
colorImage = imageResource->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 == format && !resolveAttachmentView) {
colorAttachmentView = imageView;
colorAttachmentView->ref();
} else {
colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
GrVkImageView::kColor_Type);
if (!colorAttachmentView) {
if (msaaImageResource) {
resolveAttachmentView->unref(gpu);
msaaImageResource->unref(gpu);
}
imageView->unref(gpu);
return nullptr;
}
}
GrVkTextureRenderTarget* texRT;
if (msaaImageResource) {
texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
imageResource, imageView, msaaImageResource,
colorAttachmentView,
resolveAttachmentView);
msaaImageResource->unref(gpu);
} else {
texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
imageResource, imageView,
colorAttachmentView);
}
return texRT;
}
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::ImageDesc& imageDesc) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(gpu, imageDesc);
if (!imageRsrc) {
return nullptr;
}
GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
imageDesc.fFormat, imageRsrc);
// Create() will increment the refCount of the image resource if it succeeds
imageRsrc->unref(gpu);
return trt;
}
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
const GrVkTextureInfo* info) {
SkASSERT(info);
// Wrapped textures require both image and allocation (because they can be mapped)
SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
const GrVkImage::Resource* imageResource;
if (kBorrowed_LifeCycle == lifeCycle) {
imageResource = new GrVkImage::BorrowedResource(info->fImage, info->fAlloc, flags);
} else {
imageResource = new GrVkImage::Resource(info->fImage, info->fAlloc, flags);
}
if (!imageResource) {
return nullptr;
}
GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
format, imageResource);
if (trt) {
trt->fCurrentLayout = info->fImageLayout;
}
// Create() will increment the refCount of the image resource if it succeeds
imageResource->unref(gpu);
return trt;
}