brw_shader.cpp revision 1d5d67f8adac9f94715de9804adb536d9a7ec5ee
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#include "brw_vs.h" 28} 29#include "brw_fs.h" 30#include "glsl/ir_optimization.h" 31#include "glsl/ir_print_visitor.h" 32 33struct gl_shader * 34brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 35{ 36 struct brw_shader *shader; 37 38 shader = rzalloc(NULL, struct brw_shader); 39 if (shader) { 40 shader->base.Type = type; 41 shader->base.Name = name; 42 _mesa_init_shader(ctx, &shader->base); 43 } 44 45 return &shader->base; 46} 47 48struct gl_shader_program * 49brw_new_shader_program(struct gl_context *ctx, GLuint name) 50{ 51 struct brw_shader_program *prog; 52 prog = rzalloc(NULL, struct brw_shader_program); 53 if (prog) { 54 prog->base.Name = name; 55 _mesa_init_shader_program(ctx, &prog->base); 56 } 57 return &prog->base; 58} 59 60/** 61 * Performs a compile of the shader stages even when we don't know 62 * what non-orthogonal state will be set, in the hope that it reflects 63 * the eventual NOS used, and thus allows us to produce link failures. 64 */ 65bool 66brw_shader_precompile(struct gl_context *ctx, struct gl_shader_program *prog) 67{ 68 if (!brw_fs_precompile(ctx, prog)) 69 return false; 70 71 if (!brw_vs_precompile(ctx, prog)) 72 return false; 73 74 return true; 75} 76 77GLboolean 78brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 79{ 80 struct brw_context *brw = brw_context(ctx); 81 struct intel_context *intel = &brw->intel; 82 unsigned int stage; 83 84 for (stage = 0; stage < ARRAY_SIZE(prog->_LinkedShaders); stage++) { 85 struct brw_shader *shader = 86 (struct brw_shader *)prog->_LinkedShaders[stage]; 87 88 if (!shader) 89 continue; 90 91 void *mem_ctx = ralloc_context(NULL); 92 bool progress; 93 94 if (shader->ir) 95 ralloc_free(shader->ir); 96 shader->ir = new(shader) exec_list; 97 clone_ir_list(mem_ctx, shader->ir, shader->base.ir); 98 99 do_mat_op_to_vec(shader->ir); 100 lower_instructions(shader->ir, 101 MOD_TO_FRACT | 102 DIV_TO_MUL_RCP | 103 SUB_TO_ADD_NEG | 104 EXP_TO_EXP2 | 105 LOG_TO_LOG2); 106 107 /* Pre-gen6 HW can only nest if-statements 16 deep. Beyond this, 108 * if-statements need to be flattened. 109 */ 110 if (intel->gen < 6) 111 lower_if_to_cond_assign(shader->ir, 16); 112 113 do_lower_texture_projection(shader->ir); 114 do_vec_index_to_cond_assign(shader->ir); 115 brw_do_cubemap_normalize(shader->ir); 116 lower_noise(shader->ir); 117 lower_quadop_vector(shader->ir, false); 118 119 bool input = true; 120 bool output = stage == MESA_SHADER_FRAGMENT; 121 bool temp = stage == MESA_SHADER_FRAGMENT; 122 bool uniform = stage == MESA_SHADER_FRAGMENT; 123 124 lower_variable_index_to_cond_assign(shader->ir, 125 input, output, temp, uniform); 126 127 do { 128 progress = false; 129 130 if (stage == MESA_SHADER_FRAGMENT) { 131 brw_do_channel_expressions(shader->ir); 132 brw_do_vector_splitting(shader->ir); 133 } 134 135 progress = do_lower_jumps(shader->ir, true, true, 136 true, /* main return */ 137 false, /* continue */ 138 false /* loops */ 139 ) || progress; 140 141 progress = do_common_optimization(shader->ir, true, true, 32) 142 || progress; 143 } while (progress); 144 145 validate_ir_tree(shader->ir); 146 147 reparent_ir(shader->ir, shader->ir); 148 ralloc_free(mem_ctx); 149 } 150 151 if (!_mesa_ir_link_shader(ctx, prog)) 152 return false; 153 154 if (!brw_shader_precompile(ctx, prog)) 155 return false; 156 157 return true; 158} 159 160 161int 162brw_type_for_base_type(const struct glsl_type *type) 163{ 164 switch (type->base_type) { 165 case GLSL_TYPE_FLOAT: 166 return BRW_REGISTER_TYPE_F; 167 case GLSL_TYPE_INT: 168 case GLSL_TYPE_BOOL: 169 return BRW_REGISTER_TYPE_D; 170 case GLSL_TYPE_UINT: 171 return BRW_REGISTER_TYPE_UD; 172 case GLSL_TYPE_ARRAY: 173 case GLSL_TYPE_STRUCT: 174 case GLSL_TYPE_SAMPLER: 175 /* These should be overridden with the type of the member when 176 * dereferenced into. BRW_REGISTER_TYPE_UD seems like a likely 177 * way to trip up if we don't. 178 */ 179 return BRW_REGISTER_TYPE_UD; 180 default: 181 assert(!"not reached"); 182 return BRW_REGISTER_TYPE_F; 183 } 184} 185 186uint32_t 187brw_conditional_for_comparison(unsigned int op) 188{ 189 switch (op) { 190 case ir_binop_less: 191 return BRW_CONDITIONAL_L; 192 case ir_binop_greater: 193 return BRW_CONDITIONAL_G; 194 case ir_binop_lequal: 195 return BRW_CONDITIONAL_LE; 196 case ir_binop_gequal: 197 return BRW_CONDITIONAL_GE; 198 case ir_binop_equal: 199 case ir_binop_all_equal: /* same as equal for scalars */ 200 return BRW_CONDITIONAL_Z; 201 case ir_binop_nequal: 202 case ir_binop_any_nequal: /* same as nequal for scalars */ 203 return BRW_CONDITIONAL_NZ; 204 default: 205 assert(!"not reached: bad operation for comparison"); 206 return BRW_CONDITIONAL_NZ; 207 } 208} 209 210uint32_t 211brw_math_function(enum opcode op) 212{ 213 switch (op) { 214 case SHADER_OPCODE_RCP: 215 return BRW_MATH_FUNCTION_INV; 216 case SHADER_OPCODE_RSQ: 217 return BRW_MATH_FUNCTION_RSQ; 218 case SHADER_OPCODE_SQRT: 219 return BRW_MATH_FUNCTION_SQRT; 220 case SHADER_OPCODE_EXP2: 221 return BRW_MATH_FUNCTION_EXP; 222 case SHADER_OPCODE_LOG2: 223 return BRW_MATH_FUNCTION_LOG; 224 case SHADER_OPCODE_POW: 225 return BRW_MATH_FUNCTION_POW; 226 case SHADER_OPCODE_SIN: 227 return BRW_MATH_FUNCTION_SIN; 228 case SHADER_OPCODE_COS: 229 return BRW_MATH_FUNCTION_COS; 230 case SHADER_OPCODE_INT_QUOTIENT: 231 return BRW_MATH_FUNCTION_INT_DIV_QUOTIENT; 232 case SHADER_OPCODE_INT_REMAINDER: 233 return BRW_MATH_FUNCTION_INT_DIV_REMAINDER; 234 default: 235 assert(!"not reached: unknown math function"); 236 return 0; 237 } 238} 239