Expand texturability testing to cover mip-mapped textures, and fix iOS
Don't allow creation of mip-mapped textures when caps says we don't support mip-mapping. Skip testing of mip-mapped resources in the resource size test, when creation will fail. For iOS devices with ES2, the APPLE BGRA8888 extension is more trouble than it's worth. Even though it lets the internal and external formats not match, it appears that the driver remembers the first external format, so subsequent attempts to upload with the other swizzle will fail. Up until now, creation of these textures was failing anyway, so now just make it more explicit that we don't support BGRA in this situation. Now that we're testing our TexStorage path, fix a few other problems that showed up: - Command Buffer doesn't like extension formats. - X86 PowerVR and Adreno devices don't like BGRA. Re-land of : https://skia-review.googlesource.com/18382 Re-re-land of: https://skia-review.googlesource.com/18261 BUG=skia: Change-Id: Ie12793549a6807300d6ece68cd6b92495e85c3fe Reviewed-on: https://skia-review.googlesource.com/18403 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
fcc8adc5e4
commit
48c9919335
@ -65,7 +65,7 @@ bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (levelCount > 1 && GrPixelConfigIsSint(desc.fConfig)) {
|
||||
if (levelCount > 1 && (GrPixelConfigIsSint(desc.fConfig) || !caps.mipMapSupport())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1571,14 +1571,16 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_BGRA;
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_BGRA8;
|
||||
if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
|
||||
// The APPLE extension doesn't make this renderable.
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
|
||||
if (version < GR_GL_VER(3,0) && !ctxInfo.hasExtension("GL_EXT_texture_storage")) {
|
||||
// On ES2 the internal format of a BGRA texture is RGBA with the APPLE extension.
|
||||
// Though, that seems to not be the case if the texture storage extension is
|
||||
// present. The specs don't exactly make that clear.
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA;
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8;
|
||||
// This APPLE extension introduces complexity on ES2. It leaves the internal format
|
||||
// as RGBA, but allows BGRA as the external format. From testing, it appears that the
|
||||
// driver remembers the external format when the texture is created (with TexImage).
|
||||
// If you then try to upload data in the other swizzle (with TexSubImage), it fails.
|
||||
// We could work around this, but it adds even more state tracking to code that is
|
||||
// already too tricky. Instead, we opt not to support BGRA on ES2 with this extension.
|
||||
// This also side-steps some ambiguous interactions with the texture storage extension.
|
||||
if (version >= GR_GL_VER(3,0)) {
|
||||
// The APPLE extension doesn't make this renderable.
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
|
||||
}
|
||||
} else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
|
||||
@ -1590,8 +1592,21 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (texStorageSupported) {
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
|
||||
|
||||
bool isX86PowerVR = false;
|
||||
#if defined(SK_CPU_X86)
|
||||
if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
|
||||
isX86PowerVR = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Adreno 3xx, 4xx, 5xx, and NexusPlayer all fail if we try to use TexStorage with BGRA
|
||||
if (texStorageSupported &&
|
||||
kAdreno3xx_GrGLRenderer != ctxInfo.renderer() &&
|
||||
kAdreno4xx_GrGLRenderer != ctxInfo.renderer() &&
|
||||
kAdreno5xx_GrGLRenderer != ctxInfo.renderer() &&
|
||||
!isX86PowerVR) {
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
|
||||
}
|
||||
fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
|
||||
|
||||
@ -1612,13 +1627,11 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
}
|
||||
} else {
|
||||
fSRGBSupport = ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB");
|
||||
#if defined(SK_CPU_X86)
|
||||
if (kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) {
|
||||
// NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
|
||||
// blacklist that device (and any others that might be sharing the same driver).
|
||||
// NexusPlayer has strange bugs with sRGB (skbug.com/4148). This is a targeted fix to
|
||||
// blacklist that device (and any others that might be sharing the same driver).
|
||||
if (isX86PowerVR) {
|
||||
fSRGBSupport = false;
|
||||
}
|
||||
#endif
|
||||
// ES through 3.1 requires EXT_srgb_write_control to support toggling
|
||||
// sRGB writing for destinations.
|
||||
// See https://bug.skia.org/5329 for Adreno4xx issue.
|
||||
@ -1642,6 +1655,10 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
fSRGBSupport = false;
|
||||
}
|
||||
|
||||
// ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
|
||||
// not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
|
||||
bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
|
||||
|
||||
uint32_t srgbRenderFlags = allRenderFlags;
|
||||
// MacPro devices with AMD cards fail to create MSAA sRGB render buffers
|
||||
#if defined(SK_BUILD_FOR_MAC)
|
||||
@ -1662,7 +1679,8 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
|
||||
srgbRenderFlags;
|
||||
}
|
||||
if (texStorageSupported) {
|
||||
// ES2 Command Buffer does not allow TexStorage with SRGB8_ALPHA8_EXT
|
||||
if (texStorageSupported && !isCommandBufferES2) {
|
||||
fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
|
||||
}
|
||||
fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
|
||||
@ -1789,7 +1807,8 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
// Core profile removes ALPHA8 support, but we should have chosen R8 in that case.
|
||||
fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= allRenderFlags;
|
||||
}
|
||||
if (texStorageSupported) {
|
||||
// ES2 Command Buffer does not allow TexStorage with R8_EXT (so Alpha_8 and Gray_8)
|
||||
if (texStorageSupported && !isCommandBufferES2) {
|
||||
fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
|
||||
}
|
||||
|
||||
@ -1822,7 +1841,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
|
||||
fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
|
||||
}
|
||||
#endif
|
||||
if (texStorageSupported) {
|
||||
if (texStorageSupported && !isCommandBufferES2) {
|
||||
fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
|
||||
: GrSurface(gpu, desc)
|
||||
, GrVkImage(info, GrVkImage::kNot_Wrapped)
|
||||
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
|
||||
desc.fIsMipMapped)
|
||||
info.fLevelCount > 1)
|
||||
, fTextureView(view)
|
||||
, fLinearTextureView(nullptr) {
|
||||
this->registerWithCache(budgeted);
|
||||
@ -49,7 +49,7 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
|
||||
: GrSurface(gpu, desc)
|
||||
, GrVkImage(info, wrapped)
|
||||
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
|
||||
desc.fIsMipMapped)
|
||||
info.fLevelCount > 1)
|
||||
, fTextureView(view)
|
||||
, fLinearTextureView(nullptr) {
|
||||
this->registerWithCacheWrapped();
|
||||
@ -64,7 +64,7 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
|
||||
: GrSurface(gpu, desc)
|
||||
, GrVkImage(info, wrapped)
|
||||
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
|
||||
desc.fIsMipMapped)
|
||||
info.fLevelCount > 1)
|
||||
, fTextureView(view)
|
||||
, fLinearTextureView(nullptr) {
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "GrTest.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrSurfacePriv.h"
|
||||
#include "SkMipMap.h"
|
||||
#include "Test.h"
|
||||
|
||||
// Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
|
||||
@ -99,6 +100,16 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
|
||||
desc.fWidth = 64;
|
||||
desc.fHeight = 64;
|
||||
|
||||
// Enough space for the first mip of our largest pixel config
|
||||
const size_t pixelBufferSize = desc.fWidth * desc.fHeight *
|
||||
GrBytesPerPixel(kRGBA_float_GrPixelConfig);
|
||||
std::unique_ptr<char[]> pixelData(new char[pixelBufferSize]);
|
||||
memset(pixelData.get(), 0, pixelBufferSize);
|
||||
|
||||
// We re-use the same mip level objects (with updated pointers and rowBytes) for each config
|
||||
const int levelCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
|
||||
std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[levelCount]);
|
||||
|
||||
for (GrPixelConfig config : configs) {
|
||||
for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
|
||||
desc.fFlags = kNone_GrSurfaceFlags;
|
||||
@ -109,6 +120,18 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
|
||||
sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
|
||||
REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig));
|
||||
|
||||
size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
|
||||
for (int i = 0; i < levelCount; ++i) {
|
||||
texels[i].fPixels = pixelData.get();
|
||||
texels[i].fRowBytes = rowBytes >> i;
|
||||
}
|
||||
sk_sp<GrTextureProxy> proxy = resourceProvider->createMipMappedTexture(
|
||||
desc, SkBudgeted::kNo, texels.get(), levelCount);
|
||||
REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
|
||||
(caps->isConfigTexturable(desc.fConfig) &&
|
||||
caps->mipMapSupport() &&
|
||||
!GrPixelConfigIsSint(desc.fConfig)));
|
||||
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
|
||||
REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false));
|
||||
|
@ -1714,7 +1714,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
|
||||
|
||||
|
||||
// Mipmapped versions
|
||||
{
|
||||
if (context->caps()->mipMapSupport()) {
|
||||
sk_sp<GrTextureProxy> proxy;
|
||||
|
||||
proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user