13de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt/* 23de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * Copyright © 2010 Intel Corporation 33de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 43de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 53de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * copy of this software and associated documentation files (the "Software"), 63de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * to deal in the Software without restriction, including without limitation 73de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 93de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * Software is furnished to do so, subject to the following conditions: 103de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 113de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * The above copyright notice and this permission notice (including the next 123de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * paragraph) shall be included in all copies or substantial portions of the 133de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * Software. 143de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 153de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 183de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 193de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 203de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 213de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * DEALINGS IN THE SOFTWARE. 223de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt */ 233de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 243de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt/** @file lower_discard_flow.cpp 253de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 263de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * Implements the GLSL 1.30 revision 9 rule for fragment shader 273de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * discard handling: 283de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 293de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * "Control flow exits the shader, and subsequent implicit or 303de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * explicit derivatives are undefined when this control flow is 313de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * non-uniform (meaning different fragments within the primitive 323de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * take different control paths)." 333de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 343de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * There seem to be two conflicting things here. "Control flow exits 353de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * the shader" sounds like the discarded fragments should effectively 363de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * jump to the end of the shader, but that breaks derivatives in the 373de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * case of uniform control flow and causes rendering failure in the 383de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * bushes in Unigine Tropics. 393de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * 403de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * The question, then, is whether the intent was "loops stop at the 413de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * point that the only active channels left are discarded pixels" or 423de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * "discarded pixels become inactive at the point that control flow 433de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * returns to the top of a loop". This implements the second 443de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt * interpretation. 453de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt */ 463de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 473de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt#include "glsl_types.h" 483de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt#include "ir.h" 493de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt#include "program/hash_table.h" 503de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 513de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtclass lower_discard_flow_visitor : public ir_hierarchical_visitor { 523de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtpublic: 533de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt lower_discard_flow_visitor(ir_variable *discarded) 543de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt : discarded(discarded) 553de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt { 563de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt mem_ctx = ralloc_parent(discarded); 573de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt } 583de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 593de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ~lower_discard_flow_visitor() 603de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt { 613de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt } 623de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 633de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_visitor_status visit_enter(ir_discard *ir); 643de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_visitor_status visit_enter(ir_loop_jump *ir); 653de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_visitor_status visit_enter(ir_loop *ir); 663de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_visitor_status visit_enter(ir_function_signature *ir); 673de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 683de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_if *generate_discard_break(); 693de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 703de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_variable *discarded; 713de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt void *mem_ctx; 723de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt}; 733de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 743de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtir_visitor_status 753de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow_visitor::visit_enter(ir_loop_jump *ir) 763de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 773de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt if (ir->mode != ir_loop_jump::jump_continue) 783de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 793de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 803de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir->insert_before(generate_discard_break()); 813de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 823de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 833de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 843de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 853de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtir_visitor_status 863de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow_visitor::visit_enter(ir_discard *ir) 873de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 883de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded); 893de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_rvalue *rhs = new(mem_ctx) ir_constant(true); 903de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs); 913de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir->insert_before(assign); 923de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 933de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 943de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 953de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 963de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtir_visitor_status 973de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow_visitor::visit_enter(ir_loop *ir) 983de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 993de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir->body_instructions.push_tail(generate_discard_break()); 1003de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1013de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 1023de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 1033de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1043de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtir_visitor_status 1053de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow_visitor::visit_enter(ir_function_signature *ir) 1063de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 1073de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt if (strcmp(ir->function_name(), "main") != 0) 1083de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 1093de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1103de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded); 1113de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_rvalue *rhs = new(mem_ctx) ir_constant(false); 1123de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs); 1133de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir->body.push_head(assign); 1143de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1153de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return visit_continue; 1163de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 1173de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1183de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtir_if * 1193de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow_visitor::generate_discard_break() 1203de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 1213de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_rvalue *if_condition = new(mem_ctx) ir_dereference_variable(discarded); 1223de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_if *if_inst = new(mem_ctx) ir_if(if_condition); 1233de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1243de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_instruction *br = new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); 1253de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt if_inst->then_instructions.push_tail(br); 1263de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1273de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt return if_inst; 1283de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 1293de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1303de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtvoid 1313de1395fa5a563c13774ac1c38722c16cecc521dEric Anholtlower_discard_flow(exec_list *ir) 1323de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt{ 1333de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt void *mem_ctx = ir; 1343de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1353de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_variable *var = new(mem_ctx) ir_variable(glsl_type::bool_type, 1363de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt "discarded", 1373de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir_var_temporary); 1383de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1393de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt ir->push_head(var); 1403de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1413de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt lower_discard_flow_visitor v(var); 1423de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt 1433de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt visit_list_elements(&v, ir); 1443de1395fa5a563c13774ac1c38722c16cecc521dEric Anholt} 145