~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to src/mesa/drivers/windows/gldirect/dx9/gld_vb_mesa_render_dx9.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-01-23 10:20:24 UTC
  • mfrom: (1.2.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20090123102024-1f3kmb3aea7wzk67
Tags: 7.3~rc3-1ubuntu1
* Merge with Debian experimental.
* Drop 102_dont_vblank.patch, since the new drm code in the kernel
  fixes the bugs that it worked around.
* Bump the build-dependency of libdrm to 2.4.4. It's the first version
  with necessary changes to build this.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*
3
 
 * Mesa 3-D graphics library
4
 
 * Version:  3.5
5
 
 *
6
 
 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
7
 
 *
8
 
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 
 * copy of this software and associated documentation files (the "Software"),
10
 
 * to deal in the Software without restriction, including without limitation
11
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 
 * and/or sell copies of the Software, and to permit persons to whom the
13
 
 * Software is furnished to do so, subject to the following conditions:
14
 
 *
15
 
 * The above copyright notice and this permission notice shall be included
16
 
 * in all copies or substantial portions of the Software.
17
 
 *
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 
 *
25
 
 * Authors:
26
 
 *    Keith Whitwell <keithw@valinux.com>
27
 
 */
28
 
 
29
 
 
30
 
/*
31
 
 * Render whole vertex buffers, including projection of vertices from
32
 
 * clip space and clipping of primitives.
33
 
 *
34
 
 * This file makes calls to project vertices and to the point, line
35
 
 * and triangle rasterizers via the function pointers:
36
 
 *
37
 
 *    context->Driver.Render.*
38
 
 *
39
 
 */
40
 
 
41
 
 
42
 
//---------------------------------------------------------------------------
43
 
 
44
 
#include "dglcontext.h"
45
 
#include "ddlog.h"
46
 
#include "gld_dx9.h"
47
 
 
48
 
//---------------------------------------------------------------------------
49
 
 
50
 
#include "glheader.h"
51
 
#include "context.h"
52
 
#include "macros.h"
53
 
#include "mtypes.h"
54
 
//#include "mmath.h"
55
 
 
56
 
#include "math/m_matrix.h"
57
 
#include "math/m_xform.h"
58
 
 
59
 
#include "tnl/t_pipeline.h"
60
 
 
61
 
/**********************************************************************/
62
 
/*                        Clip single primitives                      */
63
 
/**********************************************************************/
64
 
 
65
 
 
66
 
#if defined(USE_IEEE)
67
 
#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1<<31))
68
 
//#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31))
69
 
#else
70
 
#define NEGATIVE(x) (x < 0)
71
 
//#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
72
 
/* Could just use (x*y<0) except for the flatshading requirements.
73
 
 * Maybe there's a better way?
74
 
 */
75
 
#endif
76
 
 
77
 
 
78
 
#define W(i) coord[i][3]
79
 
#define Z(i) coord[i][2]
80
 
#define Y(i) coord[i][1]
81
 
#define X(i) coord[i][0]
82
 
#define SIZE 4
83
 
#define TAG(x) x##_4
84
 
#include "tnl/t_vb_cliptmp.h"
85
 
 
86
 
 
87
 
 
88
 
/**********************************************************************/
89
 
/*              Clip and render whole begin/end objects               */
90
 
/**********************************************************************/
91
 
 
92
 
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
93
 
#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
94
 
#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
95
 
 
96
 
 
97
 
/* Vertices, with the possibility of clipping.
98
 
 */
99
 
#define RENDER_POINTS( start, count ) \
100
 
   tnl->Driver.Render.Points( ctx, start, count )
101
 
 
102
 
#define RENDER_LINE( v1, v2 )                   \
103
 
do {                                            \
104
 
   GLubyte c1 = mask[v1], c2 = mask[v2];        \
105
 
   GLubyte ormask = c1|c2;                      \
106
 
   if (!ormask)                                 \
107
 
      LineFunc( ctx, v1, v2 );                  \
108
 
   else if (!(c1 & c2 & 0x3f))                  \
109
 
      clip_line_4( ctx, v1, v2, ormask );       \
110
 
} while (0)
111
 
 
112
 
#define RENDER_TRI( v1, v2, v3 )                        \
113
 
do {                                                    \
114
 
   GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \
115
 
   GLubyte ormask = c1|c2|c3;                           \
116
 
   if (!ormask)                                         \
117
 
      TriangleFunc( ctx, v1, v2, v3 );                  \
118
 
   else if (!(c1 & c2 & c3 & 0x3f))                     \
119
 
      clip_tri_4( ctx, v1, v2, v3, ormask );            \
120
 
} while (0)
121
 
 
122
 
#define RENDER_QUAD( v1, v2, v3, v4 )                   \
123
 
do {                                                    \
124
 
   GLubyte c1 = mask[v1], c2 = mask[v2];                \
125
 
   GLubyte c3 = mask[v3], c4 = mask[v4];                \
126
 
   GLubyte ormask = c1|c2|c3|c4;                        \
127
 
   if (!ormask)                                         \
128
 
      QuadFunc( ctx, v1, v2, v3, v4 );                  \
129
 
   else if (!(c1 & c2 & c3 & c4 & 0x3f))                \
130
 
      clip_quad_4( ctx, v1, v2, v3, v4, ormask );       \
131
 
} while (0)
132
 
 
133
 
 
134
 
#define LOCAL_VARS                                              \
135
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);                          \
136
 
   struct vertex_buffer *VB = &tnl->vb;                         \
137
 
   const GLuint * const elt = VB->Elts;                         \
138
 
   const GLubyte *mask = VB->ClipMask;                          \
139
 
   const GLuint sz = VB->ClipPtr->size;                         \
140
 
   const tnl_line_func LineFunc = tnl->Driver.Render.Line;              \
141
 
   const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle;  \
142
 
   const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad;              \
143
 
   const GLboolean stipple = ctx->Line.StippleFlag;             \
144
 
   (void) (LineFunc && TriangleFunc && QuadFunc);               \
145
 
   (void) elt; (void) mask; (void) sz; (void) stipple;
146
 
 
147
 
#define TAG(x) clip_##x##_verts
148
 
#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
149
 
#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx )
150
 
#define PRESERVE_VB_DEFS
151
 
#include "tnl/t_vb_rendertmp.h"
152
 
 
153
 
 
154
 
 
155
 
/* Elts, with the possibility of clipping.
156
 
 */
157
 
#undef ELT
158
 
#undef TAG
159
 
#define ELT(x) elt[x]
160
 
#define TAG(x) clip_##x##_elts
161
 
#include "tnl/t_vb_rendertmp.h"
162
 
 
163
 
/* TODO: do this for all primitives, verts and elts:
164
 
 */
165
 
static void clip_elt_triangles( GLcontext *ctx,
166
 
                                GLuint start,
167
 
                                GLuint count,
168
 
                                GLuint flags )
169
 
{
170
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
171
 
   tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
172
 
   struct vertex_buffer *VB = &tnl->vb;
173
 
   const GLuint * const elt = VB->Elts;
174
 
   GLubyte *mask = VB->ClipMask;
175
 
   GLuint last = count-2;
176
 
   GLuint j;
177
 
   (void) flags;
178
 
 
179
 
   tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES );
180
 
 
181
 
   for (j=start; j < last; j+=3 ) {
182
 
      GLubyte c1 = mask[elt[j]];
183
 
      GLubyte c2 = mask[elt[j+1]];
184
 
      GLubyte c3 = mask[elt[j+2]];
185
 
      GLubyte ormask = c1|c2|c3;
186
 
      if (ormask) {
187
 
         if (start < j)
188
 
            render_tris( ctx, start, j, 0 );
189
 
         if (!(c1&c2&c3&0x3f))
190
 
            clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask );
191
 
         start = j+3;
192
 
      }
193
 
   }
194
 
 
195
 
   if (start < j)
196
 
      render_tris( ctx, start, j, 0 );
197
 
}
198
 
 
199
 
/**********************************************************************/
200
 
/*                  Render whole begin/end objects                    */
201
 
/**********************************************************************/
202
 
 
203
 
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
204
 
#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
205
 
#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
206
 
 
207
 
 
208
 
/* Vertices, no clipping.
209
 
 */
210
 
#define RENDER_POINTS( start, count ) \
211
 
   tnl->Driver.Render.Points( ctx, start, count )
212
 
 
213
 
#define RENDER_LINE( v1, v2 ) \
214
 
   LineFunc( ctx, v1, v2 )
215
 
 
216
 
#define RENDER_TRI( v1, v2, v3 ) \
217
 
   TriangleFunc( ctx, v1, v2, v3 )
218
 
 
219
 
#define RENDER_QUAD( v1, v2, v3, v4 ) \
220
 
   QuadFunc( ctx, v1, v2, v3, v4 )
221
 
 
222
 
#define TAG(x) _gld_tnl_##x##_verts
223
 
 
224
 
#define LOCAL_VARS                                              \
225
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);                          \
226
 
   struct vertex_buffer *VB = &tnl->vb;                         \
227
 
   const GLuint * const elt = VB->Elts;                         \
228
 
   const tnl_line_func LineFunc = tnl->Driver.Render.Line;              \
229
 
   const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle;  \
230
 
   const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad;              \
231
 
   (void) (LineFunc && TriangleFunc && QuadFunc);               \
232
 
   (void) elt;
233
 
 
234
 
#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx )
235
 
#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
236
 
#define RENDER_TAB_QUALIFIER
237
 
#define PRESERVE_VB_DEFS
238
 
#include "tnl/t_vb_rendertmp.h"
239
 
 
240
 
 
241
 
/* Elts, no clipping.
242
 
 */
243
 
#undef ELT
244
 
#define TAG(x) _gld_tnl_##x##_elts
245
 
#define ELT(x) elt[x]
246
 
#include "tnl/t_vb_rendertmp.h"
247
 
 
248
 
 
249
 
/**********************************************************************/
250
 
/*              Helper functions for drivers                  */
251
 
/**********************************************************************/
252
 
/*
253
 
void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n )
254
 
{
255
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
256
 
   struct vertex_buffer *VB = &tnl->vb;
257
 
   GLuint *tmp = VB->Elts;
258
 
 
259
 
   VB->Elts = (GLuint *)elts;
260
 
   tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
261
 
   VB->Elts = tmp;
262
 
}
263
 
 
264
 
void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
265
 
{
266
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
267
 
   tnl->Driver.Render.Line( ctx, ii, jj );
268
 
}
269
 
*/
270
 
 
271
 
 
272
 
/**********************************************************************/
273
 
/*              Clip and render whole vertex buffers                  */
274
 
/**********************************************************************/
275
 
 
276
 
tnl_points_func _gldSetupPoints[4] = {
277
 
        gld_Points2D_DX9,
278
 
        gld_Points2D_DX9,
279
 
        gld_Points2D_DX9,
280
 
        gld_Points2D_DX9
281
 
};
282
 
tnl_line_func _gldSetupLine[4] = {
283
 
        gld_Line2DFlat_DX9,
284
 
        gld_Line2DSmooth_DX9,
285
 
        gld_Line2DFlat_DX9,
286
 
        gld_Line2DSmooth_DX9,
287
 
};
288
 
tnl_triangle_func _gldSetupTriangle[4] = {
289
 
        gld_Triangle2DFlat_DX9,
290
 
        gld_Triangle2DSmooth_DX9,
291
 
        gld_Triangle2DFlatExtras_DX9,
292
 
        gld_Triangle2DSmoothExtras_DX9
293
 
};
294
 
tnl_quad_func _gldSetupQuad[4] = {
295
 
        gld_Quad2DFlat_DX9,
296
 
        gld_Quad2DSmooth_DX9,
297
 
        gld_Quad2DFlatExtras_DX9,
298
 
        gld_Quad2DSmoothExtras_DX9
299
 
};
300
 
 
301
 
//---------------------------------------------------------------------------
302
 
 
303
 
static GLboolean _gld_mesa_render_stage_run(
304
 
        GLcontext *ctx,
305
 
        struct tnl_pipeline_stage *stage)
306
 
{
307
 
        GLD_context                             *gldCtx = GLD_GET_CONTEXT(ctx);
308
 
        GLD_driver_dx9                  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
309
 
                
310
 
        TNLcontext                              *tnl = TNL_CONTEXT(ctx);
311
 
        struct vertex_buffer    *VB = &tnl->vb;
312
 
        tnl_render_func                         *tab;
313
 
        GLint                                   pass = 0;
314
 
        GLD_pb_dx9                              *gldPB;
315
 
 
316
 
        /* Allow the drivers to lock before projected verts are built so
317
 
    * that window coordinates are guarenteed not to change before
318
 
    * rendering.
319
 
    */
320
 
        ASSERT(tnl->Driver.Render.Start);
321
 
        
322
 
        tnl->Driver.Render.Start( ctx );
323
 
        
324
 
        // NOTE: Setting D3DRS_SOFTWAREVERTEXPROCESSING for a mixed-mode device resets
325
 
        //       stream, indices and shader to default values of NULL or 0.
326
 
/*      if ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) &&
327
 
                gld->VStwosidelight.hShader &&
328
 
                !ctx->Fog.Enabled)
329
 
        {
330
 
                IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware);
331
 
                _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader));
332
 
                gldPB = &gld->PBtwosidelight;
333
 
                tnl->Driver.Render.Points       = gld_Points2DTwoside_DX9;
334
 
                if (ctx->_TriangleCaps & DD_FLATSHADE) {
335
 
                        tnl->Driver.Render.Line         = gld_Line2DFlatTwoside_DX9;
336
 
                        tnl->Driver.Render.Triangle     = gld_Triangle2DFlatTwoside_DX9;
337
 
                        tnl->Driver.Render.Quad         = gld_Quad2DFlatTwoside_DX9;
338
 
                } else {
339
 
                        tnl->Driver.Render.Line         = gld_Line2DSmoothTwoside_DX9;
340
 
                        tnl->Driver.Render.Triangle     = gld_Triangle2DSmoothTwoside_DX9;
341
 
                        tnl->Driver.Render.Quad         = gld_Quad2DSmoothTwoside_DX9;
342
 
                }
343
 
        } else {*/
344
 
//              IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
345
 
                IDirect3DDevice9_SetSoftwareVertexProcessing(gld->pDev, TRUE);
346
 
                gldPB = &gld->PB2d;
347
 
                _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
348
 
                _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
349
 
                tnl->Driver.Render.Points       = _gldSetupPoints[gld->iSetupFunc];
350
 
                tnl->Driver.Render.Line         = _gldSetupLine[gld->iSetupFunc];
351
 
                tnl->Driver.Render.Triangle     = _gldSetupTriangle[gld->iSetupFunc];
352
 
                tnl->Driver.Render.Quad         = _gldSetupQuad[gld->iSetupFunc];
353
 
//      }
354
 
 
355
 
        _GLD_DX9_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD));
356
 
        gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0;
357
 
        // Allocate primitive pointers
358
 
        // gldPB->pPoints is always first
359
 
        gldPB->pLines           = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine);
360
 
        gldPB->pTriangles       = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle);
361
 
 
362
 
        ASSERT(tnl->Driver.Render.BuildVertices);
363
 
        ASSERT(tnl->Driver.Render.PrimitiveNotify);
364
 
        ASSERT(tnl->Driver.Render.Points);
365
 
        ASSERT(tnl->Driver.Render.Line);
366
 
        ASSERT(tnl->Driver.Render.Triangle);
367
 
        ASSERT(tnl->Driver.Render.Quad);
368
 
        ASSERT(tnl->Driver.Render.ResetLineStipple);
369
 
        ASSERT(tnl->Driver.Render.Interp);
370
 
        ASSERT(tnl->Driver.Render.CopyPV);
371
 
        ASSERT(tnl->Driver.Render.ClippedLine);
372
 
        ASSERT(tnl->Driver.Render.ClippedPolygon);
373
 
        ASSERT(tnl->Driver.Render.Finish);
374
 
        
375
 
        tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 );
376
 
        
377
 
        if (VB->ClipOrMask) {
378
 
                tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
379
 
                clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
380
 
        }
381
 
        else {
382
 
                tab = (VB->Elts ? 
383
 
                        tnl->Driver.Render.PrimTabElts : 
384
 
                tnl->Driver.Render.PrimTabVerts);
385
 
        }
386
 
        
387
 
        do {
388
 
                GLuint i, length, flags = 0;
389
 
                for (i = 0 ; !(flags & PRIM_END) ; i += length) {
390
 
                        flags = VB->Primitive[i].mode;
391
 
                        length= VB->Primitive[i].count;
392
 
                        ASSERT(length || (flags & PRIM_END));
393
 
                        ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1);
394
 
                        if (length)
395
 
                                tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
396
 
                }
397
 
        } while (tnl->Driver.Render.Multipass &&
398
 
                tnl->Driver.Render.Multipass( ctx, ++pass ));
399
 
        
400
 
        
401
 
//      tnl->Driver.Render.Finish( ctx );
402
 
        
403
 
        _GLD_DX9_VB(Unlock(gldPB->pVB));
404
 
 
405
 
        _GLD_DX9_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, 0, gldPB->dwStride));
406
 
 
407
 
        if (gldPB->nPoints) {
408
 
                _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints));
409
 
                gldPB->nPoints = 0;
410
 
        }
411
 
 
412
 
        if (gldPB->nLines) {
413
 
                _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines));
414
 
                gldPB->nLines = 0;
415
 
        }
416
 
 
417
 
        if (gldPB->nTriangles) {
418
 
                _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles));
419
 
                gldPB->nTriangles = 0;
420
 
        }
421
 
 
422
 
        return GL_FALSE;                /* finished the pipe */
423
 
}
424
 
 
425
 
 
426
 
/**********************************************************************/
427
 
/*                          Render pipeline stage                     */
428
 
/**********************************************************************/
429
 
 
430
 
 
431
 
 
432
 
 
433
 
const struct tnl_pipeline_stage _gld_mesa_render_stage =
434
 
{
435
 
   "gld_mesa_render_stage",
436
 
   NULL,
437
 
   NULL,
438
 
   NULL,
439
 
   NULL,
440
 
   _gld_mesa_render_stage_run   /* run */
441
 
};
442
 
 
443
 
//---------------------------------------------------------------------------