Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for VertexAttribI4* and VertexAttribIPointer #26135

Merged
merged 2 commits into from Apr 7, 2020
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Add initial support for VertexAttribI4*, VertexAttribIPointer

Adds initial support for the WebGL2 `VertexAttribI4i`, `VertexAttribI4iv`, `VertexAttribI4ui`, `VertexAttribI4uiv` and `VertexAttribIPointer` calls.
  • Loading branch information
imiklos authored and jdm committed Apr 7, 2020
commit 62f00df79d8945e43c42a6100d87faefa1aa04e0
@@ -1297,7 +1297,6 @@ impl WebGLImpl {
WebGLCommand::GetFragDataLocation(program_id, ref name, ref sender) => {
let location =
gl.get_frag_data_location(program_id.get(), &to_name_in_compiled_shader(name));
assert!(location >= 0);
sender.send(location).unwrap();
},
WebGLCommand::GetUniformLocation(program_id, ref name, ref chan) => {
@@ -1402,6 +1401,12 @@ impl WebGLImpl {
WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) => {
gl.vertex_attrib_4f(attrib_id, x, y, z, w)
},
WebGLCommand::VertexAttribI(attrib_id, x, y, z, w) => {
gl.vertex_attrib_4i(attrib_id, x, y, z, w)
},
WebGLCommand::VertexAttribU(attrib_id, x, y, z, w) => {
gl.vertex_attrib_4ui(attrib_id, x, y, z, w)
},
WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) => {
gl.vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset)
},
@@ -387,6 +387,8 @@ pub enum WebGLCommand {
UseProgram(Option<WebGLProgramId>),
ValidateProgram(WebGLProgramId),
VertexAttrib(u32, f32, f32, f32, f32),
VertexAttribI(u32, i32, i32, i32, i32),
VertexAttribU(u32, u32, u32, u32, u32),
VertexAttribPointer(u32, i32, u32, bool, i32, u32),
VertexAttribPointer2f(u32, i32, bool, i32, u32),
SetViewport(i32, i32, i32, i32),
@@ -3,12 +3,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::dom::bindings::cell::{ref_filter_map, DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants2;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use crate::dom::bindings::root::{Dom, MutNullableDom};
use crate::dom::webglbuffer::WebGLBuffer;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use canvas_traits::webgl::{
ActiveAttribInfo, WebGLCommand, WebGLError, WebGLResult, WebGLVertexArrayId,
ActiveAttribInfo, WebGLCommand, WebGLError, WebGLResult, WebGLVersion, WebGLVertexArrayId,
};
use std::cell::Cell;

@@ -85,6 +86,10 @@ impl VertexArrayObject {
})
}

pub fn set_vertex_attrib_type(&self, index: u32, type_: u32) {
self.vertex_attribs.borrow_mut()[index as usize].type_ = type_;
}

pub fn vertex_attrib_pointer(
&self,
index: u32,
@@ -108,12 +113,27 @@ impl VertexArrayObject {
if stride < 0 || stride > 255 || offset < 0 {
return Err(WebGLError::InvalidValue);
}

let is_webgl2 = match self.context.webgl_version() {
WebGLVersion::WebGL2 => true,
_ => false,
};

let bytes_per_component: i32 = match type_ {
constants::BYTE | constants::UNSIGNED_BYTE => 1,
constants::SHORT | constants::UNSIGNED_SHORT => 2,
constants::FLOAT => 4,
constants::INT | constants::UNSIGNED_INT if is_webgl2 => 4,
constants2::HALF_FLOAT if is_webgl2 => 2,
sparkle::gl::FIXED if is_webgl2 => 4,
constants2::INT_2_10_10_10_REV | constants2::UNSIGNED_INT_2_10_10_10_REV
if is_webgl2 && size == 4 =>
{
4
},
_ => return Err(WebGLError::InvalidEnum),
};

if offset % bytes_per_component as i64 > 0 || stride % bytes_per_component > 0 {
return Err(WebGLError::InvalidOperation);
}
@@ -25,7 +25,7 @@ use crate::dom::webglprogram::WebGLProgram;
use crate::dom::webglquery::WebGLQuery;
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
use crate::dom::webglrenderingcontext::{
uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext,
uniform_get, uniform_typed, LayoutCanvasWebGLRenderingContextHelpers, VertexAttrib, WebGLRenderingContext,
};
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
use crate::dom::webglshader::WebGLShader;
@@ -230,6 +230,62 @@ impl WebGL2RenderingContext {
}
}

fn validate_vertex_attribs_for_draw(&self) {
let program = match self.base.current_program() {
Some(program) => program,
None => return,
};
let groups = [
[
constants::INT,
constants::INT_VEC2,
constants::INT_VEC3,
constants::INT_VEC4,
],
[
constants::UNSIGNED_INT,
constants::UNSIGNED_INT_VEC2,
constants::UNSIGNED_INT_VEC3,
constants::UNSIGNED_INT_VEC4,
],
[
constants::FLOAT,
constants::FLOAT_VEC2,
constants::FLOAT_VEC3,
constants::FLOAT_VEC4,
],
];
let vao = self.current_vao();
for prog_attrib in program.active_attribs().iter() {
let attrib = handle_potential_webgl_error!(
self.base,
vao.get_vertex_attrib(prog_attrib.location as u32)
.ok_or(InvalidOperation),
return
);

let current_vertex_attrib =
self.base.current_vertex_attribs()[prog_attrib.location as usize];
let attrib_data_base_type = if !attrib.enabled_as_array {
match current_vertex_attrib {
VertexAttrib::Int(_, _, _, _) => constants::INT,
VertexAttrib::Uint(_, _, _, _) => constants::UNSIGNED_INT,
VertexAttrib::Float(_, _, _, _) => constants::FLOAT,
}
} else {
attrib.type_
};

let contains = groups
.iter()
.find(|g| g.contains(&attrib_data_base_type) && g.contains(&prog_attrib.type_));
if contains.is_none() {
self.base.webgl_error(InvalidOperation);
return;
}
}
}

pub fn base_context(&self) -> DomRoot<WebGLRenderingContext> {
DomRoot::from_ref(&*self.base)
}
@@ -739,6 +795,28 @@ impl WebGL2RenderingContext {

true
}

fn vertex_attrib_i(&self, index: u32, x: i32, y: i32, z: i32, w: i32) {
if index >= self.base.limits().max_vertex_attribs {
return self.base.webgl_error(InvalidValue);
}
self.base.current_vertex_attribs()[index as usize] = VertexAttrib::Int(x, y, z, w);
self.current_vao()
.set_vertex_attrib_type(index, constants::INT);
self.base
.send_command(WebGLCommand::VertexAttribI(index, x, y, z, w));
}

fn vertex_attrib_u(&self, index: u32, x: u32, y: u32, z: u32, w: u32) {
if index >= self.base.limits().max_vertex_attribs {
return self.base.webgl_error(InvalidValue);
}
self.base.current_vertex_attribs()[index as usize] = VertexAttrib::Uint(x, y, z, w);
self.current_vao()
.set_vertex_attrib_type(index, constants::UNSIGNED_INT);
self.base
.send_command(WebGLCommand::VertexAttribU(index, x, y, z, w));
}
}

impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
@@ -1569,12 +1647,14 @@ 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.validate_vertex_attribs_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.validate_vertex_attribs_for_draw();
self.base.DrawElements(mode, count, type_, offset)
}

@@ -2591,6 +2671,40 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
self.base.VertexAttrib4fv(indx, v)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn VertexAttribI4i(&self, index: u32, x: i32, y: i32, z: i32, w: i32) {
self.vertex_attrib_i(index, x, y, z, w)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn VertexAttribI4iv(&self, index: u32, v: Int32ArrayOrLongSequence) {
let values = match v {
Int32ArrayOrLongSequence::Int32Array(v) => v.to_vec(),
Int32ArrayOrLongSequence::LongSequence(v) => v,
};
if values.len() < 4 {
return self.base.webgl_error(InvalidValue);
}
self.vertex_attrib_i(index, values[0], values[1], values[2], values[3]);
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn VertexAttribI4ui(&self, index: u32, x: u32, y: u32, z: u32, w: u32) {
self.vertex_attrib_u(index, x, y, z, w)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn VertexAttribI4uiv(&self, index: u32, v: Uint32ArrayOrUnsignedLongSequence) {
let values = match v {
Uint32ArrayOrUnsignedLongSequence::Uint32Array(v) => v.to_vec(),
Uint32ArrayOrUnsignedLongSequence::UnsignedLongSequence(v) => v,
};
if values.len() < 4 {
return self.base.webgl_error(InvalidValue);
}
self.vertex_attrib_u(index, values[0], values[1], values[2], values[3]);
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttribPointer(
&self,
@@ -2605,6 +2719,21 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
.VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset)
}

/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
fn VertexAttribIPointer(&self, index: u32, size: i32, type_: u32, stride: i32, offset: i64) {
match type_ {
constants::BYTE |
constants::UNSIGNED_BYTE |
constants::SHORT |
constants::UNSIGNED_SHORT |
constants::INT |
constants::UNSIGNED_INT => {},
_ => return self.base.webgl_error(InvalidEnum),
};
self.base
.VertexAttribPointer(index, size, type_, false, stride, offset)
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
fn Viewport(&self, x: i32, y: i32, width: i32, height: i32) {
self.base.Viewport(x, y, width, height)
@@ -2820,6 +2949,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();
self.validate_vertex_attribs_for_draw();
handle_potential_webgl_error!(
self.base,
self.base
@@ -2837,6 +2967,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
primcount: i32,
) {
self.validate_uniform_block_for_draw();
self.validate_vertex_attribs_for_draw();
handle_potential_webgl_error!(
self.base,
self.base
@@ -2859,6 +2990,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
return;
}
self.validate_uniform_block_for_draw();
self.validate_vertex_attribs_for_draw();
handle_potential_webgl_error!(
self.base,
self.base
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.