Make transferability a per-format flag in GrGLCaps

Add workaround for 16 bit unorm on freedreno

Make sure callsites are checking for transfer alignment
of 0 to indicate unsupported.

Bug: skia:11876
Change-Id: Ia1c22a430f675fc57724f220f5dee5b23f325f3c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/421317
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2021-06-24 11:56:50 -04:00 committed by Skia Commit-Bot
parent 65f65465eb
commit eac233ac2a
6 changed files with 101 additions and 37 deletions

View File

@ -967,7 +967,16 @@ void GrSurfaceContext::asyncRescaleAndReadPixelsYUV420(GrDirectContext* dContext
auto texMatrix = SkMatrix::Translate(x, y);
bool doSynchronousRead = !this->caps()->transferFromSurfaceToBufferSupport();
auto [readCT, offsetAlignment] =
this->caps()->supportedReadPixelsColorType(yFC->colorInfo().colorType(),
yFC->asSurfaceProxy()->backendFormat(),
GrColorType::kAlpha_8);
if (readCT == GrColorType::kUnknown) {
callback(callbackContext, nullptr);
return;
}
bool doSynchronousRead = !this->caps()->transferFromSurfaceToBufferSupport() ||
!offsetAlignment;
PixelTransferResult yTransfer, uTransfer, vTransfer;
// This matrix generates (r,g,b,a) = (0, 0, 0, y)

View File

@ -1357,7 +1357,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGBA_8888;
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
info.fFlags |= msaaRenderFlags;
} else if (GR_IS_GR_GL_ES(standard)) {
@ -1493,7 +1493,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
if (r8Support) {
info.fFlags |= FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags |= FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
if (texStorageSupported) {
@ -1608,7 +1610,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kAlpha_8;
if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (alpha8IsRenderable && alpha8IsValidForGL) {
// We will use ALPHA8 to create MSAA renderbuffers.
@ -1695,7 +1697,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
lum8Supported = true;
}
if (lum8Supported) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (texStorageSupported && lum8SizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
@ -1775,7 +1777,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
la8Supported = true;
}
if (la8Supported) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
}
if (texStorageSupported && la8SizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
@ -1879,7 +1881,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
if (GR_IS_GR_GL_ES(standard)) {
if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
info.fFlags = FormatInfo::kTexturable_Flag | nonMSAARenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| nonMSAARenderFlags;
// GL_EXT_texture storage has defined interactions with
// GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but
// without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format.
@ -1899,7 +1903,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
if (version >= GR_GL_VER(3,0)) {
// The APPLE extension doesn't explicitly make this renderable, but
// internally it appears to use RGBA8, which we'll patch up below.
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
supportsBGRATexStorage = true;
}
}
@ -1962,12 +1968,18 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultColorType = GrColorType::kBGR_565;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(4, 2) || ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
} else if (GR_IS_GR_GL_ES(standard)) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
} else if (GR_IS_GR_WEBGL(standard)) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
}
// 565 is not a sized internal format on desktop GL. So on desktop with
// 565 we always use an unsized internal format to let the system pick
@ -2074,7 +2086,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
if (rgba16FTextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (rgba16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
@ -2198,7 +2210,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
if (r16FTextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (r16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
@ -2284,7 +2296,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultColorType = GrColorType::kGray_F16;
if (lum16FSupported) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (texStorageSupported && lum16FSizedFormatSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
@ -2345,7 +2357,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultExternalFormat = GR_GL_RGB;
info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE;
info.fDefaultColorType = GrColorType::kRGB_888;
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
// Even in OpenGL 4.6 GL_RGB8 is required to be color renderable but not required to be
// a supported render buffer format. Since we usually use render buffers for MSAA on
@ -2422,7 +2434,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
rg8Support = version >= GR_GL_VER(2, 0);
}
if (rg8Support) {
info.fFlags |= FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags |= FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
if (texStorageSupported) {
info.fFlags |= FormatInfo::kUseTexStorage_Flag;
info.fInternalFormatForTexImageOrStorage = GR_GL_RG8;
@ -2482,10 +2496,12 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultColorType = GrColorType::kRGBA_1010102;
if (GR_IS_GR_GL(standard) ||
(GR_IS_GR_GL_ES(standard) && version >= GR_GL_VER(3, 0))) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
info.fFlags = FormatInfo::kTexturable_Flag
| FormatInfo::kTransfers_Flag
| msaaRenderFlags;
} else if (GR_IS_GR_GL_ES(standard) &&
ctxInfo.hasExtension("GL_EXT_texture_type_2_10_10_10_REV")) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
} // No WebGL support
if (texStorageSupported) {
@ -2580,7 +2596,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultExternalFormat = GR_GL_RGBA;
info.fDefaultExternalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
info.fDefaultColorType = GrColorType::kABGR_4444;
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (GR_IS_GR_GL(standard)) {
if (version >= GR_GL_VER(4, 2)) {
info.fFlags |= msaaRenderFlags;
@ -2687,7 +2703,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
if (srgb8Alpha8TextureSupport) {
info.fFlags = FormatInfo::kTexturable_Flag;
info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (srgb8Alpha8RenderTargetSupport) {
info.fFlags |= formatWorkarounds.fDisableSRGBRenderWithMSAAForMacAMD
? nonMSAARenderFlags
@ -2822,6 +2838,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
if (r16Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
@ -2892,6 +2911,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
if (rg16Supported) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
@ -2959,6 +2981,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultColorType = GrColorType::kRGBA_16161616;
if (rgba16Support) {
info.fFlags = FormatInfo::kTexturable_Flag | msaaRenderFlags;
if (!formatWorkarounds.fDisallowUnorm16Transfers) {
info.fFlags |= FormatInfo::kTransfers_Flag;
}
}
if (texStorageSupported) {
@ -3046,7 +3071,7 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
info.fDefaultExternalType = halfFloatType;
info.fDefaultColorType = GrColorType::kRG_F16;
if (rg16FTextureSupport) {
info.fFlags |= FormatInfo::kTexturable_Flag;
info.fFlags |= FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag;
if (rg16FRenderTargetSupport) {
info.fFlags |= fpRenderFlags;
}
@ -4171,6 +4196,10 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
// crbug.com/1203652
fAlwaysDrawQuadsIndexed = true;
}
if (ctxInfo.driver() == GrGLDriver::kFreedreno) {
formatWorkarounds->fDisallowUnorm16Transfers = true;
}
}
void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
@ -4283,9 +4312,9 @@ GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
SkImage::CompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
if (compression != SkImage::CompressionType::kNone) {
return { SkCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
: GrColorType::kRGBA_8888,
offset_alignment_for_transfer_buffer(GR_GL_UNSIGNED_BYTE) };
return {SkCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
: GrColorType::kRGBA_8888,
0};
}
// We first try to find a supported read pixels GrColorType that matches the requested
@ -4302,8 +4331,11 @@ GrCaps::SupportedRead GrGLCaps::onSupportedReadPixelsColorType(
if (ioInfo.fExternalReadFormat != 0) {
if (formatInfo.fHaveQueriedImplementationReadSupport ||
!ioInfo.fRequiresImplementationReadQuery) {
GrGLenum transferOffsetAlignment =
offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
GrGLenum transferOffsetAlignment = 0;
if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
transferOffsetAlignment =
offset_alignment_for_transfer_buffer(ioInfo.fExternalType);
}
if (ioInfo.fColorType == dstColorType) {
return {dstColorType, transferOffsetAlignment};
}
@ -4328,6 +4360,10 @@ GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfa
GrColorType fallbackCT = GrColorType::kUnknown;
const auto& formatInfo = this->getFormatInfo(surfaceFormat.asGLFormat());
bool foundSurfaceCT = false;
size_t transferOffsetAlignment = 0;
if (formatInfo.fFlags & FormatInfo::kTransfers_Flag) {
transferOffsetAlignment = 1;
}
for (int i = 0; !foundSurfaceCT && i < formatInfo.fColorTypeInfoCount; ++i) {
if (formatInfo.fColorTypeInfos[i].fColorType == surfaceColorType) {
const ColorTypeInfo& ctInfo = formatInfo.fColorTypeInfos[i];
@ -4336,7 +4372,7 @@ GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfa
const auto& ioInfo = ctInfo.fExternalIOFormats[j];
if (ioInfo.fExternalTexImageFormat != 0) {
if (ioInfo.fColorType == srcColorType) {
return {srcColorType, 1};
return {srcColorType, transferOffsetAlignment};
}
// Currently we just pick the first supported format that we find as our
// fallback.
@ -4347,7 +4383,7 @@ GrCaps::SupportedWrite GrGLCaps::supportedWritePixelsColorType(GrColorType surfa
}
}
}
return {fallbackCT, 1};
return {fallbackCT, transferOffsetAlignment};
}
bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {

View File

@ -475,6 +475,7 @@ private:
bool fDisallowDirectRG8ReadPixels = false;
bool fDisallowBGRA8ReadPixels = false;
bool fDisallowR8ForPowerVRSGX54x = false;
bool fDisallowUnorm16Transfers = false;
};
void applyDriverCorrectnessWorkarounds(const GrGLContextInfo&, const GrContextOptions&,
@ -673,12 +674,17 @@ private:
}
enum {
kTexturable_Flag = 0x1,
kTexturable_Flag = 0x01,
/** kFBOColorAttachment means that even if the format cannot be a GrRenderTarget, we can
still attach it to a FBO for blitting or reading pixels. */
kFBOColorAttachment_Flag = 0x2,
kFBOColorAttachmentWithMSAA_Flag = 0x4,
kUseTexStorage_Flag = 0x8,
kFBOColorAttachment_Flag = 0x02,
kFBOColorAttachmentWithMSAA_Flag = 0x04,
kUseTexStorage_Flag = 0x08,
/**
* Are pixel buffer objects supported in/out of this format? Ignored if PBOs are not
* supported at all.
*/
kTransfers_Flag = 0x10,
};
uint32_t fFlags = 0;

View File

@ -369,6 +369,7 @@ static bool is_commamd_buffer(const char* rendererString, const char* versionStr
static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStandard standard,
GrGLVendor vendor,
const char* vendorString,
const char* rendererString,
const char* versionString) {
SkASSERT(rendererString);
@ -378,7 +379,10 @@ static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStan
GrGLDriverVersion driverVersion = GR_GL_DRIVER_UNKNOWN_VER;
int major, minor, rev, driverMajor, driverMinor, driverPoint;
if (GR_IS_GR_GL(standard)) {
// This is the same on ES and regular GL.
if (!strcmp(vendorString, "freedreno")) {
driver = GrGLDriver::kFreedreno;
} else if (GR_IS_GR_GL(standard)) {
if (vendor == GrGLVendor::kNVIDIA) {
driver = GrGLDriver::kNVIDIA;
int n = sscanf(versionString,
@ -554,6 +558,7 @@ get_angle_gl_vendor_and_renderer(
auto [angleDriver, angleDriverVersion] = get_driver_and_version(kGLES_GrGLStandard,
angleVendor,
angleVendorString,
angleRendererString,
angleVersionString);
@ -629,10 +634,10 @@ GrGLDriverInfo GrGLGetDriverInfo(const GrGLInterface* interface) {
return reinterpret_cast<const char*>(bytes);
};
const char* const version = getString(GR_GL_VERSION);
const char* const slversion = getString(GR_GL_SHADING_LANGUAGE_VERSION);
const char* const renderer = getString(GR_GL_RENDERER);
const char* const vendor = getString(GR_GL_VENDOR);
const char* const version = getString(GR_GL_VERSION);
const char* const slversion = getString(GR_GL_SHADING_LANGUAGE_VERSION);
const char* const renderer = getString(GR_GL_RENDERER);
const char* const vendor = getString(GR_GL_VENDOR);
info.fVersion = GrGLGetVersionFromString(version);
info.fGLSLVersion = get_glsl_version(slversion);
@ -641,6 +646,7 @@ GrGLDriverInfo GrGLGetDriverInfo(const GrGLInterface* interface) {
std::tie(info.fDriver, info.fDriverVersion) = get_driver_and_version(interface->fStandard,
info.fVendor,
vendor,
renderer,
version);

View File

@ -209,6 +209,7 @@ enum class GrGLDriver {
kIntel,
kSwiftShader,
kQualcomm,
kFreedreno,
kAndroidEmulator,
kUnknown
};

View File

@ -152,6 +152,9 @@ void basic_transfer_to_test(skiatest::Reporter* reporter,
// either of which may differ from 'colorType'.
GrCaps::SupportedWrite allowedSrc =
caps->supportedWritePixelsColorType(colorType, tex->backendFormat(), colorType);
if (!allowedSrc.fOffsetAlignmentForTransferBuffer) {
return;
}
size_t srcRowBytes = GrAlignTo(GrColorTypeBytesPerPixel(allowedSrc.fColorType) * srcBufferWidth,
caps->transferBufferAlignment());
@ -331,6 +334,9 @@ void basic_transfer_from_test(skiatest::Reporter* reporter, const sk_gpu_test::C
// Create the transfer buffer.
auto allowedRead =
caps->supportedReadPixelsColorType(colorType, tex->backendFormat(), colorType);
if (!allowedRead.fOffsetAlignmentForTransferBuffer) {
return;
}
GrImageInfo readInfo(allowedRead.fColorType, kUnpremul_SkAlphaType, nullptr, kTexDims);
size_t bpp = GrColorTypeBytesPerPixel(allowedRead.fColorType);