brw_fs.h revision d5599c0b6a22cd0bbc475ec715824660144d02a0
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 if (dst.file == GRF) 218 assert(dst.reg_offset >= 0); 219 } 220 221 fs_inst(int opcode, fs_reg dst, fs_reg src0) 222 { 223 init(); 224 this->opcode = opcode; 225 this->dst = dst; 226 this->src[0] = src0; 227 228 if (dst.file == GRF) 229 assert(dst.reg_offset >= 0); 230 if (src[0].file == GRF) 231 assert(src[0].reg_offset >= 0); 232 } 233 234 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1) 235 { 236 init(); 237 this->opcode = opcode; 238 this->dst = dst; 239 this->src[0] = src0; 240 this->src[1] = src1; 241 242 if (dst.file == GRF) 243 assert(dst.reg_offset >= 0); 244 if (src[0].file == GRF) 245 assert(src[0].reg_offset >= 0); 246 if (src[1].file == GRF) 247 assert(src[1].reg_offset >= 0); 248 } 249 250 fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1, fs_reg src2) 251 { 252 init(); 253 this->opcode = opcode; 254 this->dst = dst; 255 this->src[0] = src0; 256 this->src[1] = src1; 257 this->src[2] = src2; 258 259 if (dst.file == GRF) 260 assert(dst.reg_offset >= 0); 261 if (src[0].file == GRF) 262 assert(src[0].reg_offset >= 0); 263 if (src[1].file == GRF) 264 assert(src[1].reg_offset >= 0); 265 if (src[2].file == GRF) 266 assert(src[2].reg_offset >= 0); 267 } 268 269 int opcode; /* BRW_OPCODE_* or FS_OPCODE_* */ 270 fs_reg dst; 271 fs_reg src[3]; 272 bool saturate; 273 bool predicated; 274 int conditional_mod; /**< BRW_CONDITIONAL_* */ 275 276 int mlen; /**< SEND message length */ 277 int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ 278 int sampler; 279 int target; /**< MRT target. */ 280 bool eot; 281 bool header_present; 282 bool shadow_compare; 283 284 /** @{ 285 * Annotation for the generated IR. One of the two can be set. 286 */ 287 ir_instruction *ir; 288 const char *annotation; 289 /** @} */ 290}; 291 292class fs_visitor : public ir_visitor 293{ 294public: 295 296 fs_visitor(struct brw_wm_compile *c, struct brw_shader *shader) 297 { 298 this->c = c; 299 this->p = &c->func; 300 this->brw = p->brw; 301 this->fp = brw->fragment_program; 302 this->intel = &brw->intel; 303 this->ctx = &intel->ctx; 304 this->mem_ctx = talloc_new(NULL); 305 this->shader = shader; 306 this->fail = false; 307 this->variable_ht = hash_table_ctor(0, 308 hash_table_pointer_hash, 309 hash_table_pointer_compare); 310 311 this->frag_color = NULL; 312 this->frag_data = NULL; 313 this->frag_depth = NULL; 314 this->first_non_payload_grf = 0; 315 316 this->current_annotation = NULL; 317 this->annotation_string = NULL; 318 this->annotation_ir = NULL; 319 this->base_ir = NULL; 320 321 this->virtual_grf_sizes = NULL; 322 this->virtual_grf_next = 1; 323 this->virtual_grf_array_size = 0; 324 this->virtual_grf_def = NULL; 325 this->virtual_grf_use = NULL; 326 327 this->kill_emitted = false; 328 } 329 330 ~fs_visitor() 331 { 332 talloc_free(this->mem_ctx); 333 hash_table_dtor(this->variable_ht); 334 } 335 336 fs_reg *variable_storage(ir_variable *var); 337 int virtual_grf_alloc(int size); 338 339 void visit(ir_variable *ir); 340 void visit(ir_assignment *ir); 341 void visit(ir_dereference_variable *ir); 342 void visit(ir_dereference_record *ir); 343 void visit(ir_dereference_array *ir); 344 void visit(ir_expression *ir); 345 void visit(ir_texture *ir); 346 void visit(ir_if *ir); 347 void visit(ir_constant *ir); 348 void visit(ir_swizzle *ir); 349 void visit(ir_return *ir); 350 void visit(ir_loop *ir); 351 void visit(ir_loop_jump *ir); 352 void visit(ir_discard *ir); 353 void visit(ir_call *ir); 354 void visit(ir_function *ir); 355 void visit(ir_function_signature *ir); 356 357 fs_inst *emit(fs_inst inst); 358 void assign_curb_setup(); 359 void calculate_urb_setup(); 360 void assign_urb_setup(); 361 void assign_regs(); 362 void assign_regs_trivial(); 363 void split_virtual_grfs(); 364 void calculate_live_intervals(); 365 bool propagate_constants(); 366 bool register_coalesce(); 367 bool compute_to_mrf(); 368 bool dead_code_eliminate(); 369 bool virtual_grf_interferes(int a, int b); 370 void generate_code(); 371 void generate_fb_write(fs_inst *inst); 372 void generate_linterp(fs_inst *inst, struct brw_reg dst, 373 struct brw_reg *src); 374 void generate_tex(fs_inst *inst, struct brw_reg dst); 375 void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); 376 void generate_discard_not(fs_inst *inst, struct brw_reg temp); 377 void generate_discard_and(fs_inst *inst, struct brw_reg temp); 378 void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 379 void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src); 380 381 void emit_dummy_fs(); 382 fs_reg *emit_fragcoord_interpolation(ir_variable *ir); 383 fs_reg *emit_frontfacing_interpolation(ir_variable *ir); 384 fs_reg *emit_general_interpolation(ir_variable *ir); 385 void emit_interpolation_setup_gen4(); 386 void emit_interpolation_setup_gen6(); 387 fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate); 388 fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate); 389 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0); 390 fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1); 391 void emit_bool_to_cond_code(ir_rvalue *condition); 392 393 void emit_fb_writes(); 394 void emit_assignment_writes(fs_reg &l, fs_reg &r, 395 const glsl_type *type, bool predicated); 396 397 struct brw_reg interp_reg(int location, int channel); 398 int setup_uniform_values(int loc, const glsl_type *type); 399 void setup_builtin_uniform_values(ir_variable *ir); 400 401 struct brw_context *brw; 402 const struct gl_fragment_program *fp; 403 struct intel_context *intel; 404 struct gl_context *ctx; 405 struct brw_wm_compile *c; 406 struct brw_compile *p; 407 struct brw_shader *shader; 408 void *mem_ctx; 409 exec_list instructions; 410 411 int *virtual_grf_sizes; 412 int virtual_grf_next; 413 int virtual_grf_array_size; 414 int *virtual_grf_def; 415 int *virtual_grf_use; 416 417 struct hash_table *variable_ht; 418 ir_variable *frag_color, *frag_data, *frag_depth; 419 int first_non_payload_grf; 420 int urb_setup[FRAG_ATTRIB_MAX]; 421 bool kill_emitted; 422 423 /** @{ debug annotation info */ 424 const char *current_annotation; 425 ir_instruction *base_ir; 426 const char **annotation_string; 427 ir_instruction **annotation_ir; 428 /** @} */ 429 430 bool fail; 431 432 /* Result of last visit() method. */ 433 fs_reg result; 434 435 fs_reg pixel_x; 436 fs_reg pixel_y; 437 fs_reg wpos_w; 438 fs_reg pixel_w; 439 fs_reg delta_x; 440 fs_reg delta_y; 441 442 int grf_used; 443}; 444 445GLboolean brw_do_channel_expressions(struct exec_list *instructions); 446GLboolean brw_do_vector_splitting(struct exec_list *instructions); 447