Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/compiler/brw_clip_line.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 brw_clip_line_alloc_regs( struct brw_clip_compile *c )
39
{
40
const struct intel_device_info *devinfo = c->func.devinfo;
41
GLuint i = 0,j;
42
43
/* Register usage is static, precompute here:
44
*/
45
c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
46
47
if (c->key.nr_userclip) {
48
c->reg.fixed_planes = brw_vec4_grf(i, 0);
49
i += (6 + c->key.nr_userclip + 1) / 2;
50
51
c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
52
}
53
else
54
c->prog_data.curb_read_length = 0;
55
56
57
/* Payload vertices plus space for more generated vertices:
58
*/
59
for (j = 0; j < 4; j++) {
60
c->reg.vertex[j] = brw_vec4_grf(i, 0);
61
i += c->nr_regs;
62
}
63
64
c->reg.t = brw_vec1_grf(i, 0);
65
c->reg.t0 = brw_vec1_grf(i, 1);
66
c->reg.t1 = brw_vec1_grf(i, 2);
67
c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
68
c->reg.plane_equation = brw_vec4_grf(i, 4);
69
i++;
70
71
c->reg.dp0 = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
72
c->reg.dp1 = brw_vec1_grf(i, 4);
73
i++;
74
75
if (!c->key.nr_userclip) {
76
c->reg.fixed_planes = brw_vec8_grf(i, 0);
77
i++;
78
}
79
80
c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
81
c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W);
82
i++;
83
84
if (devinfo->ver == 5) {
85
c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
86
i++;
87
}
88
89
c->first_tmp = i;
90
c->last_tmp = i;
91
92
c->prog_data.urb_read_length = c->nr_regs; /* ? */
93
c->prog_data.total_grf = i;
94
}
95
96
97
/* Line clipping, more or less following the following algorithm:
98
*
99
* for (p=0;p<MAX_PLANES;p++) {
100
* if (clipmask & (1 << p)) {
101
* GLfloat dp0 = DOTPROD( vtx0, plane[p] );
102
* GLfloat dp1 = DOTPROD( vtx1, plane[p] );
103
*
104
* if (dp1 < 0.0f) {
105
* GLfloat t = dp1 / (dp1 - dp0);
106
* if (t > t1) t1 = t;
107
* } else {
108
* GLfloat t = dp0 / (dp0 - dp1);
109
* if (t > t0) t0 = t;
110
* }
111
*
112
* if (t0 + t1 >= 1.0)
113
* return;
114
* }
115
* }
116
*
117
* interp( ctx, newvtx0, vtx0, vtx1, t0 );
118
* interp( ctx, newvtx1, vtx1, vtx0, t1 );
119
*
120
*/
121
static void clip_and_emit_line( struct brw_clip_compile *c )
122
{
123
struct brw_codegen *p = &c->func;
124
struct brw_indirect vtx0 = brw_indirect(0, 0);
125
struct brw_indirect vtx1 = brw_indirect(1, 0);
126
struct brw_indirect newvtx0 = brw_indirect(2, 0);
127
struct brw_indirect newvtx1 = brw_indirect(3, 0);
128
struct brw_indirect plane_ptr = brw_indirect(4, 0);
129
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
130
GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
131
GLint clipdist0_offset = c->key.nr_userclip
132
? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0)
133
: 0;
134
135
brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0]));
136
brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1]));
137
brw_MOV(p, get_addr_reg(newvtx0), brw_address(c->reg.vertex[2]));
138
brw_MOV(p, get_addr_reg(newvtx1), brw_address(c->reg.vertex[3]));
139
brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
140
141
/* Note: init t0, t1 together:
142
*/
143
brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
144
145
brw_clip_init_planes(c);
146
brw_clip_init_clipmask(c);
147
148
/* -ve rhw workaround */
149
if (p->devinfo->has_negative_rhw_bug) {
150
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
151
brw_imm_ud(1<<20));
152
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
153
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
154
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
155
}
156
157
/* Set the initial vertex source mask: The first 6 planes are the bounds
158
* of the view volume; the next 8 planes are the user clipping planes.
159
*/
160
brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0));
161
162
/* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0].
163
* We'll increment 6 times before we start hitting actual user clipping. */
164
brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float)));
165
166
brw_DO(p, BRW_EXECUTE_1);
167
{
168
/* if (planemask & 1)
169
*/
170
brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
171
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
172
173
brw_IF(p, BRW_EXECUTE_1);
174
{
175
brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1));
176
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
177
brw_IF(p, BRW_EXECUTE_1);
178
{
179
/* user clip distance: just fetch the correct float from each vertex */
180
struct brw_indirect temp_ptr = brw_indirect(7, 0);
181
brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset);
182
brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0));
183
brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset);
184
brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0));
185
}
186
brw_ELSE(p);
187
{
188
/* fixed plane: fetch the hpos, dp4 against the plane. */
189
if (c->key.nr_userclip)
190
brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
191
else
192
brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
193
194
brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation);
195
brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation);
196
}
197
brw_ENDIF(p);
198
199
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f));
200
201
brw_IF(p, BRW_EXECUTE_1);
202
{
203
/*
204
* Both can be negative on GM965/G965 due to RHW workaround
205
* if so, this object should be rejected.
206
*/
207
if (p->devinfo->has_negative_rhw_bug) {
208
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
209
brw_IF(p, BRW_EXECUTE_1);
210
{
211
brw_clip_kill_thread(c);
212
}
213
brw_ENDIF(p);
214
}
215
216
brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
217
brw_math_invert(p, c->reg.t, c->reg.t);
218
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
219
220
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
221
brw_MOV(p, c->reg.t1, c->reg.t);
222
brw_inst_set_pred_control(p->devinfo, brw_last_inst,
223
BRW_PREDICATE_NORMAL);
224
}
225
brw_ELSE(p);
226
{
227
/* Coming back in. We know that both cannot be negative
228
* because the line would have been culled in that case.
229
*/
230
231
/* If both are positive, do nothing */
232
/* Only on GM965/G965 */
233
if (p->devinfo->has_negative_rhw_bug) {
234
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
235
brw_IF(p, BRW_EXECUTE_1);
236
}
237
238
{
239
brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
240
brw_math_invert(p, c->reg.t, c->reg.t);
241
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
242
243
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
244
brw_MOV(p, c->reg.t0, c->reg.t);
245
brw_inst_set_pred_control(p->devinfo, brw_last_inst,
246
BRW_PREDICATE_NORMAL);
247
}
248
249
if (p->devinfo->has_negative_rhw_bug) {
250
brw_ENDIF(p);
251
}
252
}
253
brw_ENDIF(p);
254
}
255
brw_ENDIF(p);
256
257
/* plane_ptr++;
258
*/
259
brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
260
261
/* while (planemask>>=1) != 0
262
*/
263
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
264
brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
265
brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1));
266
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
267
brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float)));
268
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
269
}
270
brw_WHILE(p);
271
brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
272
273
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
274
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
275
brw_IF(p, BRW_EXECUTE_1);
276
{
277
brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false);
278
brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false);
279
280
brw_clip_emit_vue(c, newvtx0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
281
(_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
282
| URB_WRITE_PRIM_START);
283
brw_clip_emit_vue(c, newvtx1, BRW_URB_WRITE_EOT_COMPLETE,
284
(_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
285
| URB_WRITE_PRIM_END);
286
}
287
brw_ENDIF(p);
288
brw_clip_kill_thread(c);
289
}
290
291
292
293
void brw_emit_line_clip( struct brw_clip_compile *c )
294
{
295
brw_clip_line_alloc_regs(c);
296
brw_clip_init_ff_sync(c);
297
298
if (c->key.contains_flat_varying) {
299
if (c->key.pv_first)
300
brw_clip_copy_flatshaded_attributes(c, 1, 0);
301
else
302
brw_clip_copy_flatshaded_attributes(c, 0, 1);
303
}
304
305
clip_and_emit_line(c);
306
}
307
308