2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "brw_defines.h"
34 #include "brw_context.h"
41 /***********************************************************************
46 static void alloc_regs( struct brw_sf_compile
*c
)
50 /* Values computed by fixed function unit:
52 c
->pv
= retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD
);
53 c
->det
= brw_vec1_grf(1, 2);
54 c
->dx0
= brw_vec1_grf(1, 3);
55 c
->dx2
= brw_vec1_grf(1, 4);
56 c
->dy0
= brw_vec1_grf(1, 5);
57 c
->dy2
= brw_vec1_grf(1, 6);
59 /* z and 1/w passed in seperately:
61 c
->z
[0] = brw_vec1_grf(2, 0);
62 c
->inv_w
[0] = brw_vec1_grf(2, 1);
63 c
->z
[1] = brw_vec1_grf(2, 2);
64 c
->inv_w
[1] = brw_vec1_grf(2, 3);
65 c
->z
[2] = brw_vec1_grf(2, 4);
66 c
->inv_w
[2] = brw_vec1_grf(2, 5);
71 for (i
= 0; i
< c
->nr_verts
; i
++) {
72 c
->vert
[i
] = brw_vec8_grf(reg
, 0);
73 reg
+= c
->nr_attr_regs
;
76 /* Temporaries, allocated after last vertex reg.
78 c
->inv_det
= brw_vec1_grf(reg
, 0); reg
++;
79 c
->a1_sub_a0
= brw_vec8_grf(reg
, 0); reg
++;
80 c
->a2_sub_a0
= brw_vec8_grf(reg
, 0); reg
++;
81 c
->tmp
= brw_vec8_grf(reg
, 0); reg
++;
83 /* Note grf allocation:
85 c
->prog_data
.total_grf
= reg
;
88 /* Outputs of this program - interpolation coefficients for
91 c
->m1Cx
= brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, 1, 0);
92 c
->m2Cy
= brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, 2, 0);
93 c
->m3C0
= brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, 3, 0);
97 static void copy_z_inv_w( struct brw_sf_compile
*c
)
99 struct brw_compile
*p
= &c
->func
;
102 brw_push_insn_state(p
);
104 /* Copy both scalars with a single MOV:
106 for (i
= 0; i
< c
->nr_verts
; i
++)
107 brw_MOV(p
, vec2(suboffset(c
->vert
[i
], 2)), vec2(c
->z
[i
]));
109 brw_pop_insn_state(p
);
113 static void invert_det( struct brw_sf_compile
*c
)
117 BRW_MATH_FUNCTION_INV
,
118 BRW_MATH_SATURATE_NONE
,
121 BRW_MATH_DATA_SCALAR
,
122 BRW_MATH_PRECISION_FULL
);
126 #define NON_PERPECTIVE_ATTRS (FRAG_BIT_WPOS | \
130 static boolean
calculate_masks( struct brw_sf_compile
*c
,
136 boolean is_last_attr
= (reg
== c
->nr_setup_regs
- 1);
137 unsigned persp_mask
= c
->key
.persp_mask
;
138 unsigned linear_mask
= c
->key
.linear_mask
;
140 debug_printf("persp_mask: %x\n", persp_mask
);
141 debug_printf("linear_mask: %x\n", linear_mask
);
147 if (persp_mask
& (1 << (reg
*2)))
150 if (linear_mask
& (1 << (reg
*2)))
153 /* Maybe only processs one attribute on the final round:
155 if (reg
*2+1 < c
->nr_setup_attrs
) {
158 if (persp_mask
& (1 << (reg
*2+1)))
161 if (linear_mask
& (1 << (reg
*2+1)))
165 debug_printf("pc: %x\n", *pc
);
166 debug_printf("pc_persp: %x\n", *pc_persp
);
167 debug_printf("pc_linear: %x\n", *pc_linear
);
175 void brw_emit_tri_setup( struct brw_sf_compile
*c
)
177 struct brw_compile
*p
= &c
->func
;
180 debug_printf("%s START ==============\n", __FUNCTION__
);
188 for (i
= 0; i
< c
->nr_setup_regs
; i
++)
190 /* Pair of incoming attributes:
192 struct brw_reg a0
= offset(c
->vert
[0], i
);
193 struct brw_reg a1
= offset(c
->vert
[1], i
);
194 struct brw_reg a2
= offset(c
->vert
[2], i
);
195 ushort pc
= 0, pc_persp
= 0, pc_linear
= 0;
196 boolean last
= calculate_masks(c
, i
, &pc
, &pc_persp
, &pc_linear
);
200 brw_set_predicate_control_flag_value(p
, pc_persp
);
201 brw_MUL(p
, a0
, a0
, c
->inv_w
[0]);
202 brw_MUL(p
, a1
, a1
, c
->inv_w
[1]);
203 brw_MUL(p
, a2
, a2
, c
->inv_w
[2]);
207 /* Calculate coefficients for interpolated values:
211 brw_set_predicate_control_flag_value(p
, pc_linear
);
213 brw_ADD(p
, c
->a1_sub_a0
, a1
, negate(a0
));
214 brw_ADD(p
, c
->a2_sub_a0
, a2
, negate(a0
));
218 brw_MUL(p
, brw_null_reg(), c
->a1_sub_a0
, c
->dy2
);
219 brw_MAC(p
, c
->tmp
, c
->a2_sub_a0
, negate(c
->dy0
));
220 brw_MUL(p
, c
->m1Cx
, c
->tmp
, c
->inv_det
);
224 brw_MUL(p
, brw_null_reg(), c
->a2_sub_a0
, c
->dx0
);
225 brw_MAC(p
, c
->tmp
, c
->a1_sub_a0
, negate(c
->dx2
));
226 brw_MUL(p
, c
->m2Cy
, c
->tmp
, c
->inv_det
);
230 brw_set_predicate_control_flag_value(p
, pc
);
231 /* start point for interpolation
233 brw_MOV(p
, c
->m3C0
, a0
);
235 /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
236 * the send instruction:
241 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
245 0, /* response len */
247 last
, /* writes complete */
249 BRW_URB_SWIZZLE_TRANSPOSE
); /* XXX: Swizzle control "SF to windower" */
253 debug_printf("%s DONE ==============\n", __FUNCTION__
);
259 void brw_emit_line_setup( struct brw_sf_compile
*c
)
261 struct brw_compile
*p
= &c
->func
;
270 for (i
= 0; i
< c
->nr_setup_regs
; i
++)
272 /* Pair of incoming attributes:
274 struct brw_reg a0
= offset(c
->vert
[0], i
);
275 struct brw_reg a1
= offset(c
->vert
[1], i
);
276 ushort pc
, pc_persp
, pc_linear
;
277 boolean last
= calculate_masks(c
, i
, &pc
, &pc_persp
, &pc_linear
);
281 brw_set_predicate_control_flag_value(p
, pc_persp
);
282 brw_MUL(p
, a0
, a0
, c
->inv_w
[0]);
283 brw_MUL(p
, a1
, a1
, c
->inv_w
[1]);
286 /* Calculate coefficients for position, color:
289 brw_set_predicate_control_flag_value(p
, pc_linear
);
291 brw_ADD(p
, c
->a1_sub_a0
, a1
, negate(a0
));
293 brw_MUL(p
, c
->tmp
, c
->a1_sub_a0
, c
->dx0
);
294 brw_MUL(p
, c
->m1Cx
, c
->tmp
, c
->inv_det
);
296 brw_MUL(p
, c
->tmp
, c
->a1_sub_a0
, c
->dy0
);
297 brw_MUL(p
, c
->m2Cy
, c
->tmp
, c
->inv_det
);
301 brw_set_predicate_control_flag_value(p
, pc
);
303 /* start point for interpolation
305 brw_MOV(p
, c
->m3C0
, a0
);
307 /* Copy m0..m3 to URB.
316 0, /* response len */
318 last
, /* writes complete */
319 i
*4, /* urb destination offset */
320 BRW_URB_SWIZZLE_TRANSPOSE
);
326 /* Points setup - several simplifications as all attributes are
327 * constant across the face of the point (point sprites excluded!)
329 void brw_emit_point_setup( struct brw_sf_compile
*c
)
331 struct brw_compile
*p
= &c
->func
;
338 brw_MOV(p
, c
->m1Cx
, brw_imm_ud(0)); /* zero - move out of loop */
339 brw_MOV(p
, c
->m2Cy
, brw_imm_ud(0)); /* zero - move out of loop */
341 for (i
= 0; i
< c
->nr_setup_regs
; i
++)
343 struct brw_reg a0
= offset(c
->vert
[0], i
);
344 ushort pc
, pc_persp
, pc_linear
;
345 boolean last
= calculate_masks(c
, i
, &pc
, &pc_persp
, &pc_linear
);
349 /* This seems odd as the values are all constant, but the
350 * fragment shader will be expecting it:
352 brw_set_predicate_control_flag_value(p
, pc_persp
);
353 brw_MUL(p
, a0
, a0
, c
->inv_w
[0]);
357 /* The delta values are always zero, just send the starting
358 * coordinate. Again, this is to fit in with the interpolation
359 * code in the fragment shader.
362 brw_set_predicate_control_flag_value(p
, pc
);
364 brw_MOV(p
, c
->m3C0
, a0
); /* constant value */
366 /* Copy m0..m3 to URB.
375 0, /* response len */
377 last
, /* writes complete */
378 i
*4, /* urb destination offset */
379 BRW_URB_SWIZZLE_TRANSPOSE
);