d1ae9fcb72086e8706da9fc953ebdf3285960643
[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