OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [drm-4.0/] [radeon_state.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* radeon_state.c -- State support for Radeon -*- linux-c -*-
2
 *
3
 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice (including the next
14
 * paragraph) shall be included in all copies or substantial portions of the
15
 * Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 * DEALINGS IN THE SOFTWARE.
24
 *
25
 * Authors:
26
 *    Kevin E. Martin <martin@valinux.com>
27
 *    Gareth Hughes <gareth@valinux.com>
28
 *
29
 */
30
 
31
#define __NO_VERSION__
32
#include "drmP.h"
33
#include "radeon_drv.h"
34
#include "drm.h"
35
#include <linux/delay.h>
36
 
37
 
38
/* ================================================================
39
 * CP hardware state programming functions
40
 */
41
 
42
static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
43
                                          drm_clip_rect_t *box )
44
{
45
        RING_LOCALS;
46
 
47
        DRM_DEBUG( "   box:  x1=%d y1=%d  x2=%d y2=%d\n",
48
                   box->x1, box->y1, box->x2, box->y2 );
49
 
50
        BEGIN_RING( 4 );
51
 
52
        OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
53
        OUT_RING( (box->y1 << 16) | box->x1 );
54
 
55
        OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
56
        OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
57
 
58
        ADVANCE_RING();
59
}
60
 
61
static inline void radeon_emit_context( drm_radeon_private_t *dev_priv )
62
{
63
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
64
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
65
        RING_LOCALS;
66
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
67
 
68
        BEGIN_RING( 14 );
69
 
70
        OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
71
        OUT_RING( ctx->pp_misc );
72
        OUT_RING( ctx->pp_fog_color );
73
        OUT_RING( ctx->re_solid_color );
74
        OUT_RING( ctx->rb3d_blendcntl );
75
        OUT_RING( ctx->rb3d_depthoffset );
76
        OUT_RING( ctx->rb3d_depthpitch );
77
        OUT_RING( ctx->rb3d_zstencilcntl );
78
 
79
        OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
80
        OUT_RING( ctx->pp_cntl );
81
        OUT_RING( ctx->rb3d_cntl );
82
        OUT_RING( ctx->rb3d_coloroffset );
83
 
84
        OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
85
        OUT_RING( ctx->rb3d_colorpitch );
86
 
87
        ADVANCE_RING();
88
}
89
 
90
static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv )
91
{
92
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
93
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
94
        RING_LOCALS;
95
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
96
 
97
        BEGIN_RING( 2 );
98
 
99
        OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
100
        OUT_RING( ctx->se_coord_fmt );
101
 
102
        ADVANCE_RING();
103
}
104
 
105
static inline void radeon_emit_line( drm_radeon_private_t *dev_priv )
106
{
107
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
108
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
109
        RING_LOCALS;
110
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
111
 
112
        BEGIN_RING( 5 );
113
 
114
        OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
115
        OUT_RING( ctx->re_line_pattern );
116
        OUT_RING( ctx->re_line_state );
117
 
118
        OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
119
        OUT_RING( ctx->se_line_width );
120
 
121
        ADVANCE_RING();
122
}
123
 
124
static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv )
125
{
126
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
127
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
128
        RING_LOCALS;
129
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
130
 
131
        BEGIN_RING( 5 );
132
 
133
        OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
134
        OUT_RING( ctx->pp_lum_matrix );
135
 
136
        OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
137
        OUT_RING( ctx->pp_rot_matrix_0 );
138
        OUT_RING( ctx->pp_rot_matrix_1 );
139
 
140
        ADVANCE_RING();
141
}
142
 
143
static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv )
144
{
145
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
146
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
147
        RING_LOCALS;
148
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
149
 
150
        BEGIN_RING( 4 );
151
 
152
        OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
153
        OUT_RING( ctx->rb3d_stencilrefmask );
154
        OUT_RING( ctx->rb3d_ropcntl );
155
        OUT_RING( ctx->rb3d_planemask );
156
 
157
        ADVANCE_RING();
158
}
159
 
160
static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv )
161
{
162
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
163
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
164
        RING_LOCALS;
165
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
166
 
167
        BEGIN_RING( 7 );
168
 
169
        OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
170
        OUT_RING( ctx->se_vport_xscale );
171
        OUT_RING( ctx->se_vport_xoffset );
172
        OUT_RING( ctx->se_vport_yscale );
173
        OUT_RING( ctx->se_vport_yoffset );
174
        OUT_RING( ctx->se_vport_zscale );
175
        OUT_RING( ctx->se_vport_zoffset );
176
 
177
        ADVANCE_RING();
178
}
179
 
180
static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv )
181
{
182
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
183
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
184
        RING_LOCALS;
185
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
186
 
187
        BEGIN_RING( 4 );
188
 
189
        OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
190
        OUT_RING( ctx->se_cntl );
191
        OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
192
        OUT_RING( ctx->se_cntl_status );
193
 
194
        ADVANCE_RING();
195
}
196
 
197
static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv )
198
{
199
#ifdef TCL_ENABLE
200
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
201
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
202
        RING_LOCALS;
203
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
204
 
205
        BEGIN_RING( 29 );
206
 
207
        OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) );
208
        OUT_RING( ctx->se_tcl_material_emmissive.red );
209
        OUT_RING( ctx->se_tcl_material_emmissive.green );
210
        OUT_RING( ctx->se_tcl_material_emmissive.blue );
211
        OUT_RING( ctx->se_tcl_material_emmissive.alpha );
212
        OUT_RING( ctx->se_tcl_material_ambient.red );
213
        OUT_RING( ctx->se_tcl_material_ambient.green );
214
        OUT_RING( ctx->se_tcl_material_ambient.blue );
215
        OUT_RING( ctx->se_tcl_material_ambient.alpha );
216
        OUT_RING( ctx->se_tcl_material_diffuse.red );
217
        OUT_RING( ctx->se_tcl_material_diffuse.green );
218
        OUT_RING( ctx->se_tcl_material_diffuse.blue );
219
        OUT_RING( ctx->se_tcl_material_diffuse.alpha );
220
        OUT_RING( ctx->se_tcl_material_specular.red );
221
        OUT_RING( ctx->se_tcl_material_specular.green );
222
        OUT_RING( ctx->se_tcl_material_specular.blue );
223
        OUT_RING( ctx->se_tcl_material_specular.alpha );
224
        OUT_RING( ctx->se_tcl_shininess );
225
        OUT_RING( ctx->se_tcl_output_vtx_fmt );
226
        OUT_RING( ctx->se_tcl_output_vtx_sel );
227
        OUT_RING( ctx->se_tcl_matrix_select_0 );
228
        OUT_RING( ctx->se_tcl_matrix_select_1 );
229
        OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl );
230
        OUT_RING( ctx->se_tcl_texture_proc_ctl );
231
        OUT_RING( ctx->se_tcl_light_model_ctl );
232
        for ( i = 0 ; i < 4 ; i++ ) {
233
                OUT_RING( ctx->se_tcl_per_light_ctl[i] );
234
        }
235
 
236
        ADVANCE_RING();
237
#else
238
        DRM_ERROR( "TCL not enabled!\n" );
239
#endif
240
}
241
 
242
static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv )
243
{
244
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
245
        drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
246
        RING_LOCALS;
247
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
248
 
249
        BEGIN_RING( 2 );
250
 
251
        OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
252
        OUT_RING( ctx->re_misc );
253
 
254
        ADVANCE_RING();
255
}
256
 
257
static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
258
{
259
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
260
        drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0];
261
        RING_LOCALS;
262
        DRM_DEBUG( "    %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
263
 
264
        BEGIN_RING( 9 );
265
 
266
        OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
267
        OUT_RING( tex->pp_txfilter );
268
        OUT_RING( tex->pp_txformat );
269
        OUT_RING( tex->pp_txoffset );
270
        OUT_RING( tex->pp_txcblend );
271
        OUT_RING( tex->pp_txablend );
272
        OUT_RING( tex->pp_tfactor );
273
 
274
        OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
275
        OUT_RING( tex->pp_border_color );
276
 
277
        ADVANCE_RING();
278
}
279
 
280
static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
281
{
282
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
283
        drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1];
284
        RING_LOCALS;
285
        DRM_DEBUG( "    %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
286
 
287
        BEGIN_RING( 9 );
288
 
289
        OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
290
        OUT_RING( tex->pp_txfilter );
291
        OUT_RING( tex->pp_txformat );
292
        OUT_RING( tex->pp_txoffset );
293
        OUT_RING( tex->pp_txcblend );
294
        OUT_RING( tex->pp_txablend );
295
        OUT_RING( tex->pp_tfactor );
296
 
297
        OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
298
        OUT_RING( tex->pp_border_color );
299
 
300
        ADVANCE_RING();
301
}
302
 
303
static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
304
{
305
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
306
        drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2];
307
        RING_LOCALS;
308
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
309
 
310
        BEGIN_RING( 9 );
311
 
312
        OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
313
        OUT_RING( tex->pp_txfilter );
314
        OUT_RING( tex->pp_txformat );
315
        OUT_RING( tex->pp_txoffset );
316
        OUT_RING( tex->pp_txcblend );
317
        OUT_RING( tex->pp_txablend );
318
        OUT_RING( tex->pp_tfactor );
319
 
320
        OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
321
        OUT_RING( tex->pp_border_color );
322
 
323
        ADVANCE_RING();
324
}
325
 
326
static inline void radeon_emit_state( drm_radeon_private_t *dev_priv )
327
{
328
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
329
        unsigned int dirty = sarea_priv->dirty;
330
 
331
        DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
332
 
333
        if ( dirty & RADEON_UPLOAD_CONTEXT ) {
334
                radeon_emit_context( dev_priv );
335
                sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT;
336
        }
337
 
338
        if ( dirty & RADEON_UPLOAD_VERTFMT ) {
339
                radeon_emit_vertfmt( dev_priv );
340
                sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT;
341
        }
342
 
343
        if ( dirty & RADEON_UPLOAD_LINE ) {
344
                radeon_emit_line( dev_priv );
345
                sarea_priv->dirty &= ~RADEON_UPLOAD_LINE;
346
        }
347
 
348
        if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
349
                radeon_emit_bumpmap( dev_priv );
350
                sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP;
351
        }
352
 
353
        if ( dirty & RADEON_UPLOAD_MASKS ) {
354
                radeon_emit_masks( dev_priv );
355
                sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS;
356
        }
357
 
358
        if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
359
                radeon_emit_viewport( dev_priv );
360
                sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT;
361
        }
362
 
363
        if ( dirty & RADEON_UPLOAD_SETUP ) {
364
                radeon_emit_setup( dev_priv );
365
                sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP;
366
        }
367
 
368
        if ( dirty & RADEON_UPLOAD_TCL ) {
369
#ifdef TCL_ENABLE
370
                radeon_emit_tcl( dev_priv );
371
#endif
372
                sarea_priv->dirty &= ~RADEON_UPLOAD_TCL;
373
        }
374
 
375
        if ( dirty & RADEON_UPLOAD_MISC ) {
376
                radeon_emit_misc( dev_priv );
377
                sarea_priv->dirty &= ~RADEON_UPLOAD_MISC;
378
        }
379
 
380
        if ( dirty & RADEON_UPLOAD_TEX0 ) {
381
                radeon_emit_tex0( dev_priv );
382
                sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0;
383
        }
384
 
385
        if ( dirty & RADEON_UPLOAD_TEX1 ) {
386
                radeon_emit_tex1( dev_priv );
387
                sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1;
388
        }
389
 
390
        if ( dirty & RADEON_UPLOAD_TEX2 ) {
391
#if 0
392
                radeon_emit_tex2( dev_priv );
393
#endif
394
                sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2;
395
        }
396
 
397
        sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
398
                               RADEON_UPLOAD_TEX1IMAGES |
399
                               RADEON_UPLOAD_TEX2IMAGES |
400
                               RADEON_REQUIRE_QUIESCENCE);
401
}
402
 
403
 
404
#if RADEON_PERFORMANCE_BOXES
405
/* ================================================================
406
 * Performance monitoring functions
407
 */
408
 
409
static void radeon_clear_box( drm_radeon_private_t *dev_priv,
410
                              int x, int y, int w, int h,
411
                              int r, int g, int b )
412
{
413
        u32 pitch, offset;
414
        u32 color;
415
        RING_LOCALS;
416
 
417
        switch ( dev_priv->color_fmt ) {
418
        case RADEON_COLOR_FORMAT_RGB565:
419
                color = (((r & 0xf8) << 8) |
420
                         ((g & 0xfc) << 3) |
421
                         ((b & 0xf8) >> 3));
422
                break;
423
        case RADEON_COLOR_FORMAT_ARGB8888:
424
        default:
425
                color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
426
                break;
427
        }
428
 
429
        offset = dev_priv->back_offset;
430
        pitch = dev_priv->back_pitch >> 3;
431
 
432
        BEGIN_RING( 6 );
433
 
434
        OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
435
        OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
436
                  RADEON_GMC_BRUSH_SOLID_COLOR |
437
                  (dev_priv->color_fmt << 8) |
438
                  RADEON_GMC_SRC_DATATYPE_COLOR |
439
                  RADEON_ROP3_P |
440
                  RADEON_GMC_CLR_CMP_CNTL_DIS );
441
 
442
        OUT_RING( (pitch << 22) | (offset >> 5) );
443
        OUT_RING( color );
444
 
445
        OUT_RING( (x << 16) | y );
446
        OUT_RING( (w << 16) | h );
447
 
448
        ADVANCE_RING();
449
}
450
 
451
static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
452
{
453
        if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
454
                radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
455
        } else {
456
                atomic_set( &dev_priv->idle_count, 0 );
457
        }
458
}
459
 
460
#endif
461
 
462
 
463
/* ================================================================
464
 * CP command dispatch functions
465
 */
466
 
467
static void radeon_print_dirty( const char *msg, unsigned int flags )
468
{
469
        DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
470
                   msg,
471
                   flags,
472
                   (flags & RADEON_UPLOAD_CONTEXT)     ? "context, " : "",
473
                   (flags & RADEON_UPLOAD_VERTFMT)     ? "vertfmt, " : "",
474
                   (flags & RADEON_UPLOAD_LINE)        ? "line, " : "",
475
                   (flags & RADEON_UPLOAD_BUMPMAP)     ? "bumpmap, " : "",
476
                   (flags & RADEON_UPLOAD_MASKS)       ? "masks, " : "",
477
                   (flags & RADEON_UPLOAD_VIEWPORT)    ? "viewport, " : "",
478
                   (flags & RADEON_UPLOAD_SETUP)       ? "setup, " : "",
479
                   (flags & RADEON_UPLOAD_TCL)         ? "tcl, " : "",
480
                   (flags & RADEON_UPLOAD_MISC)        ? "misc, " : "",
481
                   (flags & RADEON_UPLOAD_TEX0)        ? "tex0, " : "",
482
                   (flags & RADEON_UPLOAD_TEX1)        ? "tex1, " : "",
483
                   (flags & RADEON_UPLOAD_TEX2)        ? "tex2, " : "",
484
                   (flags & RADEON_UPLOAD_CLIPRECTS)   ? "cliprects, " : "",
485
                   (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
486
}
487
 
488
static void radeon_cp_dispatch_clear( drm_device_t *dev,
489
                                      drm_radeon_clear_t *clear )
490
{
491
        drm_radeon_private_t *dev_priv = dev->dev_private;
492
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
493
        int nbox = sarea_priv->nbox;
494
        drm_clip_rect_t *pbox = sarea_priv->boxes;
495
        unsigned int flags = clear->flags;
496
        int i;
497
        RING_LOCALS;
498
        DRM_DEBUG( "%s\n", __FUNCTION__ );
499
 
500
        radeon_update_ring_snapshot( dev_priv );
501
 
502
        if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
503
                unsigned int tmp = flags;
504
 
505
                flags &= ~(RADEON_FRONT | RADEON_BACK);
506
                if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;
507
                if ( tmp & RADEON_BACK )  flags |= RADEON_FRONT;
508
        }
509
 
510
        for ( i = 0 ; i < nbox ; i++ ) {
511
                int x = pbox[i].x1;
512
                int y = pbox[i].y1;
513
                int w = pbox[i].x2 - x;
514
                int h = pbox[i].y2 - y;
515
 
516
                DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
517
                           x, y, w, h, flags );
518
 
519
                if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
520
                        BEGIN_RING( 4 );
521
 
522
                        /* Ensure the 3D stream is idle before doing a
523
                         * 2D fill to clear the front or back buffer.
524
                         */
525
                        RADEON_WAIT_UNTIL_3D_IDLE();
526
 
527
                        OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
528
                        OUT_RING( sarea_priv->context_state.rb3d_planemask );
529
 
530
                        ADVANCE_RING();
531
 
532
                        /* Make sure we restore the 3D state next time.
533
                         */
534
                        dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
535
                                                        RADEON_UPLOAD_MASKS);
536
                }
537
 
538
                if ( flags & RADEON_FRONT ) {
539
                        BEGIN_RING( 6 );
540
 
541
                        OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
542
                        OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
543
                                  RADEON_GMC_BRUSH_SOLID_COLOR |
544
                                  (dev_priv->color_fmt << 8) |
545
                                  RADEON_GMC_SRC_DATATYPE_COLOR |
546
                                  RADEON_ROP3_P |
547
                                  RADEON_GMC_CLR_CMP_CNTL_DIS );
548
 
549
                        OUT_RING( dev_priv->front_pitch_offset );
550
                        OUT_RING( clear->clear_color );
551
 
552
                        OUT_RING( (x << 16) | y );
553
                        OUT_RING( (w << 16) | h );
554
 
555
                        ADVANCE_RING();
556
                }
557
 
558
                if ( flags & RADEON_BACK ) {
559
                        BEGIN_RING( 6 );
560
 
561
                        OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
562
                        OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
563
                                  RADEON_GMC_BRUSH_SOLID_COLOR |
564
                                  (dev_priv->color_fmt << 8) |
565
                                  RADEON_GMC_SRC_DATATYPE_COLOR |
566
                                  RADEON_ROP3_P |
567
                                  RADEON_GMC_CLR_CMP_CNTL_DIS );
568
 
569
                        OUT_RING( dev_priv->back_pitch_offset );
570
                        OUT_RING( clear->clear_color );
571
 
572
                        OUT_RING( (x << 16) | y );
573
                        OUT_RING( (w << 16) | h );
574
 
575
                        ADVANCE_RING();
576
 
577
                }
578
 
579
                if ( flags & RADEON_DEPTH ) {
580
                        drm_radeon_depth_clear_t *depth_clear =
581
                           &dev_priv->depth_clear;
582
 
583
                        if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
584
                                radeon_emit_state( dev_priv );
585
                        }
586
 
587
                        /* FIXME: Render a rectangle to clear the depth
588
                         * buffer.  So much for those "fast Z clears"...
589
                         */
590
                        BEGIN_RING( 23 );
591
 
592
                        RADEON_WAIT_UNTIL_2D_IDLE();
593
 
594
                        OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
595
                        OUT_RING( 0x00000000 );
596
                        OUT_RING( depth_clear->rb3d_cntl );
597
                        OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) );
598
                        OUT_RING( depth_clear->rb3d_zstencilcntl );
599
                        OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) );
600
                        OUT_RING( 0x00000000 );
601
                        OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
602
                        OUT_RING( depth_clear->se_cntl );
603
 
604
                        OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) );
605
                        OUT_RING( RADEON_VTX_Z_PRESENT );
606
                        OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
607
                                   RADEON_PRIM_WALK_RING |
608
                                   RADEON_MAOS_ENABLE |
609
                                   RADEON_VTX_FMT_RADEON_MODE |
610
                                   (3 << RADEON_NUM_VERTICES_SHIFT)) );
611
 
612
                        OUT_RING( clear->rect.ui[CLEAR_X1] );
613
                        OUT_RING( clear->rect.ui[CLEAR_Y1] );
614
                        OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
615
 
616
                        OUT_RING( clear->rect.ui[CLEAR_X1] );
617
                        OUT_RING( clear->rect.ui[CLEAR_Y2] );
618
                        OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
619
 
620
                        OUT_RING( clear->rect.ui[CLEAR_X2] );
621
                        OUT_RING( clear->rect.ui[CLEAR_Y2] );
622
                        OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
623
 
624
                        ADVANCE_RING();
625
 
626
                        /* Make sure we restore the 3D state next time.
627
                         */
628
                        dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
629
                                                        RADEON_UPLOAD_SETUP |
630
                                                        RADEON_UPLOAD_MASKS);
631
                }
632
        }
633
 
634
        /* Increment the clear counter.  The client-side 3D driver must
635
         * wait on this value before performing the clear ioctl.  We
636
         * need this because the card's so damned fast...
637
         */
638
        dev_priv->sarea_priv->last_clear++;
639
 
640
        BEGIN_RING( 4 );
641
 
642
        RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear );
643
        RADEON_WAIT_UNTIL_IDLE();
644
 
645
        ADVANCE_RING();
646
}
647
 
648
static void radeon_cp_dispatch_swap( drm_device_t *dev )
649
{
650
        drm_radeon_private_t *dev_priv = dev->dev_private;
651
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
652
        int nbox = sarea_priv->nbox;
653
        drm_clip_rect_t *pbox = sarea_priv->boxes;
654
        int i;
655
        RING_LOCALS;
656
        DRM_DEBUG( "%s\n", __FUNCTION__ );
657
 
658
        radeon_update_ring_snapshot( dev_priv );
659
 
660
#if RADEON_PERFORMANCE_BOXES
661
        /* Do some trivial performance monitoring...
662
         */
663
        radeon_cp_performance_boxes( dev_priv );
664
#endif
665
 
666
        /* Wait for the 3D stream to idle before dispatching the bitblt.
667
         * This will prevent data corruption between the two streams.
668
         */
669
        BEGIN_RING( 2 );
670
 
671
        RADEON_WAIT_UNTIL_3D_IDLE();
672
 
673
        ADVANCE_RING();
674
 
675
        for ( i = 0 ; i < nbox ; i++ ) {
676
                int x = pbox[i].x1;
677
                int y = pbox[i].y1;
678
                int w = pbox[i].x2 - x;
679
                int h = pbox[i].y2 - y;
680
 
681
                DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n",
682
                           x, y, w, h );
683
 
684
                BEGIN_RING( 7 );
685
 
686
                OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) );
687
                OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
688
                          RADEON_GMC_DST_PITCH_OFFSET_CNTL |
689
                          RADEON_GMC_BRUSH_NONE |
690
                          (dev_priv->color_fmt << 8) |
691
                          RADEON_GMC_SRC_DATATYPE_COLOR |
692
                          RADEON_ROP3_S |
693
                          RADEON_DP_SRC_SOURCE_MEMORY |
694
                          RADEON_GMC_CLR_CMP_CNTL_DIS |
695
                          RADEON_GMC_WR_MSK_DIS );
696
 
697
                OUT_RING( dev_priv->back_pitch_offset );
698
                OUT_RING( dev_priv->front_pitch_offset );
699
 
700
                OUT_RING( (x << 16) | y );
701
                OUT_RING( (x << 16) | y );
702
                OUT_RING( (w << 16) | h );
703
 
704
                ADVANCE_RING();
705
        }
706
 
707
        /* Increment the frame counter.  The client-side 3D driver must
708
         * throttle the framerate by waiting for this value before
709
         * performing the swapbuffer ioctl.
710
         */
711
        dev_priv->sarea_priv->last_frame++;
712
 
713
        BEGIN_RING( 4 );
714
 
715
        RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
716
        RADEON_WAIT_UNTIL_2D_IDLE();
717
 
718
        ADVANCE_RING();
719
}
720
 
721
static void radeon_cp_dispatch_flip( drm_device_t *dev )
722
{
723
        drm_radeon_private_t *dev_priv = dev->dev_private;
724
        RING_LOCALS;
725
        DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
726
 
727
        radeon_update_ring_snapshot( dev_priv );
728
 
729
#if RADEON_PERFORMANCE_BOXES
730
        /* Do some trivial performance monitoring...
731
         */
732
        radeon_cp_performance_boxes( dev_priv );
733
#endif
734
 
735
        BEGIN_RING( 6 );
736
 
737
        RADEON_WAIT_UNTIL_3D_IDLE();
738
        RADEON_WAIT_UNTIL_PAGE_FLIPPED();
739
 
740
        OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
741
 
742
        if ( dev_priv->current_page == 0 ) {
743
                OUT_RING( dev_priv->back_offset );
744
                dev_priv->current_page = 1;
745
        } else {
746
                OUT_RING( dev_priv->front_offset );
747
                dev_priv->current_page = 0;
748
        }
749
 
750
        ADVANCE_RING();
751
 
752
        /* Increment the frame counter.  The client-side 3D driver must
753
         * throttle the framerate by waiting for this value before
754
         * performing the swapbuffer ioctl.
755
         */
756
        dev_priv->sarea_priv->last_frame++;
757
 
758
        BEGIN_RING( 2 );
759
 
760
        RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
761
 
762
        ADVANCE_RING();
763
}
764
 
765
static void radeon_cp_dispatch_vertex( drm_device_t *dev,
766
                                       drm_buf_t *buf )
767
{
768
        drm_radeon_private_t *dev_priv = dev->dev_private;
769
        drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
770
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
771
        int format = sarea_priv->vc_format;
772
        int offset = dev_priv->agp_buffers_offset + buf->offset;
773
        int size = buf->used;
774
        int prim = buf_priv->prim;
775
        int i = 0;
776
        RING_LOCALS;
777
        DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox );
778
 
779
        radeon_update_ring_snapshot( dev_priv );
780
 
781
        if ( 0 )
782
                radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty );
783
 
784
        if ( buf->used ) {
785
                buf_priv->dispatched = 1;
786
 
787
                if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
788
                        radeon_emit_state( dev_priv );
789
                }
790
 
791
                do {
792
                        /* Emit the next set of up to three cliprects */
793
                        if ( i < sarea_priv->nbox ) {
794
                                radeon_emit_clip_rect( dev_priv,
795
                                                       &sarea_priv->boxes[i] );
796
                        }
797
 
798
                        /* Emit the vertex buffer rendering commands */
799
                        BEGIN_RING( 5 );
800
 
801
                        OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
802
                        OUT_RING( offset );
803
                        OUT_RING( size );
804
                        OUT_RING( format );
805
                        OUT_RING( prim | RADEON_PRIM_WALK_LIST |
806
                                  RADEON_COLOR_ORDER_RGBA |
807
                                  RADEON_VTX_FMT_RADEON_MODE |
808
                                  (size << RADEON_NUM_VERTICES_SHIFT) );
809
 
810
                        ADVANCE_RING();
811
 
812
                        i++;
813
                } while ( i < sarea_priv->nbox );
814
        }
815
 
816
        if ( buf_priv->discard ) {
817
                buf_priv->age = dev_priv->sarea_priv->last_dispatch;
818
 
819
                /* Emit the vertex buffer age */
820
                BEGIN_RING( 2 );
821
                RADEON_DISPATCH_AGE( buf_priv->age );
822
                ADVANCE_RING();
823
 
824
                buf->pending = 1;
825
                buf->used = 0;
826
                /* FIXME: Check dispatched field */
827
                buf_priv->dispatched = 0;
828
        }
829
 
830
        dev_priv->sarea_priv->last_dispatch++;
831
 
832
        sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
833
        sarea_priv->nbox = 0;
834
}
835
 
836
 
837
static void radeon_cp_dispatch_indirect( drm_device_t *dev,
838
                                         drm_buf_t *buf,
839
                                         int start, int end )
840
{
841
        drm_radeon_private_t *dev_priv = dev->dev_private;
842
        drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
843
        RING_LOCALS;
844
        DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
845
                   buf->idx, start, end );
846
 
847
        radeon_update_ring_snapshot( dev_priv );
848
 
849
        if ( start != end ) {
850
                int offset = (dev_priv->agp_buffers_offset
851
                              + buf->offset + start);
852
                int dwords = (end - start + 3) / sizeof(u32);
853
 
854
                /* Indirect buffer data must be an even number of
855
                 * dwords, so if we've been given an odd number we must
856
                 * pad the data with a Type-2 CP packet.
857
                 */
858
                if ( dwords & 1 ) {
859
                        u32 *data = (u32 *)
860
                                ((char *)dev_priv->buffers->handle
861
                                 + buf->offset + start);
862
                        data[dwords++] = RADEON_CP_PACKET2;
863
                }
864
 
865
                buf_priv->dispatched = 1;
866
 
867
                /* Fire off the indirect buffer */
868
                BEGIN_RING( 3 );
869
 
870
                OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) );
871
                OUT_RING( offset );
872
                OUT_RING( dwords );
873
 
874
                ADVANCE_RING();
875
        }
876
 
877
        if ( buf_priv->discard ) {
878
                buf_priv->age = dev_priv->sarea_priv->last_dispatch;
879
 
880
                /* Emit the indirect buffer age */
881
                BEGIN_RING( 2 );
882
                RADEON_DISPATCH_AGE( buf_priv->age );
883
                ADVANCE_RING();
884
 
885
                buf->pending = 1;
886
                buf->used = 0;
887
                /* FIXME: Check dispatched field */
888
                buf_priv->dispatched = 0;
889
        }
890
 
891
        dev_priv->sarea_priv->last_dispatch++;
892
}
893
 
894
static void radeon_cp_dispatch_indices( drm_device_t *dev,
895
                                        drm_buf_t *buf,
896
                                        int start, int end,
897
                                        int count )
898
{
899
        drm_radeon_private_t *dev_priv = dev->dev_private;
900
        drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
901
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
902
        int format = sarea_priv->vc_format;
903
        int offset = dev_priv->agp_buffers_offset;
904
        int prim = buf_priv->prim;
905
        u32 *data;
906
        int dwords;
907
        int i = 0;
908
        RING_LOCALS;
909
        DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
910
 
911
        radeon_update_ring_snapshot( dev_priv );
912
 
913
        if ( 0 )
914
                radeon_print_dirty( "dispatch_indices", sarea_priv->dirty );
915
 
916
        if ( start != end ) {
917
                buf_priv->dispatched = 1;
918
 
919
                if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
920
                        radeon_emit_state( dev_priv );
921
                }
922
 
923
                dwords = (end - start + 3) / sizeof(u32);
924
 
925
                data = (u32 *)((char *)dev_priv->buffers->handle
926
                               + buf->offset + start);
927
 
928
                data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
929
 
930
                data[1] = offset;
931
                data[2] = RADEON_MAX_VB_VERTS;
932
                data[3] = format;
933
                data[4] = (prim | RADEON_PRIM_WALK_IND |
934
                           RADEON_COLOR_ORDER_RGBA |
935
                           RADEON_VTX_FMT_RADEON_MODE |
936
                           (count << RADEON_NUM_VERTICES_SHIFT) );
937
 
938
                if ( count & 0x1 ) {
939
                        data[dwords-1] &= 0x0000ffff;
940
                }
941
 
942
                do {
943
                        /* Emit the next set of up to three cliprects */
944
                        if ( i < sarea_priv->nbox ) {
945
                                radeon_emit_clip_rect( dev_priv,
946
                                                       &sarea_priv->boxes[i] );
947
                        }
948
 
949
                        radeon_cp_dispatch_indirect( dev, buf, start, end );
950
 
951
                        i++;
952
                } while ( i < sarea_priv->nbox );
953
        }
954
 
955
        if ( buf_priv->discard ) {
956
                buf_priv->age = dev_priv->sarea_priv->last_dispatch;
957
 
958
                /* Emit the vertex buffer age */
959
                BEGIN_RING( 2 );
960
                RADEON_DISPATCH_AGE( buf_priv->age );
961
                ADVANCE_RING();
962
 
963
                buf->pending = 1;
964
                /* FIXME: Check dispatched field */
965
                buf_priv->dispatched = 0;
966
        }
967
 
968
        dev_priv->sarea_priv->last_dispatch++;
969
 
970
        sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
971
        sarea_priv->nbox = 0;
972
}
973
 
974
static int radeon_cp_dispatch_blit( drm_device_t *dev,
975
                                    drm_radeon_blit_t *blit )
976
{
977
        drm_radeon_private_t *dev_priv = dev->dev_private;
978
        drm_device_dma_t *dma = dev->dma;
979
        drm_buf_t *buf;
980
        drm_radeon_buf_priv_t *buf_priv;
981
        u32 format;
982
        u32 *data;
983
        int dword_shift, dwords;
984
        RING_LOCALS;
985
        DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
986
                   blit->offset >> 10, blit->pitch, blit->format,
987
                   blit->x, blit->y, blit->width, blit->height );
988
 
989
        radeon_update_ring_snapshot( dev_priv );
990
 
991
        /* The compiler won't optimize away a division by a variable,
992
         * even if the only legal values are powers of two.  Thus, we'll
993
         * use a shift instead.
994
         */
995
        switch ( blit->format ) {
996
        case RADEON_TXF_32BPP_ARGB8888:
997
        case RADEON_TXF_32BPP_RGBA8888:
998
                format = RADEON_COLOR_FORMAT_ARGB8888;
999
                dword_shift = 0;
1000
                break;
1001
        case RADEON_TXF_16BPP_AI88:
1002
        case RADEON_TXF_16BPP_ARGB1555:
1003
        case RADEON_TXF_16BPP_RGB565:
1004
        case RADEON_TXF_16BPP_ARGB4444:
1005
                format = RADEON_COLOR_FORMAT_RGB565;
1006
                dword_shift = 1;
1007
                break;
1008
        case RADEON_TXF_8BPP_I:
1009
        case RADEON_TXF_8BPP_RGB332:
1010
                format = RADEON_COLOR_FORMAT_CI8;
1011
                dword_shift = 2;
1012
                break;
1013
        default:
1014
                DRM_ERROR( "invalid blit format %d\n", blit->format );
1015
                return -EINVAL;
1016
        }
1017
 
1018
        /* Flush the pixel cache.  This ensures no pixel data gets mixed
1019
         * up with the texture data from the host data blit, otherwise
1020
         * part of the texture image may be corrupted.
1021
         */
1022
        BEGIN_RING( 4 );
1023
 
1024
        RADEON_FLUSH_CACHE();
1025
        RADEON_WAIT_UNTIL_IDLE();
1026
 
1027
        ADVANCE_RING();
1028
 
1029
        /* Dispatch the indirect buffer.
1030
         */
1031
        buf = dma->buflist[blit->idx];
1032
        buf_priv = buf->dev_private;
1033
 
1034
        if ( buf->pid != current->pid ) {
1035
                DRM_ERROR( "process %d using buffer owned by %d\n",
1036
                           current->pid, buf->pid );
1037
                return -EINVAL;
1038
        }
1039
        if ( buf->pending ) {
1040
                DRM_ERROR( "sending pending buffer %d\n", blit->idx );
1041
                return -EINVAL;
1042
        }
1043
 
1044
        buf_priv->discard = 1;
1045
 
1046
        dwords = (blit->width * blit->height) >> dword_shift;
1047
        if ( !dwords ) dwords = 1;
1048
 
1049
        data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
1050
 
1051
        data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
1052
        data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1053
                   RADEON_GMC_BRUSH_NONE |
1054
                   (format << 8) |
1055
                   RADEON_GMC_SRC_DATATYPE_COLOR |
1056
                   RADEON_ROP3_S |
1057
                   RADEON_DP_SRC_SOURCE_HOST_DATA |
1058
                   RADEON_GMC_CLR_CMP_CNTL_DIS |
1059
                   RADEON_GMC_WR_MSK_DIS);
1060
 
1061
        data[2] = (blit->pitch << 22) | (blit->offset >> 10);
1062
        data[3] = 0xffffffff;
1063
        data[4] = 0xffffffff;
1064
        data[5] = (blit->y << 16) | blit->x;
1065
        data[6] = (blit->height << 16) | blit->width;
1066
        data[7] = dwords;
1067
 
1068
        buf->used = (dwords + 8) * sizeof(u32);
1069
 
1070
        radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
1071
 
1072
        /* Flush the pixel cache after the blit completes.  This ensures
1073
         * the texture data is written out to memory before rendering
1074
         * continues.
1075
         */
1076
        BEGIN_RING( 4 );
1077
 
1078
        RADEON_FLUSH_CACHE();
1079
        RADEON_WAIT_UNTIL_2D_IDLE();
1080
 
1081
        ADVANCE_RING();
1082
 
1083
        return 0;
1084
}
1085
 
1086
static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
1087
{
1088
        drm_radeon_private_t *dev_priv = dev->dev_private;
1089
        int i;
1090
        RING_LOCALS;
1091
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1092
 
1093
        radeon_update_ring_snapshot( dev_priv );
1094
 
1095
        BEGIN_RING( 35 );
1096
 
1097
        OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) );
1098
        OUT_RING( 0x00000000 );
1099
 
1100
        OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) );
1101
        for ( i = 0 ; i < 32 ; i++ ) {
1102
                OUT_RING( stipple[i] );
1103
        }
1104
 
1105
        ADVANCE_RING();
1106
}
1107
 
1108
 
1109
/* ================================================================
1110
 * IOCTL functions
1111
 */
1112
 
1113
int radeon_cp_clear( struct inode *inode, struct file *filp,
1114
                     unsigned int cmd, unsigned long arg )
1115
{
1116
        drm_file_t *priv = filp->private_data;
1117
        drm_device_t *dev = priv->dev;
1118
        drm_radeon_private_t *dev_priv = dev->dev_private;
1119
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1120
        drm_radeon_clear_t clear;
1121
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1122
 
1123
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1124
             dev->lock.pid != current->pid ) {
1125
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1126
                return -EINVAL;
1127
        }
1128
 
1129
        if ( copy_from_user( &clear, (drm_radeon_clear_t *) arg,
1130
                             sizeof(clear) ) )
1131
                return -EFAULT;
1132
 
1133
        if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
1134
                sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
1135
 
1136
        radeon_cp_dispatch_clear( dev, &clear );
1137
 
1138
        return 0;
1139
}
1140
 
1141
int radeon_cp_swap( struct inode *inode, struct file *filp,
1142
                    unsigned int cmd, unsigned long arg )
1143
{
1144
        drm_file_t *priv = filp->private_data;
1145
        drm_device_t *dev = priv->dev;
1146
        drm_radeon_private_t *dev_priv = dev->dev_private;
1147
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1148
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1149
 
1150
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1151
             dev->lock.pid != current->pid ) {
1152
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1153
                return -EINVAL;
1154
        }
1155
 
1156
        if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
1157
                sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
1158
 
1159
        if ( !dev_priv->page_flipping ) {
1160
                radeon_cp_dispatch_swap( dev );
1161
                dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
1162
                                                RADEON_UPLOAD_MASKS);
1163
        } else {
1164
                radeon_cp_dispatch_flip( dev );
1165
        }
1166
 
1167
        return 0;
1168
}
1169
 
1170
int radeon_cp_vertex( struct inode *inode, struct file *filp,
1171
                      unsigned int cmd, unsigned long arg )
1172
{
1173
        drm_file_t *priv = filp->private_data;
1174
        drm_device_t *dev = priv->dev;
1175
        drm_radeon_private_t *dev_priv = dev->dev_private;
1176
        drm_device_dma_t *dma = dev->dma;
1177
        drm_buf_t *buf;
1178
        drm_radeon_buf_priv_t *buf_priv;
1179
        drm_radeon_vertex_t vertex;
1180
 
1181
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1182
             dev->lock.pid != current->pid ) {
1183
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1184
                return -EINVAL;
1185
        }
1186
        if ( !dev_priv || dev_priv->is_pci ) {
1187
                DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
1188
                return -EINVAL;
1189
        }
1190
 
1191
        if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg,
1192
                             sizeof(vertex) ) )
1193
                return -EFAULT;
1194
 
1195
        DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n",
1196
                   __FUNCTION__, current->pid,
1197
                   vertex.idx, vertex.count, vertex.discard );
1198
 
1199
        if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
1200
                DRM_ERROR( "buffer index %d (of %d max)\n",
1201
                           vertex.idx, dma->buf_count - 1 );
1202
                return -EINVAL;
1203
        }
1204
        if ( vertex.prim < 0 ||
1205
             vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
1206
                DRM_ERROR( "buffer prim %d\n", vertex.prim );
1207
                return -EINVAL;
1208
        }
1209
 
1210
        VB_AGE_CHECK_WITH_RET( dev_priv );
1211
 
1212
        buf = dma->buflist[vertex.idx];
1213
        buf_priv = buf->dev_private;
1214
 
1215
        if ( buf->pid != current->pid ) {
1216
                DRM_ERROR( "process %d using buffer owned by %d\n",
1217
                           current->pid, buf->pid );
1218
                return -EINVAL;
1219
        }
1220
        if ( buf->pending ) {
1221
                DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
1222
                return -EINVAL;
1223
        }
1224
 
1225
        buf->used = vertex.count;
1226
        buf_priv->prim = vertex.prim;
1227
        buf_priv->discard = vertex.discard;
1228
 
1229
        radeon_cp_dispatch_vertex( dev, buf );
1230
 
1231
        return 0;
1232
}
1233
 
1234
int radeon_cp_indices( struct inode *inode, struct file *filp,
1235
                       unsigned int cmd, unsigned long arg )
1236
{
1237
        drm_file_t *priv = filp->private_data;
1238
        drm_device_t *dev = priv->dev;
1239
        drm_radeon_private_t *dev_priv = dev->dev_private;
1240
        drm_device_dma_t *dma = dev->dma;
1241
        drm_buf_t *buf;
1242
        drm_radeon_buf_priv_t *buf_priv;
1243
        drm_radeon_indices_t elts;
1244
        int count;
1245
 
1246
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1247
             dev->lock.pid != current->pid ) {
1248
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1249
                return -EINVAL;
1250
        }
1251
        if ( !dev_priv || dev_priv->is_pci ) {
1252
                DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
1253
                return -EINVAL;
1254
        }
1255
 
1256
        if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg,
1257
                             sizeof(elts) ) )
1258
                return -EFAULT;
1259
 
1260
        DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n",
1261
                   __FUNCTION__, current->pid,
1262
                   elts.idx, elts.start, elts.end, elts.discard );
1263
 
1264
        if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
1265
                DRM_ERROR( "buffer index %d (of %d max)\n",
1266
                           elts.idx, dma->buf_count - 1 );
1267
                return -EINVAL;
1268
        }
1269
        if ( elts.prim < 0 ||
1270
             elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
1271
                DRM_ERROR( "buffer prim %d\n", elts.prim );
1272
                return -EINVAL;
1273
        }
1274
 
1275
        VB_AGE_CHECK_WITH_RET( dev_priv );
1276
 
1277
        buf = dma->buflist[elts.idx];
1278
        buf_priv = buf->dev_private;
1279
 
1280
        if ( buf->pid != current->pid ) {
1281
                DRM_ERROR( "process %d using buffer owned by %d\n",
1282
                           current->pid, buf->pid );
1283
                return -EINVAL;
1284
        }
1285
        if ( buf->pending ) {
1286
                DRM_ERROR( "sending pending buffer %d\n", elts.idx );
1287
                return -EINVAL;
1288
        }
1289
 
1290
        count = (elts.end - elts.start) / sizeof(u16);
1291
        elts.start -= RADEON_INDEX_PRIM_OFFSET;
1292
 
1293
        if ( elts.start & 0x7 ) {
1294
                DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
1295
                return -EINVAL;
1296
        }
1297
        if ( elts.start < buf->used ) {
1298
                DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
1299
                return -EINVAL;
1300
        }
1301
 
1302
        buf->used = elts.end;
1303
        buf_priv->prim = elts.prim;
1304
        buf_priv->discard = elts.discard;
1305
 
1306
        radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count );
1307
 
1308
        return 0;
1309
}
1310
 
1311
int radeon_cp_blit( struct inode *inode, struct file *filp,
1312
                    unsigned int cmd, unsigned long arg )
1313
{
1314
        drm_file_t *priv = filp->private_data;
1315
        drm_device_t *dev = priv->dev;
1316
        drm_radeon_private_t *dev_priv = dev->dev_private;
1317
        drm_device_dma_t *dma = dev->dma;
1318
        drm_radeon_blit_t blit;
1319
 
1320
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1321
             dev->lock.pid != current->pid ) {
1322
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1323
                return -EINVAL;
1324
        }
1325
 
1326
        if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg,
1327
                             sizeof(blit) ) )
1328
                return -EFAULT;
1329
 
1330
        DRM_DEBUG( "%s: pid=%d index=%d\n",
1331
                   __FUNCTION__, current->pid, blit.idx );
1332
 
1333
        if ( blit.idx < 0 || blit.idx > dma->buf_count ) {
1334
                DRM_ERROR( "sending %d buffers (of %d max)\n",
1335
                           blit.idx, dma->buf_count );
1336
                return -EINVAL;
1337
        }
1338
 
1339
        VB_AGE_CHECK_WITH_RET( dev_priv );
1340
 
1341
        return radeon_cp_dispatch_blit( dev, &blit );
1342
}
1343
 
1344
int radeon_cp_stipple( struct inode *inode, struct file *filp,
1345
                       unsigned int cmd, unsigned long arg )
1346
{
1347
        drm_file_t *priv = filp->private_data;
1348
        drm_device_t *dev = priv->dev;
1349
        drm_radeon_stipple_t stipple;
1350
        u32 mask[32];
1351
 
1352
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1353
             dev->lock.pid != current->pid ) {
1354
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1355
                return -EINVAL;
1356
        }
1357
 
1358
        if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
1359
                             sizeof(stipple) ) )
1360
                return -EFAULT;
1361
 
1362
        if ( copy_from_user( &mask, stipple.mask,
1363
                             32 * sizeof(u32) ) )
1364
                return -EFAULT;
1365
 
1366
        radeon_cp_dispatch_stipple( dev, mask );
1367
 
1368
        return 0;
1369
}
1370
 
1371
int radeon_cp_indirect( struct inode *inode, struct file *filp,
1372
                        unsigned int cmd, unsigned long arg )
1373
{
1374
        drm_file_t *priv = filp->private_data;
1375
        drm_device_t *dev = priv->dev;
1376
        drm_radeon_private_t *dev_priv = dev->dev_private;
1377
        drm_device_dma_t *dma = dev->dma;
1378
        drm_buf_t *buf;
1379
        drm_radeon_buf_priv_t *buf_priv;
1380
        drm_radeon_indirect_t indirect;
1381
        RING_LOCALS;
1382
 
1383
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1384
             dev->lock.pid != current->pid ) {
1385
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1386
                return -EINVAL;
1387
        }
1388
        if ( !dev_priv || dev_priv->is_pci ) {
1389
                DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
1390
                return -EINVAL;
1391
        }
1392
 
1393
        if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg,
1394
                             sizeof(indirect) ) )
1395
                return -EFAULT;
1396
 
1397
        DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
1398
                   indirect.idx, indirect.start,
1399
                   indirect.end, indirect.discard );
1400
 
1401
        if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
1402
                DRM_ERROR( "buffer index %d (of %d max)\n",
1403
                           indirect.idx, dma->buf_count - 1 );
1404
                return -EINVAL;
1405
        }
1406
 
1407
        buf = dma->buflist[indirect.idx];
1408
        buf_priv = buf->dev_private;
1409
 
1410
        if ( buf->pid != current->pid ) {
1411
                DRM_ERROR( "process %d using buffer owned by %d\n",
1412
                           current->pid, buf->pid );
1413
                return -EINVAL;
1414
        }
1415
        if ( buf->pending ) {
1416
                DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
1417
                return -EINVAL;
1418
        }
1419
 
1420
        if ( indirect.start < buf->used ) {
1421
                DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
1422
                           indirect.start, buf->used );
1423
                return -EINVAL;
1424
        }
1425
 
1426
        VB_AGE_CHECK_WITH_RET( dev_priv );
1427
 
1428
        buf->used = indirect.end;
1429
        buf_priv->discard = indirect.discard;
1430
 
1431
        /* Wait for the 3D stream to idle before the indirect buffer
1432
         * containing 2D acceleration commands is processed.
1433
         */
1434
        BEGIN_RING( 2 );
1435
 
1436
        RADEON_WAIT_UNTIL_3D_IDLE();
1437
 
1438
        ADVANCE_RING();
1439
 
1440
        /* Dispatch the indirect buffer full of commands from the
1441
         * X server.  This is insecure and is thus only available to
1442
         * privileged clients.
1443
         */
1444
        radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
1445
 
1446
        return 0;
1447
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.