Fix vulkan caps checks for external formats.

Change-Id: I586e823efefdfbdf0397e3c1940e787930daaa00
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243738
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2019-09-26 15:18:32 -04:00 committed by Skia Commit-Bot
parent 7f367983b5
commit a7b7fe030e
6 changed files with 56 additions and 15 deletions

View File

@ -1194,11 +1194,33 @@ void GrVkCaps::FormatInfo::init(const GrVkInterface* interface,
}
}
// For many checks in caps, we need to know whether the GrBackendFormat is external or not. If it is
// external the VkFormat will be VK_NULL_HANDLE which is not handled by our various format
// capability checks.
static bool backend_format_is_external(const GrBackendFormat& format) {
const GrVkYcbcrConversionInfo* ycbcrInfo = format.getVkYcbcrConversionInfo();
SkASSERT(ycbcrInfo);
// All external formats have a valid ycbcrInfo used for sampling and a non zero external format.
if (ycbcrInfo->isValid() && ycbcrInfo->fExternalFormat != 0) {
#ifdef SK_DEBUG
VkFormat vkFormat;
SkAssertResult(format.asVkFormat(&vkFormat));
SkASSERT(vkFormat == VK_NULL_HANDLE);
#endif
return true;
}
return false;
}
bool GrVkCaps::isFormatSRGB(const GrBackendFormat& format) const {
VkFormat vkFormat;
if (!format.asVkFormat(&vkFormat)) {
return false;
}
if (backend_format_is_external(format)) {
return false;
}
return format_is_srgb(vkFormat);
}
@ -1209,8 +1231,6 @@ bool GrVkCaps::isFormatCompressed(const GrBackendFormat& format) const {
return false;
}
SkASSERT(GrVkFormatIsSupported(vkFormat));
return vkFormat == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
}
@ -1231,6 +1251,11 @@ bool GrVkCaps::isFormatTexturable(const GrBackendFormat& format) const {
if (!format.asVkFormat(&vkFormat)) {
return false;
}
if (backend_format_is_external(format)) {
// We can always texture from an external format (assuming we have the ycbcr conversion
// info which we require to be passed in).
return true;
}
return this->isVkFormatTexturable(vkFormat);
}
@ -1338,8 +1363,9 @@ GrCaps::SupportedWrite GrVkCaps::supportedWritePixelsColorType(GrColorType surfa
return {GrColorType::kUnknown, 0};
}
if (GrVkFormatNeedsYcbcrSampler(vkFormat)) {
// We don't support the ability to upload to external formats or formats that require a ycbcr
// sampler. In general these types of formats are only used for sampling in a shader.
if (backend_format_is_external(surfaceFormat) || GrVkFormatNeedsYcbcrSampler(vkFormat)) {
return {GrColorType::kUnknown, 0};
}
@ -1400,7 +1426,7 @@ bool GrVkCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
if (ycbcrInfo->isValid() && !GrVkFormatNeedsYcbcrSampler(vkFormat)) {
// Format may be undefined for external images, which are required to have YCbCr conversion.
if (VK_FORMAT_UNDEFINED == vkFormat) {
if (VK_FORMAT_UNDEFINED == vkFormat && ycbcrInfo->fExternalFormat != 0) {
return true;
}
return false;

View File

@ -1105,14 +1105,17 @@ static bool check_image_info(const GrVkCaps& caps,
return false;
}
if (info.fImageLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && !caps.supportsSwapchain()) {
return false;
}
if (info.fYcbcrConversionInfo.isValid()) {
if (!caps.supportsYcbcrConversion()) {
return false;
}
}
if (info.fImageLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && !caps.supportsSwapchain()) {
return false;
if (info.fYcbcrConversionInfo.fExternalFormat != 0) {
return true;
}
}
SkASSERT(GrVkFormatColorTypePairIsValid(info.fFormat, colorType));
@ -1120,6 +1123,9 @@ static bool check_image_info(const GrVkCaps& caps,
}
static bool check_tex_image_info(const GrVkCaps& caps, const GrVkImageInfo& info) {
if (info.fYcbcrConversionInfo.isValid() && info.fYcbcrConversionInfo.fExternalFormat != 0) {
return true;
}
if (info.fImageTiling == VK_IMAGE_TILING_OPTIMAL) {
if (!caps.isVkFormatTexturable(info.fFormat)) {
return false;
@ -1344,6 +1350,7 @@ bool GrVkGpu::onRegenerateMipMapLevels(GrTexture* tex) {
SkDebugf("Trying to create mipmap for linear tiled texture");
return false;
}
SkASSERT(tex->texturePriv().textureType() == GrTextureType::k2D);
// determine if we can blit to and from this format
const GrVkCaps& caps = this->vkCaps();

View File

@ -79,7 +79,6 @@ VkImageAspectFlags vk_format_to_aspect_flags(VkFormat format) {
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
SkASSERT(GrVkFormatIsSupported(format));
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}

View File

@ -31,6 +31,8 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
GrTextureType::k2D, mipMapsStatus)
, fTextureView(view) {
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
// We don't support creating external GrVkTextures
SkASSERT(!info.fYcbcrConversionInfo.isValid() || !info.fYcbcrConversionInfo.fExternalFormat);
this->registerWithCache(budgeted);
if (GrVkFormatIsCompressed(info.fFormat)) {
this->setReadOnly();
@ -40,11 +42,11 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
GrVkTexture::GrVkTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout, const GrVkImageView* view,
GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership,
GrWrapCacheable cacheable, GrIOType ioType)
GrWrapCacheable cacheable, GrIOType ioType, bool isExternal)
: GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, info.fProtected)
, GrVkImage(info, std::move(layout), ownership)
, INHERITED(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, info.fProtected,
GrTextureType::k2D, mipMapsStatus)
isExternal ? GrTextureType::kExternal : GrTextureType::k2D, mipMapsStatus)
, fTextureView(view) {
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
if (ioType == kRead_GrIOType) {
@ -67,6 +69,9 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
GrTextureType::k2D, mipMapsStatus)
, fTextureView(view) {
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
// Since this ctor is only called from GrVkTextureRenderTarget, we can't have a ycbcr conversion
// since we don't support that on render targets.
SkASSERT(!info.fYcbcrConversionInfo.isValid());
}
sk_sp<GrVkTexture> GrVkTexture::MakeNewTexture(GrVkGpu* gpu, SkBudgeted budgeted,
@ -116,8 +121,11 @@ sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
bool isExternal = info.fYcbcrConversionInfo.isValid() &&
(info.fYcbcrConversionInfo.fExternalFormat != 0);
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, desc, info, std::move(layout), imageView,
mipMapsStatus, ownership, cacheable, ioType));
mipMapsStatus, ownership, cacheable, ioType,
isExternal));
}
GrVkTexture::~GrVkTexture() {

View File

@ -62,7 +62,7 @@ private:
GrMipMapsStatus);
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, sk_sp<GrVkImageLayout>,
const GrVkImageView*, GrMipMapsStatus, GrBackendObjectOwnership, GrWrapCacheable,
GrIOType);
GrIOType, bool isExternal);
// 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).

View File

@ -294,7 +294,8 @@ GrGLSLUniformHandler::SamplerHandle GrVkUniformHandler::addSampler(const GrTextu
void GrVkUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
for (int i = 0; i < fSamplers.count(); ++i) {
const UniformInfo& sampler = fSamplers[i];
SkASSERT(sampler.fVariable.getType() == kTexture2DSampler_GrSLType);
SkASSERT(sampler.fVariable.getType() == kTexture2DSampler_GrSLType ||
sampler.fVariable.getType() == kTextureExternalSampler_GrSLType);
if (visibility == sampler.fVisibility) {
sampler.fVariable.appendDecl(fProgramBuilder->shaderCaps(), out);
out->append(";\n");