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:
Lee Salzman 2020-05-01 00:33:39 +00:00
Родитель d6438ad24b
Коммит 50f17f6abd
2 изменённых файлов: 63 добавлений и 45 удалений

Просмотреть файл

@ -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");