Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
30
  */
31
 
32
#include "main/glheader.h"
33
#include "main/macros.h"
34
#include "main/enums.h"
35
#include "program/program.h"
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_clip.h"
43
 
44
 
45
 
46
static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
47
{
48
   struct brw_context *brw = c->func.brw;
49
   GLuint i = 0,j;
50
 
51
   /* Register usage is static, precompute here:
52
    */
53
   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
54
 
55
   if (c->key.nr_userclip) {
56
      c->reg.fixed_planes = brw_vec4_grf(i, 0);
57
      i += (6 + c->key.nr_userclip + 1) / 2;
58
 
59
      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
60
   }
61
   else
62
      c->prog_data.curb_read_length = 0;
63
 
64
 
65
   /* Payload vertices plus space for more generated vertices:
66
    */
67
   for (j = 0; j < 4; j++) {
68
      c->reg.vertex[j] = brw_vec4_grf(i, 0);
69
      i += c->nr_regs;
70
   }
71
 
72
   c->reg.t           = brw_vec1_grf(i, 0);
73
   c->reg.t0          = brw_vec1_grf(i, 1);
74
   c->reg.t1          = brw_vec1_grf(i, 2);
75
   c->reg.planemask   = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
76
   c->reg.plane_equation = brw_vec4_grf(i, 4);
77
   i++;
78
 
79
   c->reg.dp0         = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
80
   c->reg.dp1         = brw_vec1_grf(i, 4);
81
   i++;
82
 
83
   if (!c->key.nr_userclip) {
84
      c->reg.fixed_planes = brw_vec8_grf(i, 0);
85
      i++;
86
   }
87
 
88
   if (brw->gen == 5) {
89
      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
90
      i++;
91
   }
92
 
93
   c->first_tmp = i;
94
   c->last_tmp = i;
95
 
96
   c->prog_data.urb_read_length = c->nr_regs; /* ? */
97
   c->prog_data.total_grf = i;
98
}
99
 
100
 
101
 
102
/* Line clipping, more or less following the following algorithm:
103
 *
104
 *  for (p=0;p
105
 *     if (clipmask & (1 << p)) {
106
 *        GLfloat dp0 = DOTPROD( vtx0, plane[p] );
107
 *        GLfloat dp1 = DOTPROD( vtx1, plane[p] );
108
 *
109
 *        if (IS_NEGATIVE(dp1)) {
110
 *           GLfloat t = dp1 / (dp1 - dp0);
111
 *           if (t > t1) t1 = t;
112
 *        } else {
113
 *           GLfloat t = dp0 / (dp0 - dp1);
114
 *           if (t > t0) t0 = t;
115
 *        }
116
 *
117
 *        if (t0 + t1 >= 1.0)
118
 *           return;
119
 *     }
120
 *  }
121
 *
122
 *  interp( ctx, newvtx0, vtx0, vtx1, t0 );
123
 *  interp( ctx, newvtx1, vtx1, vtx0, t1 );
124
 *
125
 */
126
static void clip_and_emit_line( struct brw_clip_compile *c )
127
{
128
   /* FIXME: use VARYING_SLOT_CLIP_VERTEX if available for user clip planes. */
129
 
130
   struct brw_compile *p = &c->func;
131
   struct brw_context *brw = p->brw;
132
   struct brw_indirect vtx0     = brw_indirect(0, 0);
133
   struct brw_indirect vtx1      = brw_indirect(1, 0);
134
   struct brw_indirect newvtx0   = brw_indirect(2, 0);
135
   struct brw_indirect newvtx1   = brw_indirect(3, 0);
136
   struct brw_indirect plane_ptr = brw_indirect(4, 0);
137
   struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
138
   GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
139
 
140
   brw_MOV(p, get_addr_reg(vtx0),      brw_address(c->reg.vertex[0]));
141
   brw_MOV(p, get_addr_reg(vtx1),      brw_address(c->reg.vertex[1]));
142
   brw_MOV(p, get_addr_reg(newvtx0),   brw_address(c->reg.vertex[2]));
143
   brw_MOV(p, get_addr_reg(newvtx1),   brw_address(c->reg.vertex[3]));
144
   brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
145
 
146
   /* Note: init t0, t1 together:
147
    */
148
   brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
149
 
150
   brw_clip_init_planes(c);
151
   brw_clip_init_clipmask(c);
152
 
153
   /* -ve rhw workaround */
154
   if (brw->has_negative_rhw_bug) {
155
      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
156
      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
157
              brw_imm_ud(1<<20));
158
      brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
159
   }
160
 
161
   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
162
 
163
   brw_DO(p, BRW_EXECUTE_1);
164
   {
165
      /* if (planemask & 1)
166
       */
167
      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
168
      brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
169
 
170
      brw_IF(p, BRW_EXECUTE_1);
171
      {
172
	 if (c->key.nr_userclip)
173
	    brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
174
	 else
175
	    brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
176
 
177
	 /* dp = DP4(vtx->position, plane)
178
	  */
179
	 brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation);
180
 
181
	 /* if (IS_NEGATIVE(dp1))
182
	  */
183
	 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
184
	 brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation);
185
	 brw_IF(p, BRW_EXECUTE_1);
186
	 {
187
             /*
188
              * Both can be negative on GM965/G965 due to RHW workaround
189
              * if so, this object should be rejected.
190
              */
191
             if (brw->has_negative_rhw_bug) {
192
                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
193
                 brw_IF(p, BRW_EXECUTE_1);
194
                 {
195
                     brw_clip_kill_thread(c);
196
                 }
197
                 brw_ENDIF(p);
198
             }
199
 
200
             brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
201
             brw_math_invert(p, c->reg.t, c->reg.t);
202
             brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
203
 
204
             brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
205
             brw_MOV(p, c->reg.t1, c->reg.t);
206
             brw_set_predicate_control(p, BRW_PREDICATE_NONE);
207
	 }
208
	 brw_ELSE(p);
209
	 {
210
             /* Coming back in.  We know that both cannot be negative
211
              * because the line would have been culled in that case.
212
              */
213
 
214
             /* If both are positive, do nothing */
215
             /* Only on GM965/G965 */
216
             if (brw->has_negative_rhw_bug) {
217
                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
218
                 brw_IF(p, BRW_EXECUTE_1);
219
             }
220
 
221
             {
222
                 brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
223
                 brw_math_invert(p, c->reg.t, c->reg.t);
224
                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
225
 
226
                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
227
                 brw_MOV(p, c->reg.t0, c->reg.t);
228
                 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
229
             }
230
 
231
             if (brw->has_negative_rhw_bug) {
232
                 brw_ENDIF(p);
233
             }
234
         }
235
	 brw_ENDIF(p);
236
      }
237
      brw_ENDIF(p);
238
 
239
      /* plane_ptr++;
240
       */
241
      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
242
 
243
      /* while (planemask>>=1) != 0
244
       */
245
      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
246
      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
247
   }
248
   brw_WHILE(p);
249
 
250
   brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
251
   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
252
   brw_IF(p, BRW_EXECUTE_1);
253
   {
254
      brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false);
255
      brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false);
256
 
257
      brw_clip_emit_vue(c, newvtx0, 1, 0,
258
                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
259
                        | URB_WRITE_PRIM_START);
260
      brw_clip_emit_vue(c, newvtx1, 0, 1,
261
                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
262
                        | URB_WRITE_PRIM_END);
263
   }
264
   brw_ENDIF(p);
265
   brw_clip_kill_thread(c);
266
}
267
 
268
 
269
 
270
void brw_emit_line_clip( struct brw_clip_compile *c )
271
{
272
   brw_clip_line_alloc_regs(c);
273
   brw_clip_init_ff_sync(c);
274
 
275
   if (c->key.do_flat_shading) {
276
      if (c->key.pv_first)
277
         brw_clip_copy_colors(c, 1, 0);
278
      else
279
         brw_clip_copy_colors(c, 0, 1);
280
   }
281
 
282
   clip_and_emit_line(c);
283
}