Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r200 / r200_cmdbuf.c
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 <keith@tungstengraphics.com>
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                 if (!rmesa->radeon.radeonScreen->kernel_mm) {
150                         OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
151                         OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
152                         OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset,
153                                         rmesa->radeon.tcl.elt_dma_bo,
154                                         rmesa->radeon.tcl.elt_dma_offset,
155                                         RADEON_GEM_DOMAIN_GTT, 0, 0);
156                         OUT_BATCH((vertex_count + 1)/2);
157                 } else {
158                         OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
159                         OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
160                         OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset);
161                         OUT_BATCH((vertex_count + 1)/2);
162                         radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
163                                               rmesa->radeon.tcl.elt_dma_bo,
164                                               RADEON_GEM_DOMAIN_GTT, 0, 0);
165                 }
166                 END_BATCH();
167         }
168 }
169
170 void r200FlushElts(struct gl_context *ctx)
171 {
172    r200ContextPtr rmesa = R200_CONTEXT(ctx);
173    int nr, elt_used = rmesa->tcl.elt_used;
174
175    radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);
176
177    assert( rmesa->radeon.dma.flush == r200FlushElts );
178    rmesa->radeon.dma.flush = NULL;
179
180    nr = elt_used / 2;
181
182    radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);
183
184    r200FireEB(rmesa, nr, rmesa->tcl.hw_primitive);
185
186    radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
187    rmesa->radeon.tcl.elt_dma_bo = NULL;
188
189    if (R200_ELT_BUF_SZ > elt_used)
190      radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
191
192    if (radeon_is_debug_enabled(RADEON_SYNC, RADEON_CRITICAL)
193          && !rmesa->radeon.radeonScreen->kernel_mm) {
194       radeon_print(RADEON_SYNC, RADEON_NORMAL, "%s: Syncing\n", __FUNCTION__);
195       radeonFinish( rmesa->radeon.glCtx );
196    }
197 }
198
199
200 GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
201                                     GLuint primitive,
202                                     GLuint min_nr )
203 {
204    GLushort *retval;
205
206    radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
207
208    assert((primitive & R200_VF_PRIM_WALK_IND));
209    
210    radeonEmitState(&rmesa->radeon);
211
212    radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
213                         &rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4);
214    rmesa->tcl.elt_used = min_nr * 2;
215
216    radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
217    retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
218    
219    assert(!rmesa->radeon.dma.flush);
220    rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
221    rmesa->radeon.dma.flush = r200FlushElts;
222
223    return retval;
224 }
225
226 void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count)
227 {
228    BATCH_LOCALS(&rmesa->radeon);
229
230    if (rmesa->radeon.radeonScreen->kernel_mm) {
231            BEGIN_BATCH_NO_AUTOSTATE(2);
232            OUT_BATCH(CP_PACKET0(R200_SE_VF_MAX_VTX_INDX, 0));
233            OUT_BATCH(count);
234            END_BATCH();
235    }
236 }
237
238 void r200EmitVertexAOS( r200ContextPtr rmesa,
239                         GLuint vertex_size,
240                         struct radeon_bo *bo,
241                         GLuint offset )
242 {
243    BATCH_LOCALS(&rmesa->radeon);
244
245    radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s:  vertex_size 0x%x offset 0x%x \n",
246               __FUNCTION__, vertex_size, offset);
247
248
249    BEGIN_BATCH(7);
250    OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, 2);
251    OUT_BATCH(1);
252    OUT_BATCH(vertex_size | (vertex_size << 8));
253    OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
254    END_BATCH();
255 }
256
257 void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset)
258 {
259    BATCH_LOCALS(&rmesa->radeon);
260    uint32_t voffset;
261    int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
262    int i;
263    
264    radeon_print(RADEON_RENDER, RADEON_VERBOSE,
265            "%s: nr=%d, ofs=0x%08x\n",
266            __FUNCTION__, nr, offset);
267
268    BEGIN_BATCH(sz+2+ (nr*2));
269    OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, sz - 1);
270    OUT_BATCH(nr);
271
272     
273    if (!rmesa->radeon.radeonScreen->kernel_mm) {
274       for (i = 0; i + 1 < nr; i += 2) {
275          OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
276                    (rmesa->radeon.tcl.aos[i].stride << 8) |
277                    (rmesa->radeon.tcl.aos[i + 1].components << 16) |
278                    (rmesa->radeon.tcl.aos[i + 1].stride << 24));
279                         
280          voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
281             offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
282          OUT_BATCH_RELOC(voffset,
283                          rmesa->radeon.tcl.aos[i].bo,
284                          voffset,
285                          RADEON_GEM_DOMAIN_GTT,
286                          0, 0);
287          voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
288             offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
289          OUT_BATCH_RELOC(voffset,
290                          rmesa->radeon.tcl.aos[i+1].bo,
291                          voffset,
292                          RADEON_GEM_DOMAIN_GTT,
293                          0, 0);
294       }
295       
296       if (nr & 1) {
297          OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
298                    (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
299          voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
300             offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
301          OUT_BATCH_RELOC(voffset,
302                          rmesa->radeon.tcl.aos[nr - 1].bo,
303                          voffset,
304                          RADEON_GEM_DOMAIN_GTT,
305                          0, 0);
306       }
307    } else {
308       for (i = 0; i + 1 < nr; i += 2) {
309          OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
310                    (rmesa->radeon.tcl.aos[i].stride << 8) |
311                    (rmesa->radeon.tcl.aos[i + 1].components << 16) |
312                    (rmesa->radeon.tcl.aos[i + 1].stride << 24));
313          
314          voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
315             offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
316          OUT_BATCH(voffset);
317          voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
318             offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
319          OUT_BATCH(voffset);
320       }
321       
322       if (nr & 1) {
323          OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
324                    (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
325          voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
326             offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
327          OUT_BATCH(voffset);
328       }
329       for (i = 0; i + 1 < nr; i += 2) {
330          voffset =  rmesa->radeon.tcl.aos[i + 0].offset +
331             offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
332          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
333                                rmesa->radeon.tcl.aos[i+0].bo,
334                                RADEON_GEM_DOMAIN_GTT,
335                                0, 0);
336          voffset =  rmesa->radeon.tcl.aos[i + 1].offset +
337             offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
338          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
339                                rmesa->radeon.tcl.aos[i+1].bo,
340                                RADEON_GEM_DOMAIN_GTT,
341                                0, 0);
342       }
343       if (nr & 1) {
344          voffset =  rmesa->radeon.tcl.aos[nr - 1].offset +
345             offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
346          radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
347                                rmesa->radeon.tcl.aos[nr-1].bo,
348                                RADEON_GEM_DOMAIN_GTT,
349                                0, 0);
350       }
351    }
352    END_BATCH();
353 }