diff options
author | Istvan <istvan.miklos@h-lab.eu> | 2020-03-18 10:53:23 +0100 |
---|---|---|
committer | Istvan <istvan.miklos@h-lab.eu> | 2020-03-30 13:55:01 +0200 |
commit | bfa43fbeba1ffb1adca44d18bb22dbee81069af9 (patch) | |
tree | 8710396fb106aa65a34cff6c0a48ea0da5417e74 | |
parent | c3ecf2ecef36bfc35ba75442c81d54fd2bc695be (diff) | |
download | servo-bfa43fbeba1ffb1adca44d18bb22dbee81069af9.tar.gz servo-bfa43fbeba1ffb1adca44d18bb22dbee81069af9.zip |
Add support for DrawRangeElements in WebGL2
Adds initial support for the WebGL2 `DrawRangeElements` call.
8 files changed, 174 insertions, 66 deletions
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index ff627d121ad..b7e9d1a0a17 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -2178,6 +2178,7 @@ impl WebGLImpl { base_name: from_name_in_compiled_shader(&name).into(), size: if is_array { Some(size) } else { None }, type_, + bind_index: None, } }) .collect::<Vec<_>>() diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index d5be8822ee9..0b08e12925c 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -770,6 +770,8 @@ pub struct ActiveUniformInfo { pub size: Option<i32>, /// The type of the uniform. pub type_: u32, + /// The index of the indexed uniform buffer binding, if it is bound. + pub bind_index: Option<u32>, } impl ActiveUniformInfo { diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 03eb5e7abc2..3892d2bf320 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -189,6 +189,48 @@ impl WebGL2RenderingContext { self.base.current_vao_webgl2() } + pub fn validate_uniform_block_for_draw(&self) { + let program = match self.base.current_program() { + Some(program) => program, + None => return, + }; + for uniform_block in program.active_uniform_blocks().iter() { + let data_size = uniform_block.size as usize; + for block in program.active_uniforms().iter() { + let index = match block.bind_index { + Some(index) => index, + None => continue, + }; + let indexed = &self.indexed_uniform_buffer_bindings[index as usize]; + let buffer = match indexed.buffer.get() { + Some(buffer) => buffer, + None => { + self.base.webgl_error(InvalidOperation); + return; + }, + }; + if indexed.size.get() == 0 { + if data_size > buffer.capacity() { + self.base.webgl_error(InvalidOperation); + return; + } + } else { + let start = indexed.start.get() as usize; + let mut size = indexed.size.get() as usize; + if start >= size { + self.base.webgl_error(InvalidOperation); + return; + } + size -= start; + if data_size > size { + self.base.webgl_error(InvalidOperation); + return; + } + } + } + } + } + pub fn base_context(&self) -> DomRoot<WebGLRenderingContext> { DomRoot::from_ref(&*self.base) } @@ -1527,11 +1569,13 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 fn DrawArrays(&self, mode: u32, first: i32, count: i32) { + self.validate_uniform_block_for_draw(); self.base.DrawArrays(mode, first, count) } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11 fn DrawElements(&self, mode: u32, count: i32, type_: u32, offset: i64) { + self.validate_uniform_block_for_draw(); self.base.DrawElements(mode, count, type_, offset) } @@ -2776,6 +2820,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.9 fn DrawArraysInstanced(&self, mode: u32, first: i32, count: i32, primcount: i32) { + self.validate_uniform_block_for_draw(); handle_potential_webgl_error!( self.base, self.base @@ -2792,6 +2837,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { offset: i64, primcount: i32, ) { + self.validate_uniform_block_for_draw(); handle_potential_webgl_error!( self.base, self.base @@ -2800,6 +2846,28 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.9 + fn DrawRangeElements( + &self, + mode: u32, + start: u32, + end: u32, + count: i32, + type_: u32, + offset: i64, + ) { + if end < start { + self.base.webgl_error(InvalidValue); + return; + } + self.validate_uniform_block_for_draw(); + handle_potential_webgl_error!( + self.base, + self.base + .draw_elements_instanced(mode, count, type_, offset, 1) + ) + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.9 fn VertexAttribDivisor(&self, index: u32, divisor: u32) { self.base.vertex_attrib_divisor(index, divisor); } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index d3a726c1e11..78542e7497b 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -572,6 +572,11 @@ impl WebGLProgram { return Err(WebGLError::InvalidValue); } + let mut active_uniforms = self.active_uniforms.borrow_mut(); + if active_uniforms.len() > block_binding as usize { + active_uniforms[block_binding as usize].bind_index = Some(block_binding); + } + self.upcast::<WebGLObject>() .context() .send_command(WebGLCommand::UniformBlockBinding( diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 8e76eb552a3..476c6b5a076 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -960,7 +960,11 @@ impl WebGLRenderingContext { let type_size = match type_ { constants::UNSIGNED_BYTE => 1, constants::UNSIGNED_SHORT => 2, - constants::UNSIGNED_INT if self.extension_manager.is_element_index_uint_enabled() => 4, + constants::UNSIGNED_INT => match self.webgl_version() { + WebGLVersion::WebGL1 if self.extension_manager.is_element_index_uint_enabled() => 4, + WebGLVersion::WebGL2 => 4, + _ => return Err(InvalidEnum), + }, _ => return Err(InvalidEnum), }; if offset % type_size != 0 { diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index dca86da39fe..a05142da935 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -461,7 +461,7 @@ interface mixin WebGL2RenderingContextBase void vertexAttribDivisor(GLuint index, GLuint divisor); void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount); - // void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset); + void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset); /* Reading back pixels */ // WebGL1: diff --git a/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini deleted file mode 100644 index 808e1f516c4..00000000000 --- a/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini +++ /dev/null @@ -1,32 +0,0 @@ -[uniform-block-buffer-size.html] - expected: ERROR - [WebGL test #7: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArraysInstanced: UniformBlock not populated with a large enough buffer] - expected: FAIL - - [WebGL test #16: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] - expected: FAIL - - [WebGL test #5: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArraysInstanced: UniformBlock is backed by a buffer with no data store] - expected: FAIL - - [WebGL test #13: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArraysInstanced: bindBufferRange set size too small for UniformBlock] - expected: FAIL - - [WebGL test #4: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: UniformBlock is backed by a buffer with no data store] - expected: FAIL - - [WebGL test #12: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: bindBufferRange set size too small for UniformBlock] - expected: FAIL - - [WebGL test #15: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: UniformBlock is not backed by a buffer] - expected: FAIL - - [WebGL test #6: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: UniformBlock not populated with a large enough buffer] - expected: FAIL - - [WebGL test #2: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: UniformBlock is not backed by a buffer] - expected: FAIL - - [WebGL test #3: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArraysInstanced: UniformBlock is not backed by a buffer] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini index 9cb14f444b9..dccd8faaee3 100644 --- a/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini +++ b/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini @@ -1,9 +1,15 @@ [simultaneous_binding.html] expected: ERROR + [WebGL test #72: buffer should match expected values] + expected: FAIL + + [WebGL test #87: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously] + expected: FAIL + [WebGL test #6: buffer should match expected values] expected: FAIL - [WebGL test #50: Unexpected error before drawing: 1282] + [WebGL test #15: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as vertex attrib and tf simultaneously] expected: FAIL [WebGL test #4: Unexpected error before drawing: 1282] @@ -12,105 +18,159 @@ [WebGL test #59: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #45: Unexpected error before drawing: 1282] + [WebGL test #37: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #13: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #47: buffer should match expected values] expected: FAIL - [WebGL test #41: Unexpected error before drawing: 1282] + [WebGL test #49: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as vertex attrib and tf simultaneously] expected: FAIL - [WebGL test #46: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #43: buffer should match expected values] + expected: FAIL + + [WebGL test #17: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #79: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + expected: FAIL + + [WebGL test #52: should be the same as before as nothing has executed] + expected: FAIL + + [WebGL test #26: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #60: getError expected: NO_ERROR. Was INVALID_OPERATION : tf buffer not used as uniform buffer anymore] + expected: FAIL + + [WebGL test #102: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferData with double bound buffer] + expected: FAIL + + [WebGL test #45: Unexpected error before drawing: 1282] expected: FAIL [WebGL test #8: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #15: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as vertex attrib and tf simultaneously] + [WebGL test #78: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #37: Unexpected error before drawing: 1282] + [WebGL test #62: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #27: getError expected: NO_ERROR. Was INVALID_OPERATION : tf buffer not used as uniform buffer anymore] + [WebGL test #22: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #16: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as vertex attrib and tf simultaneously] + [WebGL test #10: buffer should match expected values] + expected: FAIL + + [WebGL test #70: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #83: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #81: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as vertex attrib and tf simultaneously] + expected: FAIL + + [WebGL test #74: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #19: should be the same as before as nothing has executed] + expected: FAIL + + [WebGL test #5: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + expected: FAIL + + [WebGL test #95: Unexpected error before drawing: 1282] + expected: FAIL + + [WebGL test #20: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as uniform buffer and tf simultaneously] + expected: FAIL + + [WebGL test #9: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL [WebGL test #29: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #55: Unexpected error before drawing: 1282] + [WebGL test #76: buffer should match expected values] expected: FAIL - [WebGL test #14: buffer should match expected values] + [WebGL test #46: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #38: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #75: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #54: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously] + [WebGL test #27: getError expected: NO_ERROR. Was INVALID_OPERATION : tf buffer not used as uniform buffer anymore] expected: FAIL - [WebGL test #47: buffer should match expected values] + [WebGL test #88: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #49: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as vertex attrib and tf simultaneously] + [WebGL test #14: buffer should match expected values] expected: FAIL - [WebGL test #10: buffer should match expected values] + [WebGL test #80: buffer should match expected values] expected: FAIL - [WebGL test #12: Unexpected error before drawing: 1282] + [WebGL test #54: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously] + expected: FAIL + + [WebGL test #82: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as vertex attrib and tf simultaneously] + expected: FAIL + + [WebGL test #92: Unexpected error before drawing: 1282] expected: FAIL [WebGL test #48: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as vertex attrib and tf simultaneously] expected: FAIL - [WebGL test #43: buffer should match expected values] + [WebGL test #71: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #42: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #85: should be the same as before as nothing has executed] expected: FAIL - [WebGL test #17: Unexpected error before drawing: 1282] + [WebGL test #21: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously] expected: FAIL - [WebGL test #22: Unexpected error before drawing: 1282] + [WebGL test #50: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #19: should be the same as before as nothing has executed] + [WebGL test #86: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as uniform buffer and tf simultaneously] expected: FAIL - [WebGL test #52: should be the same as before as nothing has executed] + [WebGL test #12: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #39: buffer should match expected values] + [WebGL test #13: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #5: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #41: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #62: Unexpected error before drawing: 1282] + [WebGL test #16: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as vertex attrib and tf simultaneously] expected: FAIL - [WebGL test #53: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as uniform buffer and tf simultaneously] + [WebGL test #55: Unexpected error before drawing: 1282] expected: FAIL - [WebGL test #26: Unexpected error before drawing: 1282] + [WebGL test #38: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #21: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously] + [WebGL test #42: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] expected: FAIL - [WebGL test #20: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as uniform buffer and tf simultaneously] + [WebGL test #39: buffer should match expected values] expected: FAIL - [WebGL test #60: getError expected: NO_ERROR. Was INVALID_OPERATION : tf buffer not used as uniform buffer anymore] + [WebGL test #93: getError expected: NO_ERROR. Was INVALID_OPERATION : tf buffer not used as uniform buffer anymore] expected: FAIL - [WebGL test #9: getError expected: NO_ERROR. Was INVALID_OPERATION : transform feedback should be successful] + [WebGL test #53: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as uniform buffer and tf simultaneously] expected: FAIL |