aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/webrender/glsl-to-cxx/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrender/glsl-to-cxx/src')
-rw-r--r--third_party/webrender/glsl-to-cxx/src/hir.rs999
-rw-r--r--third_party/webrender/glsl-to-cxx/src/lib.rs354
2 files changed, 371 insertions, 982 deletions
diff --git a/third_party/webrender/glsl-to-cxx/src/hir.rs b/third_party/webrender/glsl-to-cxx/src/hir.rs
index 287ae8d035b..710b50b7af2 100644
--- a/third_party/webrender/glsl-to-cxx/src/hir.rs
+++ b/third_party/webrender/glsl-to-cxx/src/hir.rs
@@ -1,38 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Large chunks of this file are derived from the glsl crate which is:
- * Copyright (c) 2018, Dimitri Sabadie <dimitri.sabadie@gmail.com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * * Neither the name of Dimitri Sabadie <dimitri.sabadie@gmail.com> nor the names of other
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use glsl::syntax;
use glsl::syntax::{ArrayedIdentifier, ArraySpecifier, AssignmentOp, BinaryOp, Identifier};
@@ -77,7 +45,6 @@ pub enum SamplerFormat {
RGBA32F,
RGBA32I,
R8,
- RG8,
}
impl SamplerFormat {
@@ -88,7 +55,6 @@ impl SamplerFormat {
SamplerFormat::RGBA32F => Some("RGBA32F"),
SamplerFormat::RGBA32I => Some("RGBA32I"),
SamplerFormat::R8 => Some("R8"),
- SamplerFormat::RG8 => Some("RG8"),
}
}
}
@@ -788,14 +754,6 @@ impl Type {
array_sizes: None,
}
}
-
- pub fn new_array(kind: TypeKind, size: i32) -> Self {
- Type {
- kind,
- precision: None,
- array_sizes: Some(Box::new(ArraySizes { sizes: vec![make_const(TypeKind::Int, size)] })),
- }
- }
}
impl LiftFrom<&syntax::FullySpecifiedType> for Type {
@@ -902,7 +860,7 @@ impl RunClass {
#[derive(Debug, Clone, PartialEq)]
pub enum SymDecl {
- NativeFunction(FunctionType, Option<&'static str>, RunClass),
+ NativeFunction(FunctionType, Option<&'static str>),
UserFunction(Rc<FunctionDefinition>, RunClass),
Local(StorageClass, Type, RunClass),
Global(
@@ -969,8 +927,6 @@ pub struct State {
modified_globals: RefCell<Vec<SymRef>>,
pub used_globals: RefCell<Vec<SymRef>>,
pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
- clip_dist_sym: SymRef,
- pub used_clip_dist: u32,
}
impl State {
@@ -986,8 +942,6 @@ impl State {
modified_globals: RefCell::new(Vec::new()),
used_globals: RefCell::new(Vec::new()),
texel_fetches: HashMap::new(),
- clip_dist_sym: SymRef(0),
- used_clip_dist: 0,
}
}
@@ -1795,9 +1749,6 @@ fn translate_variable_declaration(
"r8" => {
storage = StorageClass::Sampler(SamplerFormat::R8);
}
- "rg8" => {
- storage = StorageClass::Sampler(SamplerFormat::RG8);
- }
_ => {}
}
}
@@ -1904,33 +1855,11 @@ fn translate_declaration(
syntax::Declaration::FunctionPrototype(p) => {
Declaration::FunctionPrototype(translate_function_prototype(state, p))
}
- syntax::Declaration::Global(ty, ids) => {
- // glsl non-es supports requalifying variables, but we don't yet.
- // However, we still want to allow global layout qualifiers for
- // KHR_advanced_blend_equation.
- if !ids.is_empty() {
- panic!();
- }
- let _ = for qual in &ty.qualifiers {
- match qual {
- syntax::TypeQualifierSpec::Layout(l) => {
- for id in &l.ids {
- match id {
- syntax::LayoutQualifierSpec::Identifier(key, _) => {
- match key.as_str() {
- "blend_support_all_equations" => (),
- _ => panic!(),
- }
- }
- _ => panic!(),
- }
- }
- }
- syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out) => (),
- _ => panic!(),
- }
- };
- Declaration::Global(lift_type_qualifier_for_declaration(state, &Some(ty.clone())).unwrap(), ids.clone())
+ syntax::Declaration::Global(_ty, _ids) => {
+ panic!();
+ // glsl non-es supports requalifying variables
+ // we don't right now
+ //Declaration::Global(..)
}
syntax::Declaration::InitDeclaratorList(dl) => {
translate_init_declarator_list(state, dl, default_run_class)
@@ -1944,9 +1873,6 @@ fn is_vector(ty: &Type) -> bool {
TypeKind::Vec2
| TypeKind::Vec3
| TypeKind::Vec4
- | TypeKind::BVec2
- | TypeKind::BVec3
- | TypeKind::BVec4
| TypeKind::IVec2
| TypeKind::IVec3
| TypeKind::IVec4 => ty.array_sizes == None,
@@ -1954,32 +1880,6 @@ fn is_vector(ty: &Type) -> bool {
}
}
-fn index_vector(ty: &Type) -> Option<TypeKind> {
- use TypeKind::*;
- if ty.array_sizes != None {
- return None;
- }
- Some(match ty.kind {
- Vec2 => Float,
- Vec3 => Float,
- Vec4 => Float,
- DVec2 => Double,
- DVec3 => Double,
- DVec4 => Double,
- BVec2 => Bool,
- BVec3 => Bool,
- BVec4 => Bool,
- IVec2 => Int,
- IVec3 => Int,
- IVec4 => Int,
- UVec2 => UInt,
- UVec3 => UInt,
- UVec4 => UInt,
- _ => return None,
- })
-
-}
-
fn index_matrix(ty: &Type) -> Option<TypeKind> {
use TypeKind::*;
if ty.array_sizes != None {
@@ -2015,28 +1915,30 @@ fn is_ivec(ty: &Type) -> bool {
}
}
-fn can_implicitly_convert_to(src: &Type, dst: &Type) -> bool {
+fn compatible_type(lhs: &Type, rhs: &Type) -> bool {
// XXX: use an underlying type helper
- if src == &Type::new(TypeKind::Double) && dst == &Type::new(TypeKind::Float) {
- // We're not supposed to implicitly convert from double to float but glsl 4 has a bug
- // where it parses unannotated float constants as double.
+ if lhs == &Type::new(TypeKind::Double) && rhs == &Type::new(TypeKind::Float) {
+ true
+ } else if rhs == &Type::new(TypeKind::Double) && lhs == &Type::new(TypeKind::Float) {
true
- } else if dst == &Type::new(TypeKind::Double) && src == &Type::new(TypeKind::Float) {
+ } else if rhs == &Type::new(TypeKind::Int) &&
+ (lhs == &Type::new(TypeKind::Float) || lhs == &Type::new(TypeKind::Double))
+ {
true
- } else if (dst == &Type::new(TypeKind::Float) || dst == &Type::new(TypeKind::Double)) &&
- src == &Type::new(TypeKind::Int)
+ } else if (rhs == &Type::new(TypeKind::Float) || rhs == &Type::new(TypeKind::Double)) &&
+ lhs == &Type::new(TypeKind::Int)
{
true
- } else if (dst == &Type::new(TypeKind::Vec2) || dst == &Type::new(TypeKind::DVec2)) &&
- src == &Type::new(TypeKind::IVec2)
+ } else if (rhs == &Type::new(TypeKind::Vec2) || rhs == &Type::new(TypeKind::DVec2)) &&
+ lhs == &Type::new(TypeKind::IVec2)
{
true
- } else if dst == &Type::new(TypeKind::IVec2) &&
- (src == &Type::new(TypeKind::Vec2) || src == &Type::new(TypeKind::DVec2))
+ } else if rhs == &Type::new(TypeKind::IVec2) &&
+ (lhs == &Type::new(TypeKind::Vec2) || lhs == &Type::new(TypeKind::DVec2))
{
true
} else {
- src.kind == dst.kind && src.array_sizes == dst.array_sizes
+ lhs.kind == rhs.kind && lhs.array_sizes == rhs.array_sizes
}
}
@@ -2086,7 +1988,7 @@ pub fn is_output(expr: &Expr, state: &State) -> Option<SymRef> {
match &expr.kind {
ExprKind::Variable(i) => match state.sym(*i).decl {
SymDecl::Global(storage, ..) => match storage {
- StorageClass::In | StorageClass::Out => return Some(*i),
+ StorageClass::Out => return Some(*i),
_ => {}
},
SymDecl::Local(..) => {}
@@ -2230,18 +2132,6 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
if !globals.contains(&global) {
globals.push(global);
}
- if global == state.clip_dist_sym {
- if let ExprKind::Bracket(_, idx) = &lhs.kind {
- // Get the constant array index used for gl_ClipDistance and add it to the used mask.
- let idx = match idx.kind {
- ExprKind::IntConst(idx) => idx,
- ExprKind::UIntConst(idx) => idx as i32,
- _ => panic!("bad index for gl_ClipDistance"),
- };
- assert!(idx >= 0 && idx < 4);
- state.used_clip_dist |= 1 << idx;
- }
- }
}
Expr {
kind: ExprKind::Assignment(lhs, op.clone(), rhs),
@@ -2251,23 +2141,28 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
syntax::Expr::Binary(op, lhs, rhs) => {
let lhs = Box::new(translate_expression(state, lhs));
let rhs = Box::new(translate_expression(state, rhs));
+ let ty = if op == &BinaryOp::Mult {
+ if lhs.ty.kind == TypeKind::Mat3 && rhs.ty.kind == TypeKind::Vec3 {
+ rhs.ty.clone()
+ } else if lhs.ty.kind == TypeKind::Mat4 && rhs.ty.kind == TypeKind::Vec4 {
+ rhs.ty.clone()
+ } else if lhs.ty.kind == TypeKind::Mat2 && rhs.ty.kind == TypeKind::Vec2 {
+ rhs.ty.clone()
+ } else if lhs.ty.kind == TypeKind::Mat2 && rhs.ty.kind == TypeKind::Float {
+ lhs.ty.clone()
+ } else {
+ promoted_type(&lhs.ty, &rhs.ty)
+ }
+ } else {
+ promoted_type(&lhs.ty, &rhs.ty)
+ };
+
+ // comparison operators have a bool result
let ty = match op {
- BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
- // comparison operators have a bool result
+ BinaryOp::Equal | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
Type::new(TypeKind::Bool)
}
- BinaryOp::Mult => {
- match (lhs.ty.kind, rhs.ty.kind) {
- (TypeKind::Mat2, TypeKind::Vec2) |
- (TypeKind::Mat3, TypeKind::Vec3) |
- (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
- (TypeKind::Mat2, TypeKind::Float) |
- (TypeKind::Mat3, TypeKind::Float) |
- (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
- _ => promoted_type(&lhs.ty, &rhs.ty),
- }
- }
- _ => promoted_type(&lhs.ty, &rhs.ty),
+ _ => ty,
};
Expr {
@@ -2330,19 +2225,6 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
.insert((sampler, base), TexelFetchOffsets::new(x, y));
}
}
- } else if name == "swgl_stepInterp" {
- let mut globals = state.modified_globals.borrow_mut();
- for (i, sym) in state.syms.iter().enumerate() {
- match &sym.borrow().decl {
- SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
- let symref = SymRef(i as u32);
- if !globals.contains(&symref) {
- globals.push(symref);
- }
- }
- _ => {}
- }
- }
}
let sym = match state.lookup(name) {
Some(s) => s,
@@ -2358,31 +2240,19 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
}
}
match &state.sym(sym).decl {
- SymDecl::NativeFunction(fn_ty, _, _) => {
- // Search for a signature where all parameter types are
- // compatible. If there are many compatible signatures,
- // then choose the one with the most exact matches.
- // This is an approximation of the algorith described in
- // the "Function Definitions" section of the spec.
+ SymDecl::NativeFunction(fn_ty, _) => {
let mut ret = None;
- let mut best_score = 0;
- 'next_sig: for sig in &fn_ty.signatures {
- let mut score = 0;
+ for sig in &fn_ty.signatures {
+ let mut matching = true;
for (e, p) in params.iter().zip(sig.params.iter()) {
- if e.ty == *p {
- score += 1;
- } else if !can_implicitly_convert_to(&e.ty, p) {
- continue 'next_sig;
+ if !compatible_type(&e.ty, p) {
+ matching = false;
+ break;
}
}
- if score >= best_score {
+ if matching {
ret = Some(sig.ret.clone());
- best_score = score;
- // If all parameters match exactly, then there
- // is no need to search for other matches.
- if best_score >= params.len() {
- break;
- }
+ break;
}
}
ret_ty = match ret {
@@ -2417,7 +2287,7 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
}
_ => {}
}
- can_implicitly_convert_to(&e.ty, &d.ty)
+ compatible_type(&e.ty, &d.ty)
}
FunctionParameterDeclaration::Unnamed(..) => panic!(),
};
@@ -2438,7 +2308,6 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
syntax::Expr::Variable(i) => match i.as_str() {
"vec4" => TypeKind::Vec4,
"vec2" => TypeKind::Vec2,
- "int" => TypeKind::Int,
_ => panic!("unexpected type constructor {:?}", i),
},
_ => panic!(),
@@ -2563,8 +2432,8 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
}
syntax::Expr::Bracket(e, specifier) => {
let e = Box::new(translate_expression(state, e));
- let ty = if let Some(ty) = index_vector(&e.ty) {
- Type::new(ty)
+ let ty = if is_vector(&e.ty) {
+ Type::new(TypeKind::Float)
} else if let Some(ty) = index_matrix(&e.ty) {
Type::new(ty)
} else {
@@ -2895,13 +2764,12 @@ fn translate_external_declaration(
}
}
-fn declare_function_ext(
+fn declare_function(
state: &mut State,
name: &str,
cxx_name: Option<&'static str>,
ret: Type,
params: Vec<Type>,
- run_class: RunClass,
) {
let sig = FunctionSignature { ret, params };
match state.lookup_sym_mut(name) {
@@ -2917,7 +2785,6 @@ fn declare_function_ext(
signatures: NonEmpty::new(sig),
},
cxx_name,
- run_class,
),
);
}
@@ -2926,16 +2793,6 @@ fn declare_function_ext(
//state.declare(name, Type::Function(FunctionType{ v}))
}
-fn declare_function(
- state: &mut State,
- name: &str,
- cxx_name: Option<&'static str>,
- ret: Type,
- params: Vec<Type>,
-) {
- declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
-}
-
pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
// global scope
state.push_scope("global".into());
@@ -2952,13 +2809,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
"vec2",
Some("make_vec2"),
Type::new(Vec2),
- vec![Type::new(Float), Type::new(Float)],
- );
- declare_function(
- state,
- "vec2",
- Some("make_vec2"),
- Type::new(Vec2),
vec![Type::new(IVec2)],
);
declare_function(
@@ -2994,13 +2844,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
"vec4",
Some("make_vec4"),
Type::new(Vec4),
- vec![Type::new(Float)],
- );
- declare_function(
- state,
- "vec4",
- Some("make_vec4"),
- Type::new(Vec4),
vec![Type::new(Vec3), Type::new(Float)],
);
declare_function(
@@ -3053,32 +2896,12 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
);
declare_function(
state,
- "bvec3",
- Some("make_bvec3"),
- Type::new(BVec3),
- vec![Type::new(Bool)],
- );
- declare_function(
- state,
- "bvec4",
- Some("make_bvec4"),
- Type::new(BVec4),
- vec![Type::new(Bool)],
- );
- declare_function(
- state,
"bvec4",
Some("make_bvec4"),
Type::new(BVec4),
vec![Type::new(BVec2), Type::new(BVec2)],
);
- declare_function(
- state,
- "bvec4",
- Some("make_bvec4"),
- Type::new(BVec4),
- vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
- );
+
declare_function(
state,
"int",
@@ -3166,13 +2989,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
"ivec4",
Some("make_ivec4"),
Type::new(IVec4),
- vec![Type::new(Vec4)],
- );
- declare_function(
- state,
- "ivec4",
- Some("make_ivec4"),
- Type::new(IVec4),
vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
);
@@ -3267,9 +3083,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
- declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
- declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
declare_function(
state,
"dot",
@@ -3284,38 +3097,56 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Float),
vec![Type::new(Vec2), Type::new(Vec2)],
);
- for t in &[Vec2, Vec3, Vec4] {
- declare_function(
- state,
- "min",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(Float)],
- );
- declare_function(
- state,
- "max",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(Float)],
- );
- }
- for t in &[Int, Float, Vec2, Vec3, Vec4] {
- declare_function(
- state,
- "min",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(*t)],
- );
- declare_function(
- state,
- "max",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(*t)],
- );
- }
+ declare_function(
+ state,
+ "min",
+ None,
+ Type::new(Float),
+ vec![Type::new(Float), Type::new(Float)],
+ );
+ declare_function(
+ state,
+ "min",
+ None,
+ Type::new(Vec2),
+ vec![Type::new(Vec2), Type::new(Vec2)],
+ );
+ declare_function(
+ state,
+ "min",
+ None,
+ Type::new(Vec3),
+ vec![Type::new(Vec3), Type::new(Vec3)],
+ );
+
+ declare_function(
+ state,
+ "max",
+ None,
+ Type::new(Float),
+ vec![Type::new(Float), Type::new(Float)],
+ );
+ declare_function(
+ state,
+ "max",
+ None,
+ Type::new(Vec2),
+ vec![Type::new(Vec2), Type::new(Vec2)],
+ );
+ declare_function(
+ state,
+ "max",
+ None,
+ Type::new(Vec2),
+ vec![Type::new(Vec2), Type::new(Float)],
+ );
+ declare_function(
+ state,
+ "max",
+ None,
+ Type::new(Vec3),
+ vec![Type::new(Vec3), Type::new(Vec3)],
+ );
declare_function(
state,
@@ -3405,152 +3236,96 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
state,
"step",
None,
- Type::new(Vec2),
- vec![Type::new(Float), Type::new(Vec2)],
- );
- declare_function(
- state,
- "step",
- None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Vec3)],
);
declare_function(
state,
- "step",
- None,
- Type::new(Vec4),
- vec![Type::new(Float), Type::new(Vec4)],
- );
- declare_function(
- state,
"notEqual",
None,
Type::new(BVec4),
vec![Type::new(IVec4), Type::new(IVec4)],
);
- declare_function_ext(
+ declare_function(
state,
"fwidth",
None,
Type::new(Vec2),
vec![Type::new(Vec2)],
- RunClass::Scalar,
);
- declare_function_ext(
+ declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
+ declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
+ declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
+ declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
+ declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
+ declare_function(
state,
- "dFdx",
+ "clamp",
None,
- Type::new(Float),
- vec![Type::new(Float)],
- RunClass::Scalar,
+ Type::new(Vec3),
+ vec![Type::new(Vec3), Type::new(Float), Type::new(Float)],
);
- declare_function_ext(
+ declare_function(
state,
- "dFdx",
+ "clamp",
+ None,
+ Type::new(Double),
+ vec![Type::new(Double), Type::new(Double), Type::new(Double)],
+ );
+ declare_function(
+ state,
+ "clamp",
None,
Type::new(Vec2),
- vec![Type::new(Vec2)],
- RunClass::Scalar,
+ vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
);
-
- declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
- for t in &[Vec2, Vec3, Vec4] {
- declare_function(
- state,
- "clamp",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(Float), Type::new(Float)],
- );
- }
- for t in &[Float, Vec2, Vec3, Vec4] {
- declare_function(
- state,
- "clamp",
- None,
- Type::new(*t),
- vec![Type::new(*t), Type::new(*t), Type::new(*t)],
- );
- }
declare_function(
state,
- "length",
+ "clamp",
None,
- Type::new(Float),
- vec![Type::new(Vec2)],
+ Type::new(Vec3),
+ vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
);
- declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
- declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
- declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
- for t in &[Float, Vec2] {
- // recip is non-standard
- declare_function(
- state,
- "recip",
- None,
- Type::new(*t),
- vec![Type::new(*t)],
- );
- declare_function(
- state,
- "inversesqrt",
- None,
- Type::new(*t),
- vec![Type::new(*t)],
- );
- declare_function(
- state,
- "sqrt",
- None,
- Type::new(*t),
- vec![Type::new(*t)],
- );
- }
declare_function(
state,
- "distance",
+ "clamp",
None,
- Type::new(Float),
- vec![Type::new(Vec2), Type::new(Vec2)],
+ Type::new(Vec4),
+ vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
);
-
declare_function(
state,
- "equal",
+ "length",
None,
- Type::new(BVec2),
- vec![Type::new(Vec2), Type::new(Vec2)],
+ Type::new(Float),
+ vec![Type::new(Vec2)],
);
+ declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
+ declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
+ declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
declare_function(
state,
- "equal",
+ "inversesqrt",
None,
- Type::new(BVec4),
- vec![Type::new(Vec4), Type::new(Vec4)],
+ Type::new(Float),
+ vec![Type::new(Float)],
);
declare_function(
state,
- "notEqual",
+ "sqrt",
None,
- Type::new(BVec2),
- vec![Type::new(Vec2), Type::new(Vec2)],
+ Type::new(Float),
+ vec![Type::new(Float)],
);
declare_function(
state,
- "notEqual",
+ "distance",
None,
- Type::new(BVec4),
- vec![Type::new(Vec4), Type::new(Vec4)],
+ Type::new(Float),
+ vec![Type::new(Vec2), Type::new(Vec2)],
);
+
declare_function(
state,
"lessThanEqual",
@@ -3581,13 +3356,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
);
declare_function(
state,
- "lessThan",
- None,
- Type::new(BVec4),
- vec![Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
"greaterThan",
None,
Type::new(BVec2),
@@ -3595,13 +3363,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
);
declare_function(
state,
- "greaterThan",
- None,
- Type::new(BVec4),
- vec![Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
"greaterThanEqual",
None,
Type::new(BVec2),
@@ -3611,7 +3372,7 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
state,
"greaterThanEqual",
None,
- Type::new(BVec4),
+ Type::new(BVec2),
vec![Type::new(Vec4), Type::new(Vec4)],
);
declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
@@ -3631,22 +3392,22 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
state,
"floor",
None,
- Type::new(Float),
- vec![Type::new(Float)],
+ Type::new(Double),
+ vec![Type::new(Double)],
);
declare_function(
state,
"ceil",
None,
- Type::new(Float),
- vec![Type::new(Float)],
+ Type::new(Double),
+ vec![Type::new(Double)],
);
declare_function(
state,
"round",
None,
- Type::new(Float),
- vec![Type::new(Float)],
+ Type::new(Double),
+ vec![Type::new(Double)],
);
declare_function(
state,
@@ -3655,13 +3416,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Float),
vec![Type::new(Float)],
);
- declare_function(
- state,
- "fract",
- None,
- Type::new(Vec2),
- vec![Type::new(Vec2)],
- );
declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
@@ -3676,6 +3430,13 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
state,
"texelFetch",
None,
+ Type::new(Vec4),
+ vec![Type::new(Sampler2DArray), Type::new(IVec3), Type::new(Int)],
+ );
+ declare_function(
+ state,
+ "texelFetch",
+ None,
Type::new(IVec4),
vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
);
@@ -3719,6 +3480,27 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
);
declare_function(
state,
+ "texture",
+ None,
+ Type::new(Vec4),
+ vec![Type::new(Sampler2DArray), Type::new(Vec3)],
+ );
+ declare_function(
+ state,
+ "textureLod",
+ None,
+ Type::new(Vec4),
+ vec![Type::new(Sampler2DArray), Type::new(Vec3), Type::new(Float)],
+ );
+ declare_function(
+ state,
+ "textureSize",
+ None,
+ Type::new(IVec3),
+ vec![Type::new(Sampler2DArray), Type::new(Int)],
+ );
+ declare_function(
+ state,
"textureSize",
None,
Type::new(IVec2),
@@ -3765,417 +3547,6 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
"gl_Position",
SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
);
- state.clip_dist_sym = state.declare(
- "gl_ClipDistance",
- SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
- );
-
- state.declare(
- "swgl_SpanLength",
- SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
- );
- state.declare(
- "swgl_StepSize",
- SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
- );
-
- for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
- declare_function_ext(
- state,
- "swgl_forceScalar",
- None,
- Type::new(*t),
- vec![Type::new(*t)],
- RunClass::Scalar,
- );
- }
-
- // GL_ARB_shader_group_vote
- for (name, cxx_name) in &[("anyInvocations", "test_any"),
- ("allInvocations", "test_all"),
- ("allInvocationsEqual", "test_equal")] {
- declare_function_ext(
- state,
- name,
- Some(cxx_name),
- Type::new(Bool),
- vec![Type::new(Bool)],
- RunClass::Scalar,
- );
- }
-
- declare_function(
- state,
- "swgl_stepInterp",
- None,
- Type::new(Void),
- vec![],
- );
-
- for t in &[Float, Vec2, Vec3, Vec4] {
- declare_function_ext(
- state,
- "swgl_interpStep",
- None,
- Type::new(*t),
- vec![Type::new(*t)],
- RunClass::Scalar,
- );
- }
-
- declare_function(
- state,
- "swgl_commitPartialSolidRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Int), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitPartialSolidR8",
- None,
- Type::new(Void),
- vec![Type::new(Int), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitSolidRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitSolidR8",
- None,
- Type::new(Void),
- vec![Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitColorR8",
- None,
- Type::new(Void),
- vec![Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_blendDropShadow",
- None,
- Type::new(Void),
- vec![Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_blendSubpixelText",
- None,
- Type::new(Void),
- vec![Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_clipMask",
- None,
- Type::new(Void),
- vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
- );
- declare_function(
- state,
- "swgl_antiAlias",
- None,
- Type::new(Void),
- vec![Type::new(Int)],
- );
- declare_function(
- state,
- "swgl_antiAlias",
- None,
- Type::new(Void),
- vec![Type::new(BVec4)],
- );
- declare_function_ext(
- state,
- "swgl_validateGradient",
- None,
- Type::new(Int),
- vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
- RunClass::Scalar,
- );
- declare_function(
- state,
- "swgl_commitLinearGradientRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitRadialGradientRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
- Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitGradientRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitGradientColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
- );
- for s in &[Sampler2D, Sampler2DRect] {
- declare_function_ext(
- state,
- "swgl_isTextureLinear",
- None,
- Type::new(Bool),
- vec![Type::new(*s)],
- RunClass::Scalar,
- );
- declare_function_ext(
- state,
- "swgl_isTextureRGBA8",
- None,
- Type::new(Bool),
- vec![Type::new(*s)],
- RunClass::Scalar,
- );
- declare_function_ext(
- state,
- "swgl_isTextureR8",
- None,
- Type::new(Bool),
- vec![Type::new(*s)],
- RunClass::Scalar,
- );
- declare_function(
- state,
- "swgl_commitTextureLinearRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearR8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearR8ToRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitPartialTextureLinearR8",
- None,
- Type::new(Void),
- vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitPartialTextureLinearInvertR8",
- None,
- Type::new(Void),
- vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorR8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorR8ToRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
- );
-
- declare_function(
- state,
- "swgl_commitTextureLinearRepeatRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearRepeatColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
- );
-
- declare_function(
- state,
- "swgl_commitTextureNearestRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureNearestColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureNearestRepeatRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureNearestRepeatColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
- );
-
- declare_function(
- state,
- "swgl_commitTextureRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureRepeatRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4)],
- );
- declare_function(
- state,
- "swgl_commitTextureRepeatColorRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
- Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
- );
-
- declare_function(
- state,
- "swgl_commitGaussianBlurRGBA8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
- Type::new(Int), Type::new(Vec2)],
- );
- declare_function(
- state,
- "swgl_commitGaussianBlurR8",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
- Type::new(Int), Type::new(Vec2)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int), Type::new(Float)],
- );
- declare_function(
- state,
- "swgl_commitTextureLinearColorYUV",
- None,
- Type::new(Void),
- vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(*s), Type::new(Vec2), Type::new(Vec4),
- Type::new(Int), Type::new(Int), Type::new(Float)],
- );
- }
TranslationUnit(tu.0.map(state, translate_external_declaration))
}
@@ -4227,13 +3598,7 @@ fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunC
};
match fun {
FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
- SymDecl::NativeFunction(_, _, ref ret_class) => {
- if *ret_class != RunClass::Unknown {
- *ret_class
- } else {
- run_class
- }
- }
+ SymDecl::NativeFunction(..) => run_class,
SymDecl::UserFunction(ref fd, ref run_class) => {
for (&(mut arg_class, assign), param) in
arg_classes.iter().zip(fd.prototype.parameters.iter())
diff --git a/third_party/webrender/glsl-to-cxx/src/lib.rs b/third_party/webrender/glsl-to-cxx/src/lib.rs
index a42f14a23b6..409af02d586 100644
--- a/third_party/webrender/glsl-to-cxx/src/lib.rs
+++ b/third_party/webrender/glsl-to-cxx/src/lib.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-extern crate glsl;
+use glsl;
mod hir;
@@ -61,6 +61,8 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
.to_string_lossy()
.to_string();
+ let frag_include = args.next();
+
let (vs_state, vs_hir, vs_is_frag) = parse_shader(vertex_file);
let (fs_state, fs_hir, fs_is_frag) = parse_shader(frag_file);
@@ -77,6 +79,7 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
vs_hir,
vs_is_frag,
&uniform_indices,
+ None,
);
result += "\n";
result += &translate_shader(
@@ -85,6 +88,7 @@ pub fn translate(args: &mut dyn Iterator<Item = String>) -> String {
fs_hir,
fs_is_frag,
&uniform_indices,
+ frag_include,
);
result
}
@@ -116,6 +120,7 @@ fn translate_shader(
hir: hir::TranslationUnit,
is_frag: bool,
uniform_indices: &UniformIndices,
+ include_file: Option<String>,
) -> String {
//println!("{:#?}", state);
@@ -180,6 +185,8 @@ fn translate_shader(
uses_discard: false,
used_fragcoord: Cell::new(0),
use_perspective: false,
+ has_draw_span_rgba8: false,
+ has_draw_span_r8: false,
used_globals: RefCell::new(Vec::new()),
texel_fetches: RefCell::new(Vec::new()),
};
@@ -208,6 +215,10 @@ fn translate_shader(
show_translation_unit(&mut state, &hir);
+ if let Some(include_file) = include_file {
+ write_include_file(&mut state, include_file);
+ }
+
let pruned_inputs: Vec<_> = inputs
.iter()
.filter(|i| state.used_globals.borrow().contains(i))
@@ -239,7 +250,6 @@ fn translate_shader(
write!(state, " return this;\n}}\n");
write!(state, "FragmentShaderImpl* get_fragment_shader() override {{\n");
write!(state, " return this;\n}}\n");
- write!(state, "const char* get_name() const override {{ return \"{}\"; }}\n", name);
write!(state, "static ProgramImpl* loader() {{ return new {}_program; }}\n", name);
write!(state, "}};\n\n");
}
@@ -292,7 +302,8 @@ fn write_program_samplers(state: &mut OutputState, uniform_indices: &UniformIndi
match tk {
hir::TypeKind::Sampler2D
| hir::TypeKind::Sampler2DRect
- | hir::TypeKind::ISampler2D => {
+ | hir::TypeKind::ISampler2D
+ | hir::TypeKind::Sampler2DArray => {
write!(state, " ");
show_type_kind(state, &tk);
let suffix = if let hir::StorageClass::Sampler(format) = storage {
@@ -315,7 +326,8 @@ fn write_program_samplers(state: &mut OutputState, uniform_indices: &UniformIndi
match tk {
hir::TypeKind::Sampler2D
| hir::TypeKind::Sampler2DRect
- | hir::TypeKind::ISampler2D => {
+ | hir::TypeKind::ISampler2D
+ | hir::TypeKind::Sampler2DArray => {
write!(state, " case {}:\n", index);
write!(state, " {}_slot = value;\n", name);
write!(state, " return true;\n");
@@ -343,6 +355,9 @@ fn write_bind_textures(state: &mut OutputState, uniforms: &UniformIndices) {
hir::TypeKind::ISampler2D => write!(state,
" {0} = lookup_isampler(&samplers.{0}_impl, samplers.{0}_slot);\n",
name),
+ hir::TypeKind::Sampler2DArray => write!(state,
+ " {0} = lookup_sampler_array(&samplers.{0}_impl, samplers.{0}_slot);\n",
+ name),
_ => {}
};
}
@@ -393,8 +408,9 @@ fn write_set_uniform_4fv(
if float4_compatible(tk.clone()) {
write!(
state,
- " self->{} = vec4_scalar::load_from_ptr(value);\n",
- name
+ " self->{} = {}_scalar(value);\n",
+ name,
+ tk.glsl_primitive_type_name().unwrap(),
);
} else {
write!(state, " assert(0); // {}\n", name);
@@ -535,9 +551,6 @@ fn write_load_attribs(state: &mut OutputState, attribs: &[hir::SymRef]) {
fn write_store_outputs(state: &mut OutputState, outputs: &[hir::SymRef]) {
let is_scalar = state.is_scalar.replace(true);
write!(state, "public:\nstruct InterpOutputs {{\n");
- if state.hir.used_clip_dist != 0 {
- state.write(" Float swgl_ClipDistance;\n");
- }
for i in outputs {
let sym = state.hir.sym(*i);
match &sym.decl {
@@ -563,15 +576,6 @@ fn write_store_outputs(state: &mut OutputState, outputs: &[hir::SymRef]) {
state,
" auto* dest = reinterpret_cast<InterpOutputs*>(dest_ptr);\n"
);
- if state.hir.used_clip_dist != 0 {
- for (i, comp) in "xyzw".chars().enumerate() {
- if (state.hir.used_clip_dist & (1 << i)) != 0 {
- write!(state, " dest->swgl_ClipDistance.{} = get_nth(gl_ClipDistance[{}], n);\n", comp, i);
- } else {
- write!(state, " dest->swgl_ClipDistance.{} = 0.0f;\n", comp);
- }
- }
- }
for i in outputs {
let sym = state.hir.sym(*i);
match &sym.decl {
@@ -622,7 +626,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
write!(state,
"static void read_interp_inputs(\
- Self *self, const InterpInputs *init, const InterpInputs *step) {{\n");
+ Self *self, const InterpInputs *init, const InterpInputs *step, float step_width) {{\n");
for i in inputs {
let sym = state.hir.sym(*i);
match &sym.decl {
@@ -636,7 +640,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
);
write!(
state,
- " self->interp_step.{0} = step->{0} * 4.0f;\n",
+ " self->interp_step.{0} = step->{0} * step_width;\n",
name
);
}
@@ -653,7 +657,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
if state.use_perspective {
write!(state,
"static void read_perspective_inputs(\
- Self *self, const InterpInputs *init, const InterpInputs *step) {{\n");
+ Self *self, const InterpInputs *init, const InterpInputs *step, float step_width) {{\n");
if has_varying {
write!(state, " Float w = 1.0f / self->gl_FragCoord.w;\n");
}
@@ -671,7 +675,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
write!(state, " self->{0} = self->interp_perspective.{0} * w;\n", name);
write!(
state,
- " self->interp_step.{0} = step->{0} * 4.0f;\n",
+ " self->interp_step.{0} = step->{0} * step_width;\n",
name
);
}
@@ -682,12 +686,9 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
write!(state, "}}\n");
}
- write!(state, "ALWAYS_INLINE void step_interp_inputs(int steps = 4) {{\n");
+ write!(state, "ALWAYS_INLINE void step_interp_inputs() {{\n");
if (used_fragcoord & 1) != 0 {
- write!(state, " step_fragcoord(steps);\n");
- }
- if !inputs.is_empty() {
- write!(state, " float chunks = steps * 0.25f;\n");
+ write!(state, " step_fragcoord();\n");
}
for i in inputs {
let sym = state.hir.sym(*i);
@@ -695,7 +696,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
hir::SymDecl::Global(_, _, _, run_class) => {
if *run_class != hir::RunClass::Scalar {
let name = sym.name.as_str();
- write!(state, " {0} += interp_step.{0} * chunks;\n", name);
+ write!(state, " {0} += interp_step.{0};\n", name);
}
}
_ => panic!(),
@@ -704,14 +705,11 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
write!(state, "}}\n");
if state.use_perspective {
- write!(state, "ALWAYS_INLINE void step_perspective_inputs(int steps = 4) {{\n");
+ write!(state, "ALWAYS_INLINE void step_perspective_inputs() {{\n");
if (used_fragcoord & 1) != 0 {
- write!(state, " step_fragcoord(steps);\n");
- }
- write!(state, " step_perspective(steps);\n");
- if !inputs.is_empty() {
- write!(state, " float chunks = steps * 0.25f;\n");
+ write!(state, " step_fragcoord();\n");
}
+ write!(state, " step_perspective();\n");
if has_varying {
write!(state, " Float w = 1.0f / gl_FragCoord.w;\n");
}
@@ -721,7 +719,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
hir::SymDecl::Global(_, _, _, run_class) => {
if *run_class != hir::RunClass::Scalar {
let name = sym.name.as_str();
- write!(state, " interp_perspective.{0} += interp_step.{0} * chunks;\n", name);
+ write!(state, " interp_perspective.{0} += interp_step.{0};\n", name);
write!(state, " {0} = w * interp_perspective.{0};\n", name);
}
}
@@ -730,6 +728,58 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) {
}
write!(state, "}}\n");
}
+
+ if state.has_draw_span_rgba8 || state.has_draw_span_r8 {
+ write!(
+ state,
+ "ALWAYS_INLINE void step_interp_inputs(int chunks) {{\n"
+ );
+ if (used_fragcoord & 1) != 0 {
+ write!(state, " step_fragcoord(chunks);\n");
+ }
+ for i in inputs {
+ let sym = state.hir.sym(*i);
+ match &sym.decl {
+ hir::SymDecl::Global(_, _, _, run_class) => {
+ if *run_class != hir::RunClass::Scalar {
+ let name = sym.name.as_str();
+ write!(state, " {0} += interp_step.{0} * chunks;\n", name);
+ }
+ }
+ _ => panic!(),
+ }
+ }
+ write!(state, "}}\n");
+ }
+}
+
+fn write_include_file(state: &mut OutputState, include_file: String) {
+ let include_contents = std::fs::read_to_string(&include_file).unwrap();
+
+ let mut offset = 0;
+ while offset < include_contents.len() {
+ let s = &include_contents[offset ..];
+ if let Some(start_proto) = s.find("draw_span") {
+ let s = &s[start_proto ..];
+ if let Some(end_proto) = s.find(')') {
+ let proto = &s[.. end_proto];
+ if proto.contains("uint32_t") {
+ state.has_draw_span_rgba8 = true;
+ } else if proto.contains("uint8_t") {
+ state.has_draw_span_r8 = true;
+ }
+ offset += start_proto + end_proto;
+ continue;
+ }
+ }
+ break;
+ }
+
+ let include_name = std::path::Path::new(&include_file)
+ .file_name()
+ .unwrap()
+ .to_string_lossy();
+ write!(state, "\n#include \"{}\"\n\n", include_name);
}
pub struct OutputState {
@@ -754,6 +804,8 @@ pub struct OutputState {
uses_discard: bool,
used_fragcoord: Cell<i32>,
use_perspective: bool,
+ has_draw_span_rgba8: bool,
+ has_draw_span_r8: bool,
used_globals: RefCell<Vec<hir::SymRef>>,
texel_fetches: RefCell<Vec<(hir::SymRef, hir::SymRef, hir::TexelFetchOffsets)>>,
}
@@ -822,7 +874,7 @@ fn add_used_global(state: &OutputState, i: &hir::SymRef) {
pub fn show_sym(state: &OutputState, i: &hir::SymRef) {
let sym = state.hir.sym(*i);
match &sym.decl {
- hir::SymDecl::NativeFunction(_, ref cxx_name, _) => {
+ hir::SymDecl::NativeFunction(_, ref cxx_name) => {
let mut name = sym.name.as_str();
if state.output_cxx {
name = cxx_name.unwrap_or(name);
@@ -1515,10 +1567,8 @@ fn expr_run_class(state: &OutputState, expr: &hir::Expr) -> hir::RunClass {
});
match fun {
hir::FunIdentifier::Identifier(ref sym) => match &state.hir.sym(*sym).decl {
- hir::SymDecl::NativeFunction(_, _, ref ret_class) => {
- if *ret_class != hir::RunClass::Unknown {
- *ret_class
- } else if arg_mask != 0 {
+ hir::SymDecl::NativeFunction(..) => {
+ if arg_mask != 0 {
hir::RunClass::Vector
} else {
hir::RunClass::Scalar
@@ -1846,21 +1896,33 @@ pub fn show_hir_expr_inner(state: &OutputState, expr: &hir::Expr, top_level: boo
&state.hir, &args[0], &args[1], &args[3],
) {
let base_sym = state.hir.sym(base);
- let sampler_sym = state.hir.sym(sampler);
- add_used_global(state, &sampler);
- if let hir::SymDecl::Global(..) = &base_sym.decl {
- add_used_global(state, &base);
+ if symbol_run_class(&base_sym.decl, state.vector_mask)
+ == hir::RunClass::Scalar
+ {
+ let sampler_sym = state.hir.sym(sampler);
+ add_used_global(state, &sampler);
+ if let hir::SymDecl::Global(..) = &base_sym.decl {
+ add_used_global(state, &base);
+ }
+ if y != 0 {
+ write!(
+ state,
+ "{}_{}_fetch[{}+{}*{}->stride]",
+ sampler_sym.name,
+ base_sym.name,
+ x,
+ y,
+ sampler_sym.name
+ );
+ } else {
+ write!(
+ state,
+ "{}_{}_fetch[{}]",
+ sampler_sym.name, base_sym.name, x
+ );
+ }
+ return;
}
- write!(
- state,
- "texelFetchUnchecked({}, {}_{}_fetch, {}, {})",
- sampler_sym.name,
- sampler_sym.name,
- base_sym.name,
- x,
- y,
- );
- return;
}
}
show_sym(state, name)
@@ -2296,12 +2358,15 @@ pub fn show_declaration(state: &mut OutputState, d: &hir::Declaration) {
let base = list.head.name;
let base_sym = state.hir.sym(base);
if let hir::SymDecl::Local(..) = &base_sym.decl {
- let mut texel_fetches = state.texel_fetches.borrow_mut();
- while let Some(idx) = texel_fetches.iter().position(|&(_, b, _)| b == base)
+ if symbol_run_class(&base_sym.decl, state.vector_mask) == hir::RunClass::Scalar
{
- let (sampler, _, offsets) = texel_fetches.remove(idx);
- let sampler_sym = state.hir.sym(sampler);
- define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
+ let mut texel_fetches = state.texel_fetches.borrow_mut();
+ while let Some(idx) = texel_fetches.iter().position(|&(_, b, _)| b == base)
+ {
+ let (sampler, _, offsets) = texel_fetches.remove(idx);
+ let sampler_sym = state.hir.sym(sampler);
+ define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
+ }
}
}
}
@@ -2319,22 +2384,19 @@ pub fn show_declaration(state: &mut OutputState, d: &hir::Declaration) {
//state.write(";\n");
}
hir::Declaration::Global(ref qual, ref identifiers) => {
- // We only want to output GLSL layout qualifiers if not C++
- if !state.output_cxx {
- show_type_qualifier(state, &qual);
+ show_type_qualifier(state, &qual);
- if !identifiers.is_empty() {
- let mut iter = identifiers.iter();
- let first = iter.next().unwrap();
- show_identifier(state, first);
+ if !identifiers.is_empty() {
+ let mut iter = identifiers.iter();
+ let first = iter.next().unwrap();
+ show_identifier(state, first);
- for identifier in iter {
- let _ = write!(state, ", {}", identifier);
- }
+ for identifier in iter {
+ let _ = write!(state, ", {}", identifier);
}
-
- state.write(";\n");
}
+
+ state.write(";\n");
}
hir::Declaration::StructDefinition(ref sym) => {
show_sym_decl(state, sym);
@@ -2610,32 +2672,32 @@ fn define_texel_fetch_ptr(
offsets: &hir::TexelFetchOffsets,
) {
show_indent(state);
- let ptr_type = if let hir::SymDecl::Global(_, _, ty, _) = &sampler_sym.decl {
- if symbol_run_class(&base_sym.decl, state.vector_mask) == hir::RunClass::Scalar {
- match ty.kind {
- hir::TypeKind::Sampler2D
- | hir::TypeKind::Sampler2DRect => "vec4_scalar*",
- hir::TypeKind::ISampler2D => "ivec4_scalar*",
- _ => panic!(),
+ if let hir::SymDecl::Global(_, _, ty, _) = &sampler_sym.decl {
+ match ty.kind {
+ hir::TypeKind::Sampler2D
+ | hir::TypeKind::Sampler2DRect => {
+ write!(
+ state,
+ "vec4_scalar* {}_{}_fetch = ",
+ sampler_sym.name, base_sym.name
+ );
}
- } else {
- "I32"
+ hir::TypeKind::ISampler2D => {
+ write!(
+ state,
+ "ivec4_scalar* {}_{}_fetch = ",
+ sampler_sym.name, base_sym.name
+ );
+ }
+ _ => panic!(),
}
} else {
panic!();
- };
+ }
write!(
state,
- "{} {}_{}_fetch = texelFetchPtr({}, {}, {}, {}, {}, {});\n",
- ptr_type,
- sampler_sym.name,
- base_sym.name,
- sampler_sym.name,
- base_sym.name,
- offsets.min_x,
- offsets.max_x,
- offsets.min_y,
- offsets.max_y,
+ "texelFetchPtr({}, {}, {}, {}, {}, {});\n",
+ sampler_sym.name, base_sym.name, offsets.min_x, offsets.max_x, offsets.min_y, offsets.max_y
);
}
@@ -2688,64 +2750,27 @@ pub fn show_function_definition(
}
if state.output_cxx {
- match fd.prototype.name.as_str() {
- "swgl_drawSpanRGBA8" |
- "swgl_drawSpanR8" => {
- // Partial spans are not drawn using span shaders, but rather drawn with a fragment shader
- // where the span shader left off. We need to undo any changes to the interpolants made by
- // the span shaders so that we can reset the interpolants to where the fragment shader
- // expects them. We do this by saving them in an _Undo_ struct on entry to the span shader,
- // and then restore them in the _Undo_ struct destructor.
- let mut needs_undo = vec![];
- for global in &fd.globals {
- let sym = state.hir.sym(*global);
- match &sym.decl {
- hir::SymDecl::Global(hir::StorageClass::In, _, ty, hir::RunClass::Vector) => {
- if needs_undo.is_empty() {
- state.write("struct _Undo_ {\nSelf* self;\n");
- }
- show_type(state, ty);
- write!(state, " {};\n", sym.name);
- needs_undo.push(sym.name.clone());
- }
- _ => {}
- }
- }
- if !needs_undo.is_empty() {
- state.write("explicit _Undo_(Self* self) : self(self)");
- for name in &needs_undo {
- write!(state, ", {0}(self->{0})", name);
- }
- state.write(" {}\n");
- state.write("~_Undo_() {\n");
- for name in &needs_undo {
- write!(state, "self->{0} = {0};\n", name);
- }
- state.write("}} _undo_(this);\n");
- }
- }
- _ => {}
- }
-
let mut texel_fetches = state.texel_fetches.borrow_mut();
texel_fetches.clear();
for ((sampler, base), offsets) in fd.texel_fetches.iter() {
- add_used_global(state, sampler);
- let sampler_sym = state.hir.sym(*sampler);
let base_sym = state.hir.sym(*base);
- match &base_sym.decl {
- hir::SymDecl::Global(..) => {
- add_used_global(state, base);
- define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
- }
- hir::SymDecl::Local(..) => {
- if fd.prototype.has_parameter(*base) {
+ if symbol_run_class(&base_sym.decl, vector_mask) == hir::RunClass::Scalar {
+ add_used_global(state, sampler);
+ let sampler_sym = state.hir.sym(*sampler);
+ match &base_sym.decl {
+ hir::SymDecl::Global(..) => {
+ add_used_global(state, base);
define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
- } else {
- texel_fetches.push((*sampler, *base, offsets.clone()));
}
+ hir::SymDecl::Local(..) => {
+ if fd.prototype.has_parameter(*base) {
+ define_texel_fetch_ptr(state, &base_sym, &sampler_sym, &offsets);
+ } else {
+ texel_fetches.push((*sampler, *base, offsets.clone()));
+ }
+ }
+ _ => panic!(),
}
- _ => panic!(),
}
}
}
@@ -3170,7 +3195,7 @@ pub fn show_iteration_statement(state: &mut OutputState, ist: &hir::IterationSta
show_statement(state, body);
state.write(" while (");
show_hir_expr(state, cond);
- state.write(");\n");
+ state.write(")\n");
}
hir::IterationStatement::For(ref init, ref rest, ref body) => {
state.write("for (");
@@ -3241,7 +3266,7 @@ pub fn show_jump_statement(state: &mut OutputState, j: &hir::JumpStatement) {
if state.output_cxx {
state.uses_discard = true;
if let Some(mask) = &state.mask {
- state.write("swgl_IsPixelDiscarded |= (");
+ state.write("isPixelDiscarded |= (");
show_hir_expr(state, mask);
state.write(")");
if state.return_declared {
@@ -3249,7 +3274,7 @@ pub fn show_jump_statement(state: &mut OutputState, j: &hir::JumpStatement) {
}
state.write(";\n");
} else {
- state.write("swgl_IsPixelDiscarded = true;\n");
+ state.write("isPixelDiscarded = true;\n");
}
} else {
state.write("discard;\n");
@@ -3554,11 +3579,9 @@ pub fn show_translation_unit(state: &mut OutputState, tu: &hir::TranslationUnit)
state.flush_buffer();
}
if state.output_cxx {
- for name in &["main", "swgl_drawSpanRGBA8", "swgl_drawSpanR8"] {
- if let Some(sym) = state.hir.lookup(name) {
- show_cxx_function_definition(state, sym, 0);
- state.flush_buffer();
- }
+ if let Some(name) = state.hir.lookup("main") {
+ show_cxx_function_definition(state, name, 0);
+ state.flush_buffer();
}
}
}
@@ -3568,33 +3591,37 @@ fn write_abi(state: &mut OutputState) {
ShaderKind::Fragment => {
state.write("static void run(Self *self) {\n");
if state.uses_discard {
- state.write(" self->swgl_IsPixelDiscarded = false;\n");
+ state.write(" self->isPixelDiscarded = false;\n");
}
state.write(" self->main();\n");
state.write(" self->step_interp_inputs();\n");
state.write("}\n");
- state.write("static void skip(Self* self, int steps) {\n");
- state.write(" self->step_interp_inputs(steps);\n");
+ state.write("static void skip(Self* self, int chunks) {\n");
+ state.write(" self->step_interp_inputs();\n");
+ state.write(" while (--chunks > 0) self->step_interp_inputs();\n");
state.write("}\n");
if state.use_perspective {
state.write("static void run_perspective(Self *self) {\n");
if state.uses_discard {
- state.write(" self->swgl_IsPixelDiscarded = false;\n");
+ state.write(" self->isPixelDiscarded = false;\n");
}
state.write(" self->main();\n");
state.write(" self->step_perspective_inputs();\n");
state.write("}\n");
- state.write("static void skip_perspective(Self* self, int steps) {\n");
- state.write(" self->step_perspective_inputs(steps);\n");
+ state.write("static void skip_perspective(Self* self, int chunks) {\n");
+ state.write(" self->step_perspective_inputs();\n");
+ state.write(" while (--chunks > 0) self->step_perspective_inputs();\n");
state.write("}\n");
}
- if state.hir.lookup("swgl_drawSpanRGBA8").is_some() {
+ if state.has_draw_span_rgba8 {
state.write(
- "static int draw_span_RGBA8(Self* self) { DISPATCH_DRAW_SPAN(self, RGBA8); }\n");
+ "static void draw_span_RGBA8(Self* self, uint32_t* buf, int len) { \
+ DISPATCH_DRAW_SPAN(self, buf, len); }\n");
}
- if state.hir.lookup("swgl_drawSpanR8").is_some() {
+ if state.has_draw_span_r8 {
state.write(
- "static int draw_span_R8(Self* self) { DISPATCH_DRAW_SPAN(self, R8); }\n");
+ "static void draw_span_R8(Self* self, uint8_t* buf, int len) { \
+ DISPATCH_DRAW_SPAN(self, buf, len); }\n");
}
write!(state, "public:\n{}_frag() {{\n", state.name);
@@ -3616,10 +3643,10 @@ fn write_abi(state: &mut OutputState) {
state.write(" init_span_func = (InitSpanFunc)&read_interp_inputs;\n");
state.write(" run_func = (RunFunc)&run;\n");
state.write(" skip_func = (SkipFunc)&skip;\n");
- if state.hir.lookup("swgl_drawSpanRGBA8").is_some() {
+ if state.has_draw_span_rgba8 {
state.write(" draw_span_RGBA8_func = (DrawSpanRGBA8Func)&draw_span_RGBA8;\n");
}
- if state.hir.lookup("swgl_drawSpanR8").is_some() {
+ if state.has_draw_span_r8 {
state.write(" draw_span_R8_func = (DrawSpanR8Func)&draw_span_R8;\n");
}
if state.uses_discard {
@@ -3643,9 +3670,6 @@ fn write_abi(state: &mut OutputState) {
state.write(" init_batch_func = (InitBatchFunc)&init_batch;\n");
state.write(" load_attribs_func = (LoadAttribsFunc)&load_attribs;\n");
state.write(" run_primitive_func = (RunPrimitiveFunc)&run;\n");
- if state.hir.used_clip_dist != 0 {
- state.write(" enable_clip_distance();\n");
- }
}
}
state.write("}\n");