Add support for some more WebGL2 limit parameters

Adds support for the following new WebGL2 GetParameter values:

- `MAX_ELEMENT_INDEX`
- `MAX_ELEMENTS_INDICES`
- `MAX_ELEMENTS_VERTICES`
- `MAX_FRAGMENT_INPUT_COMPONENTS`
- `MAX_SAMPLES`
- `MAX_SERVER_WAIT_TIMEOUT`
- `MAX_TEXTURE_LOD_BIAS`
- `MAX_VARYING_COMPONENTS`
- `MAX_VERTEX_OUTPUT_COMPONENTS`

See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2
This commit is contained in:
Mátyás Mustoha 2020-04-22 14:48:14 +02:00 committed by Josh Matthews
parent e69adfdd7a
commit c5f0bff99e
6 changed files with 147 additions and 115 deletions

4
Cargo.lock generated
View file

@ -5311,9 +5311,9 @@ dependencies = [
[[package]] [[package]]
name = "sparkle" name = "sparkle"
version = "0.1.23" version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330996cd0c6e299725511d329a94b883f685e66c05c0150daeac2d98c7580455" checksum = "b7cd7f292661a533c2a7e239af495ba63891b5723c3a6d48712b2e3823466174"
dependencies = [ dependencies = [
"gl_generator 0.13.1", "gl_generator 0.13.1",
] ]

View file

@ -35,7 +35,7 @@ raqote = {git = "https://github.com/jrmuizel/raqote"}
time = { version = "0.1.0", optional = true } time = { version = "0.1.0", optional = true }
pixels = {path = "../pixels"} pixels = {path = "../pixels"}
servo_config = {path = "../config"} servo_config = {path = "../config"}
sparkle = "0.1.22" sparkle = "0.1.24"
webrender = {git = "https://github.com/servo/webrender"} webrender = {git = "https://github.com/servo/webrender"}
webrender_api = {git = "https://github.com/servo/webrender"} webrender_api = {git = "https://github.com/servo/webrender"}
webrender_surfman = {path = "../webrender_surfman"} webrender_surfman = {path = "../webrender_surfman"}

View file

@ -82,9 +82,18 @@ impl GLLimitsDetect for GLLimits {
max_3d_texture_size, max_3d_texture_size,
max_array_texture_layers, max_array_texture_layers,
uniform_buffer_offset_alignment, uniform_buffer_offset_alignment,
max_element_index,
max_elements_indices,
max_elements_vertices,
max_fragment_input_components,
max_samples,
max_server_wait_timeout,
max_texture_lod_bias,
max_varying_components,
max_vertex_output_components,
); );
if webgl_version == WebGLVersion::WebGL2 { if webgl_version == WebGLVersion::WebGL2 {
max_uniform_block_size = gl.get_integer(gl::MAX_UNIFORM_BLOCK_SIZE); max_uniform_block_size = gl.get_integer64(gl::MAX_UNIFORM_BLOCK_SIZE);
max_uniform_buffer_bindings = gl.get_integer(gl::MAX_UNIFORM_BUFFER_BINDINGS); max_uniform_buffer_bindings = gl.get_integer(gl::MAX_UNIFORM_BUFFER_BINDINGS);
min_program_texel_offset = gl.get_integer(gl::MIN_PROGRAM_TEXEL_OFFSET); min_program_texel_offset = gl.get_integer(gl::MIN_PROGRAM_TEXEL_OFFSET);
max_program_texel_offset = gl.get_integer(gl::MAX_PROGRAM_TEXEL_OFFSET); max_program_texel_offset = gl.get_integer(gl::MAX_PROGRAM_TEXEL_OFFSET);
@ -96,16 +105,31 @@ impl GLLimitsDetect for GLLimits {
.min(max_color_attachments); .min(max_color_attachments);
max_combined_uniform_blocks = gl.get_integer(gl::MAX_COMBINED_UNIFORM_BLOCKS); max_combined_uniform_blocks = gl.get_integer(gl::MAX_COMBINED_UNIFORM_BLOCKS);
max_combined_vertex_uniform_components = max_combined_vertex_uniform_components =
gl.get_integer(gl::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); gl.get_integer64(gl::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
max_combined_fragment_uniform_components = max_combined_fragment_uniform_components =
gl.get_integer(gl::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); gl.get_integer64(gl::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
max_vertex_uniform_blocks = gl.get_integer(gl::MAX_VERTEX_UNIFORM_BLOCKS); max_vertex_uniform_blocks = gl.get_integer(gl::MAX_VERTEX_UNIFORM_BLOCKS);
max_vertex_uniform_components = gl.get_integer(gl::MAX_VERTEX_UNIFORM_COMPONENTS); max_vertex_uniform_components = gl.get_integer(gl::MAX_VERTEX_UNIFORM_COMPONENTS);
max_fragment_uniform_blocks = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_BLOCKS); max_fragment_uniform_blocks = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_BLOCKS);
max_fragment_uniform_components = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_COMPONENTS); max_fragment_uniform_components = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_COMPONENTS);
uniform_buffer_offset_alignment = gl.get_integer(gl::UNIFORM_BUFFER_OFFSET_ALIGNMENT); uniform_buffer_offset_alignment = gl.get_integer(gl::UNIFORM_BUFFER_OFFSET_ALIGNMENT);
max_3d_texture_size = gl.get_integer(gl::MAX_3D_TEXTURE_SIZE); max_3d_texture_size = gl.get_integer(gl::MAX_3D_TEXTURE_SIZE);
max_array_texture_layers = gl.get_integer(gl::MAX_ARRAY_TEXTURE_LAYERS) max_array_texture_layers = gl.get_integer(gl::MAX_ARRAY_TEXTURE_LAYERS);
max_element_index = gl
.try_get_integer64(gl::MAX_ELEMENT_INDEX)
.unwrap_or(u32::MAX as u64); // requires GL 4.3
max_elements_indices = gl.get_integer(gl::MAX_ELEMENTS_INDICES);
max_elements_vertices = gl.get_integer(gl::MAX_ELEMENTS_VERTICES);
max_fragment_input_components = gl.get_integer(gl::MAX_FRAGMENT_INPUT_COMPONENTS);
max_samples = gl.get_integer(gl::MAX_SAMPLES);
max_server_wait_timeout =
std::time::Duration::from_nanos(gl.get_integer64(gl::MAX_SERVER_WAIT_TIMEOUT));
max_texture_lod_bias = gl.get_float(gl::MAX_TEXTURE_LOD_BIAS);
max_varying_components = gl.try_get_integer(gl::MAX_VARYING_COMPONENTS).unwrap_or(
// macOS Core Profile is buggy. The spec says this value is 4 * MAX_VARYING_VECTORS.
max_varying_vectors * 4,
);
max_vertex_output_components = gl.get_integer(gl::MAX_VERTEX_OUTPUT_COMPONENTS);
} else { } else {
max_uniform_block_size = 0; max_uniform_block_size = 0;
max_uniform_buffer_bindings = 0; max_uniform_buffer_bindings = 0;
@ -124,6 +148,15 @@ impl GLLimitsDetect for GLLimits {
uniform_buffer_offset_alignment = 0; uniform_buffer_offset_alignment = 0;
max_3d_texture_size = 0; max_3d_texture_size = 0;
max_array_texture_layers = 0; max_array_texture_layers = 0;
max_element_index = 0;
max_elements_indices = 0;
max_elements_vertices = 0;
max_fragment_input_components = 0;
max_samples = 0;
max_server_wait_timeout = std::time::Duration::default();
max_texture_lod_bias = 0.0;
max_varying_components = 0;
max_vertex_output_components = 0;
} }
GLLimits { GLLimits {
@ -157,30 +190,51 @@ impl GLLimitsDetect for GLLimits {
max_3d_texture_size, max_3d_texture_size,
max_array_texture_layers, max_array_texture_layers,
uniform_buffer_offset_alignment, uniform_buffer_offset_alignment,
max_element_index,
max_elements_indices,
max_elements_vertices,
max_fragment_input_components,
max_samples,
max_server_wait_timeout,
max_texture_lod_bias,
max_varying_components,
max_vertex_output_components,
} }
} }
} }
trait GLExt { trait GLExt {
fn try_get_integer(self, parameter: GLenum) -> Option<u32>; fn try_get_integer(self, parameter: GLenum) -> Option<u32>;
fn try_get_integer64(self, parameter: GLenum) -> Option<u64>;
fn try_get_float(self, parameter: GLenum) -> Option<f32>;
fn get_integer(self, parameter: GLenum) -> u32; fn get_integer(self, parameter: GLenum) -> u32;
fn get_integer64(self, parameter: GLenum) -> u64;
fn get_float(self, parameter: GLenum) -> f32;
} }
impl<'a> GLExt for &'a Gl { macro_rules! create_fun {
($tryer:ident, $getter:ident, $gltype:ty, $glcall:ident, $rstype:ty) => {
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn try_get_integer(self, parameter: GLenum) -> Option<u32> { fn $tryer(self, parameter: GLenum) -> Option<$rstype> {
let mut value = [0]; let mut value = [<$gltype>::default()];
unsafe { unsafe {
self.get_integer_v(parameter, &mut value); self.$glcall(parameter, &mut value);
} }
if self.get_error() != gl::NO_ERROR { if self.get_error() != gl::NO_ERROR {
None None
} else { } else {
Some(value[0] as u32) Some(value[0] as $rstype)
} }
} }
fn get_integer(self, parameter: GLenum) -> u32 { fn $getter(self, parameter: GLenum) -> $rstype {
self.try_get_integer(parameter).unwrap() self.$tryer(parameter).unwrap()
} }
};
}
impl<'a> GLExt for &'a Gl {
create_fun!(try_get_integer, get_integer, i32, get_integer_v, u32);
create_fun!(try_get_integer64, get_integer64, i64, get_integer64_v, u64);
create_fun!(try_get_float, get_float, f32, get_float_v, f32);
} }

View file

@ -1050,10 +1050,10 @@ pub struct GLLimits {
pub max_uniform_buffer_bindings: u32, pub max_uniform_buffer_bindings: u32,
pub min_program_texel_offset: u32, pub min_program_texel_offset: u32,
pub max_program_texel_offset: u32, pub max_program_texel_offset: u32,
pub max_uniform_block_size: u32, pub max_uniform_block_size: u64,
pub max_combined_uniform_blocks: u32, pub max_combined_uniform_blocks: u32,
pub max_combined_vertex_uniform_components: u32, pub max_combined_vertex_uniform_components: u64,
pub max_combined_fragment_uniform_components: u32, pub max_combined_fragment_uniform_components: u64,
pub max_vertex_uniform_blocks: u32, pub max_vertex_uniform_blocks: u32,
pub max_vertex_uniform_components: u32, pub max_vertex_uniform_components: u32,
pub max_fragment_uniform_blocks: u32, pub max_fragment_uniform_blocks: u32,
@ -1061,4 +1061,13 @@ pub struct GLLimits {
pub max_3d_texture_size: u32, pub max_3d_texture_size: u32,
pub max_array_texture_layers: u32, pub max_array_texture_layers: u32,
pub uniform_buffer_offset_alignment: u32, pub uniform_buffer_offset_alignment: u32,
pub max_element_index: u64,
pub max_elements_indices: u32,
pub max_elements_vertices: u32,
pub max_fragment_input_components: u32,
pub max_samples: u32,
pub max_server_wait_timeout: std::time::Duration,
pub max_texture_lod_bias: f32,
pub max_varying_components: u32,
pub max_vertex_output_components: u32,
} }

View file

@ -887,10 +887,13 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
return rval.get(); return rval.get();
}, },
constants::MAX_CLIENT_WAIT_TIMEOUT_WEBGL => { constants::MAX_CLIENT_WAIT_TIMEOUT_WEBGL => {
return Int32Value( return DoubleValue(
self.base.limits().max_client_wait_timeout_webgl.as_nanos() as i32 self.base.limits().max_client_wait_timeout_webgl.as_nanos() as f64
); );
}, },
constants::MAX_SERVER_WAIT_TIMEOUT => {
return DoubleValue(self.base.limits().max_server_wait_timeout.as_nanos() as f64);
},
constants::SAMPLER_BINDING => unsafe { constants::SAMPLER_BINDING => unsafe {
let idx = (self.base.textures().active_unit_enum() - constants::TEXTURE0) as usize; let idx = (self.base.textures().active_unit_enum() - constants::TEXTURE0) as usize;
assert!(idx < self.samplers.len()); assert!(idx < self.samplers.len());
@ -972,28 +975,42 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
}; };
return UInt32Value(buffer); return UInt32Value(buffer);
}, },
constants::MAX_TEXTURE_LOD_BIAS => {
return DoubleValue(self.base.limits().max_texture_lod_bias as f64)
},
constants::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS => {
return DoubleValue(
self.base.limits().max_combined_fragment_uniform_components as f64,
)
},
constants::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS => {
return DoubleValue(
self.base.limits().max_combined_vertex_uniform_components as f64,
)
},
constants::MAX_ELEMENT_INDEX => {
return DoubleValue(self.base.limits().max_element_index as f64)
},
constants::MAX_UNIFORM_BLOCK_SIZE => {
return DoubleValue(self.base.limits().max_uniform_block_size as f64)
},
_ => {}, _ => {},
} }
let limit = match parameter { let limit = match parameter {
constants::MAX_UNIFORM_BUFFER_BINDINGS => { constants::MAX_3D_TEXTURE_SIZE => Some(self.base.limits().max_3d_texture_size),
Some(self.base.limits().max_uniform_buffer_bindings) constants::MAX_ARRAY_TEXTURE_LAYERS => {
Some(self.base.limits().max_array_texture_layers)
}, },
constants::MAX_UNIFORM_BLOCK_SIZE => Some(self.base.limits().max_uniform_block_size), constants::MAX_COLOR_ATTACHMENTS => Some(self.base.limits().max_color_attachments),
constants::MAX_COMBINED_UNIFORM_BLOCKS => { constants::MAX_COMBINED_UNIFORM_BLOCKS => {
Some(self.base.limits().max_combined_uniform_blocks) Some(self.base.limits().max_combined_uniform_blocks)
}, },
constants::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS => { constants::MAX_DRAW_BUFFERS => Some(self.base.limits().max_draw_buffers),
Some(self.base.limits().max_combined_vertex_uniform_components) constants::MAX_ELEMENTS_INDICES => Some(self.base.limits().max_elements_indices),
}, constants::MAX_ELEMENTS_VERTICES => Some(self.base.limits().max_elements_vertices),
constants::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS => { constants::MAX_FRAGMENT_INPUT_COMPONENTS => {
Some(self.base.limits().max_combined_fragment_uniform_components) Some(self.base.limits().max_fragment_input_components)
},
constants::MAX_VERTEX_UNIFORM_BLOCKS => {
Some(self.base.limits().max_vertex_uniform_blocks)
},
constants::MAX_VERTEX_UNIFORM_COMPONENTS => {
Some(self.base.limits().max_vertex_uniform_components)
}, },
constants::MAX_FRAGMENT_UNIFORM_BLOCKS => { constants::MAX_FRAGMENT_UNIFORM_BLOCKS => {
Some(self.base.limits().max_fragment_uniform_blocks) Some(self.base.limits().max_fragment_uniform_blocks)
@ -1001,11 +1018,26 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
constants::MAX_FRAGMENT_UNIFORM_COMPONENTS => { constants::MAX_FRAGMENT_UNIFORM_COMPONENTS => {
Some(self.base.limits().max_fragment_uniform_components) Some(self.base.limits().max_fragment_uniform_components)
}, },
constants::MAX_PROGRAM_TEXEL_OFFSET => {
Some(self.base.limits().max_program_texel_offset)
},
constants::MAX_SAMPLES => Some(self.base.limits().max_samples),
constants::MAX_UNIFORM_BUFFER_BINDINGS => {
Some(self.base.limits().max_uniform_buffer_bindings)
},
constants::MAX_VARYING_COMPONENTS => Some(self.base.limits().max_varying_components),
constants::MAX_VERTEX_OUTPUT_COMPONENTS => {
Some(self.base.limits().max_vertex_output_components)
},
constants::MAX_VERTEX_UNIFORM_BLOCKS => {
Some(self.base.limits().max_vertex_uniform_blocks)
},
constants::MAX_VERTEX_UNIFORM_COMPONENTS => {
Some(self.base.limits().max_vertex_uniform_components)
},
constants::UNIFORM_BUFFER_OFFSET_ALIGNMENT => { constants::UNIFORM_BUFFER_OFFSET_ALIGNMENT => {
Some(self.base.limits().uniform_buffer_offset_alignment) Some(self.base.limits().uniform_buffer_offset_alignment)
}, },
constants::MAX_COLOR_ATTACHMENTS => Some(self.base.limits().max_color_attachments),
constants::MAX_DRAW_BUFFERS => Some(self.base.limits().max_draw_buffers),
_ => None, _ => None,
}; };
if let Some(limit) = limit { if let Some(limit) = limit {

View file

@ -1,103 +1,40 @@
[gl-get-calls.html] [gl-get-calls.html]
[WebGL test #47: context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS) should be >= 60. Was null (of type object).] [WebGL test #55: context.getParameter(context.MAX_SAMPLES) should be >= 4. Was 1 (of type number).]
expected: FAIL expected: FAIL
[WebGL test #80: context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET) is not an instance of Number] [WebGL test #80: context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET) is not an instance of Number]
expected: FAIL expected: FAIL
[WebGL test #33: context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS) should be >= 256. Was null (of type object).]
expected: FAIL
[WebGL test #26: context.getParameter(context.UNPACK_ROW_LENGTH) should be 0 (of type number). Was null (of type object).] [WebGL test #26: context.getParameter(context.UNPACK_ROW_LENGTH) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #7: context.getParameter(context.PACK_ROW_LENGTH) should be 0 (of type number). Was null (of type object).] [WebGL test #7: context.getParameter(context.PACK_ROW_LENGTH) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #43: context.getParameter(context.MAX_ELEMENT_INDEX) should be >= 16777215. Was null (of type object).]
expected: FAIL
[WebGL test #56: context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET) is not an instance of Number]
expected: FAIL
[WebGL test #45: context.getParameter(context.MAX_ELEMENTS_INDICES) is not an instance of Number]
expected: FAIL
[WebGL test #27: context.getParameter(context.UNPACK_SKIP_IMAGES) should be 0 (of type number). Was null (of type object).] [WebGL test #27: context.getParameter(context.UNPACK_SKIP_IMAGES) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #87: context.getError() should be 0. Was 1280.] [WebGL test #87: context.getError() should be 0. Was 1280.]
expected: FAIL expected: FAIL
[WebGL test #50: context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS) is not an instance of Number]
expected: FAIL
[WebGL test #53: context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET) should be >= 7. Was null (of type object).]
expected: FAIL
[WebGL test #55: context.getParameter(context.MAX_SAMPLES) should be >= 4. Was null (of type object).]
expected: FAIL
[WebGL test #29: context.getParameter(context.UNPACK_SKIP_ROWS) should be 0 (of type number). Was null (of type object).] [WebGL test #29: context.getParameter(context.UNPACK_SKIP_ROWS) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #54: context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET) is not an instance of Number]
expected: FAIL
[WebGL test #58: context.getParameter(context.MAX_SERVER_WAIT_TIMEOUT) is not an instance of Number]
expected: FAIL
[WebGL test #59: context.getParameter(context.MAX_TEXTURE_LOD_BIAS) should be >= 2.0. Was null (of type object).]
expected: FAIL
[WebGL test #25: context.getParameter(context.UNPACK_IMAGE_HEIGHT) should be 0 (of type number). Was null (of type object).] [WebGL test #25: context.getParameter(context.UNPACK_IMAGE_HEIGHT) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #31: context.getParameter(context.MAX_3D_TEXTURE_SIZE) should be >= 256. Was null (of type object).]
expected: FAIL
[WebGL test #74: context.getParameter(context.MAX_VERTEX_OUTPUT_COMPONENTS) is not an instance of Number]
expected: FAIL
[WebGL test #73: context.getParameter(context.MAX_VERTEX_OUTPUT_COMPONENTS) should be >= 64. Was null (of type object).]
expected: FAIL
[WebGL test #72: context.getParameter(context.MAX_VARYING_COMPONENTS) is not an instance of Number]
expected: FAIL
[WebGL test #60: context.getParameter(context.MAX_TEXTURE_LOD_BIAS) is not an instance of Number]
expected: FAIL
[WebGL test #79: context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET) should be >= -8. Was null (of type object).] [WebGL test #79: context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET) should be >= -8. Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #71: context.getParameter(context.MAX_VARYING_COMPONENTS) should be >= 60. Was null (of type object).]
expected: FAIL
[WebGL test #8: context.getParameter(context.PACK_SKIP_PIXELS) should be 0 (of type number). Was null (of type object).]
expected: FAIL
[WebGL test #48: context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS) is not an instance of Number]
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 #34: context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS) is not an instance of Number]
expected: FAIL
[WebGL test #46: context.getParameter(context.MAX_ELEMENTS_VERTICES) is not an instance of Number]
expected: FAIL
[WebGL test #12: context.getParameter(context.RASTERIZER_DISCARD) should be false (of type boolean). Was null (of type object).]
expected: FAIL
[WebGL test #44: context.getParameter(context.MAX_ELEMENT_INDEX) is not an instance of Number]
expected: FAIL
[WebGL test #28: context.getParameter(context.UNPACK_SKIP_PIXELS) should be 0 (of type number). Was null (of type object).] [WebGL test #28: context.getParameter(context.UNPACK_SKIP_PIXELS) should be 0 (of type number). Was null (of type object).]
expected: FAIL expected: FAIL
[WebGL test #32: context.getParameter(context.MAX_3D_TEXTURE_SIZE) is not an instance of Number] [WebGL test #8: context.getParameter(context.PACK_SKIP_PIXELS) should be 0 (of type number). 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 #12: context.getParameter(context.RASTERIZER_DISCARD) should be false (of type boolean). Was null (of type object).]
expected: FAIL expected: FAIL