brw_fs.h revision 99b2c8570ea6f46c6564681631f0e0750a0641cc
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 FS_OPCODE_SPILL, 78 FS_OPCODE_UNSPILL, 79}; 80 81 82class fs_reg { 83public: 84 /* Callers of this talloc-based new need not call delete. It's 85 * easier to just talloc_free 'ctx' (or any of its ancestors). */ 86 static void* operator new(size_t size, void *ctx) 87 { 88 void *node; 89 90 node = talloc_size(ctx, size); 91 assert(node != NULL); 92 93 return node; 94 } 95 96 void init() 97 { 98 this->reg = 0; 99 this->reg_offset = 0; 100 this->negate = 0; 101 this->abs = 0; 102 this->hw_reg = -1; 103 } 104 105 /** Generic unset register constructor. */ 106 fs_reg() 107 { 108 init(); 109 this->file = BAD_FILE; 110 } 111 112 /** Immediate value constructor. */ 113 fs_reg(float f) 114 { 115 init(); 116 this->file = IMM; 117 this->type = BRW_REGISTER_TYPE_F; 118 this->imm.f = f; 119 } 120 121 /** Immediate value constructor. */ 122 fs_reg(int32_t i) 123 { 124 init(); 125 this->file = IMM; 126 this->type = BRW_REGISTER_TYPE_D; 127 this->imm.i = i; 128 } 129 130 /** Immediate value constructor. */ 131 fs_reg(uint32_t u) 132 { 133 init(); 134 this->file = IMM; 135 this->type = BRW_REGISTER_TYPE_UD; 136 this->imm.u = u; 137 } 138 139 /** Fixed brw_reg Immediate value constructor. */ 140 fs_reg(struct brw_reg fixed_hw_reg) 141 { 142 init(); 143 this->file = FIXED_HW_REG; 144 this->fixed_hw_reg = fixed_hw_reg; 145 this->type = fixed_hw_reg.type; 146 } 147 148 fs_reg(enum register_file file, int hw_reg); 149 fs_reg(enum register_file file, int hw_reg, uint32_t type); 150 fs_reg(class fs_visitor *v, const struct glsl_type *type); 151 152 /** Register file: ARF, GRF, MRF, IMM. */ 153 enum register_file file; 154 /** virtual register number. 0 = fixed hw reg */ 155 int reg; 156 /** Offset within the virtual register. */ 157 int reg_offset; 158 /** HW register number. Generally unset until register allocation. */ 159 int hw_reg; 160 /** Register type. BRW_REGISTER_TYPE_* */ 161 int type; 162 bool negate; 163 bool abs; 164 struct brw_reg fixed_hw_reg; 165 166 /** Value for file == BRW_IMMMEDIATE_FILE */ 167 union { 168 int32_t i; 169 uint32_t u; 170 float f; 171 } imm; 172}; 173 174class fs_inst : public exec_node { 175public: 176 /* Callers of this talloc-based new need not call delete. It's 177 * easier to just talloc_free 'ctx' (or any of its ancestors). */ 178 static void* operator new(size_t size, void *ctx) 179 { 180 void *node; 181 182 node = talloc_zero_size(ctx, size); 183 assert(node != NULL); 184 185 return node; 186 } 187 188 void init() 189 { 190 this->opcode = BRW_OPCODE_NOP; 191 this->saturate = false; 192 this->conditional_mod = BRW_CONDITIONAL_NONE; 193 this->predicated = false; 194 this->sampler = 0; 195 this->target = 0; 196 this->eot = false; 197 this->header_present = false; 198 this->shadow_compare = false; 199 this->mlen = 0; 200 this->base_mrf = 0; 201 this->offset = 0; 202 } 203 204 fs_inst() 205 { 206 init(); 207 } 208 209 fs_inst(int opcode) 210 { 211 init(); 212 this->opcode = opcode; 213 } 214 215 fs_inst(int opcode, fs_reg dst) 216 { 217 init(); 218 this->opcode = opcode; 219 this->dst = dst; 220 221 if (dst.file == GRF) 222 assert(dst.reg_offset >= 0); 223 } 224 225 fs_inst(int opcode, fs_reg dst, fs_reg src0) 226 { 227 init(); 228 this->opcode = opcode; 229 this->dst = dst; 230 this->src[0] = src0; 231 232 if (dst.file == GRF) 233 assert(dst.reg_offset >= 0); 234 if (src[0].file == GRF) 235 assert(src[0].reg_offset >= 0); 236 } 237 238 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1) 239 { 240 init(); 241 this->opcode = opcode; 242 this->dst = dst; 243 this->src[0] = src0; 244 this->src[1] = src1; 245 246 if (dst.file == GRF) 247 assert(dst.reg_offset >= 0); 248 if (src[0].file == GRF) 249 assert(src[0].reg_offset >= 0); 250 if (src[1].file == GRF) 251 assert(src[1].reg_offset >= 0); 252 } 253 254 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1, fs_reg src2) 255 { 256 init(); 257 this->opcode = opcode; 258 this->dst = dst; 259 this->src[0] = src0; 260 this->src[1] = src1; 261 this->src[2] = src2; 262 263 if (dst.file == GRF) 264 assert(dst.reg_offset >= 0); 265 if (src[0].file == GRF) 266 assert(src[0].reg_offset >= 0); 267 if (src[1].file == GRF) 268 assert(src[1].reg_offset >= 0); 269 if (src[2].file == GRF) 270 assert(src[2].reg_offset >= 0); 271 } 272 273 int opcode; /* BRW_OPCODE_* or FS_OPCODE_* */ 274 fs_reg dst; 275 fs_reg src[3]; 276 bool saturate; 277 bool predicated; 278 int conditional_mod; /**< BRW_CONDITIONAL_* */ 279 280 int mlen; /**< SEND message length */ 281 int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ 282 int sampler; 283 int target; /**< MRT target. */ 284 bool eot; 285 bool header_present; 286 bool shadow_compare; 287 uint32_t offset; /* spill/unspill offset */ 288 289 /** @{ 290 * Annotation for the generated IR. One of the two can be set. 291 */ 292 ir_instruction *ir; 293 const char *annotation; 294 /** @} */ 295}; 296 297class fs_visitor : public ir_visitor 298{ 299public: 300 301 fs_visitor(struct brw_wm_compile *c, struct brw_shader *shader) 302 { 303 this->c = c; 304 this->p = &c->func; 305 this->brw = p->brw; 306 this->fp = brw->fragment_program; 307 this->intel = &brw->intel; 308 this->ctx = &intel->ctx; 309 this->mem_ctx = talloc_new(NULL); 310 this->shader = shader; 311 this->fail = false; 312 this->variable_ht = hash_table_ctor(0, 313 hash_table_pointer_hash, 314 hash_table_pointer_compare); 315 316 this->frag_color = NULL; 317 this->frag_data = NULL; 318 this->frag_depth = NULL; 319 this->first_non_payload_grf = 0; 320 321 this->current_annotation = NULL; 322 this->annotation_string = NULL; 323 this->annotation_ir = NULL; 324 this->base_ir = NULL; 325 326 this->virtual_grf_sizes = NULL; 327 this->virtual_grf_next = 1; 328 this->virtual_grf_array_size = 0; 329 this->virtual_grf_def = NULL; 330 this->virtual_grf_use = NULL; 331 332 this->kill_emitted = false; 333 } 334 335 ~fs_visitor() 336 { 337 talloc_free(this->mem_ctx); 338 hash_table_dtor(this->variable_ht); 339 } 340 341 fs_reg *variable_storage(ir_variable *var); 342 int virtual_grf_alloc(int size); 343 344 void visit(ir_variable *ir); 345 void visit(ir_assignment *ir); 346 void visit(ir_dereference_variable *ir); 347 void visit(ir_dereference_record *ir); 348 void visit(ir_dereference_array *ir); 349 void visit(ir_expression *ir); 350 void visit(ir_texture *ir); 351 void visit(ir_if *ir); 352 void visit(ir_constant *ir); 353 void visit(ir_swizzle *ir); 354 void visit(ir_return *ir); 355 void visit(ir_loop *ir); 356 void visit(ir_loop_jump *ir); 357 void visit(ir_discard *ir); 358 void visit(ir_call *ir); 359 void visit(ir_function *ir); 360 void visit(ir_function_signature *ir); 361 362 fs_inst *emit(fs_inst inst); 363 void assign_curb_setup(); 364 void calculate_urb_setup(); 365 void assign_urb_setup(); 366 bool assign_regs(); 367 void assign_regs_trivial(); 368 int choose_spill_reg(struct ra_graph *g); 369 void spill_reg(int spill_reg); 370 void split_virtual_grfs(); 371 void calculate_live_intervals(); 372 bool propagate_constants(); 373 bool register_coalesce(); 374 bool compute_to_mrf(); 375 bool dead_code_eliminate(); 376 bool virtual_grf_interferes(int a, int b); 377 void generate_code(); 378 void generate_fb_write(fs_inst *inst); 379 void generate_linterp(fs_inst *inst, struct brw_reg dst, 380 struct brw_reg *src); 381 void generate_tex(fs_inst *inst, struct brw_reg dst); 382 void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); 383 void generate_discard_not(fs_inst *inst, struct brw_reg temp); 384 void generate_discard_and(fs_inst *inst, struct brw_reg temp); 385 void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 386 void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 387 void generate_spill(fs_inst *inst, struct brw_reg src); 388 void generate_unspill(fs_inst *inst, struct brw_reg dst); 389 390 void emit_dummy_fs(); 391 fs_reg *emit_fragcoord_interpolation(ir_variable *ir); 392 fs_reg *emit_frontfacing_interpolation(ir_variable *ir); 393 fs_reg *emit_general_interpolation(ir_variable *ir); 394 void emit_interpolation_setup_gen4(); 395 void emit_interpolation_setup_gen6(); 396 fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate); 397 fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate); 398 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0); 399 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1); 400 void emit_bool_to_cond_code(ir_rvalue *condition); 401 void emit_if_gen6(ir_if *ir); 402 void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset); 403 404 void emit_fb_writes(); 405 void emit_assignment_writes(fs_reg &l, fs_reg &r, 406 const glsl_type *type, bool predicated); 407 408 struct brw_reg interp_reg(int location, int channel); 409 int setup_uniform_values(int loc, const glsl_type *type); 410 void setup_builtin_uniform_values(ir_variable *ir); 411 412 struct brw_context *brw; 413 const struct gl_fragment_program *fp; 414 struct intel_context *intel; 415 struct gl_context *ctx; 416 struct brw_wm_compile *c; 417 struct brw_compile *p; 418 struct brw_shader *shader; 419 void *mem_ctx; 420 exec_list instructions; 421 422 int *virtual_grf_sizes; 423 int virtual_grf_next; 424 int virtual_grf_array_size; 425 int *virtual_grf_def; 426 int *virtual_grf_use; 427 428 struct hash_table *variable_ht; 429 ir_variable *frag_color, *frag_data, *frag_depth; 430 int first_non_payload_grf; 431 int urb_setup[FRAG_ATTRIB_MAX]; 432 bool kill_emitted; 433 434 /** @{ debug annotation info */ 435 const char *current_annotation; 436 ir_instruction *base_ir; 437 const char **annotation_string; 438 ir_instruction **annotation_ir; 439 /** @} */ 440 441 bool fail; 442 443 /* Result of last visit() method. */ 444 fs_reg result; 445 446 fs_reg pixel_x; 447 fs_reg pixel_y; 448 fs_reg wpos_w; 449 fs_reg pixel_w; 450 fs_reg delta_x; 451 fs_reg delta_y; 452 453 int grf_used; 454}; 455 456static const fs_reg reg_undef; 457static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F); 458static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D); 459 460GLboolean brw_do_channel_expressions(struct exec_list *instructions); 461GLboolean brw_do_vector_splitting(struct exec_list *instructions); 462