diff --git a/gfx/wr/glsl-to-cxx/src/hir.rs b/gfx/wr/glsl-to-cxx/src/hir.rs index f127bcc89157..710b50b7af2d 100644 --- a/gfx/wr/glsl-to-cxx/src/hir.rs +++ b/gfx/wr/glsl-to-cxx/src/hir.rs @@ -925,7 +925,6 @@ pub struct State { branch_run_class: RunClass, branch_declaration: SymRef, modified_globals: RefCell>, - pub used_fragcoord: i32, pub used_globals: RefCell>, pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>, } @@ -941,7 +940,6 @@ impl State { branch_run_class: RunClass::Unknown, branch_declaration: SymRef(0), modified_globals: RefCell::new(Vec::new()), - used_fragcoord: 0, used_globals: RefCell::new(Vec::new()), texel_fetches: HashMap::new(), } @@ -2368,7 +2366,7 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr { } } syntax::Expr::Dot(e, i) => { - let mut e = Box::new(translate_expression(state, e)); + let e = Box::new(translate_expression(state, e)); let ty = e.ty.clone(); let ivec = is_ivec(&ty); if is_vector(&ty) { @@ -2406,14 +2404,6 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr { let sel = SwizzleSelector::parse(i.as_str()); - if let ExprKind::Variable(ref sym) = &mut e.kind { - if state.sym(*sym).name == "gl_FragCoord" { - for c in &sel.components { - state.used_fragcoord |= 1 << c; - } - } - } - Expr { kind: ExprKind::SwizzleSelector(e, sel), ty, diff --git a/gfx/wr/glsl-to-cxx/src/lib.rs b/gfx/wr/glsl-to-cxx/src/lib.rs index edf3970a21d3..f1d198508012 100644 --- a/gfx/wr/glsl-to-cxx/src/lib.rs +++ b/gfx/wr/glsl-to-cxx/src/lib.rs @@ -183,6 +183,8 @@ fn translate_shader( deps: RefCell::new(Vec::new()), vector_mask: 0, 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()), @@ -599,14 +601,14 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { write!(state, "InterpInputs interp_step;\n"); - let mut has_perspective: bool = false; + let mut has_varying = false; for i in inputs { let sym = state.hir.sym(*i); match &sym.decl { hir::SymDecl::Global(_, _, ty, run_class) => { if *run_class != hir::RunClass::Scalar { - if !has_perspective { - has_perspective = true; + if !has_varying { + has_varying = true; write!(state, "struct InterpPerspective {{\n"); } show_type(state, ty); @@ -616,7 +618,7 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { _ => panic!(), } } - if has_perspective { + if has_varying { write!(state, "}};\n"); write!(state, "InterpPerspective interp_perspective;\n"); } @@ -647,11 +649,17 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { } write!(state, "}}\n"); - write!(state, - "static void read_perspective_inputs(\ - Self *self, const InterpInputs *init, const InterpInputs *step, float step_width) {{\n"); - if has_perspective { - write!(state, " Float w = 1.0f / self->gl_FragCoord.w;\n"); + let used_fragcoord = state.used_fragcoord.get(); + if has_varying || (used_fragcoord & (4 | 8)) != 0 { + state.use_perspective = true; + } + if state.use_perspective { + write!(state, + "static void read_perspective_inputs(\ + 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"); + } for i in inputs { let sym = state.hir.sym(*i); match &sym.decl { @@ -674,11 +682,11 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { _ => panic!(), } } + write!(state, "}}\n"); } - write!(state, "}}\n"); write!(state, "ALWAYS_INLINE void step_interp_inputs() {{\n"); - if (state.hir.used_fragcoord & 1) != 0 { + if (used_fragcoord & 1) != 0 { write!(state, " step_fragcoord();\n"); } for i in inputs { @@ -695,13 +703,15 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { } write!(state, "}}\n"); - write!(state, "ALWAYS_INLINE void step_perspective_inputs() {{\n"); - if (state.hir.used_fragcoord & 1) != 0 { - write!(state, " step_fragcoord();\n"); - } - write!(state, " step_perspective();\n"); - if has_perspective { - write!(state, " Float w = 1.0f / gl_FragCoord.w;\n"); + if state.use_perspective { + write!(state, "ALWAYS_INLINE void step_perspective_inputs() {{\n"); + if (used_fragcoord & 1) != 0 { + write!(state, " step_fragcoord();\n"); + } + write!(state, " step_perspective();\n"); + if has_varying { + write!(state, " Float w = 1.0f / gl_FragCoord.w;\n"); + } for i in inputs { let sym = state.hir.sym(*i); match &sym.decl { @@ -715,15 +725,15 @@ fn write_read_inputs(state: &mut OutputState, inputs: &[hir::SymRef]) { _ => panic!(), } } + write!(state, "}}\n"); } - 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 (state.hir.used_fragcoord & 1) != 0 { + if (used_fragcoord & 1) != 0 { write!(state, " step_fragcoord(chunks);\n"); } for i in inputs { @@ -791,6 +801,8 @@ pub struct OutputState { deps: RefCell>, vector_mask: u32, uses_discard: bool, + used_fragcoord: Cell, + use_perspective: bool, has_draw_span_rgba8: bool, has_draw_span_r8: bool, used_globals: RefCell>, @@ -2057,6 +2069,14 @@ pub fn show_hir_expr_inner(state: &OutputState, expr: &hir::Expr, top_level: boo } hir::ExprKind::SwizzleSelector(ref e, ref s) => { if state.output_cxx { + if let hir::ExprKind::Variable(ref sym) = &e.kind { + if state.hir.sym(*sym).name == "gl_FragCoord" { + state.used_fragcoord.set( + s.components.iter().fold( + state.used_fragcoord.get(), + |used, c| used | (1 << c))); + } + } state.write("("); show_hir_expr(state, &e); if state.is_lval.get() && s.components.len() > 1 { @@ -3579,17 +3599,19 @@ fn write_abi(state: &mut OutputState) { state.write(" self->step_interp_inputs();\n"); state.write(" while (--chunks > 0) self->step_interp_inputs();\n"); state.write("}\n"); - state.write("static void run_perspective(Self *self) {\n"); - if state.uses_discard { - state.write(" self->isPixelDiscarded = false;\n"); + if state.use_perspective { + state.write("static void run_perspective(Self *self) {\n"); + if state.uses_discard { + 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 chunks) {\n"); + state.write(" self->step_perspective_inputs();\n"); + state.write(" while (--chunks > 0) self->step_perspective_inputs();\n"); + state.write("}\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 chunks) {\n"); - state.write(" self->step_perspective_inputs();\n"); - state.write(" while (--chunks > 0) self->step_perspective_inputs();\n"); - state.write("}\n"); if state.has_draw_span_rgba8 { state.write( "static void draw_span_RGBA8(Self* self, uint32_t* buf, int len) { \ @@ -3629,10 +3651,16 @@ fn write_abi(state: &mut OutputState) { if state.uses_discard { state.write(" enable_discard();\n"); } - state.write(" enable_perspective();\n"); - state.write(" init_span_w_func = (InitSpanWFunc)&read_perspective_inputs;\n"); - state.write(" run_w_func = (RunWFunc)&run_perspective;\n"); - state.write(" skip_w_func = (SkipWFunc)&skip_perspective;\n"); + if state.use_perspective { + state.write(" enable_perspective();\n"); + state.write(" init_span_w_func = (InitSpanWFunc)&read_perspective_inputs;\n"); + state.write(" run_w_func = (RunWFunc)&run_perspective;\n"); + state.write(" skip_w_func = (SkipWFunc)&skip_perspective;\n"); + } else { + state.write(" init_span_w_func = (InitSpanWFunc)&read_interp_inputs;\n"); + state.write(" run_w_func = (RunWFunc)&run;\n"); + state.write(" skip_w_func = (SkipWFunc)&skip;\n"); + } } ShaderKind::Vertex => { state.write(" set_uniform_1i_func = (SetUniform1iFunc)&set_uniform_1i;\n");