~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r300/r300_ioctl.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) The Weather Channel, Inc.  2002.
 
3
Copyright (C) 2004 Nicolai Haehnle.
 
4
All Rights Reserved.
 
5
 
 
6
The Weather Channel (TM) funded Tungsten Graphics to develop the
 
7
initial release of the Radeon 8500 driver under the XFree86 license.
 
8
This notice must be preserved.
 
9
 
 
10
Permission is hereby granted, free of charge, to any person obtaining
 
11
a copy of this software and associated documentation files (the
 
12
"Software"), to deal in the Software without restriction, including
 
13
without limitation the rights to use, copy, modify, merge, publish,
 
14
distribute, sublicense, and/or sell copies of the Software, and to
 
15
permit persons to whom the Software is furnished to do so, subject to
 
16
the following conditions:
 
17
 
 
18
The above copyright notice and this permission notice (including the
 
19
next paragraph) shall be included in all copies or substantial
 
20
portions of the Software.
 
21
 
 
22
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
23
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
24
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
25
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 
26
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
27
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
28
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
29
 
 
30
**************************************************************************/
 
31
 
 
32
/**
 
33
 * \file
 
34
 *
 
35
 * \author Keith Whitwell <keith@tungstengraphics.com>
 
36
 *
 
37
 * \author Nicolai Haehnle <prefect_@gmx.net>
 
38
 */
 
39
 
 
40
#include <sched.h>
 
41
#include <errno.h>
 
42
 
 
43
#include "glheader.h"
 
44
#include "imports.h"
 
45
#include "macros.h"
 
46
#include "context.h"
 
47
#include "swrast/swrast.h"
 
48
 
 
49
#include "r300_context.h"
 
50
#include "radeon_ioctl.h"
 
51
#include "r300_ioctl.h"
 
52
#include "r300_cmdbuf.h"
 
53
#include "r300_state.h"
 
54
#include "r300_program.h"
 
55
#include "radeon_reg.h"
 
56
#include "r300_emit.h"
 
57
 
 
58
#include "vblank.h"
 
59
 
 
60
#define CLEARBUFFER_COLOR       0x1
 
61
#define CLEARBUFFER_DEPTH       0x2
 
62
#define CLEARBUFFER_STENCIL     0x4
 
63
 
 
64
static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
 
65
{
 
66
        GLcontext *ctx = r300->radeon.glCtx;
 
67
        __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
 
68
        GLuint cboffset, cbpitch;
 
69
        drm_r300_cmd_header_t *cmd2;
 
70
        int cmd_reserved = 0;
 
71
        int cmd_written = 0;
 
72
        drm_radeon_cmd_header_t *cmd = NULL;
 
73
        r300ContextPtr rmesa = r300;
 
74
 
 
75
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
76
                fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n",
 
77
                        __FUNCTION__, buffer ? "back" : "front",
 
78
                        dPriv->x, dPriv->y, dPriv->w, dPriv->h);
 
79
 
 
80
        if (buffer) {
 
81
                cboffset = r300->radeon.radeonScreen->backOffset;
 
82
                cbpitch = r300->radeon.radeonScreen->backPitch;
 
83
        } else {
 
84
                cboffset = r300->radeon.radeonScreen->frontOffset;
 
85
                cbpitch = r300->radeon.radeonScreen->frontPitch;
 
86
        }
 
87
 
 
88
        cboffset += r300->radeon.radeonScreen->fbLocation;
 
89
 
 
90
        cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 
91
        end_3d(rmesa);
 
92
 
 
93
        R300_STATECHANGE(r300, cb);
 
94
        reg_start(R300_RB3D_COLOROFFSET0, 0);
 
95
        e32(cboffset);
 
96
 
 
97
        if (r300->radeon.radeonScreen->cpp == 4)
 
98
                cbpitch |= R300_COLOR_FORMAT_ARGB8888;
 
99
        else
 
100
                cbpitch |= R300_COLOR_FORMAT_RGB565;
 
101
 
 
102
        if (r300->radeon.sarea->tiling_enabled)
 
103
                cbpitch |= R300_COLOR_TILE_ENABLE;
 
104
 
 
105
        reg_start(R300_RB3D_COLORPITCH0, 0);
 
106
        e32(cbpitch);
 
107
 
 
108
        R300_STATECHANGE(r300, cmk);
 
109
        reg_start(R300_RB3D_COLORMASK, 0);
 
110
 
 
111
        if (flags & CLEARBUFFER_COLOR) {
 
112
                e32((ctx->Color.ColorMask[BCOMP] ? R300_COLORMASK0_B : 0) |
 
113
                    (ctx->Color.ColorMask[GCOMP] ? R300_COLORMASK0_G : 0) |
 
114
                    (ctx->Color.ColorMask[RCOMP] ? R300_COLORMASK0_R : 0) |
 
115
                    (ctx->Color.ColorMask[ACOMP] ? R300_COLORMASK0_A : 0));
 
116
        } else {
 
117
                e32(0x0);
 
118
        }
 
119
 
 
120
        R300_STATECHANGE(r300, zs);
 
121
        reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2);
 
122
 
 
123
        {
 
124
                uint32_t t1, t2;
 
125
 
 
126
                t1 = 0x0;
 
127
                t2 = 0x0;
 
128
 
 
129
                if (flags & CLEARBUFFER_DEPTH) {
 
130
                        t1 |= R300_RB3D_Z_WRITE_ONLY;
 
131
                        t2 |=
 
132
                            (R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
 
133
                } else {
 
134
                        t1 |= R300_RB3D_Z_DISABLED_1;   // disable
 
135
                }
 
136
 
 
137
                if (flags & CLEARBUFFER_STENCIL) {
 
138
                        t1 |= R300_RB3D_STENCIL_ENABLE;
 
139
                        t2 |=
 
140
                            (R300_ZS_ALWAYS <<
 
141
                             R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
 
142
                            (R300_ZS_REPLACE <<
 
143
                             R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |
 
144
                            (R300_ZS_REPLACE <<
 
145
                             R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) |
 
146
                            (R300_ZS_REPLACE <<
 
147
                             R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) |
 
148
                            (R300_ZS_ALWAYS <<
 
149
                             R300_RB3D_ZS1_BACK_FUNC_SHIFT) |
 
150
                            (R300_ZS_REPLACE <<
 
151
                             R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) |
 
152
                            (R300_ZS_REPLACE <<
 
153
                             R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT) |
 
154
                            (R300_ZS_REPLACE <<
 
155
                             R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT);
 
156
                }
 
157
 
 
158
                e32(t1);
 
159
                e32(t2);
 
160
                e32(r300->state.stencil.clear);
 
161
        }
 
162
 
 
163
        cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__);
 
164
        cmd2[0].packet3.cmd_type = R300_CMD_PACKET3;
 
165
        cmd2[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
 
166
        cmd2[1].u = r300PackFloat32(dPriv->w / 2.0);
 
167
        cmd2[2].u = r300PackFloat32(dPriv->h / 2.0);
 
168
        cmd2[3].u = r300PackFloat32(ctx->Depth.Clear);
 
169
        cmd2[4].u = r300PackFloat32(1.0);
 
170
        cmd2[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
 
171
        cmd2[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
 
172
        cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
 
173
        cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
 
174
 
 
175
        reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
 
176
        e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
 
177
 
 
178
        reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
 
179
        e32(R300_RB3D_ZCACHE_UNKNOWN_03);
 
180
        cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 
181
}
 
182
 
 
183
static void r300EmitClearState(GLcontext * ctx)
 
184
{
 
185
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
186
        r300ContextPtr rmesa = r300;
 
187
        __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
 
188
        int i;
 
189
        int cmd_reserved = 0;
 
190
        int cmd_written = 0;
 
191
        drm_radeon_cmd_header_t *cmd = NULL;
 
192
        int has_tcl = 1;
 
193
 
 
194
        if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
 
195
                has_tcl = 0;
 
196
 
 
197
        /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and
 
198
         * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are
 
199
         * quite complex; see the functions in r300_emit.c.
 
200
         *
 
201
         * I believe it would be a good idea to extend the functions in
 
202
         * r300_emit.c so that they can be used to setup the default values for
 
203
         * these registers, as well as the actual values used for rendering.
 
204
         */
 
205
        R300_STATECHANGE(r300, vir[0]);
 
206
        reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
 
207
        if (!has_tcl)
 
208
                e32(0x22030003);
 
209
        else
 
210
                e32(0x21030003);
 
211
 
 
212
        /* disable fog */
 
213
        R300_STATECHANGE(r300, fogs);
 
214
        reg_start(R300_RE_FOG_STATE, 0);
 
215
        e32(0x0);
 
216
 
 
217
        R300_STATECHANGE(r300, vir[1]);
 
218
        reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
 
219
        e32(0xF688F688);
 
220
 
 
221
        /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */
 
222
        R300_STATECHANGE(r300, vic);
 
223
        reg_start(R300_VAP_INPUT_CNTL_0, 1);
 
224
        e32(R300_INPUT_CNTL_0_COLOR);
 
225
        e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
 
226
 
 
227
        if (!has_tcl) {
 
228
                R300_STATECHANGE(r300, vte);
 
229
                /* comes from fglrx startup of clear */
 
230
                reg_start(R300_SE_VTE_CNTL, 1);
 
231
                e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
 
232
                    R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
 
233
                    R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
 
234
                    R300_VPORT_Z_OFFSET_ENA);
 
235
                e32(0x8);
 
236
 
 
237
                reg_start(0x21dc, 0);
 
238
                e32(0xaaaaaaaa);
 
239
        }
 
240
 
 
241
        R300_STATECHANGE(r300, vof);
 
242
        reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
 
243
        e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
 
244
            R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT);
 
245
        e32(0x0);                       /* no textures */
 
246
 
 
247
        R300_STATECHANGE(r300, txe);
 
248
        reg_start(R300_TX_ENABLE, 0);
 
249
        e32(0x0);
 
250
 
 
251
        R300_STATECHANGE(r300, vpt);
 
252
        reg_start(R300_SE_VPORT_XSCALE, 5);
 
253
        efloat(1.0);
 
254
        efloat(dPriv->x);
 
255
        efloat(1.0);
 
256
        efloat(dPriv->y);
 
257
        efloat(1.0);
 
258
        efloat(0.0);
 
259
 
 
260
        R300_STATECHANGE(r300, at);
 
261
        reg_start(R300_PP_ALPHA_TEST, 0);
 
262
        e32(0x0);
 
263
 
 
264
        R300_STATECHANGE(r300, bld);
 
265
        reg_start(R300_RB3D_CBLEND, 1);
 
266
        e32(0x0);
 
267
        e32(0x0);
 
268
 
 
269
        R300_STATECHANGE(r300, vap_clip_cntl);
 
270
        reg_start(R300_VAP_CLIP_CNTL, 0);
 
271
        e32(R300_221C_CLEAR);
 
272
 
 
273
        R300_STATECHANGE(r300, ps);
 
274
        reg_start(R300_RE_POINTSIZE, 0);
 
275
        e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
 
276
            ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
 
277
 
 
278
        R300_STATECHANGE(r300, ri);
 
279
        reg_start(R300_RS_INTERP_0, 8);
 
280
        for (i = 0; i < 8; ++i) {
 
281
                e32(R300_RS_INTERP_USED);
 
282
        }
 
283
 
 
284
        R300_STATECHANGE(r300, rc);
 
285
        /* The second constant is needed to get glxgears display anything .. */
 
286
        reg_start(R300_RS_CNTL_0, 1);
 
287
        e32((1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18);
 
288
        e32(0x0);
 
289
 
 
290
        R300_STATECHANGE(r300, rr);
 
291
        reg_start(R300_RS_ROUTE_0, 0);
 
292
        e32(R300_RS_ROUTE_0_COLOR);
 
293
 
 
294
        R300_STATECHANGE(r300, fp);
 
295
        reg_start(R300_PFS_CNTL_0, 2);
 
296
        e32(0x0);
 
297
        e32(0x0);
 
298
        e32(0x0);
 
299
        reg_start(R300_PFS_NODE_0, 3);
 
300
        e32(0x0);
 
301
        e32(0x0);
 
302
        e32(0x0);
 
303
        e32(R300_PFS_NODE_OUTPUT_COLOR);
 
304
 
 
305
        R300_STATECHANGE(r300, fpi[0]);
 
306
        R300_STATECHANGE(r300, fpi[1]);
 
307
        R300_STATECHANGE(r300, fpi[2]);
 
308
        R300_STATECHANGE(r300, fpi[3]);
 
309
 
 
310
        reg_start(R300_PFS_INSTR0_0, 0);
 
311
        e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
 
312
 
 
313
        reg_start(R300_PFS_INSTR1_0, 0);
 
314
        e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
 
315
 
 
316
        reg_start(R300_PFS_INSTR2_0, 0);
 
317
        e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
 
318
 
 
319
        reg_start(R300_PFS_INSTR3_0, 0);
 
320
        e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
 
321
 
 
322
        if (has_tcl) {
 
323
                R300_STATECHANGE(r300, pvs);
 
324
                reg_start(R300_VAP_PVS_CNTL_1, 2);
 
325
                e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
 
326
                    (0 << R300_PVS_CNTL_1_POS_END_SHIFT) |
 
327
                    (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT));
 
328
                e32(0x0);
 
329
                e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
 
330
 
 
331
                R300_STATECHANGE(r300, vpi);
 
332
                vsf_start_fragment(0x0, 8);
 
333
                e32(VP_OUT(ADD, OUT, 0, XYZW));
 
334
                e32(VP_IN(IN, 0));
 
335
                e32(VP_ZERO());
 
336
                e32(0x0);
 
337
 
 
338
                e32(VP_OUT(ADD, OUT, 1, XYZW));
 
339
                e32(VP_IN(IN, 1));
 
340
                e32(VP_ZERO());
 
341
                e32(0x0);
 
342
        }
 
343
}
 
344
 
 
345
/**
 
346
 * Buffer clear
 
347
 */
 
348
static void r300Clear(GLcontext * ctx, GLbitfield mask)
 
349
{
 
350
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
351
        __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
 
352
        int flags = 0;
 
353
        int bits = 0;
 
354
        int swapped;
 
355
 
 
356
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
357
                fprintf(stderr, "r300Clear\n");
 
358
 
 
359
        {
 
360
                LOCK_HARDWARE(&r300->radeon);
 
361
                UNLOCK_HARDWARE(&r300->radeon);
 
362
                if (dPriv->numClipRects == 0)
 
363
                        return;
 
364
        }
 
365
 
 
366
        if (mask & BUFFER_BIT_FRONT_LEFT) {
 
367
                flags |= BUFFER_BIT_FRONT_LEFT;
 
368
                mask &= ~BUFFER_BIT_FRONT_LEFT;
 
369
        }
 
370
 
 
371
        if (mask & BUFFER_BIT_BACK_LEFT) {
 
372
                flags |= BUFFER_BIT_BACK_LEFT;
 
373
                mask &= ~BUFFER_BIT_BACK_LEFT;
 
374
        }
 
375
 
 
376
        if (mask & BUFFER_BIT_DEPTH) {
 
377
                bits |= CLEARBUFFER_DEPTH;
 
378
                mask &= ~BUFFER_BIT_DEPTH;
 
379
        }
 
380
 
 
381
        if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) {
 
382
                bits |= CLEARBUFFER_STENCIL;
 
383
                mask &= ~BUFFER_BIT_STENCIL;
 
384
        }
 
385
 
 
386
        if (mask) {
 
387
                if (RADEON_DEBUG & DEBUG_FALLBACKS)
 
388
                        fprintf(stderr, "%s: swrast clear, mask: %x\n",
 
389
                                __FUNCTION__, mask);
 
390
                _swrast_Clear(ctx, mask);
 
391
        }
 
392
 
 
393
        swapped = r300->radeon.sarea->pfCurrentPage == 1;
 
394
 
 
395
        /* Make sure it fits there. */
 
396
        r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);
 
397
        if (flags || bits)
 
398
                r300EmitClearState(ctx);
 
399
 
 
400
        if (flags & BUFFER_BIT_FRONT_LEFT) {
 
401
                r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
 
402
                bits = 0;
 
403
        }
 
404
 
 
405
        if (flags & BUFFER_BIT_BACK_LEFT) {
 
406
                r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
 
407
                bits = 0;
 
408
        }
 
409
 
 
410
        if (bits)
 
411
                r300ClearBuffer(r300, bits, 0);
 
412
 
 
413
}
 
414
 
 
415
void r300Flush(GLcontext * ctx)
 
416
{
 
417
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
418
 
 
419
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
420
                fprintf(stderr, "%s\n", __FUNCTION__);
 
421
 
 
422
        if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
 
423
                r300FlushCmdBuf(r300, __FUNCTION__);
 
424
}
 
425
 
 
426
#ifdef USER_BUFFERS
 
427
#include "r300_mem.h"
 
428
 
 
429
static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
 
430
{
 
431
        struct r300_dma_buffer *dmabuf;
 
432
        size = MAX2(size, RADEON_BUFFER_SIZE * 16);
 
433
 
 
434
        if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
 
435
                fprintf(stderr, "%s\n", __FUNCTION__);
 
436
 
 
437
        if (rmesa->dma.flush) {
 
438
                rmesa->dma.flush(rmesa);
 
439
        }
 
440
 
 
441
        if (rmesa->dma.current.buf)
 
442
                r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
 
443
 
 
444
        if (rmesa->dma.nr_released_bufs > 4)
 
445
                r300FlushCmdBuf(rmesa, __FUNCTION__);
 
446
 
 
447
        dmabuf = CALLOC_STRUCT(r300_dma_buffer);
 
448
        dmabuf->buf = (void *)1;        /* hack */
 
449
        dmabuf->refcount = 1;
 
450
 
 
451
        dmabuf->id = r300_mem_alloc(rmesa, 4, size);
 
452
        if (dmabuf->id == 0) {
 
453
                LOCK_HARDWARE(&rmesa->radeon);  /* no need to validate */
 
454
 
 
455
                r300FlushCmdBufLocked(rmesa, __FUNCTION__);
 
456
                radeonWaitForIdleLocked(&rmesa->radeon);
 
457
 
 
458
                dmabuf->id = r300_mem_alloc(rmesa, 4, size);
 
459
 
 
460
                UNLOCK_HARDWARE(&rmesa->radeon);
 
461
 
 
462
                if (dmabuf->id == 0) {
 
463
                        fprintf(stderr,
 
464
                                "Error: Could not get dma buffer... exiting\n");
 
465
                        _mesa_exit(-1);
 
466
                }
 
467
        }
 
468
 
 
469
        rmesa->dma.current.buf = dmabuf;
 
470
        rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id);
 
471
        rmesa->dma.current.end = size;
 
472
        rmesa->dma.current.start = 0;
 
473
        rmesa->dma.current.ptr = 0;
 
474
}
 
475
 
 
476
void r300ReleaseDmaRegion(r300ContextPtr rmesa,
 
477
                          struct r300_dma_region *region, const char *caller)
 
478
{
 
479
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
480
                fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
 
481
 
 
482
        if (!region->buf)
 
483
                return;
 
484
 
 
485
        if (rmesa->dma.flush)
 
486
                rmesa->dma.flush(rmesa);
 
487
 
 
488
        if (--region->buf->refcount == 0) {
 
489
                r300_mem_free(rmesa, region->buf->id);
 
490
                FREE(region->buf);
 
491
                rmesa->dma.nr_released_bufs++;
 
492
        }
 
493
 
 
494
        region->buf = 0;
 
495
        region->start = 0;
 
496
}
 
497
 
 
498
/* Allocates a region from rmesa->dma.current.  If there isn't enough
 
499
 * space in current, grab a new buffer (and discard what was left of current)
 
500
 */
 
501
void r300AllocDmaRegion(r300ContextPtr rmesa,
 
502
                        struct r300_dma_region *region,
 
503
                        int bytes, int alignment)
 
504
{
 
505
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
506
                fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
 
507
 
 
508
        if (rmesa->dma.flush)
 
509
                rmesa->dma.flush(rmesa);
 
510
 
 
511
        if (region->buf)
 
512
                r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
 
513
 
 
514
        alignment--;
 
515
        rmesa->dma.current.start = rmesa->dma.current.ptr =
 
516
            (rmesa->dma.current.ptr + alignment) & ~alignment;
 
517
 
 
518
        if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
 
519
                r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7);
 
520
 
 
521
        region->start = rmesa->dma.current.start;
 
522
        region->ptr = rmesa->dma.current.start;
 
523
        region->end = rmesa->dma.current.start + bytes;
 
524
        region->address = rmesa->dma.current.address;
 
525
        region->buf = rmesa->dma.current.buf;
 
526
        region->buf->refcount++;
 
527
 
 
528
        rmesa->dma.current.ptr += bytes;        /* bug - if alignment > 7 */
 
529
        rmesa->dma.current.start =
 
530
            rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
 
531
 
 
532
        assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
 
533
}
 
534
 
 
535
#else
 
536
static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
 
537
{
 
538
        struct r300_dma_buffer *dmabuf;
 
539
        int fd = rmesa->radeon.dri.fd;
 
540
        int index = 0;
 
541
        int size = 0;
 
542
        drmDMAReq dma;
 
543
        int ret;
 
544
 
 
545
        if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
 
546
                fprintf(stderr, "%s\n", __FUNCTION__);
 
547
 
 
548
        if (rmesa->dma.flush) {
 
549
                rmesa->dma.flush(rmesa);
 
550
        }
 
551
 
 
552
        if (rmesa->dma.current.buf)
 
553
                r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
 
554
 
 
555
        if (rmesa->dma.nr_released_bufs > 4)
 
556
                r300FlushCmdBuf(rmesa, __FUNCTION__);
 
557
 
 
558
        dma.context = rmesa->radeon.dri.hwContext;
 
559
        dma.send_count = 0;
 
560
        dma.send_list = NULL;
 
561
        dma.send_sizes = NULL;
 
562
        dma.flags = 0;
 
563
        dma.request_count = 1;
 
564
        dma.request_size = RADEON_BUFFER_SIZE;
 
565
        dma.request_list = &index;
 
566
        dma.request_sizes = &size;
 
567
        dma.granted_count = 0;
 
568
 
 
569
        LOCK_HARDWARE(&rmesa->radeon);  /* no need to validate */
 
570
 
 
571
        ret = drmDMA(fd, &dma);
 
572
 
 
573
        if (ret != 0) {
 
574
                /* Try to release some buffers and wait until we can't get any more */
 
575
                if (rmesa->dma.nr_released_bufs) {
 
576
                        r300FlushCmdBufLocked(rmesa, __FUNCTION__);
 
577
                }
 
578
 
 
579
                if (RADEON_DEBUG & DEBUG_DMA)
 
580
                        fprintf(stderr, "Waiting for buffers\n");
 
581
 
 
582
                radeonWaitForIdleLocked(&rmesa->radeon);
 
583
                ret = drmDMA(fd, &dma);
 
584
 
 
585
                if (ret != 0) {
 
586
                        UNLOCK_HARDWARE(&rmesa->radeon);
 
587
                        fprintf(stderr,
 
588
                                "Error: Could not get dma buffer... exiting\n");
 
589
                        _mesa_exit(-1);
 
590
                }
 
591
        }
 
592
 
 
593
        UNLOCK_HARDWARE(&rmesa->radeon);
 
594
 
 
595
        if (RADEON_DEBUG & DEBUG_DMA)
 
596
                fprintf(stderr, "Allocated buffer %d\n", index);
 
597
 
 
598
        dmabuf = CALLOC_STRUCT(r300_dma_buffer);
 
599
        dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
 
600
        dmabuf->refcount = 1;
 
601
 
 
602
        rmesa->dma.current.buf = dmabuf;
 
603
        rmesa->dma.current.address = dmabuf->buf->address;
 
604
        rmesa->dma.current.end = dmabuf->buf->total;
 
605
        rmesa->dma.current.start = 0;
 
606
        rmesa->dma.current.ptr = 0;
 
607
}
 
608
 
 
609
void r300ReleaseDmaRegion(r300ContextPtr rmesa,
 
610
                          struct r300_dma_region *region, const char *caller)
 
611
{
 
612
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
613
                fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
 
614
 
 
615
        if (!region->buf)
 
616
                return;
 
617
 
 
618
        if (rmesa->dma.flush)
 
619
                rmesa->dma.flush(rmesa);
 
620
 
 
621
        if (--region->buf->refcount == 0) {
 
622
                drm_radeon_cmd_header_t *cmd;
 
623
 
 
624
                if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
 
625
                        fprintf(stderr, "%s -- DISCARD BUF %d\n",
 
626
                                __FUNCTION__, region->buf->buf->idx);
 
627
                cmd =
 
628
                    (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
 
629
                                                                sizeof
 
630
                                                                (*cmd) / 4,
 
631
                                                                __FUNCTION__);
 
632
                cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
 
633
                cmd->dma.buf_idx = region->buf->buf->idx;
 
634
 
 
635
                FREE(region->buf);
 
636
                rmesa->dma.nr_released_bufs++;
 
637
        }
 
638
 
 
639
        region->buf = 0;
 
640
        region->start = 0;
 
641
}
 
642
 
 
643
/* Allocates a region from rmesa->dma.current.  If there isn't enough
 
644
 * space in current, grab a new buffer (and discard what was left of current)
 
645
 */
 
646
void r300AllocDmaRegion(r300ContextPtr rmesa,
 
647
                        struct r300_dma_region *region,
 
648
                        int bytes, int alignment)
 
649
{
 
650
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
651
                fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
 
652
 
 
653
        if (rmesa->dma.flush)
 
654
                rmesa->dma.flush(rmesa);
 
655
 
 
656
        if (region->buf)
 
657
                r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
 
658
 
 
659
        alignment--;
 
660
        rmesa->dma.current.start = rmesa->dma.current.ptr =
 
661
            (rmesa->dma.current.ptr + alignment) & ~alignment;
 
662
 
 
663
        if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
 
664
                r300RefillCurrentDmaRegion(rmesa);
 
665
 
 
666
        region->start = rmesa->dma.current.start;
 
667
        region->ptr = rmesa->dma.current.start;
 
668
        region->end = rmesa->dma.current.start + bytes;
 
669
        region->address = rmesa->dma.current.address;
 
670
        region->buf = rmesa->dma.current.buf;
 
671
        region->buf->refcount++;
 
672
 
 
673
        rmesa->dma.current.ptr += bytes;        /* bug - if alignment > 7 */
 
674
        rmesa->dma.current.start =
 
675
            rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
 
676
 
 
677
        assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
 
678
}
 
679
 
 
680
#endif
 
681
 
 
682
GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
 
683
                           GLint size)
 
684
{
 
685
        int offset =
 
686
            (char *)pointer -
 
687
            (char *)rmesa->radeon.radeonScreen->gartTextures.map;
 
688
        int valid = (size >= 0 && offset >= 0
 
689
                     && offset + size <
 
690
                     rmesa->radeon.radeonScreen->gartTextures.size);
 
691
 
 
692
        if (RADEON_DEBUG & DEBUG_IOCTL)
 
693
                fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
 
694
                        valid);
 
695
 
 
696
        return valid;
 
697
}
 
698
 
 
699
GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
 
700
{
 
701
        int offset =
 
702
            (char *)pointer -
 
703
            (char *)rmesa->radeon.radeonScreen->gartTextures.map;
 
704
 
 
705
        //fprintf(stderr, "offset=%08x\n", offset);
 
706
 
 
707
        if (offset < 0
 
708
            || offset > rmesa->radeon.radeonScreen->gartTextures.size)
 
709
                return ~0;
 
710
        else
 
711
                return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
 
712
}
 
713
 
 
714
void r300InitIoctlFuncs(struct dd_function_table *functions)
 
715
{
 
716
        functions->Clear = r300Clear;
 
717
        functions->Finish = radeonFinish;
 
718
        functions->Flush = r300Flush;
 
719
}