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:
parent
7f367983b5
commit
a7b7fe030e
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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).
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user