brw_fs.h revision f9995b30756140724f41daf963fa06167912be7f
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 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 * 26 */ 27 28extern "C" { 29 30#include <sys/types.h> 31 32#include "main/macros.h" 33#include "main/shaderobj.h" 34#include "main/uniforms.h" 35#include "program/prog_parameter.h" 36#include "program/prog_print.h" 37#include "program/prog_optimize.h" 38#include "program/register_allocate.h" 39#include "program/sampler.h" 40#include "program/hash_table.h" 41#include "brw_context.h" 42#include "brw_eu.h" 43#include "brw_wm.h" 44#include "talloc.h" 45} 46#include "../glsl/glsl_types.h" 47#include "../glsl/ir.h" 48 49enum register_file { 50 ARF = BRW_ARCHITECTURE_REGISTER_FILE, 51 GRF = BRW_GENERAL_REGISTER_FILE, 52 MRF = BRW_MESSAGE_REGISTER_FILE, 53 IMM = BRW_IMMEDIATE_VALUE, 54 FIXED_HW_REG, /* a struct brw_reg */ 55 UNIFORM, /* prog_data->params[hw_reg] */ 56 BAD_FILE 57}; 58 59enum fs_opcodes { 60 FS_OPCODE_FB_WRITE = 256, 61 FS_OPCODE_RCP, 62 FS_OPCODE_RSQ, 63 FS_OPCODE_SQRT, 64 FS_OPCODE_EXP2, 65 FS_OPCODE_LOG2, 66 FS_OPCODE_POW, 67 FS_OPCODE_SIN, 68 FS_OPCODE_COS, 69 FS_OPCODE_DDX, 70 FS_OPCODE_DDY, 71 FS_OPCODE_LINTERP, 72 FS_OPCODE_TEX, 73 FS_OPCODE_TXB, 74 FS_OPCODE_TXL, 75 FS_OPCODE_DISCARD_NOT, 76 FS_OPCODE_DISCARD_AND, 77}; 78 79 80class fs_reg { 81public: 82 /* Callers of this talloc-based new need not call delete. It's 83 * easier to just talloc_free 'ctx' (or any of its ancestors). */ 84 static void* operator new(size_t size, void *ctx) 85 { 86 void *node; 87 88 node = talloc_size(ctx, size); 89 assert(node != NULL); 90 91 return node; 92 } 93 94 void init() 95 { 96 this->reg = 0; 97 this->reg_offset = 0; 98 this->negate = 0; 99 this->abs = 0; 100 this->hw_reg = -1; 101 } 102 103 /** Generic unset register constructor. */ 104 fs_reg() 105 { 106 init(); 107 this->file = BAD_FILE; 108 } 109 110 /** Immediate value constructor. */ 111 fs_reg(float f) 112 { 113 init(); 114 this->file = IMM; 115 this->type = BRW_REGISTER_TYPE_F; 116 this->imm.f = f; 117 } 118 119 /** Immediate value constructor. */ 120 fs_reg(int32_t i) 121 { 122 init(); 123 this->file = IMM; 124 this->type = BRW_REGISTER_TYPE_D; 125 this->imm.i = i; 126 } 127 128 /** Immediate value constructor. */ 129 fs_reg(uint32_t u) 130 { 131 init(); 132 this->file = IMM; 133 this->type = BRW_REGISTER_TYPE_UD; 134 this->imm.u = u; 135 } 136 137 /** Fixed brw_reg Immediate value constructor. */ 138 fs_reg(struct brw_reg fixed_hw_reg) 139 { 140 init(); 141 this->file = FIXED_HW_REG; 142 this->fixed_hw_reg = fixed_hw_reg; 143 this->type = fixed_hw_reg.type; 144 } 145 146 fs_reg(enum register_file file, int hw_reg); 147 fs_reg(class fs_visitor *v, const struct glsl_type *type); 148 149 /** Register file: ARF, GRF, MRF, IMM. */ 150 enum register_file file; 151 /** virtual register number. 0 = fixed hw reg */ 152 int reg; 153 /** Offset within the virtual register. */ 154 int reg_offset; 155 /** HW register number. Generally unset until register allocation. */ 156 int hw_reg; 157 /** Register type. BRW_REGISTER_TYPE_* */ 158 int type; 159 bool negate; 160 bool abs; 161 struct brw_reg fixed_hw_reg; 162 163 /** Value for file == BRW_IMMMEDIATE_FILE */ 164 union { 165 int32_t i; 166 uint32_t u; 167 float f; 168 } imm; 169}; 170 171class fs_inst : public exec_node { 172public: 173 /* Callers of this talloc-based new need not call delete. It's 174 * easier to just talloc_free 'ctx' (or any of its ancestors). */ 175 static void* operator new(size_t size, void *ctx) 176 { 177 void *node; 178 179 node = talloc_zero_size(ctx, size); 180 assert(node != NULL); 181 182 return node; 183 } 184 185 void init() 186 { 187 this->opcode = BRW_OPCODE_NOP; 188 this->saturate = false; 189 this->conditional_mod = BRW_CONDITIONAL_NONE; 190 this->predicated = false; 191 this->sampler = 0; 192 this->target = 0; 193 this->eot = false; 194 this->header_present = false; 195 this->shadow_compare = false; 196 this->mlen = 0; 197 this->base_mrf = 0; 198 } 199 200 fs_inst() 201 { 202 init(); 203 } 204 205 fs_inst(int opcode) 206 { 207 init(); 208 this->opcode = opcode; 209 } 210 211 fs_inst(int opcode, fs_reg dst) 212 { 213 init(); 214 this->opcode = opcode; 215 this->dst = dst; 216 } 217 218 fs_inst(int opcode, fs_reg dst, fs_reg src0) 219 { 220 init(); 221 this->opcode = opcode; 222 this->dst = dst; 223 this->src[0] = src0; 224 } 225 226 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1) 227 { 228 init(); 229 this->opcode = opcode; 230 this->dst = dst; 231 this->src[0] = src0; 232 this->src[1] = src1; 233 } 234 235 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1, fs_reg src2) 236 { 237 init(); 238 this->opcode = opcode; 239 this->dst = dst; 240 this->src[0] = src0; 241 this->src[1] = src1; 242 this->src[2] = src2; 243 } 244 245 int opcode; /* BRW_OPCODE_* or FS_OPCODE_* */ 246 fs_reg dst; 247 fs_reg src[3]; 248 bool saturate; 249 bool predicated; 250 int conditional_mod; /**< BRW_CONDITIONAL_* */ 251 252 int mlen; /**< SEND message length */ 253 int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ 254 int sampler; 255 int target; /**< MRT target. */ 256 bool eot; 257 bool header_present; 258 bool shadow_compare; 259 260 /** @{ 261 * Annotation for the generated IR. One of the two can be set. 262 */ 263 ir_instruction *ir; 264 const char *annotation; 265 /** @} */ 266}; 267 268class fs_visitor : public ir_visitor 269{ 270public: 271 272 fs_visitor(struct brw_wm_compile *c, struct brw_shader *shader) 273 { 274 this->c = c; 275 this->p = &c->func; 276 this->brw = p->brw; 277 this->fp = brw->fragment_program; 278 this->intel = &brw->intel; 279 this->ctx = &intel->ctx; 280 this->mem_ctx = talloc_new(NULL); 281 this->shader = shader; 282 this->fail = false; 283 this->variable_ht = hash_table_ctor(0, 284 hash_table_pointer_hash, 285 hash_table_pointer_compare); 286 287 this->frag_color = NULL; 288 this->frag_data = NULL; 289 this->frag_depth = NULL; 290 this->first_non_payload_grf = 0; 291 292 this->current_annotation = NULL; 293 this->annotation_string = NULL; 294 this->annotation_ir = NULL; 295 this->base_ir = NULL; 296 297 this->virtual_grf_sizes = NULL; 298 this->virtual_grf_next = 1; 299 this->virtual_grf_array_size = 0; 300 this->virtual_grf_def = NULL; 301 this->virtual_grf_use = NULL; 302 303 this->kill_emitted = false; 304 } 305 306 ~fs_visitor() 307 { 308 talloc_free(this->mem_ctx); 309 hash_table_dtor(this->variable_ht); 310 } 311 312 fs_reg *variable_storage(ir_variable *var); 313 int virtual_grf_alloc(int size); 314 315 void visit(ir_variable *ir); 316 void visit(ir_assignment *ir); 317 void visit(ir_dereference_variable *ir); 318 void visit(ir_dereference_record *ir); 319 void visit(ir_dereference_array *ir); 320 void visit(ir_expression *ir); 321 void visit(ir_texture *ir); 322 void visit(ir_if *ir); 323 void visit(ir_constant *ir); 324 void visit(ir_swizzle *ir); 325 void visit(ir_return *ir); 326 void visit(ir_loop *ir); 327 void visit(ir_loop_jump *ir); 328 void visit(ir_discard *ir); 329 void visit(ir_call *ir); 330 void visit(ir_function *ir); 331 void visit(ir_function_signature *ir); 332 333 fs_inst *emit(fs_inst inst); 334 void assign_curb_setup(); 335 void calculate_urb_setup(); 336 void assign_urb_setup(); 337 void assign_regs(); 338 void assign_regs_trivial(); 339 void calculate_live_intervals(); 340 bool propagate_constants(); 341 bool register_coalesce(); 342 bool compute_to_mrf(); 343 bool dead_code_eliminate(); 344 bool virtual_grf_interferes(int a, int b); 345 void generate_code(); 346 void generate_fb_write(fs_inst *inst); 347 void generate_linterp(fs_inst *inst, struct brw_reg dst, 348 struct brw_reg *src); 349 void generate_tex(fs_inst *inst, struct brw_reg dst); 350 void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); 351 void generate_discard_not(fs_inst *inst, struct brw_reg temp); 352 void generate_discard_and(fs_inst *inst, struct brw_reg temp); 353 void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 354 void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 355 356 void emit_dummy_fs(); 357 fs_reg *emit_fragcoord_interpolation(ir_variable *ir); 358 fs_reg *emit_frontfacing_interpolation(ir_variable *ir); 359 fs_reg *emit_general_interpolation(ir_variable *ir); 360 void emit_interpolation_setup_gen4(); 361 void emit_interpolation_setup_gen6(); 362 fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate); 363 fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate); 364 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0); 365 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1); 366 367 void emit_fb_writes(); 368 void emit_assignment_writes(fs_reg &l, fs_reg &r, 369 const glsl_type *type, bool predicated); 370 371 struct brw_reg interp_reg(int location, int channel); 372 int setup_uniform_values(int loc, const glsl_type *type); 373 void setup_builtin_uniform_values(ir_variable *ir); 374 375 struct brw_context *brw; 376 const struct gl_fragment_program *fp; 377 struct intel_context *intel; 378 struct gl_context *ctx; 379 struct brw_wm_compile *c; 380 struct brw_compile *p; 381 struct brw_shader *shader; 382 void *mem_ctx; 383 exec_list instructions; 384 385 int *virtual_grf_sizes; 386 int virtual_grf_next; 387 int virtual_grf_array_size; 388 int *virtual_grf_def; 389 int *virtual_grf_use; 390 391 struct hash_table *variable_ht; 392 ir_variable *frag_color, *frag_data, *frag_depth; 393 int first_non_payload_grf; 394 int urb_setup[FRAG_ATTRIB_MAX]; 395 bool kill_emitted; 396 397 /** @{ debug annotation info */ 398 const char *current_annotation; 399 ir_instruction *base_ir; 400 const char **annotation_string; 401 ir_instruction **annotation_ir; 402 /** @} */ 403 404 bool fail; 405 406 /* Result of last visit() method. */ 407 fs_reg result; 408 409 fs_reg pixel_x; 410 fs_reg pixel_y; 411 fs_reg wpos_w; 412 fs_reg pixel_w; 413 fs_reg delta_x; 414 fs_reg delta_y; 415 416 int grf_used; 417}; 418 419GLboolean brw_do_channel_expressions(struct exec_list *instructions); 420GLboolean brw_do_vector_splitting(struct exec_list *instructions); 421