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 | }>><>><>><>><>><>><>>><>><>><>><>><>>>>>>>> |