radeon: Drop dri2 checks now that it's always true.
[profile/ivi/mesa.git] / src / mesa / drivers / dri / radeon / radeon_ioctl.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                      VA Linux Systems Inc., Fremont, California.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31  * Authors:
32  *   Kevin E. Martin <martin@valinux.com>
33  *   Gareth Hughes <gareth@valinux.com>
34  *   Keith Whitwell <keith@tungstengraphics.com>
35  */
36
37 #include <sched.h>
38 #include <errno.h>
39
40 #include "main/attrib.h"
41 #include "main/bufferobj.h"
42 #include "swrast/swrast.h"
43
44 #include "main/glheader.h"
45 #include "main/imports.h"
46 #include "main/simple_list.h"
47
48 #include "radeon_context.h"
49 #include "radeon_common.h"
50 #include "radeon_ioctl.h"
51
52 #define STANDALONE_MMIO
53
54 #include "vblank.h"
55
56 #define RADEON_TIMEOUT             512
57 #define RADEON_IDLE_RETRY           16
58
59
60 /* =============================================================
61  * Kernel command buffer handling
62  */
63
64 /* The state atoms will be emitted in the order they appear in the atom list,
65  * so this step is important.
66  */
67 void radeonSetUpAtomList( r100ContextPtr rmesa )
68 {
69    int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
70
71    make_empty_list(&rmesa->radeon.hw.atomlist);
72    rmesa->radeon.hw.atomlist.name = "atom-list";
73
74    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
75    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
76    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
77    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
78    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
79    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
80    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
81    for (i = 0; i < mtu; ++i) {
82        insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
83        insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
84        insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
85    }
86    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
87    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
88    for (i = 0; i < 3 + mtu; ++i)
89       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
90    for (i = 0; i < 8; ++i)
91       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
92    for (i = 0; i < 6; ++i)
93       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
94    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.stp);
95    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
96    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
97    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
98    insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
99 }
100
101 static void radeonEmitScissor(r100ContextPtr rmesa)
102 {
103     BATCH_LOCALS(&rmesa->radeon);
104     if (rmesa->radeon.state.scissor.enabled) {
105         BEGIN_BATCH(6);
106         OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 0));
107         OUT_BATCH(rmesa->hw.ctx.cmd[CTX_PP_CNTL] | RADEON_SCISSOR_ENABLE);
108         OUT_BATCH(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
109         OUT_BATCH((rmesa->radeon.state.scissor.rect.y1 << 16) |
110                   rmesa->radeon.state.scissor.rect.x1);
111         OUT_BATCH(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
112         OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2) << 16) |
113                   (rmesa->radeon.state.scissor.rect.x2));
114         END_BATCH();
115     } else {
116         BEGIN_BATCH(2);
117         OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 0));
118         OUT_BATCH(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ~RADEON_SCISSOR_ENABLE);
119         END_BATCH();
120     }
121 }
122
123 /* Fire a section of the retained (indexed_verts) buffer as a regular
124  * primtive.
125  */
126 extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
127                                 GLuint vertex_format,
128                                 GLuint primitive,
129                                 GLuint vertex_nr )
130 {
131    BATCH_LOCALS(&rmesa->radeon);
132
133    assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
134
135    radeonEmitState(&rmesa->radeon);
136    radeonEmitScissor(rmesa);
137
138 #if RADEON_OLD_PACKETS
139    BEGIN_BATCH(8);
140    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
141    OUT_BATCH(rmesa->ioctl.vertex_offset);
142
143    OUT_BATCH(vertex_nr);
144    OUT_BATCH(vertex_format);
145    OUT_BATCH(primitive |  RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
146              RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
147              RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
148              (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
149
150    radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
151                          rmesa->ioctl.bo,
152                          RADEON_GEM_DOMAIN_GTT,
153                          0, 0);
154
155    END_BATCH();
156
157 #else
158    BEGIN_BATCH(4);
159    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1);
160    OUT_BATCH(vertex_format);
161    OUT_BATCH(primitive |
162              RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
163              RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
164              RADEON_CP_VC_CNTL_MAOS_ENABLE |
165              RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
166              (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
167    END_BATCH();
168 #endif
169 }
170
171 void radeonFlushElts( struct gl_context *ctx )
172 {
173    r100ContextPtr rmesa = R100_CONTEXT(ctx);
174    BATCH_LOCALS(&rmesa->radeon);
175    int nr;
176    uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
177    int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
178
179    if (RADEON_DEBUG & RADEON_IOCTL)
180       fprintf(stderr, "%s\n", __FUNCTION__);
181
182    assert( rmesa->radeon.dma.flush == radeonFlushElts );
183    rmesa->radeon.dma.flush = NULL;
184
185    nr = rmesa->tcl.elt_used;
186
187 #if RADEON_OLD_PACKETS
188    dwords -= 2;
189 #endif
190
191 #if RADEON_OLD_PACKETS
192    cmd[1] |= (dwords + 3) << 16;
193    cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
194 #else
195    cmd[1] |= (dwords + 2) << 16;
196    cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
197 #endif
198
199    rmesa->radeon.cmdbuf.cs->cdw += dwords;
200    rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
201
202 #if RADEON_OLD_PACKETS
203    radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
204                          rmesa->ioctl.bo,
205                          RADEON_GEM_DOMAIN_GTT,
206                          0, 0);
207 #endif
208
209    END_BATCH();
210
211    if (RADEON_DEBUG & RADEON_SYNC) {
212       fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
213       radeonFinish( rmesa->radeon.glCtx );
214    }
215
216 }
217
218 GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
219                                     GLuint vertex_format,
220                                     GLuint primitive,
221                                     GLuint min_nr )
222 {
223    GLushort *retval;
224    int align_min_nr;
225    BATCH_LOCALS(&rmesa->radeon);
226
227    if (RADEON_DEBUG & RADEON_IOCTL)
228       fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
229
230    assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
231
232    radeonEmitState(&rmesa->radeon);
233    radeonEmitScissor(rmesa);
234
235    rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
236
237    /* round up min_nr to align the state */
238    align_min_nr = (min_nr + 1) & ~1;
239
240 #if RADEON_OLD_PACKETS
241    BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
242    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
243    OUT_BATCH(rmesa->ioctl.vertex_offset);
244    OUT_BATCH(rmesa->ioctl.vertex_max);
245    OUT_BATCH(vertex_format);
246    OUT_BATCH(primitive |
247              RADEON_CP_VC_CNTL_PRIM_WALK_IND |
248              RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
249              RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
250 #else
251    BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
252    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
253    OUT_BATCH(vertex_format);
254    OUT_BATCH(primitive |
255              RADEON_CP_VC_CNTL_PRIM_WALK_IND |
256              RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
257              RADEON_CP_VC_CNTL_MAOS_ENABLE |
258              RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
259 #endif
260
261
262    rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
263    rmesa->tcl.elt_used = min_nr;
264
265    retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
266
267    if (RADEON_DEBUG & RADEON_RENDER)
268       fprintf(stderr, "%s: header prim %x \n",
269               __FUNCTION__, primitive);
270
271    assert(!rmesa->radeon.dma.flush);
272    rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
273    rmesa->radeon.dma.flush = radeonFlushElts;
274
275    return retval;
276 }
277
278 void radeonEmitVertexAOS( r100ContextPtr rmesa,
279                           GLuint vertex_size,
280                           struct radeon_bo *bo,
281                           GLuint offset )
282 {
283 #if RADEON_OLD_PACKETS
284    rmesa->ioctl.vertex_offset = offset;
285    rmesa->ioctl.bo = bo;
286 #else
287    BATCH_LOCALS(&rmesa->radeon);
288
289    if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_IOCTL))
290       fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
291               __FUNCTION__, vertex_size, offset);
292
293    BEGIN_BATCH(7);
294    OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2);
295    OUT_BATCH(1);
296    OUT_BATCH(vertex_size | (vertex_size << 8));
297    OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
298    END_BATCH();
299
300 #endif
301 }
302
303
304 void radeonEmitAOS( r100ContextPtr rmesa,
305                     GLuint nr,
306                     GLuint offset )
307 {
308 #if RADEON_OLD_PACKETS
309    assert( nr == 1 );
310    rmesa->ioctl.bo = rmesa->radeon.tcl.aos[0].bo;
311    rmesa->ioctl.vertex_offset =
312      (rmesa->radeon.tcl.aos[0].offset + offset * rmesa->radeon.tcl.aos[0].stride * 4);
313    rmesa->ioctl.vertex_max = rmesa->radeon.tcl.aos[0].count;
314 #else
315    BATCH_LOCALS(&rmesa->radeon);
316    uint32_t voffset;
317    //   int sz = AOS_BUFSZ(nr);
318    int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
319    int i;
320
321    if (RADEON_DEBUG & RADEON_IOCTL)
322       fprintf(stderr, "%s\n", __FUNCTION__);
323
324    BEGIN_BATCH(sz+2+(nr * 2));
325    OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
326    OUT_BATCH(nr);
327
328    {
329       for (i = 0; i + 1 < nr; i += 2) {
330          OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
331                    (rmesa->radeon.tcl.aos[i].stride << 8) |
332                    (rmesa->radeon.tcl.aos[i + 1].components << 16) |
333                    (rmesa->radeon.tcl.aos[i + 1].stride << 24));
334
335          voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
336             offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
337          OUT_BATCH(voffset);
338          voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
339             offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
340          OUT_BATCH(voffset);
341       }
342
343       if (nr & 1) {
344          OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
345                    (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
346          voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
347             offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
348          OUT_BATCH(voffset);
349       }
350       for (i = 0; i + 1 < nr; i += 2) {
351          voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
352             offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
353          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
354                                rmesa->radeon.tcl.aos[i+0].bo,
355                                RADEON_GEM_DOMAIN_GTT,
356                                0, 0);
357          voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
358             offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
359          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
360                                rmesa->radeon.tcl.aos[i+1].bo,
361                                RADEON_GEM_DOMAIN_GTT,
362                                0, 0);
363       }
364       if (nr & 1) {
365          voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
366             offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
367          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
368                                rmesa->radeon.tcl.aos[nr-1].bo,
369                                RADEON_GEM_DOMAIN_GTT,
370                                0, 0);
371       }
372    }
373    END_BATCH();
374
375 #endif
376 }
377
378 /* ================================================================
379  * Buffer clear
380  */
381 #define RADEON_MAX_CLEARS       256
382
383 static void radeonClear( struct gl_context *ctx, GLbitfield mask )
384 {
385    r100ContextPtr rmesa = R100_CONTEXT(ctx);
386    GLuint flags = 0;
387    GLuint orig_mask = mask;
388
389    if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
390       rmesa->radeon.front_buffer_dirty = GL_TRUE;
391    }
392
393    if ( RADEON_DEBUG & RADEON_IOCTL ) {
394       fprintf( stderr, "radeonClear\n");
395    }
396
397    radeon_firevertices(&rmesa->radeon);
398
399    if ( mask & BUFFER_BIT_FRONT_LEFT ) {
400       flags |= RADEON_FRONT;
401       mask &= ~BUFFER_BIT_FRONT_LEFT;
402    }
403
404    if ( mask & BUFFER_BIT_BACK_LEFT ) {
405       flags |= RADEON_BACK;
406       mask &= ~BUFFER_BIT_BACK_LEFT;
407    }
408
409    if ( mask & BUFFER_BIT_DEPTH ) {
410       flags |= RADEON_DEPTH;
411       mask &= ~BUFFER_BIT_DEPTH;
412    }
413
414    if ( (mask & BUFFER_BIT_STENCIL) ) {
415       flags |= RADEON_STENCIL;
416       mask &= ~BUFFER_BIT_STENCIL;
417    }
418
419    if ( mask ) {
420       if (RADEON_DEBUG & RADEON_FALLBACKS)
421          fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
422       _swrast_Clear( ctx, mask );
423    }
424
425    if ( !flags )
426       return;
427
428    if (rmesa->using_hyperz) {
429       flags |= RADEON_USE_COMP_ZBUF;
430 /*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
431          flags |= RADEON_USE_HIERZ; */
432       if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
433             ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
434           flags |= RADEON_CLEAR_FASTZ;
435       }
436    }
437
438    radeonUserClear(ctx, orig_mask);
439 }
440
441 void radeonInitIoctlFuncs( struct gl_context *ctx )
442 {
443     ctx->Driver.Clear = radeonClear;
444     ctx->Driver.Finish = radeonFinish;
445     ctx->Driver.Flush = radeonFlush;
446 }
447