Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 1 | /* |
| 2 | Copyright (C) Intel Corp. 2006. All Rights Reserved. |
| 3 | Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to |
| 4 | develop this 3D driver. |
| 5 | |
| 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: |
| 13 | |
| 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. |
| 17 | |
| 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. |
| 25 | |
| 26 | **********************************************************************/ |
| 27 | /* |
| 28 | * Authors: |
| 29 | * Keith Whitwell <keith@tungstengraphics.com> |
| 30 | */ |
| 31 | |
| 32 | |
Brian Paul | ecadb51 | 2008-09-18 15:17:05 -0600 | [diff] [blame] | 33 | #include "main/glheader.h" |
| 34 | #include "main/macros.h" |
| 35 | #include "main/enums.h" |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 36 | |
| 37 | #include "intel_batchbuffer.h" |
| 38 | |
| 39 | #include "brw_defines.h" |
| 40 | #include "brw_context.h" |
| 41 | #include "brw_eu.h" |
| 42 | #include "brw_util.h" |
| 43 | #include "brw_sf.h" |
| 44 | |
| 45 | |
| 46 | static struct brw_reg get_vert_attr(struct brw_sf_compile *c, |
| 47 | struct brw_reg vert, |
| 48 | GLuint attr) |
| 49 | { |
| 50 | GLuint off = c->attr_to_idx[attr] / 2; |
| 51 | GLuint sub = c->attr_to_idx[attr] % 2; |
| 52 | |
| 53 | return brw_vec4_grf(vert.nr + off, sub * 4); |
| 54 | } |
| 55 | |
| 56 | static GLboolean have_attr(struct brw_sf_compile *c, |
| 57 | GLuint attr) |
| 58 | { |
| 59 | return (c->key.attrs & (1<<attr)) ? 1 : 0; |
| 60 | } |
| 61 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 62 | /*********************************************************************** |
| 63 | * Twoside lighting |
| 64 | */ |
| 65 | static void copy_bfc( struct brw_sf_compile *c, |
| 66 | struct brw_reg vert ) |
| 67 | { |
| 68 | struct brw_compile *p = &c->func; |
| 69 | GLuint i; |
| 70 | |
| 71 | for (i = 0; i < 2; i++) { |
| 72 | if (have_attr(c, VERT_RESULT_COL0+i) && |
| 73 | have_attr(c, VERT_RESULT_BFC0+i)) |
| 74 | brw_MOV(p, |
| 75 | get_vert_attr(c, vert, VERT_RESULT_COL0+i), |
| 76 | get_vert_attr(c, vert, VERT_RESULT_BFC0+i)); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | |
| 81 | static void do_twoside_color( struct brw_sf_compile *c ) |
| 82 | { |
| 83 | struct brw_compile *p = &c->func; |
| 84 | struct brw_instruction *if_insn; |
| 85 | GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L; |
| 86 | |
| 87 | /* Already done in clip program: |
| 88 | */ |
| 89 | if (c->key.primitive == SF_UNFILLED_TRIS) |
| 90 | return; |
| 91 | |
| 92 | /* XXX: What happens if BFC isn't present? This could only happen |
| 93 | * for user-supplied vertex programs, as t_vp_build.c always does |
| 94 | * the right thing. |
| 95 | */ |
| 96 | if (!(have_attr(c, VERT_RESULT_COL0) && have_attr(c, VERT_RESULT_BFC0)) && |
| 97 | !(have_attr(c, VERT_RESULT_COL1) && have_attr(c, VERT_RESULT_BFC1))) |
| 98 | return; |
| 99 | |
| 100 | /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order |
| 101 | * to get all channels active inside the IF. In the clipping code |
| 102 | * we run with NoMask, so it's not an option and we can use |
| 103 | * BRW_EXECUTE_1 for all comparisions. |
| 104 | */ |
| 105 | brw_push_insn_state(p); |
| 106 | brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0)); |
| 107 | if_insn = brw_IF(p, BRW_EXECUTE_4); |
| 108 | { |
| 109 | switch (c->nr_verts) { |
| 110 | case 3: copy_bfc(c, c->vert[2]); |
| 111 | case 2: copy_bfc(c, c->vert[1]); |
| 112 | case 1: copy_bfc(c, c->vert[0]); |
| 113 | } |
| 114 | } |
| 115 | brw_ENDIF(p, if_insn); |
| 116 | brw_pop_insn_state(p); |
| 117 | } |
| 118 | |
| 119 | |
| 120 | |
| 121 | /*********************************************************************** |
| 122 | * Flat shading |
| 123 | */ |
| 124 | |
| 125 | #define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \ |
| 126 | (1<<VERT_RESULT_COL1)) |
| 127 | |
| 128 | static void copy_colors( struct brw_sf_compile *c, |
| 129 | struct brw_reg dst, |
| 130 | struct brw_reg src) |
| 131 | { |
| 132 | struct brw_compile *p = &c->func; |
| 133 | GLuint i; |
| 134 | |
| 135 | for (i = VERT_RESULT_COL0; i <= VERT_RESULT_COL1; i++) { |
| 136 | if (have_attr(c,i)) |
| 137 | brw_MOV(p, |
| 138 | get_vert_attr(c, dst, i), |
| 139 | get_vert_attr(c, src, i)); |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | |
| 144 | |
| 145 | /* Need to use a computed jump to copy flatshaded attributes as the |
| 146 | * vertices are ordered according to y-coordinate before reaching this |
| 147 | * point, so the PV could be anywhere. |
| 148 | */ |
| 149 | static void do_flatshade_triangle( struct brw_sf_compile *c ) |
| 150 | { |
| 151 | struct brw_compile *p = &c->func; |
| 152 | struct brw_reg ip = brw_ip_reg(); |
| 153 | GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS); |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 154 | GLuint jmpi = 1; |
| 155 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 156 | if (!nr) |
| 157 | return; |
| 158 | |
| 159 | /* Already done in clip program: |
| 160 | */ |
| 161 | if (c->key.primitive == SF_UNFILLED_TRIS) |
| 162 | return; |
| 163 | |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 164 | if (BRW_IS_IGDNG(p->brw)) |
| 165 | jmpi = 2; |
| 166 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 167 | brw_push_insn_state(p); |
| 168 | |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 169 | brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1))); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 170 | brw_JMPI(p, ip, ip, c->pv); |
| 171 | |
| 172 | copy_colors(c, c->vert[1], c->vert[0]); |
| 173 | copy_colors(c, c->vert[2], c->vert[0]); |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 174 | brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1))); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 175 | |
| 176 | copy_colors(c, c->vert[0], c->vert[1]); |
| 177 | copy_colors(c, c->vert[2], c->vert[1]); |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 178 | brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2)); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 179 | |
| 180 | copy_colors(c, c->vert[0], c->vert[2]); |
| 181 | copy_colors(c, c->vert[1], c->vert[2]); |
| 182 | |
| 183 | brw_pop_insn_state(p); |
| 184 | } |
| 185 | |
| 186 | |
| 187 | static void do_flatshade_line( struct brw_sf_compile *c ) |
| 188 | { |
| 189 | struct brw_compile *p = &c->func; |
| 190 | struct brw_reg ip = brw_ip_reg(); |
| 191 | GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS); |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 192 | GLuint jmpi = 1; |
| 193 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 194 | if (!nr) |
| 195 | return; |
| 196 | |
| 197 | /* Already done in clip program: |
| 198 | */ |
| 199 | if (c->key.primitive == SF_UNFILLED_TRIS) |
| 200 | return; |
| 201 | |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 202 | if (BRW_IS_IGDNG(p->brw)) |
| 203 | jmpi = 2; |
| 204 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 205 | brw_push_insn_state(p); |
| 206 | |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 207 | brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1))); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 208 | brw_JMPI(p, ip, ip, c->pv); |
| 209 | copy_colors(c, c->vert[1], c->vert[0]); |
| 210 | |
Xiang, Haihao | 2995bf0 | 2009-07-13 10:48:43 +0800 | [diff] [blame] | 211 | brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr)); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 212 | copy_colors(c, c->vert[0], c->vert[1]); |
| 213 | |
| 214 | brw_pop_insn_state(p); |
| 215 | } |
| 216 | |
| 217 | |
| 218 | |
| 219 | /*********************************************************************** |
| 220 | * Triangle setup. |
| 221 | */ |
| 222 | |
| 223 | |
| 224 | static void alloc_regs( struct brw_sf_compile *c ) |
| 225 | { |
| 226 | GLuint reg, i; |
| 227 | |
| 228 | /* Values computed by fixed function unit: |
| 229 | */ |
Xiang, Haihao | 7313799 | 2009-07-02 16:32:19 +0800 | [diff] [blame] | 230 | c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 231 | c->det = brw_vec1_grf(1, 2); |
| 232 | c->dx0 = brw_vec1_grf(1, 3); |
| 233 | c->dx2 = brw_vec1_grf(1, 4); |
| 234 | c->dy0 = brw_vec1_grf(1, 5); |
| 235 | c->dy2 = brw_vec1_grf(1, 6); |
| 236 | |
| 237 | /* z and 1/w passed in seperately: |
| 238 | */ |
| 239 | c->z[0] = brw_vec1_grf(2, 0); |
| 240 | c->inv_w[0] = brw_vec1_grf(2, 1); |
| 241 | c->z[1] = brw_vec1_grf(2, 2); |
| 242 | c->inv_w[1] = brw_vec1_grf(2, 3); |
| 243 | c->z[2] = brw_vec1_grf(2, 4); |
| 244 | c->inv_w[2] = brw_vec1_grf(2, 5); |
| 245 | |
| 246 | /* The vertices: |
| 247 | */ |
| 248 | reg = 3; |
| 249 | for (i = 0; i < c->nr_verts; i++) { |
| 250 | c->vert[i] = brw_vec8_grf(reg, 0); |
| 251 | reg += c->nr_attr_regs; |
| 252 | } |
| 253 | |
| 254 | /* Temporaries, allocated after last vertex reg. |
| 255 | */ |
| 256 | c->inv_det = brw_vec1_grf(reg, 0); reg++; |
| 257 | c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++; |
| 258 | c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++; |
| 259 | c->tmp = brw_vec8_grf(reg, 0); reg++; |
| 260 | |
| 261 | /* Note grf allocation: |
| 262 | */ |
| 263 | c->prog_data.total_grf = reg; |
| 264 | |
| 265 | |
| 266 | /* Outputs of this program - interpolation coefficients for |
| 267 | * rasterization: |
| 268 | */ |
| 269 | c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0); |
| 270 | c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0); |
| 271 | c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0); |
| 272 | } |
| 273 | |
| 274 | |
| 275 | static void copy_z_inv_w( struct brw_sf_compile *c ) |
| 276 | { |
| 277 | struct brw_compile *p = &c->func; |
| 278 | GLuint i; |
| 279 | |
| 280 | brw_push_insn_state(p); |
| 281 | |
| 282 | /* Copy both scalars with a single MOV: |
| 283 | */ |
| 284 | for (i = 0; i < c->nr_verts; i++) |
| 285 | brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i])); |
| 286 | |
| 287 | brw_pop_insn_state(p); |
| 288 | } |
| 289 | |
| 290 | |
| 291 | static void invert_det( struct brw_sf_compile *c) |
| 292 | { |
| 293 | /* Looks like we invert all 8 elements just to get 1/det in |
| 294 | * position 2 !?! |
| 295 | */ |
| 296 | brw_math(&c->func, |
| 297 | c->inv_det, |
| 298 | BRW_MATH_FUNCTION_INV, |
| 299 | BRW_MATH_SATURATE_NONE, |
| 300 | 0, |
| 301 | c->det, |
| 302 | BRW_MATH_DATA_SCALAR, |
| 303 | BRW_MATH_PRECISION_FULL); |
| 304 | |
| 305 | } |
| 306 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 307 | |
| 308 | static GLboolean calculate_masks( struct brw_sf_compile *c, |
| 309 | GLuint reg, |
| 310 | GLushort *pc, |
| 311 | GLushort *pc_persp, |
| 312 | GLushort *pc_linear) |
| 313 | { |
| 314 | GLboolean is_last_attr = (reg == c->nr_setup_regs - 1); |
Brian Paul | 18af7c3 | 2009-06-12 16:21:20 -0600 | [diff] [blame] | 315 | GLuint persp_mask; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 316 | GLuint linear_mask; |
| 317 | |
Brian Paul | 18af7c3 | 2009-06-12 16:21:20 -0600 | [diff] [blame] | 318 | if (c->key.do_flat_shading || c->key.linear_color) |
| 319 | persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS | |
| 320 | FRAG_BIT_COL0 | |
| 321 | FRAG_BIT_COL1); |
| 322 | else |
| 323 | persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS); |
| 324 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 325 | if (c->key.do_flat_shading) |
| 326 | linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1); |
| 327 | else |
| 328 | linear_mask = c->key.attrs; |
| 329 | |
| 330 | *pc_persp = 0; |
| 331 | *pc_linear = 0; |
| 332 | *pc = 0xf; |
| 333 | |
| 334 | if (persp_mask & (1 << c->idx_to_attr[reg*2])) |
| 335 | *pc_persp = 0xf; |
| 336 | |
| 337 | if (linear_mask & (1 << c->idx_to_attr[reg*2])) |
| 338 | *pc_linear = 0xf; |
| 339 | |
| 340 | /* Maybe only processs one attribute on the final round: |
| 341 | */ |
| 342 | if (reg*2+1 < c->nr_setup_attrs) { |
| 343 | *pc |= 0xf0; |
| 344 | |
| 345 | if (persp_mask & (1 << c->idx_to_attr[reg*2+1])) |
| 346 | *pc_persp |= 0xf0; |
| 347 | |
| 348 | if (linear_mask & (1 << c->idx_to_attr[reg*2+1])) |
| 349 | *pc_linear |= 0xf0; |
| 350 | } |
| 351 | |
| 352 | return is_last_attr; |
| 353 | } |
| 354 | |
| 355 | |
| 356 | |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 357 | void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 358 | { |
| 359 | struct brw_compile *p = &c->func; |
| 360 | GLuint i; |
| 361 | |
| 362 | c->nr_verts = 3; |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 363 | |
| 364 | if (allocate) |
| 365 | alloc_regs(c); |
| 366 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 367 | invert_det(c); |
| 368 | copy_z_inv_w(c); |
| 369 | |
| 370 | if (c->key.do_twoside_color) |
| 371 | do_twoside_color(c); |
| 372 | |
| 373 | if (c->key.do_flat_shading) |
| 374 | do_flatshade_triangle(c); |
| 375 | |
| 376 | |
| 377 | for (i = 0; i < c->nr_setup_regs; i++) |
| 378 | { |
| 379 | /* Pair of incoming attributes: |
| 380 | */ |
| 381 | struct brw_reg a0 = offset(c->vert[0], i); |
| 382 | struct brw_reg a1 = offset(c->vert[1], i); |
| 383 | struct brw_reg a2 = offset(c->vert[2], i); |
| 384 | GLushort pc, pc_persp, pc_linear; |
| 385 | GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); |
| 386 | |
| 387 | if (pc_persp) |
| 388 | { |
| 389 | brw_set_predicate_control_flag_value(p, pc_persp); |
| 390 | brw_MUL(p, a0, a0, c->inv_w[0]); |
| 391 | brw_MUL(p, a1, a1, c->inv_w[1]); |
| 392 | brw_MUL(p, a2, a2, c->inv_w[2]); |
| 393 | } |
| 394 | |
| 395 | |
| 396 | /* Calculate coefficients for interpolated values: |
| 397 | */ |
| 398 | if (pc_linear) |
| 399 | { |
| 400 | brw_set_predicate_control_flag_value(p, pc_linear); |
| 401 | |
| 402 | brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); |
| 403 | brw_ADD(p, c->a2_sub_a0, a2, negate(a0)); |
| 404 | |
| 405 | /* calculate dA/dx |
| 406 | */ |
| 407 | brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2); |
| 408 | brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0)); |
| 409 | brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); |
| 410 | |
| 411 | /* calculate dA/dy |
| 412 | */ |
| 413 | brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0); |
| 414 | brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2)); |
| 415 | brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); |
| 416 | } |
| 417 | |
| 418 | { |
| 419 | brw_set_predicate_control_flag_value(p, pc); |
| 420 | /* start point for interpolation |
| 421 | */ |
| 422 | brw_MOV(p, c->m3C0, a0); |
| 423 | |
| 424 | /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in |
| 425 | * the send instruction: |
| 426 | */ |
| 427 | brw_urb_WRITE(p, |
| 428 | brw_null_reg(), |
| 429 | 0, |
| 430 | brw_vec8_grf(0, 0), /* r0, will be copied to m0 */ |
| 431 | 0, /* allocate */ |
| 432 | 1, /* used */ |
| 433 | 4, /* msg len */ |
| 434 | 0, /* response len */ |
| 435 | last, /* eot */ |
| 436 | last, /* writes complete */ |
| 437 | i*4, /* offset */ |
| 438 | BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */ |
| 439 | } |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | |
| 444 | |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 445 | void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 446 | { |
| 447 | struct brw_compile *p = &c->func; |
| 448 | GLuint i; |
| 449 | |
| 450 | |
| 451 | c->nr_verts = 2; |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 452 | |
| 453 | if (allocate) |
| 454 | alloc_regs(c); |
| 455 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 456 | invert_det(c); |
| 457 | copy_z_inv_w(c); |
| 458 | |
| 459 | if (c->key.do_flat_shading) |
| 460 | do_flatshade_line(c); |
| 461 | |
| 462 | for (i = 0; i < c->nr_setup_regs; i++) |
| 463 | { |
| 464 | /* Pair of incoming attributes: |
| 465 | */ |
| 466 | struct brw_reg a0 = offset(c->vert[0], i); |
| 467 | struct brw_reg a1 = offset(c->vert[1], i); |
| 468 | GLushort pc, pc_persp, pc_linear; |
| 469 | GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); |
| 470 | |
| 471 | if (pc_persp) |
| 472 | { |
| 473 | brw_set_predicate_control_flag_value(p, pc_persp); |
| 474 | brw_MUL(p, a0, a0, c->inv_w[0]); |
| 475 | brw_MUL(p, a1, a1, c->inv_w[1]); |
| 476 | } |
| 477 | |
| 478 | /* Calculate coefficients for position, color: |
| 479 | */ |
| 480 | if (pc_linear) { |
| 481 | brw_set_predicate_control_flag_value(p, pc_linear); |
| 482 | |
| 483 | brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); |
| 484 | |
| 485 | brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0); |
| 486 | brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); |
| 487 | |
| 488 | brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0); |
| 489 | brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); |
| 490 | } |
| 491 | |
| 492 | { |
| 493 | brw_set_predicate_control_flag_value(p, pc); |
| 494 | |
| 495 | /* start point for interpolation |
| 496 | */ |
| 497 | brw_MOV(p, c->m3C0, a0); |
| 498 | |
| 499 | /* Copy m0..m3 to URB. |
| 500 | */ |
| 501 | brw_urb_WRITE(p, |
| 502 | brw_null_reg(), |
| 503 | 0, |
| 504 | brw_vec8_grf(0, 0), |
| 505 | 0, /* allocate */ |
| 506 | 1, /* used */ |
| 507 | 4, /* msg len */ |
| 508 | 0, /* response len */ |
| 509 | last, /* eot */ |
| 510 | last, /* writes complete */ |
| 511 | i*4, /* urb destination offset */ |
| 512 | BRW_URB_SWIZZLE_TRANSPOSE); |
| 513 | } |
| 514 | } |
| 515 | } |
| 516 | |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 517 | void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate) |
Zou Nan hai | 6017943 | 2007-07-30 10:18:11 +0800 | [diff] [blame] | 518 | { |
| 519 | struct brw_compile *p = &c->func; |
| 520 | GLuint i; |
| 521 | |
| 522 | c->nr_verts = 1; |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 523 | |
| 524 | if (allocate) |
| 525 | alloc_regs(c); |
| 526 | |
Zou Nan hai | 6017943 | 2007-07-30 10:18:11 +0800 | [diff] [blame] | 527 | copy_z_inv_w(c); |
| 528 | for (i = 0; i < c->nr_setup_regs; i++) |
| 529 | { |
| 530 | struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]]; |
| 531 | struct brw_reg a0 = offset(c->vert[0], i); |
| 532 | GLushort pc, pc_persp, pc_linear; |
| 533 | GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); |
| 534 | |
| 535 | if (pc_persp) |
| 536 | { |
| 537 | if (!tex->CoordReplace) { |
| 538 | brw_set_predicate_control_flag_value(p, pc_persp); |
| 539 | brw_MUL(p, a0, a0, c->inv_w[0]); |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | if (tex->CoordReplace) { |
| 544 | /* Caculate 1.0/PointWidth */ |
| 545 | brw_math(&c->func, |
| 546 | c->tmp, |
| 547 | BRW_MATH_FUNCTION_INV, |
| 548 | BRW_MATH_SATURATE_NONE, |
| 549 | 0, |
| 550 | c->dx0, |
| 551 | BRW_MATH_DATA_SCALAR, |
| 552 | BRW_MATH_PRECISION_FULL); |
| 553 | |
Brian Paul | 26d22b0 | 2009-10-29 16:02:35 -0600 | [diff] [blame] | 554 | if (c->key.sprite_origin_lower_left) { |
Zou Nan hai | 6017943 | 2007-07-30 10:18:11 +0800 | [diff] [blame] | 555 | brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); |
| 556 | brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); |
| 557 | brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0])); |
| 558 | brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); |
| 559 | } else { |
| 560 | brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); |
| 561 | brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); |
| 562 | brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]); |
| 563 | brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); |
| 564 | } |
| 565 | } else { |
| 566 | brw_MOV(p, c->m1Cx, brw_imm_ud(0)); |
| 567 | brw_MOV(p, c->m2Cy, brw_imm_ud(0)); |
| 568 | } |
| 569 | |
| 570 | { |
| 571 | brw_set_predicate_control_flag_value(p, pc); |
| 572 | if (tex->CoordReplace) { |
Brian Paul | 26d22b0 | 2009-10-29 16:02:35 -0600 | [diff] [blame] | 573 | if (c->key.sprite_origin_lower_left) { |
Zou Nan hai | 6017943 | 2007-07-30 10:18:11 +0800 | [diff] [blame] | 574 | brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0)); |
| 575 | brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0)); |
| 576 | } |
| 577 | else |
| 578 | brw_MOV(p, c->m3C0, brw_imm_f(0.0)); |
| 579 | } else { |
| 580 | brw_MOV(p, c->m3C0, a0); /* constant value */ |
| 581 | } |
| 582 | |
| 583 | /* Copy m0..m3 to URB. |
| 584 | */ |
| 585 | brw_urb_WRITE(p, |
| 586 | brw_null_reg(), |
| 587 | 0, |
| 588 | brw_vec8_grf(0, 0), |
| 589 | 0, /* allocate */ |
| 590 | 1, /* used */ |
| 591 | 4, /* msg len */ |
| 592 | 0, /* response len */ |
| 593 | last, /* eot */ |
| 594 | last, /* writes complete */ |
| 595 | i*4, /* urb destination offset */ |
| 596 | BRW_URB_SWIZZLE_TRANSPOSE); |
| 597 | } |
| 598 | } |
| 599 | } |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 600 | |
| 601 | /* Points setup - several simplifications as all attributes are |
| 602 | * constant across the face of the point (point sprites excluded!) |
| 603 | */ |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 604 | void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 605 | { |
| 606 | struct brw_compile *p = &c->func; |
| 607 | GLuint i; |
| 608 | |
| 609 | c->nr_verts = 1; |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 610 | |
| 611 | if (allocate) |
| 612 | alloc_regs(c); |
| 613 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 614 | copy_z_inv_w(c); |
| 615 | |
| 616 | brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */ |
| 617 | brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */ |
| 618 | |
| 619 | for (i = 0; i < c->nr_setup_regs; i++) |
| 620 | { |
| 621 | struct brw_reg a0 = offset(c->vert[0], i); |
| 622 | GLushort pc, pc_persp, pc_linear; |
| 623 | GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); |
| 624 | |
| 625 | if (pc_persp) |
| 626 | { |
| 627 | /* This seems odd as the values are all constant, but the |
| 628 | * fragment shader will be expecting it: |
| 629 | */ |
| 630 | brw_set_predicate_control_flag_value(p, pc_persp); |
| 631 | brw_MUL(p, a0, a0, c->inv_w[0]); |
| 632 | } |
| 633 | |
| 634 | |
| 635 | /* The delta values are always zero, just send the starting |
| 636 | * coordinate. Again, this is to fit in with the interpolation |
| 637 | * code in the fragment shader. |
| 638 | */ |
| 639 | { |
| 640 | brw_set_predicate_control_flag_value(p, pc); |
| 641 | |
| 642 | brw_MOV(p, c->m3C0, a0); /* constant value */ |
| 643 | |
| 644 | /* Copy m0..m3 to URB. |
| 645 | */ |
| 646 | brw_urb_WRITE(p, |
| 647 | brw_null_reg(), |
| 648 | 0, |
| 649 | brw_vec8_grf(0, 0), |
| 650 | 0, /* allocate */ |
| 651 | 1, /* used */ |
| 652 | 4, /* msg len */ |
| 653 | 0, /* response len */ |
| 654 | last, /* eot */ |
| 655 | last, /* writes complete */ |
| 656 | i*4, /* urb destination offset */ |
| 657 | BRW_URB_SWIZZLE_TRANSPOSE); |
| 658 | } |
| 659 | } |
| 660 | } |
| 661 | |
| 662 | void brw_emit_anyprim_setup( struct brw_sf_compile *c ) |
| 663 | { |
| 664 | struct brw_compile *p = &c->func; |
| 665 | struct brw_reg ip = brw_ip_reg(); |
| 666 | struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0); |
Zou Nan hai | 505453a | 2007-08-02 15:27:13 +0800 | [diff] [blame] | 667 | struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 668 | struct brw_reg primmask; |
| 669 | struct brw_instruction *jmp; |
| 670 | struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 671 | |
| 672 | GLuint saveflag; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 673 | |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 674 | c->nr_verts = 3; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 675 | alloc_regs(c); |
| 676 | |
| 677 | primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD); |
| 678 | |
| 679 | brw_MOV(p, primmask, brw_imm_ud(1)); |
| 680 | brw_SHL(p, primmask, primmask, payload_prim); |
| 681 | |
| 682 | brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); |
| 683 | brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) | |
| 684 | (1<<_3DPRIM_TRISTRIP) | |
| 685 | (1<<_3DPRIM_TRIFAN) | |
| 686 | (1<<_3DPRIM_TRISTRIP_REVERSE) | |
| 687 | (1<<_3DPRIM_POLYGON) | |
| 688 | (1<<_3DPRIM_RECTLIST) | |
| 689 | (1<<_3DPRIM_TRIFAN_NOSTIPPLE))); |
Xiang, Haihao | 7313799 | 2009-07-02 16:32:19 +0800 | [diff] [blame] | 690 | jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 691 | { |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 692 | saveflag = p->flag_value; |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 693 | brw_push_insn_state(p); |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 694 | brw_emit_tri_setup( c, GL_FALSE ); |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 695 | brw_pop_insn_state(p); |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 696 | p->flag_value = saveflag; |
| 697 | /* note - thread killed in subroutine, so must |
| 698 | * restore the flag which is changed when building |
| 699 | * the subroutine. fix #13240 |
| 700 | */ |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 701 | } |
| 702 | brw_land_fwd_jump(p, jmp); |
| 703 | |
| 704 | brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); |
| 705 | brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) | |
| 706 | (1<<_3DPRIM_LINESTRIP) | |
| 707 | (1<<_3DPRIM_LINELOOP) | |
| 708 | (1<<_3DPRIM_LINESTRIP_CONT) | |
| 709 | (1<<_3DPRIM_LINESTRIP_BF) | |
| 710 | (1<<_3DPRIM_LINESTRIP_CONT_BF))); |
Xiang, Haihao | 7313799 | 2009-07-02 16:32:19 +0800 | [diff] [blame] | 711 | jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 712 | { |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 713 | saveflag = p->flag_value; |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 714 | brw_push_insn_state(p); |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 715 | brw_emit_line_setup( c, GL_FALSE ); |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 716 | brw_pop_insn_state(p); |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 717 | p->flag_value = saveflag; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 718 | /* note - thread killed in subroutine */ |
| 719 | } |
| 720 | brw_land_fwd_jump(p, jmp); |
| 721 | |
Zou Nan hai | 505453a | 2007-08-02 15:27:13 +0800 | [diff] [blame] | 722 | brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); |
| 723 | brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE)); |
Xiang, Haihao | 7313799 | 2009-07-02 16:32:19 +0800 | [diff] [blame] | 724 | jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); |
Zou Nan hai | 505453a | 2007-08-02 15:27:13 +0800 | [diff] [blame] | 725 | { |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 726 | saveflag = p->flag_value; |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 727 | brw_push_insn_state(p); |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 728 | brw_emit_point_sprite_setup( c, GL_FALSE ); |
Xiang, Haihao | ae078e1 | 2007-09-12 15:13:06 +0800 | [diff] [blame] | 729 | brw_pop_insn_state(p); |
Xiang, Haihao | e3a1ae0 | 2007-12-19 09:59:37 +0800 | [diff] [blame] | 730 | p->flag_value = saveflag; |
Zou Nan hai | 505453a | 2007-08-02 15:27:13 +0800 | [diff] [blame] | 731 | } |
| 732 | brw_land_fwd_jump(p, jmp); |
| 733 | |
Xiang, Haihao | 4cca760 | 2007-12-19 10:22:28 +0800 | [diff] [blame] | 734 | brw_emit_point_setup( c, GL_FALSE ); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 735 | } |
| 736 | |
| 737 | |
| 738 | |
| 739 | |