Add Ganesh support for LUM16F (take 2)
When Chrome has a LUM16F texture they tell Skia it is R16F. Although this has been working for them so far it causes trouble with some upcoming changes.
Change-Id: I2473f70e4f725128f143c2dfb08adb79f3c7c166
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228565
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index d8ad5f1..cfbfa9d 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -153,6 +153,7 @@
case kRGBA_1010102_GrPixelConfig: return "RGBA1010102";
case kRGBA_float_GrPixelConfig: return "RGBAFloat";
case kAlpha_half_GrPixelConfig: return "AlphaHalf";
+ case kAlpha_half_as_Lum_GrPixelConfig: return "AlphaHalf_asLum";
case kAlpha_half_as_Red_GrPixelConfig: return "AlphaHalf_asRed";
case kRGBA_half_GrPixelConfig: return "RGBAHalf";
case kRGBA_half_Clamped_GrPixelConfig: return "RGBAHalfClamped";
@@ -398,7 +399,8 @@
break;
case kAlpha_half_GrPixelConfig:
compatible = kAlpha_half_GrPixelConfig == specificConfig || // bc of the mock context
- kAlpha_half_as_Red_GrPixelConfig == specificConfig;
+ kAlpha_half_as_Red_GrPixelConfig == specificConfig ||
+ kAlpha_half_as_Lum_GrPixelConfig == specificConfig;
break;
case kRGB_888_GrPixelConfig:
compatible = kRGB_888_GrPixelConfig == specificConfig ||
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 0ac04f8..939ac3b 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -235,6 +235,7 @@
}
break;
}
+ case kAlpha_half_as_Lum_GrPixelConfig: // fall through
case kAlpha_half_as_Red_GrPixelConfig: // fall through
case kAlpha_half_GrPixelConfig: {
SkHalf alphaHalf = SkFloatToHalf(colorf.fA);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index d7fa9e7..188babe 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1374,6 +1374,8 @@
uint32_t fpRenderFlags = (GR_IS_GR_GL(standard)) ? msaaRenderFlags : nonMSAARenderFlags;
if (GR_IS_GR_GL(standard)) {
+ // TODO: it seems like GL_ARB_texture_float GL_ARB_color_buffer_float should be taken
+ // into account here
if (version >= GR_GL_VER(3, 0)) {
hasFP16Textures = true;
halfFPRenderTargetSupport = HalfFPRenderTargetSupport::kAll;
@@ -1839,6 +1841,67 @@
}
}
+ // LUMINANCE16F
+ {
+ // NOTE: We disallow lum16f on ES devices if linear filtering modes are not
+ // supported. This is for simplicity, but a more granular approach is possible.
+ bool lum16FSupported = false;
+
+ if (GR_IS_GR_GL(standard)) {
+ if (version >= GR_GL_VER(3, 0)) {
+ lum16FSupported = true;
+ } else if (ctxInfo.hasExtension("GL_ARB_texture_float")) {
+ lum16FSupported = true;
+ }
+ } else if (GR_IS_GR_GL_ES(standard)) {
+ if (version >= GR_GL_VER(3, 0)) {
+ lum16FSupported = true;
+ } else if (ctxInfo.hasExtension("GL_OES_texture_float_linear") &&
+ ctxInfo.hasExtension("GL_OES_texture_float")) {
+ lum16FSupported = true;
+ } else if (ctxInfo.hasExtension("GL_OES_texture_half_float_linear") &&
+ ctxInfo.hasExtension("GL_OES_texture_half_float")) {
+ lum16FSupported = true;
+ }
+ } // No WebGL support
+
+ if (formatWorkarounds.fDisableLuminance16F) {
+ lum16FSupported = false;
+ }
+
+ FormatInfo& info = this->getFormatInfo(GrGLFormat::kLUMINANCE16F);
+ info.fFormatType = FormatType::kFloat;
+ info.fBaseInternalFormat = GR_GL_LUMINANCE;
+ info.fSizedInternalFormat = GR_GL_LUMINANCE16F;
+ info.fInternalFormatForTexImage =
+ texImageSupportsSizedInternalFormat ? GR_GL_LUMINANCE16F : GR_GL_LUMINANCE;
+ info.fInternalFormatForRenderbuffer =
+ renderbufferStorageSupportsSizedInternalFormat ? GR_GL_LUMINANCE16F
+ : GR_GL_LUMINANCE;
+ info.fDefaultExternalType = halfFloatType;
+
+ if (lum16FSupported) {
+ info.fFlags = FormatInfo::kTextureable_Flag;
+ }
+ if (texStorageSupported &&
+ !formatWorkarounds.fDisablePerFormatTextureStorageForCommandBufferES2) {
+ info.fFlags |= FormatInfo::kCanUseTexStorage_Flag;
+ }
+
+ if (lum16FSupported) {
+ // kAlpha_F16
+ {
+ uint32_t flags = ColorTypeInfo::kUploadData_Flag;
+ info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_F16, flags);
+
+ int idx = static_cast<int>(GrColorType::kAlpha_F16);
+ if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
+ this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kLUMINANCE16F);
+ }
+ }
+ }
+ }
+
// RGB8
{
FormatInfo& info = this->getFormatInfo(GrGLFormat::kRGB8);
@@ -2461,17 +2524,38 @@
rgbaF32Info.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RGBA;
rgbaF32Info.fFormats.fExternalType = GR_GL_FLOAT;
- GrGLenum redHalfExternalType;
- if (GR_IS_GR_GL(standard) ||
- (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
- redHalfExternalType = GR_GL_HALF_FLOAT;
- } else {
- redHalfExternalType = GR_GL_HALF_FLOAT_OES;
+ // single channel half formats
+ {
+ GrGLenum halfExternalType;
+ if (GR_IS_GR_GL(standard) ||
+ (GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
+ halfExternalType = GR_GL_HALF_FLOAT;
+ } else {
+ halfExternalType = GR_GL_HALF_FLOAT_OES;
+ }
+
+ // RED16F
+ {
+ ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
+ redHalf.fFormats.fExternalType = halfExternalType;
+ redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
+
+ if (textureRedSupport) {
+ fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
+ }
+ }
+
+ // LUM16F
+ {
+ ConfigInfo& lumHalf = fConfigTable[kAlpha_half_as_Lum_GrPixelConfig];
+ lumHalf.fFormats.fExternalType = halfExternalType;
+ lumHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_LUMINANCE;
+
+ if (!textureRedSupport) {
+ fConfigTable[kAlpha_half_GrPixelConfig] = lumHalf;
+ }
+ }
}
- ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
- redHalf.fFormats.fExternalType = redHalfExternalType;
- redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
- fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
GR_GL_RGBA;
@@ -3225,6 +3309,11 @@
// Mali-400 fails ReadPixels tests, mostly with non-0xFF alpha values when read as GL_RGBA8.
formatWorkarounds->fDisableRGB8ForMali400 = kMali4xx_GrGLRenderer == ctxInfo.renderer();
+
+ // On the Intel Iris 6100, interacting with LUM16F seems to confuse the driver. After
+ // writing to/reading from a LUM16F texture reads from/writes to other formats behave
+ // erratically.
+ formatWorkarounds->fDisableLuminance16F = kIntelBroadwell_GrGLRenderer == ctxInfo.renderer();
}
void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
@@ -3411,6 +3500,8 @@
return GrGLFormat::kLUMINANCE8;
case kGray_8_as_Red_GrPixelConfig:
return GrGLFormat::kR8;
+ case kAlpha_half_as_Lum_GrPixelConfig:
+ return GrGLFormat::kLUMINANCE16F;
case kAlpha_half_as_Red_GrPixelConfig:
return GrGLFormat::kR16F;
case kRGB_ETC1_GrPixelConfig: {
@@ -3512,7 +3603,9 @@
}
break;
case GrColorType::kAlpha_F16:
- if (GR_GL_R16F == format) {
+ if (GR_GL_LUMINANCE16F == format) {
+ return kAlpha_half_as_Lum_GrPixelConfig;
+ } else if (GR_GL_R16F == format) {
return kAlpha_half_as_Red_GrPixelConfig;
}
break;
@@ -3610,6 +3703,9 @@
case GR_GL_RGB10_A2:
config = kRGBA_1010102_GrPixelConfig;
break;
+ case GR_GL_LUMINANCE16F:
+ config = kAlpha_half_as_Lum_GrPixelConfig;
+ break;
case GR_GL_R16F:
config = kAlpha_half_as_Red_GrPixelConfig;
break;
@@ -3688,7 +3784,7 @@
case GrColorType::kGray_8:
return GR_GL_LUMINANCE8 == format || GR_GL_R8 == format;
case GrColorType::kAlpha_F16:
- return GR_GL_R16F == format;
+ return GR_GL_R16F == format || GR_GL_LUMINANCE16F == format;
case GrColorType::kRGBA_F16:
return GR_GL_RGBA16F == format;
case GrColorType::kRGBA_F16_Clamped:
@@ -3736,12 +3832,13 @@
}
break;
case GrColorType::kAlpha_F16:
- SkASSERT(glFormat == GR_GL_R16F);
+ SkASSERT(glFormat == GR_GL_R16F || glFormat == GR_GL_LUMINANCE16F);
if (forOutput) {
return GrSwizzle::AAAA();
} else {
return GrSwizzle::RRRR();
}
+ break;
case GrColorType::kGray_8:
if (glFormat == GR_GL_R8) {
if (!forOutput) {
@@ -3753,9 +3850,11 @@
if (!forOutput) {
return GrSwizzle::RGB1();
}
+ break;
default:
return GrSwizzle::RGBA();
}
+
return GrSwizzle::RGBA();
}
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 437a7a9..45f3e13 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -481,6 +481,7 @@
bool fDisableNonRedSingleChannelTexStorageForANGLEGL = false;
bool fDisableBGRATextureStorageForIntelWindowsES = false;
bool fDisableRGB8ForMali400 = false;
+ bool fDisableLuminance16F = false;
};
void applyDriverCorrectnessWorkarounds(const GrGLContextInfo&, const GrContextOptions&,
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 6d3ed39..5bf4350 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -461,6 +461,7 @@
/* Luminance sized formats */
#define GR_GL_LUMINANCE8 0x8040
+#define GR_GL_LUMINANCE16F 0x881E
/* Alpha sized formats */
#define GR_GL_ALPHA8 0x803C
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 58bd698..f865d44 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -875,6 +875,7 @@
case kRGBA_4444_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kAlpha_half_GrPixelConfig:
+ case kAlpha_half_as_Lum_GrPixelConfig:
case kAlpha_half_as_Red_GrPixelConfig:
case kRGBA_half_GrPixelConfig:
case kRGBA_half_Clamped_GrPixelConfig:
@@ -3750,7 +3751,6 @@
case GrGLFormat::kRGBA4: return kRGBA_4444_GrPixelConfig;
case GrGLFormat::kRGBA32F: return kRGBA_float_GrPixelConfig;
case GrGLFormat::kRGBA16F: return kRGBA_half_GrPixelConfig;
- case GrGLFormat::kR16F: return kAlpha_half_GrPixelConfig;
case GrGLFormat::kR16: return kR_16_GrPixelConfig;
case GrGLFormat::kRG16: return kRG_1616_GrPixelConfig;
case GrGLFormat::kRGBA16: return kRGBA_16161616_GrPixelConfig;
@@ -3759,6 +3759,9 @@
// Configs with multiple equivalent formats.
+ case GrGLFormat::kR16F: return kAlpha_half_GrPixelConfig;
+ case GrGLFormat::kLUMINANCE16F: return kAlpha_half_GrPixelConfig;
+
case GrGLFormat::kALPHA8: return kAlpha_8_GrPixelConfig;
case GrGLFormat::kR8: return kAlpha_8_GrPixelConfig;
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 21aede6..fd92b39 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -608,6 +608,7 @@
case GrGLFormat::kRGB565:
case GrGLFormat::kRGBA16F:
case GrGLFormat::kR16F:
+ case GrGLFormat::kLUMINANCE16F:
case GrGLFormat::kRGB8:
case GrGLFormat::kRG8:
case GrGLFormat::kRGB10_A2:
@@ -639,6 +640,7 @@
case GrGLFormat::kRGB565:
case GrGLFormat::kRGBA16F:
case GrGLFormat::kR16F:
+ case GrGLFormat::kLUMINANCE16F:
case GrGLFormat::kRGB8:
case GrGLFormat::kRG8:
case GrGLFormat::kRGB10_A2:
@@ -666,6 +668,7 @@
case GrGLFormat::kRGBA4:
case GrGLFormat::kRG8:
case GrGLFormat::kR16F:
+ case GrGLFormat::kLUMINANCE16F:
case GrGLFormat::kR16:
return 2;
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 5d41495..644eae8 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -283,6 +283,7 @@
case GR_GL_BGRA8: return GrGLFormat::kBGRA8;
case GR_GL_RGB565: return GrGLFormat::kRGB565;
case GR_GL_RGBA16F: return GrGLFormat::kRGBA16F;
+ case GR_GL_LUMINANCE16F: return GrGLFormat::kLUMINANCE16F;
case GR_GL_R16F: return GrGLFormat::kR16F;
case GR_GL_RGB8: return GrGLFormat::kRGB8;
case GR_GL_RG8: return GrGLFormat::kRG8;
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index de5641f..77e93bd 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -91,6 +91,8 @@
case kAlpha_half_as_Red_GrPixelConfig:
*format = MTLPixelFormatR16Float;
return true;
+ case kAlpha_half_as_Lum_GrPixelConfig:
+ return false;
case kRGB_ETC1_GrPixelConfig:
#ifdef SK_BUILD_FOR_IOS
*format = MTLPixelFormatETC2_RGB8;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 355373b..09798d9 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -93,6 +93,7 @@
case kUnknown_GrPixelConfig:
case kAlpha_8_as_Alpha_GrPixelConfig:
case kGray_8_as_Lum_GrPixelConfig:
+ case kAlpha_half_as_Lum_GrPixelConfig:
SK_ABORT("Unsupported Vulkan pixel config");
return 0;
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 0153af2..197d4a0 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -77,6 +77,8 @@
case kAlpha_half_as_Red_GrPixelConfig:
*format = VK_FORMAT_R16_SFLOAT;
return true;
+ case kAlpha_half_as_Lum_GrPixelConfig:
+ return false;
case kR_16_GrPixelConfig:
*format = VK_FORMAT_R16_UNORM;
return true;
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 4ac8ed4..2f2989b 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -1143,18 +1143,19 @@
switch (modifiers.fLayout.fFormat) {
case Layout::Format::kUnspecified:
break;
- case Layout::Format::kRGBA32F: // fall through
+ case Layout::Format::kRGBA32F: // fall through
case Layout::Format::kR32F:
this->write("highp ");
break;
- case Layout::Format::kRGBA16F: // fall through
- case Layout::Format::kR16F: // fall through
+ case Layout::Format::kRGBA16F: // fall through
+ case Layout::Format::kR16F: // fall through
+ case Layout::Format::kLUMINANCE16F: // fall through
case Layout::Format::kRG16F:
this->write("mediump ");
break;
- case Layout::Format::kRGBA8: // fall through
- case Layout::Format::kR8: // fall through
- case Layout::Format::kRGBA8I: // fall through
+ case Layout::Format::kRGBA8: // fall through
+ case Layout::Format::kR8: // fall through
+ case Layout::Format::kRGBA8I: // fall through
case Layout::Format::kR8I:
this->write("lowp ");
break;
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index d4b1cb6..143aff3 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -60,6 +60,7 @@
kR32F,
kRGBA16F,
kR16F,
+ kLUMINANCE16F,
kRGBA8,
kR8,
kRGBA8I,
@@ -102,6 +103,7 @@
case Format::kR32F: return "r32f";
case Format::kRGBA16F: return "rgba16f";
case Format::kR16F: return "r16f";
+ case Format::kLUMINANCE16F: return "lum16f";
case Format::kRGBA8: return "rgba8";
case Format::kR8: return "r8";
case Format::kRGBA8I: return "rgba8i";
@@ -124,6 +126,9 @@
} else if (str == "r16f") {
*format = Format::kR16F;
return true;
+ } else if (str == "lum16f") {
+ *format = Format::kLUMINANCE16F;
+ return true;
} else if (str == "rgba8") {
*format = Format::kRGBA8;
return true;