Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 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 |
||
25 | * |
||
26 | */ |
||
27 | |||
28 | #pragma once |
||
29 | |||
30 | #include "brw_shader.h" |
||
31 | |||
32 | extern "C" { |
||
33 | |||
34 | #include |
||
35 | |||
36 | #include "main/macros.h" |
||
37 | #include "main/shaderobj.h" |
||
38 | #include "main/uniforms.h" |
||
39 | #include "program/prog_parameter.h" |
||
40 | #include "program/prog_print.h" |
||
41 | #include "program/prog_optimize.h" |
||
42 | #include "program/register_allocate.h" |
||
43 | #include "program/sampler.h" |
||
44 | #include "program/hash_table.h" |
||
45 | #include "brw_context.h" |
||
46 | #include "brw_eu.h" |
||
47 | #include "brw_wm.h" |
||
48 | #include "brw_shader.h" |
||
49 | } |
||
50 | #include "glsl/glsl_types.h" |
||
51 | #include "glsl/ir.h" |
||
52 | |||
53 | class bblock_t; |
||
54 | namespace { |
||
55 | struct acp_entry; |
||
56 | } |
||
57 | |||
58 | class fs_reg { |
||
59 | public: |
||
60 | /* Callers of this ralloc-based new need not call delete. It's |
||
61 | * easier to just ralloc_free 'ctx' (or any of its ancestors). */ |
||
62 | static void* operator new(size_t size, void *ctx) |
||
63 | { |
||
64 | void *node; |
||
65 | |||
66 | node = ralloc_size(ctx, size); |
||
67 | assert(node != NULL); |
||
68 | |||
69 | return node; |
||
70 | } |
||
71 | |||
72 | void init(); |
||
73 | |||
74 | fs_reg(); |
||
75 | fs_reg(float f); |
||
76 | fs_reg(int32_t i); |
||
77 | fs_reg(uint32_t u); |
||
78 | fs_reg(struct brw_reg fixed_hw_reg); |
||
79 | fs_reg(enum register_file file, int reg); |
||
80 | fs_reg(enum register_file file, int reg, uint32_t type); |
||
81 | fs_reg(class fs_visitor *v, const struct glsl_type *type); |
||
82 | |||
83 | bool equals(const fs_reg &r) const; |
||
84 | bool is_zero() const; |
||
85 | bool is_one() const; |
||
86 | bool is_valid_3src() const; |
||
87 | |||
88 | /** Register file: ARF, GRF, MRF, IMM. */ |
||
89 | enum register_file file; |
||
90 | /** |
||
91 | * Register number. For ARF/MRF, it's the hardware register. For |
||
92 | * GRF, it's a virtual register number until register allocation |
||
93 | */ |
||
94 | int reg; |
||
95 | /** |
||
96 | * For virtual registers, this is a hardware register offset from |
||
97 | * the start of the register block (for example, a constant index |
||
98 | * in an array access). |
||
99 | */ |
||
100 | int reg_offset; |
||
101 | /** Register type. BRW_REGISTER_TYPE_* */ |
||
102 | int type; |
||
103 | bool negate; |
||
104 | bool abs; |
||
105 | bool sechalf; |
||
106 | struct brw_reg fixed_hw_reg; |
||
107 | int smear; /* -1, or a channel of the reg to smear to all channels. */ |
||
108 | |||
109 | /** Value for file == IMM */ |
||
110 | union { |
||
111 | int32_t i; |
||
112 | uint32_t u; |
||
113 | float f; |
||
114 | } imm; |
||
115 | |||
116 | fs_reg *reladdr; |
||
117 | }; |
||
118 | |||
119 | static const fs_reg reg_undef; |
||
120 | static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F); |
||
121 | static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D); |
||
122 | |||
123 | class ip_record : public exec_node { |
||
124 | public: |
||
125 | static void* operator new(size_t size, void *ctx) |
||
126 | { |
||
127 | void *node; |
||
128 | |||
129 | node = rzalloc_size(ctx, size); |
||
130 | assert(node != NULL); |
||
131 | |||
132 | return node; |
||
133 | } |
||
134 | |||
135 | ip_record(int ip) |
||
136 | { |
||
137 | this->ip = ip; |
||
138 | } |
||
139 | |||
140 | int ip; |
||
141 | }; |
||
142 | |||
143 | class fs_inst : public backend_instruction { |
||
144 | public: |
||
145 | /* Callers of this ralloc-based new need not call delete. It's |
||
146 | * easier to just ralloc_free 'ctx' (or any of its ancestors). */ |
||
147 | static void* operator new(size_t size, void *ctx) |
||
148 | { |
||
149 | void *node; |
||
150 | |||
151 | node = rzalloc_size(ctx, size); |
||
152 | assert(node != NULL); |
||
153 | |||
154 | return node; |
||
155 | } |
||
156 | |||
157 | void init(); |
||
158 | |||
159 | fs_inst(); |
||
160 | fs_inst(enum opcode opcode); |
||
161 | fs_inst(enum opcode opcode, fs_reg dst); |
||
162 | fs_inst(enum opcode opcode, fs_reg dst, fs_reg src0); |
||
163 | fs_inst(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1); |
||
164 | fs_inst(enum opcode opcode, fs_reg dst, |
||
165 | fs_reg src0, fs_reg src1,fs_reg src2); |
||
166 | |||
167 | bool equals(fs_inst *inst); |
||
168 | bool overwrites_reg(const fs_reg ®); |
||
169 | bool is_send_from_grf(); |
||
170 | bool is_partial_write(); |
||
171 | |||
172 | fs_reg dst; |
||
173 | fs_reg src[3]; |
||
174 | bool saturate; |
||
175 | int conditional_mod; /**< BRW_CONDITIONAL_* */ |
||
176 | |||
177 | /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional |
||
178 | * mod and predication. |
||
179 | */ |
||
180 | uint8_t flag_subreg; |
||
181 | |||
182 | int mlen; /**< SEND message length */ |
||
183 | int regs_written; /**< Number of vgrfs written by a SEND message, or 1 */ |
||
184 | int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ |
||
185 | uint32_t texture_offset; /**< Texture offset bitfield */ |
||
186 | int sampler; |
||
187 | int target; /**< MRT target. */ |
||
188 | bool eot; |
||
189 | bool header_present; |
||
190 | bool shadow_compare; |
||
191 | bool force_uncompressed; |
||
192 | bool force_sechalf; |
||
193 | bool force_writemask_all; |
||
194 | uint32_t offset; /* spill/unspill offset */ |
||
195 | |||
196 | /** @{ |
||
197 | * Annotation for the generated IR. One of the two can be set. |
||
198 | */ |
||
199 | const void *ir; |
||
200 | const char *annotation; |
||
201 | /** @} */ |
||
202 | }; |
||
203 | |||
204 | /** |
||
205 | * The fragment shader front-end. |
||
206 | * |
||
207 | * Translates either GLSL IR or Mesa IR (for ARB_fragment_program) into FS IR. |
||
208 | */ |
||
209 | class fs_visitor : public backend_visitor |
||
210 | { |
||
211 | public: |
||
212 | |||
213 | fs_visitor(struct brw_context *brw, |
||
214 | struct brw_wm_compile *c, |
||
215 | struct gl_shader_program *shader_prog, |
||
216 | struct gl_fragment_program *fp, |
||
217 | unsigned dispatch_width); |
||
218 | ~fs_visitor(); |
||
219 | |||
220 | fs_reg *variable_storage(ir_variable *var); |
||
221 | int virtual_grf_alloc(int size); |
||
222 | void import_uniforms(fs_visitor *v); |
||
223 | |||
224 | void visit(ir_variable *ir); |
||
225 | void visit(ir_assignment *ir); |
||
226 | void visit(ir_dereference_variable *ir); |
||
227 | void visit(ir_dereference_record *ir); |
||
228 | void visit(ir_dereference_array *ir); |
||
229 | void visit(ir_expression *ir); |
||
230 | void visit(ir_texture *ir); |
||
231 | void visit(ir_if *ir); |
||
232 | void visit(ir_constant *ir); |
||
233 | void visit(ir_swizzle *ir); |
||
234 | void visit(ir_return *ir); |
||
235 | void visit(ir_loop *ir); |
||
236 | void visit(ir_loop_jump *ir); |
||
237 | void visit(ir_discard *ir); |
||
238 | void visit(ir_call *ir); |
||
239 | void visit(ir_function *ir); |
||
240 | void visit(ir_function_signature *ir); |
||
241 | |||
242 | void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler); |
||
243 | |||
244 | bool can_do_source_mods(fs_inst *inst); |
||
245 | |||
246 | fs_inst *emit(fs_inst inst); |
||
247 | fs_inst *emit(fs_inst *inst); |
||
248 | void emit(exec_list list); |
||
249 | |||
250 | fs_inst *emit(enum opcode opcode); |
||
251 | fs_inst *emit(enum opcode opcode, fs_reg dst); |
||
252 | fs_inst *emit(enum opcode opcode, fs_reg dst, fs_reg src0); |
||
253 | fs_inst *emit(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1); |
||
254 | fs_inst *emit(enum opcode opcode, fs_reg dst, |
||
255 | fs_reg src0, fs_reg src1, fs_reg src2); |
||
256 | |||
257 | fs_inst *MOV(fs_reg dst, fs_reg src); |
||
258 | fs_inst *NOT(fs_reg dst, fs_reg src); |
||
259 | fs_inst *RNDD(fs_reg dst, fs_reg src); |
||
260 | fs_inst *RNDE(fs_reg dst, fs_reg src); |
||
261 | fs_inst *RNDZ(fs_reg dst, fs_reg src); |
||
262 | fs_inst *FRC(fs_reg dst, fs_reg src); |
||
263 | fs_inst *ADD(fs_reg dst, fs_reg src0, fs_reg src1); |
||
264 | fs_inst *MUL(fs_reg dst, fs_reg src0, fs_reg src1); |
||
265 | fs_inst *MACH(fs_reg dst, fs_reg src0, fs_reg src1); |
||
266 | fs_inst *MAC(fs_reg dst, fs_reg src0, fs_reg src1); |
||
267 | fs_inst *SHL(fs_reg dst, fs_reg src0, fs_reg src1); |
||
268 | fs_inst *SHR(fs_reg dst, fs_reg src0, fs_reg src1); |
||
269 | fs_inst *ASR(fs_reg dst, fs_reg src0, fs_reg src1); |
||
270 | fs_inst *AND(fs_reg dst, fs_reg src0, fs_reg src1); |
||
271 | fs_inst *OR(fs_reg dst, fs_reg src0, fs_reg src1); |
||
272 | fs_inst *XOR(fs_reg dst, fs_reg src0, fs_reg src1); |
||
273 | fs_inst *IF(uint32_t predicate); |
||
274 | fs_inst *IF(fs_reg src0, fs_reg src1, uint32_t condition); |
||
275 | fs_inst *CMP(fs_reg dst, fs_reg src0, fs_reg src1, |
||
276 | uint32_t condition); |
||
277 | fs_inst *LRP(fs_reg dst, fs_reg a, fs_reg y, fs_reg x); |
||
278 | fs_inst *DEP_RESOLVE_MOV(int grf); |
||
279 | fs_inst *BFREV(fs_reg dst, fs_reg value); |
||
280 | fs_inst *BFE(fs_reg dst, fs_reg bits, fs_reg offset, fs_reg value); |
||
281 | fs_inst *BFI1(fs_reg dst, fs_reg bits, fs_reg offset); |
||
282 | fs_inst *BFI2(fs_reg dst, fs_reg bfi1_dst, fs_reg insert, fs_reg base); |
||
283 | fs_inst *FBH(fs_reg dst, fs_reg value); |
||
284 | fs_inst *FBL(fs_reg dst, fs_reg value); |
||
285 | fs_inst *CBIT(fs_reg dst, fs_reg value); |
||
286 | |||
287 | int type_size(const struct glsl_type *type); |
||
288 | fs_inst *get_instruction_generating_reg(fs_inst *start, |
||
289 | fs_inst *end, |
||
290 | fs_reg reg); |
||
291 | |||
292 | exec_list VARYING_PULL_CONSTANT_LOAD(fs_reg dst, fs_reg surf_index, |
||
293 | fs_reg varying_offset, |
||
294 | uint32_t const_offset); |
||
295 | |||
296 | bool run(); |
||
297 | void setup_payload_gen4(); |
||
298 | void setup_payload_gen6(); |
||
299 | void assign_curb_setup(); |
||
300 | void calculate_urb_setup(); |
||
301 | void assign_urb_setup(); |
||
302 | bool assign_regs(); |
||
303 | void assign_regs_trivial(); |
||
304 | void setup_payload_interference(struct ra_graph *g, int payload_reg_count, |
||
305 | int first_payload_node); |
||
306 | void setup_mrf_hack_interference(struct ra_graph *g, |
||
307 | int first_mrf_hack_node); |
||
308 | int choose_spill_reg(struct ra_graph *g); |
||
309 | void spill_reg(int spill_reg); |
||
310 | void split_virtual_grfs(); |
||
311 | void compact_virtual_grfs(); |
||
312 | void move_uniform_array_access_to_pull_constants(); |
||
313 | void setup_pull_constants(); |
||
314 | void calculate_live_intervals(); |
||
315 | bool opt_algebraic(); |
||
316 | bool opt_cse(); |
||
317 | bool opt_cse_local(bblock_t *block, exec_list *aeb); |
||
318 | bool opt_copy_propagate(); |
||
319 | bool try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry); |
||
320 | bool try_constant_propagate(fs_inst *inst, acp_entry *entry); |
||
321 | bool opt_copy_propagate_local(void *mem_ctx, bblock_t *block, |
||
322 | exec_list *acp); |
||
323 | bool register_coalesce(); |
||
324 | bool register_coalesce_2(); |
||
325 | bool compute_to_mrf(); |
||
326 | bool dead_code_eliminate(); |
||
327 | bool dead_code_eliminate_local(); |
||
328 | bool remove_dead_constants(); |
||
329 | bool remove_duplicate_mrf_writes(); |
||
330 | bool virtual_grf_interferes(int a, int b); |
||
331 | void schedule_instructions(bool post_reg_alloc); |
||
332 | void insert_gen4_send_dependency_workarounds(); |
||
333 | void insert_gen4_pre_send_dependency_workarounds(fs_inst *inst); |
||
334 | void insert_gen4_post_send_dependency_workarounds(fs_inst *inst); |
||
335 | void fail(const char *msg, ...); |
||
336 | void lower_uniform_pull_constant_loads(); |
||
337 | |||
338 | void push_force_uncompressed(); |
||
339 | void pop_force_uncompressed(); |
||
340 | void push_force_sechalf(); |
||
341 | void pop_force_sechalf(); |
||
342 | |||
343 | void emit_dummy_fs(); |
||
344 | fs_reg *emit_fragcoord_interpolation(ir_variable *ir); |
||
345 | fs_inst *emit_linterp(const fs_reg &attr, const fs_reg &interp, |
||
346 | glsl_interp_qualifier interpolation_mode, |
||
347 | bool is_centroid); |
||
348 | fs_reg *emit_frontfacing_interpolation(ir_variable *ir); |
||
349 | fs_reg *emit_general_interpolation(ir_variable *ir); |
||
350 | void emit_interpolation_setup_gen4(); |
||
351 | void emit_interpolation_setup_gen6(); |
||
352 | fs_reg rescale_texcoord(ir_texture *ir, fs_reg coordinate, |
||
353 | bool is_rect, int sampler, int texunit); |
||
354 | fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, |
||
355 | fs_reg shadow_comp, fs_reg lod, fs_reg lod2); |
||
356 | fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, |
||
357 | fs_reg shadow_comp, fs_reg lod, fs_reg lod2, |
||
358 | fs_reg sample_index); |
||
359 | fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, |
||
360 | fs_reg shadow_comp, fs_reg lod, fs_reg lod2, |
||
361 | fs_reg sample_index); |
||
362 | fs_reg fix_math_operand(fs_reg src); |
||
363 | fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0); |
||
364 | fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1); |
||
365 | void emit_lrp(fs_reg dst, fs_reg x, fs_reg y, fs_reg a); |
||
366 | void emit_minmax(uint32_t conditionalmod, fs_reg dst, |
||
367 | fs_reg src0, fs_reg src1); |
||
368 | bool try_emit_saturate(ir_expression *ir); |
||
369 | bool try_emit_mad(ir_expression *ir, int mul_arg); |
||
370 | void emit_bool_to_cond_code(ir_rvalue *condition); |
||
371 | void emit_if_gen6(ir_if *ir); |
||
372 | void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset); |
||
373 | |||
374 | void emit_fragment_program_code(); |
||
375 | void setup_fp_regs(); |
||
376 | fs_reg get_fp_src_reg(const prog_src_register *src); |
||
377 | fs_reg get_fp_dst_reg(const prog_dst_register *dst); |
||
378 | void emit_fp_alu1(enum opcode opcode, |
||
379 | const struct prog_instruction *fpi, |
||
380 | fs_reg dst, fs_reg src); |
||
381 | void emit_fp_alu2(enum opcode opcode, |
||
382 | const struct prog_instruction *fpi, |
||
383 | fs_reg dst, fs_reg src0, fs_reg src1); |
||
384 | void emit_fp_scalar_write(const struct prog_instruction *fpi, |
||
385 | fs_reg dst, fs_reg src); |
||
386 | void emit_fp_scalar_math(enum opcode opcode, |
||
387 | const struct prog_instruction *fpi, |
||
388 | fs_reg dst, fs_reg src); |
||
389 | |||
390 | void emit_fp_minmax(const struct prog_instruction *fpi, |
||
391 | fs_reg dst, fs_reg src0, fs_reg src1); |
||
392 | |||
393 | void emit_fp_sop(uint32_t conditional_mod, |
||
394 | const struct prog_instruction *fpi, |
||
395 | fs_reg dst, fs_reg src0, fs_reg src1, fs_reg one); |
||
396 | |||
397 | void emit_color_write(int target, int index, int first_color_mrf); |
||
4401 | Serge | 398 | void emit_alpha_test(); |
4358 | Serge | 399 | void emit_fb_writes(); |
400 | |||
401 | void emit_shader_time_begin(); |
||
402 | void emit_shader_time_end(); |
||
403 | void emit_shader_time_write(enum shader_time_shader_type type, |
||
404 | fs_reg value); |
||
405 | |||
406 | bool try_rewrite_rhs_to_dst(ir_assignment *ir, |
||
407 | fs_reg dst, |
||
408 | fs_reg src, |
||
409 | fs_inst *pre_rhs_inst, |
||
410 | fs_inst *last_rhs_inst); |
||
411 | void emit_assignment_writes(fs_reg &l, fs_reg &r, |
||
412 | const glsl_type *type, bool predicated); |
||
413 | void resolve_ud_negate(fs_reg *reg); |
||
414 | void resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg); |
||
415 | |||
416 | fs_reg get_timestamp(); |
||
417 | |||
418 | struct brw_reg interp_reg(int location, int channel); |
||
419 | void setup_uniform_values(ir_variable *ir); |
||
420 | void setup_builtin_uniform_values(ir_variable *ir); |
||
421 | int implied_mrf_writes(fs_inst *inst); |
||
422 | |||
423 | void dump_instruction(backend_instruction *inst); |
||
424 | |||
425 | struct gl_fragment_program *fp; |
||
426 | struct brw_wm_compile *c; |
||
427 | unsigned int sanity_param_count; |
||
428 | |||
429 | int param_size[MAX_UNIFORMS * 4]; |
||
430 | |||
431 | int *virtual_grf_sizes; |
||
432 | int virtual_grf_count; |
||
433 | int virtual_grf_array_size; |
||
434 | int *virtual_grf_start; |
||
435 | int *virtual_grf_end; |
||
436 | bool live_intervals_valid; |
||
437 | |||
438 | /* This is the map from UNIFORM hw_reg + reg_offset as generated by |
||
439 | * the visitor to the packed uniform number after |
||
440 | * remove_dead_constants() that represents the actual uploaded |
||
441 | * uniform index. |
||
442 | */ |
||
443 | int *params_remap; |
||
444 | int nr_params_remap; |
||
445 | |||
446 | struct hash_table *variable_ht; |
||
447 | fs_reg frag_depth; |
||
448 | fs_reg outputs[BRW_MAX_DRAW_BUFFERS]; |
||
449 | unsigned output_components[BRW_MAX_DRAW_BUFFERS]; |
||
450 | fs_reg dual_src_output; |
||
451 | int first_non_payload_grf; |
||
452 | /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */ |
||
453 | int max_grf; |
||
454 | int urb_setup[VARYING_SLOT_MAX]; |
||
455 | |||
456 | fs_reg *fp_temp_regs; |
||
457 | fs_reg *fp_input_regs; |
||
458 | |||
459 | /** @{ debug annotation info */ |
||
460 | const char *current_annotation; |
||
461 | const void *base_ir; |
||
462 | /** @} */ |
||
463 | |||
464 | bool failed; |
||
465 | char *fail_msg; |
||
466 | |||
467 | /* Result of last visit() method. */ |
||
468 | fs_reg result; |
||
469 | |||
470 | fs_reg pixel_x; |
||
471 | fs_reg pixel_y; |
||
472 | fs_reg wpos_w; |
||
473 | fs_reg pixel_w; |
||
474 | fs_reg delta_x[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; |
||
475 | fs_reg delta_y[BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT]; |
||
476 | fs_reg shader_start_time; |
||
477 | |||
478 | int grf_used; |
||
479 | |||
480 | const unsigned dispatch_width; /**< 8 or 16 */ |
||
481 | |||
482 | int force_uncompressed_stack; |
||
483 | int force_sechalf_stack; |
||
484 | }; |
||
485 | |||
486 | /** |
||
487 | * The fragment shader code generator. |
||
488 | * |
||
489 | * Translates FS IR to actual i965 assembly code. |
||
490 | */ |
||
491 | class fs_generator |
||
492 | { |
||
493 | public: |
||
494 | fs_generator(struct brw_context *brw, |
||
495 | struct brw_wm_compile *c, |
||
496 | struct gl_shader_program *prog, |
||
497 | struct gl_fragment_program *fp, |
||
498 | bool dual_source_output); |
||
499 | ~fs_generator(); |
||
500 | |||
501 | const unsigned *generate_assembly(exec_list *simd8_instructions, |
||
502 | exec_list *simd16_instructions, |
||
503 | unsigned *assembly_size); |
||
504 | |||
505 | private: |
||
506 | void generate_code(exec_list *instructions); |
||
507 | void generate_fb_write(fs_inst *inst); |
||
508 | void generate_pixel_xy(struct brw_reg dst, bool is_x); |
||
509 | void generate_linterp(fs_inst *inst, struct brw_reg dst, |
||
510 | struct brw_reg *src); |
||
511 | void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src); |
||
512 | void generate_math1_gen7(fs_inst *inst, |
||
513 | struct brw_reg dst, |
||
514 | struct brw_reg src); |
||
515 | void generate_math2_gen7(fs_inst *inst, |
||
516 | struct brw_reg dst, |
||
517 | struct brw_reg src0, |
||
518 | struct brw_reg src1); |
||
519 | void generate_math1_gen6(fs_inst *inst, |
||
520 | struct brw_reg dst, |
||
521 | struct brw_reg src); |
||
522 | void generate_math2_gen6(fs_inst *inst, |
||
523 | struct brw_reg dst, |
||
524 | struct brw_reg src0, |
||
525 | struct brw_reg src1); |
||
526 | void generate_math_gen4(fs_inst *inst, |
||
527 | struct brw_reg dst, |
||
528 | struct brw_reg src); |
||
529 | void generate_math_g45(fs_inst *inst, |
||
530 | struct brw_reg dst, |
||
531 | struct brw_reg src); |
||
532 | void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); |
||
533 | void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src, |
||
534 | bool negate_value); |
||
535 | void generate_spill(fs_inst *inst, struct brw_reg src); |
||
536 | void generate_unspill(fs_inst *inst, struct brw_reg dst); |
||
537 | void generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst, |
||
538 | struct brw_reg index, |
||
539 | struct brw_reg offset); |
||
540 | void generate_uniform_pull_constant_load_gen7(fs_inst *inst, |
||
541 | struct brw_reg dst, |
||
542 | struct brw_reg surf_index, |
||
543 | struct brw_reg offset); |
||
544 | void generate_varying_pull_constant_load(fs_inst *inst, struct brw_reg dst, |
||
545 | struct brw_reg index, |
||
546 | struct brw_reg offset); |
||
547 | void generate_varying_pull_constant_load_gen7(fs_inst *inst, |
||
548 | struct brw_reg dst, |
||
549 | struct brw_reg index, |
||
550 | struct brw_reg offset); |
||
551 | void generate_mov_dispatch_to_flags(fs_inst *inst); |
||
552 | void generate_set_simd4x2_offset(fs_inst *inst, |
||
553 | struct brw_reg dst, |
||
554 | struct brw_reg offset); |
||
555 | void generate_discard_jump(fs_inst *inst); |
||
556 | |||
557 | void generate_pack_half_2x16_split(fs_inst *inst, |
||
558 | struct brw_reg dst, |
||
559 | struct brw_reg x, |
||
560 | struct brw_reg y); |
||
561 | void generate_unpack_half_2x16_split(fs_inst *inst, |
||
562 | struct brw_reg dst, |
||
563 | struct brw_reg src); |
||
564 | |||
565 | void generate_shader_time_add(fs_inst *inst, |
||
566 | struct brw_reg payload, |
||
567 | struct brw_reg offset, |
||
568 | struct brw_reg value); |
||
569 | |||
570 | void patch_discard_jumps_to_fb_writes(); |
||
571 | |||
572 | struct brw_context *brw; |
||
573 | struct gl_context *ctx; |
||
574 | |||
575 | struct brw_compile *p; |
||
576 | struct brw_wm_compile *c; |
||
577 | |||
578 | struct gl_shader_program *prog; |
||
579 | struct gl_shader *shader; |
||
580 | const struct gl_fragment_program *fp; |
||
581 | |||
582 | unsigned dispatch_width; /**< 8 or 16 */ |
||
583 | |||
584 | exec_list discard_halt_patches; |
||
585 | bool dual_source_output; |
||
586 | void *mem_ctx; |
||
587 | }; |
||
588 | |||
589 | bool brw_do_channel_expressions(struct exec_list *instructions); |
||
590 | bool brw_do_vector_splitting(struct exec_list *instructions); |
||
591 | bool brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog);>>>>>>>> |