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
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
 
4
The Weather Channel (TM) funded Tungsten Graphics to develop the
5
initial release of the Radeon 8500 driver under the XFree86 license.
6
This notice must be preserved.
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
 * Authors:
31
 *   Keith Whitwell 
32
 */
33
 
34
#include "main/glheader.h"
35
#include "main/imports.h"
36
#include "main/macros.h"
37
#include "main/context.h"
38
#include "main/simple_list.h"
39
 
40
#include "radeon_common.h"
41
#include "r200_context.h"
42
#include "r200_ioctl.h"
43
#include "radeon_reg.h"
44
 
45
/* The state atoms will be emitted in the order they appear in the atom list,
46
 * so this step is important.
47
 */
48
#define insert_at_tail_if(atom_list, atom) \
49
   do { \
50
      struct radeon_state_atom* current_atom = (atom); \
51
      if (current_atom->check) \
52
	 insert_at_tail((atom_list), current_atom); \
53
   } while(0)
54
 
55
void r200SetUpAtomList( r200ContextPtr rmesa )
56
{
57
   int i, mtu;
58
 
59
   mtu = rmesa->radeon.glCtx.Const.MaxTextureUnits;
60
 
61
   make_empty_list(&rmesa->radeon.hw.atomlist);
62
   rmesa->radeon.hw.atomlist.name = "atom-list";
63
 
64
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ctx );
65
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.set );
66
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lin );
67
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msk );
68
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpt );
69
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vtx );
70
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vap );
71
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vte );
72
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msc );
73
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cst );
74
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.zbs );
75
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcl );
76
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msl );
77
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcg );
78
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.grd );
79
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.fog );
80
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tam );
81
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tf );
82
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.atf );
83
   for (i = 0; i < mtu; ++i)
84
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i] );
85
   for (i = 0; i < mtu; ++i)
86
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i] );
87
   for (i = 0; i < 6; ++i)
88
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] );
89
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] );
90
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] );
91
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.stp );
92
   for (i = 0; i < 8; ++i)
93
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] );
94
   for (i = 0; i < 3 + mtu; ++i)
95
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i] );
96
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.eye );
97
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.glt );
98
   for (i = 0; i < 2; ++i)
99
      insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mtl[i] );
100
   for (i = 0; i < 6; ++i)
101
       insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i] );
102
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.spr );
103
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ptp );
104
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.prf );
105
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pvs );
106
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[0] );
107
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[1] );
108
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[0] );
109
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[1] );
110
   insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.sci );
111
}
112
 
113
/* Fire a section of the retained (indexed_verts) buffer as a regular
114
 * primtive.
115
 */
116
void r200EmitVbufPrim( r200ContextPtr rmesa,
117
                       GLuint primitive,
118
                       GLuint vertex_nr )
119
{
120
   BATCH_LOCALS(&rmesa->radeon);
121
 
122
   assert(!(primitive & R200_VF_PRIM_WALK_IND));
123
 
124
   radeonEmitState(&rmesa->radeon);
125
 
126
   radeon_print(RADEON_RENDER|RADEON_SWRENDER,RADEON_VERBOSE,
127
           "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__,
128
           rmesa->store.cmd_used/4, primitive, vertex_nr);
129
 
130
   BEGIN_BATCH(3);
131
   OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_VBUF_2, 0);
132
   OUT_BATCH(primitive | R200_VF_PRIM_WALK_LIST | R200_VF_COLOR_ORDER_RGBA |
133
	     (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT));
134
   END_BATCH();
135
}
136
 
137
static void r200FireEB(r200ContextPtr rmesa, int vertex_count, int type)
138
{
139
	BATCH_LOCALS(&rmesa->radeon);
140
 
141
	if (vertex_count > 0) {
142
		BEGIN_BATCH(8+2);
143
		OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_INDX_2, 0);
144
		OUT_BATCH(R200_VF_PRIM_WALK_IND |
145
			  R200_VF_COLOR_ORDER_RGBA |
146
			  ((vertex_count + 0) << 16) |
147
			  type);
148
 
149
		OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
150
		OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
151
		OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset);
152
		OUT_BATCH((vertex_count + 1)/2);
153
		radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
154
				      rmesa->radeon.tcl.elt_dma_bo,
155
				      RADEON_GEM_DOMAIN_GTT, 0, 0);
156
		END_BATCH();
157
	}
158
}
159
 
160
void r200FlushElts(struct gl_context *ctx)
161
{
162
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
163
   int nr, elt_used = rmesa->tcl.elt_used;
164
 
165
   radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);
166
 
167
   assert( rmesa->radeon.dma.flush == r200FlushElts );
168
   rmesa->radeon.dma.flush = NULL;
169
 
170
   nr = elt_used / 2;
171
 
172
   radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);
173
 
174
   r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive);
175
 
176
   radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
177
   rmesa->radeon.tcl.elt_dma_bo = NULL;
178
 
179
   if (R200_ELT_BUF_SZ > elt_used)
180
     radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
181
}
182
 
183
 
184
GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
185
				    GLuint primitive,
186
				    GLuint min_nr )
187
{
188
   GLushort *retval;
189
 
190
   radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
191
 
192
   assert((primitive & R200_VF_PRIM_WALK_IND));
193
 
194
   radeonEmitState(&rmesa->radeon);
195
 
196
   radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
197
			&rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4);
198
   rmesa->tcl.elt_used = min_nr * 2;
199
 
200
   radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
201
   retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
202
 
203
   assert(!rmesa->radeon.dma.flush);
204
   rmesa->radeon.glCtx.Driver.NeedFlush |= FLUSH_STORED_VERTICES;
205
   rmesa->radeon.dma.flush = r200FlushElts;
206
 
207
   return retval;
208
}
209
 
210
void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count)
211
{
212
   BATCH_LOCALS(&rmesa->radeon);
213
 
214
   BEGIN_BATCH_NO_AUTOSTATE(2);
215
   OUT_BATCH(CP_PACKET0(R200_SE_VF_MAX_VTX_INDX, 0));
216
   OUT_BATCH(count);
217
   END_BATCH();
218
}
219
 
220
void r200EmitVertexAOS( r200ContextPtr rmesa,
221
			GLuint vertex_size,
222
 			struct radeon_bo *bo,
223
			GLuint offset )
224
{
225
   BATCH_LOCALS(&rmesa->radeon);
226
 
227
   radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s:  vertex_size 0x%x offset 0x%x \n",
228
	      __FUNCTION__, vertex_size, offset);
229
 
230
 
231
   BEGIN_BATCH(7);
232
   OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, 2);
233
   OUT_BATCH(1);
234
   OUT_BATCH(vertex_size | (vertex_size << 8));
235
   OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
236
   END_BATCH();
237
}
238
 
239
void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset)
240
{
241
   BATCH_LOCALS(&rmesa->radeon);
242
   uint32_t voffset;
243
   int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
244
   int i;
245
 
246
   radeon_print(RADEON_RENDER, RADEON_VERBOSE,
247
           "%s: nr=%d, ofs=0x%08x\n",
248
           __FUNCTION__, nr, offset);
249
 
250
   BEGIN_BATCH(sz+2+ (nr*2));
251
   OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, sz - 1);
252
   OUT_BATCH(nr);
253
 
254
   {
255
      for (i = 0; i + 1 < nr; i += 2) {
256
	 OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
257
		   (rmesa->radeon.tcl.aos[i].stride << 8) |
258
		   (rmesa->radeon.tcl.aos[i + 1].components << 16) |
259
		   (rmesa->radeon.tcl.aos[i + 1].stride << 24));
260
 
261
	 voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
262
	    offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
263
	 OUT_BATCH(voffset);
264
	 voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
265
	    offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
266
	 OUT_BATCH(voffset);
267
      }
268
 
269
      if (nr & 1) {
270
	 OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
271
		   (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
272
	 voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
273
	    offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
274
	 OUT_BATCH(voffset);
275
      }
276
      for (i = 0; i + 1 < nr; i += 2) {
277
	 voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
278
	    offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
279
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
280
			       rmesa->radeon.tcl.aos[i+0].bo,
281
			       RADEON_GEM_DOMAIN_GTT,
282
			       0, 0);
283
	 voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
284
	    offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
285
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
286
			       rmesa->radeon.tcl.aos[i+1].bo,
287
			       RADEON_GEM_DOMAIN_GTT,
288
			       0, 0);
289
      }
290
      if (nr & 1) {
291
	 voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
292
	    offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
293
	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
294
			       rmesa->radeon.tcl.aos[nr-1].bo,
295
			       RADEON_GEM_DOMAIN_GTT,
296
			       0, 0);
297
      }
298
   }
299
   END_BATCH();
300
}