fix #6991
[mesa.git] / src / mesa / drivers / dri / r300 / radeon_vtxfmt_a.c
1 /*
2 * Copyright (C) 2005 Aapo Tahkola.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 /*
29 * Authors:
30 * Aapo Tahkola <aet@rasterburn.org>
31 */
32
33 #include "context.h"
34 #include "r300_context.h"
35 #include "r300_cmdbuf.h"
36 #include "r300_ioctl.h"
37 #include "r300_maos.h"
38 #include "r300_state.h"
39 #include "radeon_mm.h"
40
41 #include "hash.h"
42 #include "dispatch.h"
43 #include "bufferobj.h"
44 #include "vtxfmt.h"
45 #include "api_validate.h"
46 #include "state.h"
47
48 #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \
49 rvb->AttribPtr[(a)].type = GL_FLOAT, \
50 rvb->AttribPtr[(a)].stride = vb->b->stride, \
51 rvb->AttribPtr[(a)].data = vb->b->data
52
53 void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer *rvb, struct vertex_buffer *vb)
54 {
55 int i;
56 GLcontext *ctx;
57 ctx = rmesa->radeon.glCtx;
58
59 memset(rvb, 0, sizeof(*rvb));
60
61 rvb->Elts = vb->Elts;
62 rvb->elt_size = 4;
63 rvb->elt_min = 0;
64 rvb->elt_max = vb->Count;
65
66 rvb->Count = vb->Count;
67
68 CONV_VB(VERT_ATTRIB_POS, ObjPtr);
69 CONV_VB(VERT_ATTRIB_NORMAL, NormalPtr);
70 CONV_VB(VERT_ATTRIB_COLOR0, ColorPtr[0]);
71 CONV_VB(VERT_ATTRIB_COLOR1, SecondaryColorPtr[0]);
72 CONV_VB(VERT_ATTRIB_FOG, FogCoordPtr);
73
74 for (i=0; i < ctx->Const.MaxTextureCoordUnits; i++)
75 CONV_VB(VERT_ATTRIB_TEX0 + i, TexCoordPtr[i]);
76
77 for (i=0; i < MAX_VERTEX_PROGRAM_ATTRIBS; i++)
78 CONV_VB(VERT_ATTRIB_GENERIC0 + i, AttribPtr[VERT_ATTRIB_GENERIC0 + i]);
79
80 rvb->Primitive = vb->Primitive;
81 rvb->PrimitiveCount = vb->PrimitiveCount;
82 rvb->LockFirst = rvb->LockCount = 0;
83 rvb->lock_uptodate = GL_FALSE;
84 }
85
86 #ifdef RADEON_VTXFMT_A
87
88 extern void _tnl_array_init( GLcontext *ctx );
89
90 #define CONV(a, b) \
91 do { \
92 if (ctx->Array.ArrayObj->b.Enabled) { \
93 rmesa->state.VB.AttribPtr[(a)].size = ctx->Array.ArrayObj->b.Size; \
94 rmesa->state.VB.AttribPtr[(a)].data = ctx->Array.ArrayObj->b.BufferObj->Name \
95 ? (void *)ADD_POINTERS(ctx->Array.ArrayObj->b.Ptr, ctx->Array.ArrayObj->b.BufferObj->Data) \
96 : (void *)ctx->Array.ArrayObj->b.Ptr; \
97 rmesa->state.VB.AttribPtr[(a)].stride = ctx->Array.ArrayObj->b.StrideB; \
98 rmesa->state.VB.AttribPtr[(a)].type = ctx->Array.ArrayObj->b.Type; \
99 enabled |= 1 << (a); \
100 } \
101 } while (0)
102
103 static int setup_arrays(r300ContextPtr rmesa, GLint start)
104 {
105 int i;
106 struct dt def = { 4, GL_FLOAT, 0, NULL };
107 GLcontext *ctx;
108 GLuint enabled = 0;
109
110 ctx = rmesa->radeon.glCtx;
111 i = r300Fallback(ctx);
112 if (i)
113 return i;
114
115 memset(rmesa->state.VB.AttribPtr, 0, VERT_ATTRIB_MAX*sizeof(struct dt));
116
117 CONV(VERT_ATTRIB_POS, Vertex);
118 CONV(VERT_ATTRIB_NORMAL, Normal);
119 CONV(VERT_ATTRIB_COLOR0, Color);
120 CONV(VERT_ATTRIB_COLOR1, SecondaryColor);
121 CONV(VERT_ATTRIB_FOG, FogCoord);
122
123 for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++)
124 CONV(VERT_ATTRIB_TEX0 + i, TexCoord[i]);
125
126 if (ctx->VertexProgram._Enabled)
127 for (i=0; i < VERT_ATTRIB_MAX; i++)
128 CONV(i, VertexAttrib[i]);
129
130 for (i=0; i < VERT_ATTRIB_MAX; i++) {
131 if (enabled & (1 << i)) {
132 rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start;
133 } else {
134 def.data = ctx->Current.Attrib[i];
135 memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt));
136 }
137
138 /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
139 fprintf(stderr, "%d is default coord\n", i);*/
140 }
141
142 for(i=0; i < VERT_ATTRIB_MAX; i++){
143 if(rmesa->state.VB.AttribPtr[i].type != GL_UNSIGNED_BYTE &&
144 rmesa->state.VB.AttribPtr[i].type != GL_FLOAT){
145 WARN_ONCE("Unsupported format %d at index %d\n", rmesa->state.VB.AttribPtr[i].type, i);
146 return R300_FALLBACK_TCL;
147 }
148 if(rmesa->state.VB.AttribPtr[i].type == GL_UNSIGNED_BYTE &&
149 rmesa->state.VB.AttribPtr[i].size != 4){
150 WARN_ONCE("Unsupported component count for ub colors\n");
151 return R300_FALLBACK_TCL;
152 }
153
154 /*fprintf(stderr, "%d: ", i);
155
156 switch(rmesa->state.VB.AttribPtr[i].type){
157 case GL_BYTE: fprintf(stderr, "byte "); break;
158 case GL_UNSIGNED_BYTE: fprintf(stderr, "u byte "); break;
159 case GL_SHORT: fprintf(stderr, "short "); break;
160 case GL_UNSIGNED_SHORT: fprintf(stderr, "u short "); break;
161 case GL_INT: fprintf(stderr, "int "); break;
162 case GL_UNSIGNED_INT: fprintf(stderr, "u int "); break;
163 case GL_FLOAT: fprintf(stderr, "float "); break;
164 case GL_2_BYTES: fprintf(stderr, "2 bytes "); break;
165 case GL_3_BYTES: fprintf(stderr, "3 bytes "); break;
166 case GL_4_BYTES: fprintf(stderr, "4 bytes "); break;
167 case GL_DOUBLE: fprintf(stderr, "double "); break;
168 default: fprintf(stderr, "unknown "); break;
169 }
170
171 fprintf(stderr, "Size %d ", rmesa->state.VB.AttribPtr[i].size);
172 fprintf(stderr, "Ptr %p ", rmesa->state.VB.AttribPtr[i].data);
173 fprintf(stderr, "Stride %d ", rmesa->state.VB.AttribPtr[i].stride);
174 fprintf(stderr, "\n");*/
175 }
176 return R300_FALLBACK_NONE;
177 }
178
179 void radeon_init_vtxfmt_a(r300ContextPtr rmesa);
180
181 static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices )
182 {
183 GET_CURRENT_CONTEXT(ctx);
184 r300ContextPtr rmesa = R300_CONTEXT(ctx);
185 int elt_size;
186 int i;
187 unsigned int min = ~0, max = 0;
188 struct tnl_prim prim;
189 static void *ptr = NULL;
190 struct r300_dma_region rvb;
191 const GLvoid *indices = c_indices;
192
193 if (count > 65535) {
194 WARN_ONCE("Too many verts!\n");
195 goto fallback;
196 }
197
198 if (ctx->Array.ElementArrayBufferObj->Name) {
199 /* use indices in the buffer object */
200 if (!ctx->Array.ElementArrayBufferObj->Data) {
201 _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
202 return;
203 }
204 /* actual address is the sum of pointers */
205 indices = (GLvoid *)
206 ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
207 }
208
209 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
210 return;
211
212 FLUSH_CURRENT( ctx, 0 );
213
214 memset(&rvb, 0, sizeof(rvb));
215 switch (type) {
216 case GL_UNSIGNED_BYTE:
217 for (i=0; i < count; i++) {
218 if(((unsigned char *)indices)[i] < min)
219 min = ((unsigned char *)indices)[i];
220 if(((unsigned char *)indices)[i] > max)
221 max = ((unsigned char *)indices)[i];
222 }
223
224 #ifdef FORCE_32BITS_ELTS
225 elt_size = 4;
226 #else
227 elt_size = 2;
228 #endif
229 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
230 rvb.aos_offset = GET_START(&rvb);
231 ptr = rvb.address + rvb.start;
232
233 #ifdef FORCE_32BITS_ELTS
234 for (i=0; i < count; i++)
235 ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
236 #else
237 for (i=0; i < count; i++)
238 ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
239 #endif
240 break;
241
242 case GL_UNSIGNED_SHORT:
243 for (i=0; i < count; i++) {
244 if(((unsigned short int *)indices)[i] < min)
245 min = ((unsigned short int *)indices)[i];
246 if(((unsigned short int *)indices)[i] > max)
247 max = ((unsigned short int *)indices)[i];
248 }
249
250 #ifdef FORCE_32BITS_ELTS
251 elt_size = 4;
252 #else
253 elt_size = 2;
254 #endif
255
256 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
257 rvb.aos_offset = GET_START(&rvb);
258 ptr = rvb.address + rvb.start;
259
260 #ifdef FORCE_32BITS_ELTS
261 for (i=0; i < count; i++)
262 ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
263 #else
264 for (i=0; i < count; i++)
265 ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
266 #endif
267 break;
268
269 case GL_UNSIGNED_INT:
270 for (i=0; i < count; i++) {
271 if(((unsigned int *)indices)[i] < min)
272 min = ((unsigned int *)indices)[i];
273 if(((unsigned int *)indices)[i] > max)
274 max = ((unsigned int *)indices)[i];
275 }
276
277 #ifdef FORCE_32BITS_ELTS
278 elt_size = 4;
279 #else
280 if (max - min <= 65535)
281 elt_size = 2;
282 else
283 elt_size = 4;
284 #endif
285 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
286 rvb.aos_offset = GET_START(&rvb);
287 ptr = rvb.address + rvb.start;
288
289
290 if (elt_size == 2)
291 for (i=0; i < count; i++)
292 ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
293 else
294 for (i=0; i < count; i++)
295 ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
296 break;
297
298 default:
299 WARN_ONCE("Unknown elt type!\n");
300 goto fallback;
301 }
302
303 if (ctx->NewState)
304 _mesa_update_state( ctx );
305
306 r300UpdateShaders(rmesa);
307
308 if (rmesa->state.VB.LockCount) {
309 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
310 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
311 return;
312
313 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
314
315 r300ReleaseArrays(ctx);
316 r300EmitArrays(ctx, GL_FALSE);
317
318 rmesa->state.VB.lock_uptodate = GL_TRUE;
319 }
320
321 if (min < rmesa->state.VB.LockFirst) {
322 WARN_ONCE("Out of range min %d vs %d!\n", min, rmesa->state.VB.LockFirst);
323 return;
324 }
325
326 if (max >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) {
327 WARN_ONCE("Out of range max %d vs %d!\n", max, rmesa->state.VB.LockFirst +
328 rmesa->state.VB.LockCount);
329 return;
330 }
331 } else {
332 if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
333 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
334 goto fallback;
335 }
336
337 rmesa->state.VB.Count = max - min + 1;
338 }
339
340 r300UpdateShaderStates(rmesa);
341
342 rmesa->state.VB.Primitive = &prim;
343 rmesa->state.VB.PrimitiveCount = 1;
344
345 prim.mode = mode | PRIM_BEGIN | PRIM_END;
346 if (rmesa->state.VB.LockCount)
347 prim.start = min - rmesa->state.VB.LockFirst;
348 else
349 prim.start = 0;
350 prim.count = count;
351
352 rmesa->state.VB.Elts = ptr;
353 rmesa->state.VB.elt_size = elt_size;
354
355 r300_run_vb_render(ctx, NULL);
356
357 if(rvb.buf)
358 radeon_mm_use(rmesa, rvb.buf->id);
359
360 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
361 return;
362
363 fallback:
364 _tnl_array_init(ctx);
365 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
366 CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices));
367 radeon_init_vtxfmt_a(rmesa);
368 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
369 }
370
371 static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices)
372 {
373 GET_CURRENT_CONTEXT(ctx);
374 r300ContextPtr rmesa = R300_CONTEXT(ctx);
375 struct tnl_prim prim;
376 int elt_size;
377 int i;
378 void *ptr = NULL;
379 struct r300_dma_region rvb;
380 const GLvoid *indices = c_indices;
381
382 if (count > 65535) {
383 WARN_ONCE("Too many verts!\n");
384 goto fallback;
385 }
386
387 if (ctx->Array.ElementArrayBufferObj->Name) {
388 /* use indices in the buffer object */
389 if (!ctx->Array.ElementArrayBufferObj->Data) {
390 _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
391 return;
392 }
393 /* actual address is the sum of pointers */
394 indices = (GLvoid *)
395 ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
396 }
397
398 if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices ))
399 return;
400
401 FLUSH_CURRENT( ctx, 0 );
402 #ifdef OPTIMIZE_ELTS
403 min = 0;
404 #endif
405
406 memset(&rvb, 0, sizeof(rvb));
407 switch (type){
408 case GL_UNSIGNED_BYTE:
409 #ifdef FORCE_32BITS_ELTS
410 elt_size = 4;
411 #else
412 elt_size = 2;
413 #endif
414 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
415 rvb.aos_offset = GET_START(&rvb);
416 ptr = rvb.address + rvb.start;
417
418 #ifdef FORCE_32BITS_ELTS
419 for(i=0; i < count; i++)
420 ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
421 #else
422 for(i=0; i < count; i++)
423 ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
424 #endif
425 break;
426
427 case GL_UNSIGNED_SHORT:
428 #ifdef FORCE_32BITS_ELTS
429 elt_size = 4;
430 #else
431 elt_size = 2;
432 #endif
433 #ifdef OPTIMIZE_ELTS
434 if (min == 0 && ctx->Array.ElementArrayBufferObj->Name){
435 ptr = indices;
436 break;
437 }
438 #endif
439 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
440 rvb.aos_offset = GET_START(&rvb);
441 ptr = rvb.address + rvb.start;
442
443 #ifdef FORCE_32BITS_ELTS
444 for(i=0; i < count; i++)
445 ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
446 #else
447 for(i=0; i < count; i++)
448 ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
449 #endif
450 break;
451
452 case GL_UNSIGNED_INT:
453 #ifdef FORCE_32BITS_ELTS
454 elt_size = 4;
455 #else
456 if (max - min <= 65535)
457 elt_size = 2;
458 else
459 elt_size = 4;
460 #endif
461 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
462 rvb.aos_offset = GET_START(&rvb);
463 ptr = rvb.address + rvb.start;
464
465 if (elt_size == 2)
466 for (i=0; i < count; i++)
467 ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
468 else
469 for (i=0; i < count; i++)
470 ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
471 break;
472
473 default:
474 WARN_ONCE("Unknown elt type!\n");
475 goto fallback;
476 }
477
478 /* XXX: setup_arrays before state update? */
479
480 if (ctx->NewState)
481 _mesa_update_state( ctx );
482
483 r300UpdateShaders(rmesa);
484
485 if (rmesa->state.VB.LockCount) {
486 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
487 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
488 goto fallback;
489
490 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
491
492 r300ReleaseArrays(ctx);
493 r300EmitArrays(ctx, GL_FALSE);
494
495 rmesa->state.VB.lock_uptodate = GL_TRUE;
496 }
497
498 if (min < rmesa->state.VB.LockFirst) {
499 WARN_ONCE("Out of range min %d vs %d!\n", min, rmesa->state.VB.LockFirst);
500 goto fallback;
501 }
502
503 /*if (max >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) {
504 WARN_ONCE("Out of range max %d vs %d!\n", max, rmesa->state.VB.LockFirst +
505 rmesa->state.VB.LockCount);
506 return;
507 }*/
508 } else {
509 if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
510 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
511 goto fallback;
512 }
513
514 rmesa->state.VB.Count = max - min + 1;
515 }
516
517 r300UpdateShaderStates(rmesa);
518
519 rmesa->state.VB.Primitive = &prim;
520 rmesa->state.VB.PrimitiveCount = 1;
521
522 prim.mode = mode | PRIM_BEGIN | PRIM_END;
523 if (rmesa->state.VB.LockCount)
524 prim.start = min - rmesa->state.VB.LockFirst;
525 else
526 prim.start = 0;
527 prim.count = count;
528
529 rmesa->state.VB.Elts = ptr;
530 rmesa->state.VB.elt_size = elt_size;
531 rmesa->state.VB.elt_min = min;
532 rmesa->state.VB.elt_max = max;
533
534 r300_run_vb_render(ctx, NULL);
535
536 if(rvb.buf)
537 radeon_mm_use(rmesa, rvb.buf->id);
538
539 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
540 return ;
541
542 fallback:
543 _tnl_array_init(ctx);
544 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
545 CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices));
546 radeon_init_vtxfmt_a(rmesa);
547 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
548 }
549
550 static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
551 {
552 GET_CURRENT_CONTEXT(ctx);
553 r300ContextPtr rmesa = R300_CONTEXT(ctx);
554 struct tnl_prim prim;
555 int i;
556
557 if (count > 65535) {
558 WARN_ONCE("Too many verts!\n");
559 goto fallback;
560 }
561
562 if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
563 return;
564
565 FLUSH_CURRENT( ctx, 0 );
566
567 if (ctx->NewState)
568 _mesa_update_state( ctx );
569
570 /* XXX: setup_arrays before state update? */
571
572 r300UpdateShaders(rmesa);
573
574 if (rmesa->state.VB.LockCount) {
575 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
576 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
577 return;
578
579 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
580
581 r300ReleaseArrays(ctx);
582 r300EmitArrays(ctx, GL_FALSE);
583
584 rmesa->state.VB.lock_uptodate = GL_TRUE;
585 }
586
587 if (start < rmesa->state.VB.LockFirst) {
588 WARN_ONCE("Out of range min %d vs %d!\n", start, rmesa->state.VB.LockFirst);
589 goto fallback;
590 }
591
592 if (start + count - 1 >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) { /* XXX */
593 WARN_ONCE("Out of range max %d vs %d!\n", start + count - 1, rmesa->state.VB.LockFirst +
594 rmesa->state.VB.LockCount);
595 goto fallback;
596 }
597 } else {
598 if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL)
599 goto fallback;
600
601 rmesa->state.VB.Count = count;
602 }
603
604 r300UpdateShaderStates(rmesa);
605
606 rmesa->state.VB.Primitive = &prim;
607 rmesa->state.VB.PrimitiveCount = 1;
608
609 prim.mode = mode | PRIM_BEGIN | PRIM_END;
610 if (rmesa->state.VB.LockCount)
611 prim.start = start - rmesa->state.VB.LockFirst;
612 else
613 prim.start = 0;
614 prim.count = count;
615
616 rmesa->state.VB.Elts = NULL;
617 rmesa->state.VB.elt_size = 0;
618 rmesa->state.VB.elt_min = 0;
619 rmesa->state.VB.elt_max = 0;
620
621 r300_run_vb_render(ctx, NULL);
622
623 return ;
624
625 fallback:
626 _tnl_array_init(ctx);
627 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
628 CALL_DrawArrays(GET_DISPATCH(), (mode, start, count));
629 radeon_init_vtxfmt_a(rmesa);
630 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
631 }
632
633 void radeon_init_vtxfmt_a(r300ContextPtr rmesa)
634 {
635 GLcontext *ctx;
636 GLvertexformat *vfmt;
637
638 ctx = rmesa->radeon.glCtx;
639 vfmt = (GLvertexformat *)ctx->TnlModule.Current;
640
641 vfmt->DrawElements = radeonDrawElements;
642 vfmt->DrawArrays = radeonDrawArrays;
643 vfmt->DrawRangeElements = radeonDrawRangeElements;
644
645 }
646 #endif
647
648 #ifdef HW_VBOS
649
650 #if 0
651 static void radeonLockArraysEXT(GLcontext *ctx, GLint first, GLsizei count)
652 {
653 r300ContextPtr rmesa = R300_CONTEXT(ctx);
654
655 /* Only when CB_DPATH is defined.
656 r300Clear tampers over the aos setup without it.
657 (r300ResetHwState cannot call r300EmitArrays)
658 */
659 #ifndef CB_DPATH
660 first = 0; count = 0;
661 #endif
662
663 if (first < 0 || count <= 0) {
664 rmesa->state.VB.LockFirst = 0;
665 rmesa->state.VB.LockCount = 0;
666 rmesa->state.VB.lock_uptodate = GL_FALSE;
667 return ;
668 }
669
670 rmesa->state.VB.LockFirst = first;
671 rmesa->state.VB.LockCount = count;
672 rmesa->state.VB.lock_uptodate = GL_FALSE;
673 }
674
675 static void radeonUnlockArraysEXT(GLcontext *ctx)
676 {
677 r300ContextPtr rmesa = R300_CONTEXT(ctx);
678
679 rmesa->state.VB.LockFirst = 0;
680 rmesa->state.VB.LockCount = 0;
681 rmesa->state.VB.lock_uptodate = GL_FALSE;
682 }
683 #endif
684
685 static struct gl_buffer_object *
686 r300NewBufferObject(GLcontext *ctx, GLuint name, GLenum target )
687 {
688 struct r300_buffer_object *obj;
689
690 (void) ctx;
691
692 obj = MALLOC_STRUCT(r300_buffer_object);
693 _mesa_initialize_buffer_object(&obj->mesa_obj, name, target);
694 return &obj->mesa_obj;
695 }
696
697 static void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
698 const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
699 {
700 r300ContextPtr rmesa = R300_CONTEXT(ctx);
701 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
702
703 /* Free previous buffer */
704 if (obj->OnCard) {
705 radeon_mm_free(rmesa, r300_obj->id);
706 obj->OnCard = GL_FALSE;
707 } else {
708 if (obj->Data)
709 _mesa_free(obj->Data);
710 }
711 #ifdef OPTIMIZE_ELTS
712 if (0) {
713 #else
714 if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
715 #endif
716 fallback:
717 obj->Data = malloc(size);
718
719 if (data)
720 _mesa_memcpy(obj->Data, data, size);
721
722 obj->OnCard = GL_FALSE;
723 } else {
724 r300_obj->id = radeon_mm_alloc(rmesa, 4, size);
725 if (r300_obj->id == 0)
726 goto fallback;
727
728 obj->Data = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
729
730 if (data)
731 _mesa_memcpy(obj->Data, data, size);
732
733 radeon_mm_unmap(rmesa, r300_obj->id);
734 obj->OnCard = GL_TRUE;
735 }
736
737 obj->Size = size;
738 obj->Usage = usage;
739 }
740
741 static void r300BufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
742 GLsizeiptrARB size, const GLvoid * data, struct gl_buffer_object * bufObj)
743 {
744 r300ContextPtr rmesa = R300_CONTEXT(ctx);
745 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
746 (void) ctx; (void) target;
747 void *ptr;
748
749 if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) {
750 if (bufObj->OnCard){
751 ptr = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
752
753 _mesa_memcpy( (GLubyte *) ptr + offset, data, size );
754
755 radeon_mm_unmap(rmesa, r300_obj->id);
756 } else {
757 _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size );
758 }
759 }
760 }
761
762 static void *r300MapBuffer(GLcontext *ctx, GLenum target, GLenum access,
763 struct gl_buffer_object *bufObj)
764 {
765 r300ContextPtr rmesa = R300_CONTEXT(ctx);
766 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
767
768 (void) ctx;
769 (void) target;
770 (void) access;
771 //ASSERT(!bufObj->OnCard);
772 /* Just return a direct pointer to the data */
773 if (bufObj->Pointer) {
774 /* already mapped! */
775 return NULL;
776 }
777
778 if (!bufObj->OnCard) {
779 bufObj->Pointer = bufObj->Data;
780 return bufObj->Pointer;
781 }
782
783 switch (access) {
784 case GL_READ_ONLY:
785 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_R);
786 break;
787
788 case GL_WRITE_ONLY:
789 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
790 break;
791
792 case GL_READ_WRITE:
793 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_RW);
794 break;
795
796 default:
797 WARN_ONCE("Unknown access type\n");
798 bufObj->Pointer = NULL;
799 break;
800 }
801
802 return bufObj->Pointer;
803 }
804
805 static GLboolean r300UnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *bufObj)
806 {
807 r300ContextPtr rmesa = R300_CONTEXT(ctx);
808 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
809
810 (void) ctx;
811 (void) target;
812 //ASSERT(!bufObj->OnCard);
813 /* XXX we might assert here that bufObj->Pointer is non-null */
814 if (!bufObj->OnCard) {
815 bufObj->Pointer = NULL;
816 return GL_TRUE;
817 }
818 radeon_mm_unmap(rmesa, r300_obj->id);
819
820 bufObj->Pointer = NULL;
821 return GL_TRUE;
822 }
823
824 static void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
825 {
826 r300ContextPtr rmesa = R300_CONTEXT(ctx);
827 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
828
829 if (obj->OnCard) {
830 radeon_mm_free(rmesa, r300_obj->id);
831 obj->Data = NULL;
832 }
833 _mesa_delete_buffer_object(ctx, obj);
834 }
835
836 void r300_evict_vbos(GLcontext *ctx, int amount)
837 {
838 r300ContextPtr rmesa = R300_CONTEXT(ctx);
839 struct _mesa_HashTable *hash = ctx->Shared->BufferObjects;
840 GLuint k = _mesa_HashFirstEntry(hash);
841 struct gl_buffer_object *obj;
842 struct r300_buffer_object *r300_obj;
843 GLvoid *data;
844
845 while (amount > 0 && k) {
846 obj = (struct gl_buffer_object *) _mesa_HashLookup(hash, k);
847 r300_obj = (struct r300_buffer_object *) obj;
848
849 if (obj->OnCard && obj->Size) {
850 obj->Data = _mesa_malloc(obj->Size);
851
852 data = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_R);
853 _mesa_memcpy(obj->Data, data, obj->Size);
854 radeon_mm_unmap(rmesa, r300_obj->id);
855
856 radeon_mm_free(rmesa, r300_obj->id);
857 r300_obj->id = 0;
858 obj->OnCard = GL_FALSE;
859
860 amount -= obj->Size;
861 }
862
863 k = _mesa_HashNextEntry(hash, k);
864 }
865
866 }
867
868 void r300_init_vbo_funcs(struct dd_function_table *functions)
869 {
870 functions->NewBufferObject = r300NewBufferObject;
871 functions->BufferData = r300BufferData;
872 functions->BufferSubData = r300BufferSubData;
873 functions->MapBuffer = r300MapBuffer;
874 functions->UnmapBuffer = r300UnmapBuffer;
875 functions->DeleteBuffer = r300DeleteBuffer;
876
877 /*functions->LockArraysEXT = radeonLockArraysEXT;
878 functions->UnlockArraysEXT = radeonUnlockArraysEXT;*/
879 }
880
881 #endif