Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
33
 *   Gareth Hughes 
34
 *   Keith Whitwell 
35
 */
36
 
37
#include 
38
#include 
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 RADEON_TIMEOUT             512
53
#define RADEON_IDLE_RETRY           16
54
 
55
 
56
/* =============================================================
57
 * Kernel command buffer handling
58
 */
59
 
60
/* The state atoms will be emitted in the order they appear in the atom list,
61
 * so this step is important.
62
 */
63
void radeonSetUpAtomList( r100ContextPtr rmesa )
64
{
65
   int i, mtu = rmesa->radeon.glCtx.Const.MaxTextureUnits;
66
 
67
   make_empty_list(&rmesa->radeon.hw.atomlist);
68
   rmesa->radeon.hw.atomlist.name = "atom-list";
69
 
70
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
71
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
72
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
73
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
74
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
75
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
76
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
77
   for (i = 0; i < mtu; ++i) {
78
       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
79
       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
80
       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
81
   }
82
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
83
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
84
   for (i = 0; i < 3 + mtu; ++i)
85
      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
86
   for (i = 0; i < 8; ++i)
87
      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
88
   for (i = 0; i < 6; ++i)
89
      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
90
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.stp);
91
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
92
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
93
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
94
   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
95
}
96
 
97
static void radeonEmitScissor(r100ContextPtr rmesa)
98
{
99
    BATCH_LOCALS(&rmesa->radeon);
100
    if (rmesa->radeon.state.scissor.enabled) {
101
        BEGIN_BATCH(6);
102
        OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 0));
103
        OUT_BATCH(rmesa->hw.ctx.cmd[CTX_PP_CNTL] | RADEON_SCISSOR_ENABLE);
104
        OUT_BATCH(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
105
        OUT_BATCH((rmesa->radeon.state.scissor.rect.y1 << 16) |
106
                  rmesa->radeon.state.scissor.rect.x1);
107
        OUT_BATCH(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
108
        OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2) << 16) |
109
                  (rmesa->radeon.state.scissor.rect.x2));
110
        END_BATCH();
111
    } else {
112
        BEGIN_BATCH(2);
113
        OUT_BATCH(CP_PACKET0(RADEON_PP_CNTL, 0));
114
        OUT_BATCH(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ~RADEON_SCISSOR_ENABLE);
115
        END_BATCH();
116
    }
117
}
118
 
119
/* Fire a section of the retained (indexed_verts) buffer as a regular
120
 * primtive.
121
 */
122
extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
123
				GLuint vertex_format,
124
				GLuint primitive,
125
				GLuint vertex_nr )
126
{
127
   BATCH_LOCALS(&rmesa->radeon);
128
 
129
   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
130
 
131
   radeonEmitState(&rmesa->radeon);
132
   radeonEmitScissor(rmesa);
133
 
134
#if RADEON_OLD_PACKETS
135
   BEGIN_BATCH(8);
136
   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
137
   OUT_BATCH(rmesa->ioctl.vertex_offset);
138
 
139
   OUT_BATCH(vertex_nr);
140
   OUT_BATCH(vertex_format);
141
   OUT_BATCH(primitive |  RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
142
	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
143
	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
144
	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
145
 
146
   radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
147
			 rmesa->ioctl.bo,
148
			 RADEON_GEM_DOMAIN_GTT,
149
			 0, 0);
150
 
151
   END_BATCH();
152
 
153
#else
154
   BEGIN_BATCH(4);
155
   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1);
156
   OUT_BATCH(vertex_format);
157
   OUT_BATCH(primitive |
158
	     RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
159
	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
160
	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
161
	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
162
	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
163
   END_BATCH();
164
#endif
165
}
166
 
167
void radeonFlushElts( struct gl_context *ctx )
168
{
169
   r100ContextPtr rmesa = R100_CONTEXT(ctx);
170
   BATCH_LOCALS(&rmesa->radeon);
171
   int nr;
172
   uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
173
   int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
174
 
175
   if (RADEON_DEBUG & RADEON_IOCTL)
176
      fprintf(stderr, "%s\n", __FUNCTION__);
177
 
178
   assert( rmesa->radeon.dma.flush == radeonFlushElts );
179
   rmesa->radeon.dma.flush = NULL;
180
 
181
   nr = rmesa->tcl.elt_used;
182
 
183
#if RADEON_OLD_PACKETS
184
   dwords -= 2;
185
#endif
186
 
187
#if RADEON_OLD_PACKETS
188
   cmd[1] |= (dwords + 3) << 16;
189
   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
190
#else
191
   cmd[1] |= (dwords + 2) << 16;
192
   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
193
#endif
194
 
195
   rmesa->radeon.cmdbuf.cs->cdw += dwords;
196
   rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
197
 
198
#if RADEON_OLD_PACKETS
199
   radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
200
			 rmesa->ioctl.bo,
201
			 RADEON_GEM_DOMAIN_GTT,
202
			 0, 0);
203
#endif
204
 
205
   END_BATCH();
206
 
207
   if (RADEON_DEBUG & RADEON_SYNC) {
208
      fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
209
      radeonFinish( &rmesa->radeon.glCtx );
210
   }
211
 
212
}
213
 
214
GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
215
				    GLuint vertex_format,
216
				    GLuint primitive,
217
				    GLuint min_nr )
218
{
219
   GLushort *retval;
220
   int align_min_nr;
221
   BATCH_LOCALS(&rmesa->radeon);
222
 
223
   if (RADEON_DEBUG & RADEON_IOCTL)
224
      fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
225
 
226
   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
227
 
228
   radeonEmitState(&rmesa->radeon);
229
   radeonEmitScissor(rmesa);
230
 
231
   rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
232
 
233
   /* round up min_nr to align the state */
234
   align_min_nr = (min_nr + 1) & ~1;
235
 
236
#if RADEON_OLD_PACKETS
237
   BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
238
   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
239
   OUT_BATCH(rmesa->ioctl.vertex_offset);
240
   OUT_BATCH(rmesa->ioctl.vertex_max);
241
   OUT_BATCH(vertex_format);
242
   OUT_BATCH(primitive |
243
	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
244
	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
245
	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
246
#else
247
   BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
248
   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
249
   OUT_BATCH(vertex_format);
250
   OUT_BATCH(primitive |
251
	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
252
	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
253
	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
254
	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
255
#endif
256
 
257
 
258
   rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
259
   rmesa->tcl.elt_used = min_nr;
260
 
261
   retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
262
 
263
   if (RADEON_DEBUG & RADEON_RENDER)
264
      fprintf(stderr, "%s: header prim %x \n",
265
	      __FUNCTION__, primitive);
266
 
267
   assert(!rmesa->radeon.dma.flush);
268
   rmesa->radeon.glCtx.Driver.NeedFlush |= FLUSH_STORED_VERTICES;
269
   rmesa->radeon.dma.flush = radeonFlushElts;
270
 
271
   return retval;
272
}
273
 
274
void radeonEmitVertexAOS( r100ContextPtr rmesa,
275
			  GLuint vertex_size,
276
			  struct radeon_bo *bo,
277
			  GLuint offset )
278
{
279
#if RADEON_OLD_PACKETS
280
   rmesa->ioctl.vertex_offset = offset;
281
   rmesa->ioctl.bo = bo;
282
#else
283
   BATCH_LOCALS(&rmesa->radeon);
284
 
285
   if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_IOCTL))
286
      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
287
	      __FUNCTION__, vertex_size, offset);
288
 
289
   BEGIN_BATCH(7);
290
   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2);
291
   OUT_BATCH(1);
292
   OUT_BATCH(vertex_size | (vertex_size << 8));
293
   OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
294
   END_BATCH();
295
 
296
#endif
297
}
298
 
299
 
300
void radeonEmitAOS( r100ContextPtr rmesa,
301
		    GLuint nr,
302
		    GLuint offset )
303
{
304
#if RADEON_OLD_PACKETS
305
   assert( nr == 1 );
306
   rmesa->ioctl.bo = rmesa->radeon.tcl.aos[0].bo;
307
   rmesa->ioctl.vertex_offset =
308
     (rmesa->radeon.tcl.aos[0].offset + offset * rmesa->radeon.tcl.aos[0].stride * 4);
309
   rmesa->ioctl.vertex_max = rmesa->radeon.tcl.aos[0].count;
310
#else
311
   BATCH_LOCALS(&rmesa->radeon);
312
   uint32_t voffset;
313
   //   int sz = AOS_BUFSZ(nr);
314
   int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
315
   int i;
316
 
317
   if (RADEON_DEBUG & RADEON_IOCTL)
318
      fprintf(stderr, "%s\n", __FUNCTION__);
319
 
320
   BEGIN_BATCH(sz+2+(nr * 2));
321
   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
322
   OUT_BATCH(nr);
323
 
324
   {
325
      for (i = 0; i + 1 < nr; i += 2) {
326
	 OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
327
		   (rmesa->radeon.tcl.aos[i].stride << 8) |
328
		   (rmesa->radeon.tcl.aos[i + 1].components << 16) |
329
		   (rmesa->radeon.tcl.aos[i + 1].stride << 24));
330
 
331
	 voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
332
	    offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
333
	 OUT_BATCH(voffset);
334
	 voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
335
	    offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
336
	 OUT_BATCH(voffset);
337
      }
338
 
339
      if (nr & 1) {
340
	 OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
341
		   (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
342
	 voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
343
	    offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
344
	 OUT_BATCH(voffset);
345
      }
346
      for (i = 0; i + 1 < nr; i += 2) {
347
	 voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
348
	    offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
349
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
350
			       rmesa->radeon.tcl.aos[i+0].bo,
351
			       RADEON_GEM_DOMAIN_GTT,
352
			       0, 0);
353
	 voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
354
	    offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
355
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
356
			       rmesa->radeon.tcl.aos[i+1].bo,
357
			       RADEON_GEM_DOMAIN_GTT,
358
			       0, 0);
359
      }
360
      if (nr & 1) {
361
	 voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
362
	    offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
363
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
364
			       rmesa->radeon.tcl.aos[nr-1].bo,
365
			       RADEON_GEM_DOMAIN_GTT,
366
			       0, 0);
367
      }
368
   }
369
   END_BATCH();
370
 
371
#endif
372
}
373
 
374
/* ================================================================
375
 * Buffer clear
376
 */
377
#define RADEON_MAX_CLEARS	256
378
 
379
static void radeonClear( struct gl_context *ctx, GLbitfield mask )
380
{
381
   r100ContextPtr rmesa = R100_CONTEXT(ctx);
382
   GLuint hwmask, swmask;
383
   GLuint hwbits = BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
384
                   BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL |
385
                   BUFFER_BIT_COLOR0;
386
 
387
   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
388
      rmesa->radeon.front_buffer_dirty = GL_TRUE;
389
   }
390
 
391
   if ( RADEON_DEBUG & RADEON_IOCTL ) {
392
      fprintf( stderr, "radeonClear\n");
393
   }
394
 
395
   radeon_firevertices(&rmesa->radeon);
396
 
397
   hwmask = mask & hwbits;
398
   swmask = mask & ~hwbits;
399
 
400
   if ( swmask ) {
401
      if (RADEON_DEBUG & RADEON_FALLBACKS)
402
	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, swmask);
403
      _swrast_Clear( ctx, swmask );
404
   }
405
 
406
   if ( !hwmask )
407
      return;
408
 
409
   radeonUserClear(ctx, hwmask);
410
}
411
 
412
void radeonInitIoctlFuncs( struct gl_context *ctx )
413
{
414
    ctx->Driver.Clear = radeonClear;
415
    ctx->Driver.Finish = radeonFinish;
416
    ctx->Driver.Flush = radeonFlush;
417
}
418