mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1634447 - don't generate perspective code if SWGL fragment shader doesn't use it. r=jrmuizel
Differential Revision: https://phabricator.services.mozilla.com/D73327
This commit is contained in:
parent
d6438ad24b
commit
50f17f6abd
@ -925,7 +925,6 @@ pub struct State {
|
||||
branch_run_class: RunClass,
|
||||
branch_declaration: SymRef,
|
||||
modified_globals: RefCell<Vec<SymRef>>,
|
||||
pub used_fragcoord: i32,
|
||||
pub used_globals: RefCell<Vec<SymRef>>,
|
||||
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,
|
||||
|
@ -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<Vec<(hir::SymRef, u32)>>,
|
||||
vector_mask: u32,
|
||||
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>>,
|
||||
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user