brw_shader.cpp revision 14b86f3c9131c1b26b01e07679cc899df0885b23
1/* 2 * Copyright © 2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24extern "C" { 25#include "main/macros.h" 26#include "brw_context.h" 27} 28#include "brw_fs.h" 29#include "../glsl/ir_optimization.h" 30#include "../glsl/ir_print_visitor.h" 31 32struct gl_shader * 33brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 34{ 35 struct brw_shader *shader; 36 37 shader = rzalloc(NULL, struct brw_shader); 38 if (shader) { 39 shader->base.Type = type; 40 shader->base.Name = name; 41 _mesa_init_shader(ctx, &shader->base); 42 } 43 44 return &shader->base; 45} 46 47struct gl_shader_program * 48brw_new_shader_program(struct gl_context *ctx, GLuint name) 49{ 50 struct brw_shader_program *prog; 51 prog = rzalloc(NULL, struct brw_shader_program); 52 if (prog) { 53 prog->base.Name = name; 54 _mesa_init_shader_program(ctx, &prog->base); 55 } 56 return &prog->base; 57} 58 59GLboolean 60brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 61{ 62 struct brw_context *brw = brw_context(ctx); 63 struct intel_context *intel = &brw->intel; 64 65 struct brw_shader *shader = 66 (struct brw_shader *)prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; 67 if (shader != NULL) { 68 void *mem_ctx = ralloc_context(NULL); 69 bool progress; 70 71 if (shader->ir) 72 ralloc_free(shader->ir); 73 shader->ir = new(shader) exec_list; 74 clone_ir_list(mem_ctx, shader->ir, shader->base.ir); 75 76 do_mat_op_to_vec(shader->ir); 77 lower_instructions(shader->ir, 78 MOD_TO_FRACT | 79 DIV_TO_MUL_RCP | 80 SUB_TO_ADD_NEG | 81 EXP_TO_EXP2 | 82 LOG_TO_LOG2); 83 84 /* Pre-gen6 HW can only nest if-statements 16 deep. Beyond this, 85 * if-statements need to be flattened. 86 */ 87 if (intel->gen < 6) 88 lower_if_to_cond_assign(shader->ir, 16); 89 90 do_lower_texture_projection(shader->ir); 91 do_vec_index_to_cond_assign(shader->ir); 92 brw_do_cubemap_normalize(shader->ir); 93 lower_noise(shader->ir); 94 lower_quadop_vector(shader->ir, false); 95 lower_variable_index_to_cond_assign(shader->ir, 96 GL_TRUE, /* input */ 97 GL_TRUE, /* output */ 98 GL_TRUE, /* temp */ 99 GL_TRUE /* uniform */ 100 ); 101 102 do { 103 progress = false; 104 105 brw_do_channel_expressions(shader->ir); 106 brw_do_vector_splitting(shader->ir); 107 108 progress = do_lower_jumps(shader->ir, true, true, 109 true, /* main return */ 110 false, /* continue */ 111 false /* loops */ 112 ) || progress; 113 114 progress = do_common_optimization(shader->ir, true, 32) || progress; 115 } while (progress); 116 117 validate_ir_tree(shader->ir); 118 119 reparent_ir(shader->ir, shader->ir); 120 ralloc_free(mem_ctx); 121 } 122 123 if (!_mesa_ir_link_shader(ctx, prog)) 124 return GL_FALSE; 125 126 return GL_TRUE; 127} 128