From 859a3a4924b3c2ebf95bbfbc2bef2c659f2b0272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ty=C3=A1s=20Mustoha?= Date: Wed, 26 Feb 2020 12:09:10 +0100 Subject: [PATCH] Allow more WebGL2 FBO attachment formats Add support for most of the framebuffer attachment formats introduced in WebGL2 for textures and renderbuffers. Related format tables: - https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml - https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glRenderbufferStorage.xhtml --- components/script/dom/webglframebuffer.rs | 126 ++++++++++++++---- components/script/dom/webglrenderbuffer.rs | 25 ++++ .../extensions/webgl_multiview.html.ini | 7 - ...ead-pixels-from-rgb8-into-pbo-bug.html.ini | 4 +- .../framebuffer-object-attachment.html.ini | 31 +---- .../rendering/clearbuffer-sub-source.html.ini | 24 +--- ...amebuffer-completeness-unaffected.html.ini | 3 - .../conformance2/state/gl-get-calls.html.ini | 12 -- 8 files changed, 136 insertions(+), 96 deletions(-) delete mode 100644 tests/wpt/webgl/meta/conformance2/extensions/webgl_multiview.html.ini diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index c2eb10fcd60a..8f5f499072af 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -219,10 +219,10 @@ impl WebGLFramebuffer { self.size.get() } - fn check_attachment_constraints( + fn check_attachment_constraints<'a>( &self, attachment: &Option, - constraints: &[u32], + mut constraints: impl Iterator, fb_size: &mut Option<(i32, i32)>, ) -> Result<(), u32> { // Get the size of this attachment. @@ -254,7 +254,7 @@ impl WebGLFramebuffer { } if let Some(format) = format { - if constraints.iter().all(|c| *c != format) { + if constraints.all(|c| *c != format) { return Err(constants::FRAMEBUFFER_INCOMPLETE_ATTACHMENT); } } @@ -269,22 +269,6 @@ impl WebGLFramebuffer { let has_z = z.is_some(); let has_s = s.is_some(); let has_zs = zs.is_some(); - let attachments = [&*z, &*s, &*zs]; - let attachment_constraints = [ - &[ - constants::DEPTH_COMPONENT16, - constants::DEPTH_COMPONENT24, - constants::DEPTH_COMPONENT32F, - constants::DEPTH24_STENCIL8, - constants::DEPTH32F_STENCIL8, - ][..], - &[ - constants::STENCIL_INDEX8, - constants::DEPTH24_STENCIL8, - constants::DEPTH32F_STENCIL8, - ][..], - &[constants::DEPTH_STENCIL][..], - ]; let is_supported = match self.webgl_version { // From the WebGL 1.0 spec, 6.6 ("Framebuffer Object Attachments"): @@ -326,7 +310,38 @@ impl WebGLFramebuffer { let mut fb_size = None; - for (attachment, constraints) in attachments.iter().zip(&attachment_constraints) { + let attachments = [&*z, &*s, &*zs]; + let webgl1_attachment_constraints = &[ + &[ + constants::DEPTH_COMPONENT16, + constants::DEPTH_COMPONENT24, + constants::DEPTH_COMPONENT32F, + constants::DEPTH24_STENCIL8, + constants::DEPTH32F_STENCIL8, + ][..], + &[ + constants::STENCIL_INDEX8, + constants::DEPTH24_STENCIL8, + constants::DEPTH32F_STENCIL8, + ][..], + &[constants::DEPTH_STENCIL][..], + ]; + let webgl2_attachment_constraints = &[ + &[constants::DEPTH_STENCIL][..], + &[constants::DEPTH_STENCIL][..], + &[][..], + ]; + let empty_attachment_constrains = &[&[][..], &[][..], &[][..]]; + let extra_attachment_constraints = match self.webgl_version { + WebGLVersion::WebGL1 => empty_attachment_constrains, + WebGLVersion::WebGL2 => webgl2_attachment_constraints, + }; + let attachment_constraints = webgl1_attachment_constraints + .iter() + .zip(extra_attachment_constraints.iter()) + .map(|(a, b)| a.iter().chain(b.iter())); + + for (attachment, constraints) in attachments.iter().zip(attachment_constraints) { if let Err(errnum) = self.check_attachment_constraints(attachment, constraints, &mut fb_size) { @@ -334,18 +349,79 @@ impl WebGLFramebuffer { } } - let color_constraints = &[ - constants::RGBA4, - constants::RGB5_A1, + let webgl1_color_constraints = &[ + constants::RGB, constants::RGB565, + constants::RGB5_A1, constants::RGBA, - constants::RGB, + constants::RGBA4, + ][..]; + let webgl2_color_constraints = &[ + constants::ALPHA, + constants::LUMINANCE, + constants::LUMINANCE_ALPHA, + constants::R11F_G11F_B10F, + constants::R16F, + constants::R16I, + constants::R16UI, + constants::R32F, + constants::R32I, + constants::R32UI, + constants::R8, + constants::R8_SNORM, + constants::R8I, + constants::R8UI, + constants::RG16F, + constants::RG16I, + constants::RG16UI, + constants::RG32F, + constants::RG32I, + constants::RG32UI, + constants::RG8, + constants::RG8_SNORM, + constants::RG8I, + constants::RG8UI, + constants::RGB10_A2, + constants::RGB10_A2UI, + constants::RGB16F, + constants::RGB16I, + constants::RGB16UI, + constants::RGB32F, + constants::RGB32I, + constants::RGB32UI, + constants::RGB8, + constants::RGB8_SNORM, + constants::RGB8I, + constants::RGB8UI, + constants::RGB9_E5, + constants::RGBA16F, + constants::RGBA16I, + constants::RGBA16UI, + constants::RGBA32F, + constants::RGBA32I, + constants::RGBA32UI, + constants::RGBA8, + constants::RGBA8_SNORM, + constants::RGBA8I, + constants::RGBA8UI, + constants::SRGB8, + constants::SRGB8_ALPHA8, ][..]; + let empty_color_constrains = &[][..]; + let extra_color_constraints = match self.webgl_version { + WebGLVersion::WebGL1 => empty_color_constrains, + WebGLVersion::WebGL2 => webgl2_color_constraints, + }; + let color_constraints = webgl1_color_constraints + .iter() + .chain(extra_color_constraints.iter()); + let has_c = self.colors.iter().any(|att| att.borrow().is_some()); for attachment in self.colors.iter() { let attachment = attachment.borrow(); + let constraints = color_constraints.clone(); if let Err(errnum) = - self.check_attachment_constraints(&*attachment, color_constraints, &mut fb_size) + self.check_attachment_constraints(&*attachment, constraints, &mut fb_size) { return self.status.set(errnum); } diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 9c173d202419..bc1a11a7ecf0 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -145,6 +145,31 @@ impl WebGLRenderbuffer { constants::RGBA4 | constants::DEPTH_COMPONENT16 | constants::STENCIL_INDEX8 => { internal_format }, + constants::R8 | + constants::R8UI | + constants::R8I | + constants::R16UI | + constants::R16I | + constants::R32UI | + constants::R32I | + constants::RG8 | + constants::RG8UI | + constants::RG8I | + constants::RG16UI | + constants::RG16I | + constants::RG32UI | + constants::RG32I | + constants::RGB8 | + constants::RGBA8 | + constants::SRGB8_ALPHA8 | + constants::RGB10_A2 | + constants::RGBA8UI | + constants::RGBA8I | + constants::RGB10_A2UI | + constants::RGBA16UI | + constants::RGBA16I | + constants::RGBA32I | + constants::RGBA32UI | constants::DEPTH_COMPONENT24 | constants::DEPTH_COMPONENT32F | constants::DEPTH24_STENCIL8 | diff --git a/tests/wpt/webgl/meta/conformance2/extensions/webgl_multiview.html.ini b/tests/wpt/webgl/meta/conformance2/extensions/webgl_multiview.html.ini deleted file mode 100644 index 3bd2103548ed..000000000000 --- a/tests/wpt/webgl/meta/conformance2/extensions/webgl_multiview.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[webgl_multiview.html] - [WebGL test #3: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR without enabling WEBGL_multiview] - expected: FAIL - - [WebGL test #2: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR without enabling WEBGL_multiview] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html.ini b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html.ini index f428e055d343..e241046227c2 100644 --- a/tests/wpt/webgl/meta/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html.ini +++ b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html.ini @@ -1,7 +1,7 @@ [read-pixels-from-rgb8-into-pbo-bug.html] - [WebGL test #1: framebuffer with RGB8 color buffer is incomplete] + [WebGL test #2: getError expected: NO_ERROR. Was INVALID_OPERATION : Tests should complete without gl errors] expected: FAIL - [WebGL test #2: getError expected: NO_ERROR. Was INVALID_ENUM : Tests should complete without gl errors] + [WebGL test #1: Expected in pixel 0: [255,0,0,255\], got: 0,0,0,0] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini index 29e24af81169..fa43cf3d5d6d 100644 --- a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini +++ b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini @@ -1,34 +1,7 @@ [framebuffer-object-attachment.html] - [WebGL test #13: gl.getParameter(gl.RED_BITS) + gl.getParameter(gl.GREEN_BITS) + gl.getParameter(gl.BLUE_BITS) + gl.getParameter(gl.ALPHA_BITS) >= 16 should be true. Was false.] + [WebGL test #45: getError expected: NO_ERROR. Was INVALID_ENUM : ] expected: FAIL - [WebGL test #10: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #20: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #21: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #17: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #9: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #11: getError expected: NO_ERROR. Was INVALID_ENUM : ] - expected: FAIL - - [WebGL test #19: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #22: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #18: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] - expected: FAIL - - [WebGL test #27: getError expected: NO_ERROR. Was INVALID_ENUM : ] + [WebGL test #28: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/clearbuffer-sub-source.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/clearbuffer-sub-source.html.ini index 319195970578..e5717f8dd50c 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/clearbuffer-sub-source.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/clearbuffer-sub-source.html.ini @@ -1,47 +1,35 @@ [clearbuffer-sub-source.html] - [WebGL test #14: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 2 should succeed] - expected: FAIL - [WebGL test #5: clearBuffer fails to work. Expected: 1,2,3,4, got: 0,0,0,0] expected: FAIL - [WebGL test #2: getError expected: NO_ERROR. Was INVALID_ENUM : clearBuffer with no srcOffset should succeed] - expected: FAIL - [WebGL test #11: clearBuffer fails to work. Expected: 1,2,3,4, got: 0,0,0,0] expected: FAIL [WebGL test #13: clearBuffer fails to work. Expected: 1,2,3,4, got: 0,0,0,0] expected: FAIL - [WebGL test #9: gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be 36053. Was 36054.] + [WebGL test #12: getError expected: NO_ERROR. Was INVALID_OPERATION : clearBuffer with srcOffset = 0 should succeed] expected: FAIL - [WebGL test #10: getError expected: NO_ERROR. Was INVALID_ENUM : clearBuffer with no srcOffset should succeed] + [WebGL test #6: getError expected: NO_ERROR. Was INVALID_OPERATION : clearBuffer with srcOffset = 2 should succeed] expected: FAIL - [WebGL test #16: getError expected: INVALID_VALUE. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 4 should fail: out of bounds] + [WebGL test #4: getError expected: NO_ERROR. Was INVALID_OPERATION : clearBuffer with srcOffset = 0 should succeed] expected: FAIL - [WebGL test #4: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 0 should succeed] + [WebGL test #14: getError expected: NO_ERROR. Was INVALID_OPERATION : clearBuffer with srcOffset = 2 should succeed] expected: FAIL [WebGL test #15: clearBuffer fails to work. Expected: 3,4,5,6, got: 0,0,0,0] expected: FAIL - [WebGL test #8: getError expected: INVALID_VALUE. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 4 should fail: out of bounds] - expected: FAIL - - [WebGL test #6: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 2 should succeed] + [WebGL test #8: getError expected: INVALID_VALUE. Was INVALID_OPERATION : clearBuffer with srcOffset = 4 should fail: out of bounds] expected: FAIL [WebGL test #7: clearBuffer fails to work. Expected: 3,4,5,6, got: 0,0,0,0] expected: FAIL - [WebGL test #12: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : clearBuffer with srcOffset = 0 should succeed] - expected: FAIL - - [WebGL test #1: gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be 36053. Was 36054.] + [WebGL test #16: getError expected: INVALID_VALUE. Was INVALID_OPERATION : clearBuffer with srcOffset = 4 should fail: out of bounds] expected: FAIL [WebGL test #3: clearBuffer fails to work. Expected: 1,2,3,4, got: 0,0,0,0] diff --git a/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-completeness-unaffected.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-completeness-unaffected.html.ini index cc4d5756d31a..31e5e1e855c3 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-completeness-unaffected.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-completeness-unaffected.html.ini @@ -3,6 +3,3 @@ [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL - [WebGL test #1: gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be 36053. Was 36054.] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/state/gl-get-calls.html.ini b/tests/wpt/webgl/meta/conformance2/state/gl-get-calls.html.ini index 3485fc3a83ba..37ba9d9f5dcd 100644 --- a/tests/wpt/webgl/meta/conformance2/state/gl-get-calls.html.ini +++ b/tests/wpt/webgl/meta/conformance2/state/gl-get-calls.html.ini @@ -8,9 +8,6 @@ [WebGL test #80: context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET) is not an instance of Number] expected: FAIL - [WebGL test #41: context.getParameter(context.MAX_DRAW_BUFFERS) should be >= 4. Was null (of type object).] - expected: FAIL - [WebGL test #33: context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS) should be >= 256. Was null (of type object).] expected: FAIL @@ -89,15 +86,9 @@ [WebGL test #48: context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS) is not an instance of Number] expected: FAIL - [WebGL test #37: context.getParameter(context.MAX_COLOR_ATTACHMENTS) should be >= 4. Was null (of type object).] - expected: FAIL - [WebGL test #9: context.getParameter(context.PACK_SKIP_ROWS) should be 0 (of type number). Was null (of type object).] expected: FAIL - [WebGL test #42: context.getParameter(context.MAX_DRAW_BUFFERS) is not an instance of Number] - expected: FAIL - [WebGL test #34: context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS) is not an instance of Number] expected: FAIL @@ -107,9 +98,6 @@ [WebGL test #12: context.getParameter(context.RASTERIZER_DISCARD) should be false (of type boolean). Was null (of type object).] expected: FAIL - [WebGL test #38: context.getParameter(context.MAX_COLOR_ATTACHMENTS) is not an instance of Number] - expected: FAIL - [WebGL test #44: context.getParameter(context.MAX_ELEMENT_INDEX) is not an instance of Number] expected: FAIL