Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/compiler/brw_clip_tri.c
4550 views
1
/*
2
Copyright (C) Intel Corp. 2006. All Rights Reserved.
3
Intel funded Tungsten Graphics 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 <[email protected]>
30
*/
31
32
#include "main/macros.h"
33
#include "main/enums.h"
34
#include "program/program.h"
35
36
#include "brw_clip.h"
37
38
static void release_tmps( struct brw_clip_compile *c )
39
{
40
c->last_tmp = c->first_tmp;
41
}
42
43
44
void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
45
GLuint nr_verts )
46
{
47
const struct intel_device_info *devinfo = c->func.devinfo;
48
GLuint i = 0,j;
49
50
/* Register usage is static, precompute here:
51
*/
52
c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
53
54
if (c->key.nr_userclip) {
55
c->reg.fixed_planes = brw_vec4_grf(i, 0);
56
i += (6 + c->key.nr_userclip + 1) / 2;
57
58
c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
59
}
60
else
61
c->prog_data.curb_read_length = 0;
62
63
64
/* Payload vertices plus space for more generated vertices:
65
*/
66
for (j = 0; j < nr_verts; j++) {
67
c->reg.vertex[j] = brw_vec4_grf(i, 0);
68
i += c->nr_regs;
69
}
70
71
if (c->vue_map.num_slots % 2 && nr_verts > 0) {
72
/* The VUE has an odd number of slots so the last register is only half
73
* used. Fill the second half with zero.
74
*/
75
for (j = 0; j < 3; j++) {
76
GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
77
78
brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
79
}
80
}
81
82
c->reg.t = brw_vec1_grf(i, 0);
83
c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
84
c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
85
c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
86
c->reg.plane_equation = brw_vec4_grf(i, 4);
87
i++;
88
89
c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
90
c->reg.dp = brw_vec1_grf(i, 4);
91
i++;
92
93
c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
94
i++;
95
96
c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
97
i++;
98
99
c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
100
i++;
101
102
if (!c->key.nr_userclip) {
103
c->reg.fixed_planes = brw_vec8_grf(i, 0);
104
i++;
105
}
106
107
if (c->key.do_unfilled) {
108
c->reg.dir = brw_vec4_grf(i, 0);
109
c->reg.offset = brw_vec4_grf(i, 4);
110
i++;
111
c->reg.tmp0 = brw_vec4_grf(i, 0);
112
c->reg.tmp1 = brw_vec4_grf(i, 4);
113
i++;
114
}
115
116
c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
117
c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W);
118
i++;
119
120
if (devinfo->ver == 5) {
121
c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
122
i++;
123
}
124
125
c->first_tmp = i;
126
c->last_tmp = i;
127
128
c->prog_data.urb_read_length = c->nr_regs; /* ? */
129
c->prog_data.total_grf = i;
130
}
131
132
133
134
void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
135
{
136
struct brw_codegen *p = &c->func;
137
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
138
139
/* Initial list of indices for incoming vertexes:
140
*/
141
brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
142
brw_CMP(p,
143
vec1(brw_null_reg()),
144
BRW_CONDITIONAL_EQ,
145
tmp0,
146
brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
147
148
/* XXX: Is there an easier way to do this? Need to reverse every
149
* second tristrip element: Can ignore sometimes?
150
*/
151
brw_IF(p, BRW_EXECUTE_1);
152
{
153
brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) );
154
brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) );
155
if (c->need_direction)
156
brw_MOV(p, c->reg.dir, brw_imm_f(-1));
157
}
158
brw_ELSE(p);
159
{
160
brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) );
161
brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) );
162
if (c->need_direction)
163
brw_MOV(p, c->reg.dir, brw_imm_f(1));
164
}
165
brw_ENDIF(p);
166
167
brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) );
168
brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
169
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
170
}
171
172
173
174
void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
175
{
176
struct brw_codegen *p = &c->func;
177
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
178
179
brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
180
brw_CMP(p,
181
vec1(brw_null_reg()),
182
BRW_CONDITIONAL_EQ,
183
tmp0,
184
brw_imm_ud(_3DPRIM_POLYGON));
185
186
brw_IF(p, BRW_EXECUTE_1);
187
{
188
brw_clip_copy_flatshaded_attributes(c, 1, 0);
189
brw_clip_copy_flatshaded_attributes(c, 2, 0);
190
}
191
brw_ELSE(p);
192
{
193
if (c->key.pv_first) {
194
brw_CMP(p,
195
vec1(brw_null_reg()),
196
BRW_CONDITIONAL_EQ,
197
tmp0,
198
brw_imm_ud(_3DPRIM_TRIFAN));
199
brw_IF(p, BRW_EXECUTE_1);
200
{
201
brw_clip_copy_flatshaded_attributes(c, 0, 1);
202
brw_clip_copy_flatshaded_attributes(c, 2, 1);
203
}
204
brw_ELSE(p);
205
{
206
brw_clip_copy_flatshaded_attributes(c, 1, 0);
207
brw_clip_copy_flatshaded_attributes(c, 2, 0);
208
}
209
brw_ENDIF(p);
210
}
211
else {
212
brw_clip_copy_flatshaded_attributes(c, 0, 2);
213
brw_clip_copy_flatshaded_attributes(c, 1, 2);
214
}
215
}
216
brw_ENDIF(p);
217
}
218
219
220
/**
221
* Loads the clip distance for a vertex into `dst`, and ends with
222
* a comparison of it to zero with the condition `cond`.
223
*
224
* - If using a fixed plane, the distance is dot(hpos, plane).
225
* - If using a user clip plane, the distance is directly available in the vertex.
226
*/
227
static inline void
228
load_clip_distance(struct brw_clip_compile *c, struct brw_indirect vtx,
229
struct brw_reg dst, GLuint hpos_offset, int cond)
230
{
231
struct brw_codegen *p = &c->func;
232
233
dst = vec4(dst);
234
brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1));
235
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
236
brw_IF(p, BRW_EXECUTE_1);
237
{
238
struct brw_indirect temp_ptr = brw_indirect(7, 0);
239
brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx), c->reg.clipdistance_offset);
240
brw_MOV(p, vec1(dst), deref_1f(temp_ptr, 0));
241
}
242
brw_ELSE(p);
243
{
244
brw_MOV(p, dst, deref_4f(vtx, hpos_offset));
245
brw_DP4(p, dst, dst, c->reg.plane_equation);
246
}
247
brw_ENDIF(p);
248
249
brw_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f));
250
}
251
252
253
/* Use mesa's clipping algorithms, translated to GFX4 assembly.
254
*/
255
void brw_clip_tri( struct brw_clip_compile *c )
256
{
257
struct brw_codegen *p = &c->func;
258
struct brw_indirect vtx = brw_indirect(0, 0);
259
struct brw_indirect vtxPrev = brw_indirect(1, 0);
260
struct brw_indirect vtxOut = brw_indirect(2, 0);
261
struct brw_indirect plane_ptr = brw_indirect(3, 0);
262
struct brw_indirect inlist_ptr = brw_indirect(4, 0);
263
struct brw_indirect outlist_ptr = brw_indirect(5, 0);
264
struct brw_indirect freelist_ptr = brw_indirect(6, 0);
265
GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
266
GLint clipdist0_offset = c->key.nr_userclip
267
? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0)
268
: 0;
269
270
brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) );
271
brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
272
brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
273
brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
274
275
brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
276
277
/* Set the initial vertex source mask: The first 6 planes are the bounds
278
* of the view volume; the next 8 planes are the user clipping planes.
279
*/
280
brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0));
281
282
/* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0].
283
* We'll increment 6 times before we start hitting actual user clipping. */
284
brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float)));
285
286
brw_DO(p, BRW_EXECUTE_1);
287
{
288
/* if (planemask & 1)
289
*/
290
brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
291
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
292
293
brw_IF(p, BRW_EXECUTE_1);
294
{
295
/* vtxOut = freelist_ptr++
296
*/
297
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) );
298
brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
299
300
if (c->key.nr_userclip)
301
brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
302
else
303
brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
304
305
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
306
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
307
308
brw_DO(p, BRW_EXECUTE_1);
309
{
310
/* vtx = *input_ptr;
311
*/
312
brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
313
314
load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, BRW_CONDITIONAL_L);
315
/* (prev < 0.0f) */
316
brw_IF(p, BRW_EXECUTE_1);
317
{
318
load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
319
/* IS_POSITIVE(next)
320
*/
321
brw_IF(p, BRW_EXECUTE_1);
322
{
323
324
/* Coming back in.
325
*/
326
brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
327
brw_math_invert(p, c->reg.t, c->reg.t);
328
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
329
330
/* If (vtxOut == 0) vtxOut = vtxPrev
331
*/
332
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
333
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev));
334
brw_inst_set_pred_control(p->devinfo, brw_last_inst,
335
BRW_PREDICATE_NORMAL);
336
337
brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false);
338
339
/* *outlist_ptr++ = vtxOut;
340
* nr_verts++;
341
* vtxOut = 0;
342
*/
343
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
344
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
345
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
346
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
347
}
348
brw_ENDIF(p);
349
350
}
351
brw_ELSE(p);
352
{
353
/* *outlist_ptr++ = vtxPrev;
354
* nr_verts++;
355
*/
356
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
357
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
358
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
359
360
load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_L);
361
/* (next < 0.0f)
362
*/
363
brw_IF(p, BRW_EXECUTE_1);
364
{
365
/* Going out of bounds. Avoid division by zero as we
366
* know dp != dpPrev from DIFFERENT_SIGNS, above.
367
*/
368
brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
369
brw_math_invert(p, c->reg.t, c->reg.t);
370
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
371
372
/* If (vtxOut == 0) vtxOut = vtx
373
*/
374
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
375
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx));
376
brw_inst_set_pred_control(p->devinfo, brw_last_inst,
377
BRW_PREDICATE_NORMAL);
378
379
brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true);
380
381
/* *outlist_ptr++ = vtxOut;
382
* nr_verts++;
383
* vtxOut = 0;
384
*/
385
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
386
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
387
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
388
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
389
}
390
brw_ENDIF(p);
391
}
392
brw_ENDIF(p);
393
394
/* vtxPrev = vtx;
395
* inlist_ptr++;
396
*/
397
brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
398
brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
399
400
/* while (--loopcount != 0)
401
*/
402
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
403
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
404
}
405
brw_WHILE(p);
406
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
407
408
/* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
409
* inlist = outlist
410
* inlist_ptr = &inlist[0]
411
* outlist_ptr = &outlist[0]
412
*/
413
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
414
brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
415
brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
416
brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
417
brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
418
}
419
brw_ENDIF(p);
420
421
/* plane_ptr++;
422
*/
423
brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
424
425
/* nr_verts >= 3
426
*/
427
brw_CMP(p,
428
vec1(brw_null_reg()),
429
BRW_CONDITIONAL_GE,
430
c->reg.nr_verts,
431
brw_imm_ud(3));
432
brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
433
434
/* && (planemask>>=1) != 0
435
*/
436
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
437
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
438
brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1));
439
brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float)));
440
}
441
brw_WHILE(p);
442
brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
443
}
444
445
446
447
void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
448
{
449
struct brw_codegen *p = &c->func;
450
451
/* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
452
*/
453
brw_ADD(p,
454
c->reg.loopcount,
455
c->reg.nr_verts,
456
brw_imm_d(-2));
457
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
458
459
brw_IF(p, BRW_EXECUTE_1);
460
{
461
struct brw_indirect v0 = brw_indirect(0, 0);
462
struct brw_indirect vptr = brw_indirect(1, 0);
463
464
brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
465
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
466
467
brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
468
((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
469
| URB_WRITE_PRIM_START));
470
471
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
472
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
473
474
brw_DO(p, BRW_EXECUTE_1);
475
{
476
brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
477
(_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
478
479
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
480
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
481
482
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
483
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
484
}
485
brw_WHILE(p);
486
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
487
488
brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
489
((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
490
| URB_WRITE_PRIM_END));
491
}
492
brw_ENDIF(p);
493
}
494
495
static void do_clip_tri( struct brw_clip_compile *c )
496
{
497
brw_clip_init_planes(c);
498
499
brw_clip_tri(c);
500
}
501
502
503
static void maybe_do_clip_tri( struct brw_clip_compile *c )
504
{
505
struct brw_codegen *p = &c->func;
506
507
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
508
brw_IF(p, BRW_EXECUTE_1);
509
{
510
do_clip_tri(c);
511
}
512
brw_ENDIF(p);
513
}
514
515
static void brw_clip_test( struct brw_clip_compile *c )
516
{
517
struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
518
struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
519
struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
520
struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
521
522
struct brw_reg v0 = get_tmp(c);
523
struct brw_reg v1 = get_tmp(c);
524
struct brw_reg v2 = get_tmp(c);
525
526
struct brw_indirect vt0 = brw_indirect(0, 0);
527
struct brw_indirect vt1 = brw_indirect(1, 0);
528
struct brw_indirect vt2 = brw_indirect(2, 0);
529
530
struct brw_codegen *p = &c->func;
531
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
532
533
GLuint hpos_offset = brw_varying_to_offset(&c->vue_map,
534
VARYING_SLOT_POS);
535
536
brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
537
brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
538
brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
539
brw_MOV(p, v0, deref_4f(vt0, hpos_offset));
540
brw_MOV(p, v1, deref_4f(vt1, hpos_offset));
541
brw_MOV(p, v2, deref_4f(vt2, hpos_offset));
542
brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
543
544
/* test nearz, xmin, ymin plane */
545
/* clip.xyz < -clip.w */
546
brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
547
brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
548
brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
549
550
/* All vertices are outside of a plane, rejected */
551
brw_AND(p, t, t1, t2);
552
brw_AND(p, t, t, t3);
553
brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
554
brw_OR(p, tmp0, tmp0, get_element(t, 2));
555
brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
556
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
557
brw_IF(p, BRW_EXECUTE_1);
558
{
559
brw_clip_kill_thread(c);
560
}
561
brw_ENDIF(p);
562
brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
563
564
/* some vertices are inside a plane, some are outside,need to clip */
565
brw_XOR(p, t, t1, t2);
566
brw_XOR(p, t1, t2, t3);
567
brw_OR(p, t, t, t1);
568
brw_AND(p, t, t, brw_imm_ud(0x1));
569
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
570
get_element(t, 0), brw_imm_ud(0));
571
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
572
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
573
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
574
get_element(t, 1), brw_imm_ud(0));
575
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
576
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
577
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
578
get_element(t, 2), brw_imm_ud(0));
579
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
580
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
581
582
/* test farz, xmax, ymax plane */
583
/* clip.xyz > clip.w */
584
brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
585
brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
586
brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
587
588
/* All vertices are outside of a plane, rejected */
589
brw_AND(p, t, t1, t2);
590
brw_AND(p, t, t, t3);
591
brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
592
brw_OR(p, tmp0, tmp0, get_element(t, 2));
593
brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
594
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
595
brw_IF(p, BRW_EXECUTE_1);
596
{
597
brw_clip_kill_thread(c);
598
}
599
brw_ENDIF(p);
600
brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
601
602
/* some vertices are inside a plane, some are outside,need to clip */
603
brw_XOR(p, t, t1, t2);
604
brw_XOR(p, t1, t2, t3);
605
brw_OR(p, t, t, t1);
606
brw_AND(p, t, t, brw_imm_ud(0x1));
607
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
608
get_element(t, 0), brw_imm_ud(0));
609
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
610
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
611
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
612
get_element(t, 1), brw_imm_ud(0));
613
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
614
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
615
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
616
get_element(t, 2), brw_imm_ud(0));
617
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
618
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
619
620
release_tmps(c);
621
}
622
623
624
void brw_emit_tri_clip( struct brw_clip_compile *c )
625
{
626
struct brw_codegen *p = &c->func;
627
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
628
brw_clip_tri_init_vertices(c);
629
brw_clip_init_clipmask(c);
630
brw_clip_init_ff_sync(c);
631
632
/* if -ve rhw workaround bit is set,
633
do cliptest */
634
if (p->devinfo->has_negative_rhw_bug) {
635
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
636
brw_imm_ud(1<<20));
637
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
638
brw_IF(p, BRW_EXECUTE_1);
639
{
640
brw_clip_test(c);
641
}
642
brw_ENDIF(p);
643
}
644
/* Can't push into do_clip_tri because with polygon (or quad)
645
* flatshading, need to apply the flatshade here because we don't
646
* respect the PV when converting to trifan for emit:
647
*/
648
if (c->key.contains_flat_varying)
649
brw_clip_tri_flat_shade(c);
650
651
if ((c->key.clip_mode == BRW_CLIP_MODE_NORMAL) ||
652
(c->key.clip_mode == BRW_CLIP_MODE_KERNEL_CLIP))
653
do_clip_tri(c);
654
else
655
maybe_do_clip_tri(c);
656
657
brw_clip_tri_emit_polygon(c);
658
659
/* Send an empty message to kill the thread:
660
*/
661
brw_clip_kill_thread(c);
662
}
663
664