--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -848,67 +848,112 @@ ValidateCompressedTexImageRestrictions(c
return true;
if (level == 0)
return false;
return (size == 0 || size == 1 || size == 2);
};
- bool supports2DArray = false;
switch (format->compression->family) {
case webgl::CompressionFamily::PVRTC:
if (!IsPowerOfTwo(width) || !IsPowerOfTwo(height)) {
webgl->ErrorInvalidValue("%s: %s requires power-of-two width and height.",
funcName, format->name);
return false;
}
break;
- // Block-aligned:
- case webgl::CompressionFamily::ES3:
- supports2DArray = true;
- break;
-
case webgl::CompressionFamily::S3TC:
- supports2DArray = true;
-
if (!fnIsDimValid_S3TC(width, format->compression->blockWidth) ||
!fnIsDimValid_S3TC(height, format->compression->blockHeight))
{
webgl->ErrorInvalidOperation("%s: %s requires that width and height are"
" block-aligned, or, if level>0, equal to 0, 1,"
" or 2.",
funcName, format->name);
return false;
}
break;
// Default: There are no restrictions on CompressedTexImage.
- default: // ATC, ETC1
+ default: // ATC, ETC1, ES3
break;
}
- bool targetSupported = true;
- switch (target.get()) {
- case LOCAL_GL_TEXTURE_3D:
- targetSupported = false;
+ return true;
+}
+
+static bool
+ValidateTargetForFormat(const char* funcName, WebGLContext* webgl, TexImageTarget target,
+ const webgl::FormatInfo* format)
+{
+ // GLES 3.0.4 p127:
+ // "Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are
+ // supported by texture image specification commands only if `target` is TEXTURE_2D,
+ // TEXTURE_2D_ARRAY, or TEXTURE_CUBE_MAP. Using these formats in conjunction with any
+ // other `target` will result in an INVALID_OPERATION error."
+
+ switch (format->effectiveFormat) {
+ // TEXTURE_2D_ARRAY but not TEXTURE_3D:
+ // D and DS formats
+ case webgl::EffectiveFormat::DEPTH_COMPONENT16:
+ case webgl::EffectiveFormat::DEPTH_COMPONENT24:
+ case webgl::EffectiveFormat::DEPTH_COMPONENT32F:
+ case webgl::EffectiveFormat::DEPTH24_STENCIL8:
+ case webgl::EffectiveFormat::DEPTH32F_STENCIL8:
+ // CompressionFamily::ES3
+ case webgl::EffectiveFormat::COMPRESSED_R11_EAC:
+ case webgl::EffectiveFormat::COMPRESSED_SIGNED_R11_EAC:
+ case webgl::EffectiveFormat::COMPRESSED_RG11_EAC:
+ case webgl::EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC:
+ case webgl::EffectiveFormat::COMPRESSED_RGB8_ETC2:
+ case webgl::EffectiveFormat::COMPRESSED_SRGB8_ETC2:
+ case webgl::EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case webgl::EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC:
+ case webgl::EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ // CompressionFamily::S3TC
+ case webgl::EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if (target == LOCAL_GL_TEXTURE_3D) {
+ webgl->ErrorInvalidOperation("%s: Format %s cannot be used with TEXTURE_3D.",
+ funcName, format->name);
+ return false;
+ }
break;
- case LOCAL_GL_TEXTURE_2D_ARRAY:
- targetSupported = supports2DArray;
+ // No 3D targets:
+ // CompressionFamily::ATC
+ case webgl::EffectiveFormat::ATC_RGB_AMD:
+ case webgl::EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case webgl::EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ // CompressionFamily::PVRTC
+ case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1:
+ case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1:
+ case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1:
+ // CompressionFamily::ETC1
+ case webgl::EffectiveFormat::ETC1_RGB8_OES:
+ if (target == LOCAL_GL_TEXTURE_3D ||
+ target == LOCAL_GL_TEXTURE_2D_ARRAY)
+ {
+ webgl->ErrorInvalidOperation("%s: Format %s cannot be used with TEXTURE_3D or"
+ " TEXTURE_2D_ARRAY.",
+ funcName, format->name);
+ return false;
+ }
break;
- }
- if (!targetSupported) {
- webgl->ErrorInvalidOperation("%s: This target is not supported by this %s.",
- funcName, format->name);
- return false;
+ default:
+ break;
}
return true;
}
void
WebGLTexture::TexStorage(const char* funcName, TexTarget target, GLsizei levels,
GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth)
@@ -943,16 +988,19 @@ WebGLTexture::TexStorage(const char* fun
auto dstUsage = mContext->mFormatUsage->GetSizedTexUsage(sizedFormat);
if (!dstUsage) {
mContext->ErrorInvalidEnum("%s: Invalid internalformat: 0x%04x", funcName,
sizedFormat);
return;
}
auto dstFormat = dstUsage->format;
+ if (!ValidateTargetForFormat(funcName, mContext, testTarget, dstFormat))
+ return;
+
if (dstFormat->compression) {
if (!ValidateCompressedTexImageRestrictions(funcName, mContext, testTarget,
testLevel, dstFormat, width, height,
depth))
{
return;
}
}
@@ -1104,16 +1152,19 @@ WebGLTexture::TexImage(const char* funcN
const bool isFunc3D = Is3D(target);
if (!blob->ValidateUnpack(mContext, funcName, isFunc3D, srcPacking))
return;
////////////////////////////////////
// Check that source and dest info are compatible
auto dstFormat = dstUsage->format;
+ if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
+ return;
+
if (!mContext->IsWebGL2() && dstFormat->hasDepth) {
if (target != LOCAL_GL_TEXTURE_2D ||
blob->mHasData ||
level != 0)
{
mContext->ErrorInvalidOperation("%s: With format %s, this function may only"
" be called with target=TEXTURE_2D,"
" data=null, and level=0.",
@@ -1283,16 +1334,19 @@ WebGLTexture::CompressedTexImage(const c
auto format = usage->format;
if (!format->compression) {
mContext->ErrorInvalidEnum("%s: Specified internalFormat must be compressed.",
funcName);
return;
}
+ if (!ValidateTargetForFormat(funcName, mContext, target, format))
+ return;
+
////////////////////////////////////
// Get source info
void* mutData;
size_t dataSize;
js::Scalar::Type jsType;
ComputeLengthAndData(view, &mutData, &dataSize, &jsType);
const void* data = mutData;
@@ -1578,16 +1632,19 @@ WebGLTexture::CopyTexImage2D(TexImageTar
if (!dstUsage) {
mContext->ErrorInvalidEnum("%s: Invalid internalFormat 0x%04x for FB format %s.",
funcName, internalFormat, srcFormat->name);
return;
}
auto dstFormat = dstUsage->format;
+ if (!ValidateTargetForFormat(funcName, mContext, target, dstFormat))
+ return;
+
if (!mContext->IsWebGL2() && dstFormat->hasDepth) {
mContext->ErrorInvalidOperation("%s: Function may not be called with format %s.",
funcName, dstFormat->name);
return;
}
if (!ValidateCopyTexImageFormats(mContext, funcName, srcFormat, dstFormat))
return;