Various fallbacks, checks and tags.
[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 "radeon_mm.h"
37
38 #include "dispatch.h"
39
40 #ifdef RADEON_VTXFMT_A
41
42 #define CONV(a, b) rmesa->state.VB.AttribPtr[(a)].size = ctx->Array.b.Size, \
43 rmesa->state.VB.AttribPtr[(a)].data = ctx->Array.b.BufferObj->Name ? \
44 ADD_POINTERS(ctx->Array.b.Ptr, ctx->Array.b.BufferObj->Data) : ctx->Array.b.Ptr, \
45 rmesa->state.VB.AttribPtr[(a)].stride = ctx->Array.b.StrideB, \
46 rmesa->state.VB.AttribPtr[(a)].type = ctx->Array.b.Type
47
48 static int setup_arrays(r300ContextPtr rmesa, GLint start)
49 {
50 int i;
51 struct dt def = { 4, GL_FLOAT, 0, NULL };
52 GLcontext *ctx;
53 GLuint enabled = 0;
54
55 ctx = rmesa->radeon.glCtx;
56 if (r300Fallback(ctx))
57 return -1;
58
59 memset(rmesa->state.VB.AttribPtr, 0, VERT_ATTRIB_MAX*sizeof(struct dt));
60
61 CONV(VERT_ATTRIB_POS, Vertex);
62 if (ctx->Array.Vertex.Enabled)
63 enabled |= 1 << VERT_ATTRIB_POS;
64
65 CONV(VERT_ATTRIB_NORMAL, Normal);
66 if (ctx->Array.Normal.Enabled)
67 enabled |= 1 << VERT_ATTRIB_NORMAL;
68
69 CONV(VERT_ATTRIB_COLOR0, Color);
70 if (ctx->Array.Color.Enabled)
71 enabled |= 1 << VERT_ATTRIB_COLOR0;
72
73 CONV(VERT_ATTRIB_COLOR1, SecondaryColor);
74 if (ctx->Array.SecondaryColor.Enabled)
75 enabled |= 1 << VERT_ATTRIB_COLOR1;
76
77 CONV(VERT_ATTRIB_FOG, FogCoord);
78 if (ctx->Array.FogCoord.Enabled)
79 enabled |= 1 << VERT_ATTRIB_FOG;
80
81 for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++) {
82 CONV(VERT_ATTRIB_TEX0 + i, TexCoord[i]);
83
84 if(ctx->Array.TexCoord[i].Enabled) {
85 enabled |= 1 << (VERT_ATTRIB_TEX0+i);
86 }
87
88 }
89
90 for (i=0; i < VERT_ATTRIB_MAX; i++) {
91 if (enabled & (1 << i)) {
92 rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start;
93 } else {
94 def.data = ctx->Current.Attrib[i];
95 memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt));
96 }
97
98 /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
99 fprintf(stderr, "%d is default coord\n", i);*/
100 }
101
102 for(i=0; i < VERT_ATTRIB_MAX; i++){
103 if(rmesa->state.VB.AttribPtr[i].type != GL_UNSIGNED_BYTE &&
104 rmesa->state.VB.AttribPtr[i].type != GL_FLOAT){
105 WARN_ONCE("Unsupported format %d at index %d\n", rmesa->state.VB.AttribPtr[i].type, i);
106 return -1;
107 }
108 if(rmesa->state.VB.AttribPtr[i].type == GL_UNSIGNED_BYTE &&
109 rmesa->state.VB.AttribPtr[i].size != 4){
110 WARN_ONCE("Unsupported component count for ub colors\n");
111 return -1;
112 }
113
114 /*fprintf(stderr, "%d: ", i);
115
116 switch(rmesa->state.VB.AttribPtr[i].type){
117 case GL_BYTE: fprintf(stderr, "byte "); break;
118 case GL_UNSIGNED_BYTE: fprintf(stderr, "u byte "); break;
119 case GL_SHORT: fprintf(stderr, "short "); break;
120 case GL_UNSIGNED_SHORT: fprintf(stderr, "u short "); break;
121 case GL_INT: fprintf(stderr, "int "); break;
122 case GL_UNSIGNED_INT: fprintf(stderr, "u int "); break;
123 case GL_FLOAT: fprintf(stderr, "float "); break;
124 case GL_2_BYTES: fprintf(stderr, "2 bytes "); break;
125 case GL_3_BYTES: fprintf(stderr, "3 bytes "); break;
126 case GL_4_BYTES: fprintf(stderr, "4 bytes "); break;
127 case GL_DOUBLE: fprintf(stderr, "double "); break;
128 default: fprintf(stderr, "unknown "); break;
129 }
130
131 fprintf(stderr, "Size %d ", rmesa->state.VB.AttribPtr[i].size);
132 fprintf(stderr, "Ptr %p ", rmesa->state.VB.AttribPtr[i].data);
133 fprintf(stderr, "Stride %d ", rmesa->state.VB.AttribPtr[i].stride);
134 fprintf(stderr, "\n");*/
135 }
136 return 0;
137 }
138
139 void radeon_init_vtxfmt_a(r300ContextPtr rmesa);
140
141 void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices )
142 {
143 GET_CURRENT_CONTEXT(ctx);
144 r300ContextPtr rmesa = R300_CONTEXT(ctx);
145 int elt_size;
146 int i;
147 unsigned int min = ~0, max = 0;
148 struct tnl_prim prim;
149 static void *ptr = NULL;
150 static struct r300_dma_region rvb;
151 GLvoid *indices;
152
153 if (count > 65535) {
154 WARN_ONCE("Too many verts!\n");
155 goto fallback;
156 }
157
158 if (ctx->Array.ElementArrayBufferObj->Name) {
159 /* use indices in the buffer object */
160 if (!ctx->Array.ElementArrayBufferObj->Data) {
161 _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
162 return;
163 }
164 /* actual address is the sum of pointers */
165 indices = (const GLvoid *)
166 ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
167 }
168
169 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
170 return;
171
172 FLUSH_CURRENT( ctx, 0 );
173 /*
174 fprintf(stderr, "dt at %s:\n", __FUNCTION__);
175 for(i=0; i < VERT_ATTRIB_MAX; i++){
176 fprintf(stderr, "dt %d:", i);
177 dump_dt(&rmesa->state.VB.AttribPtr[i], rmesa->state.VB.Count);
178 }*/
179 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
180
181 switch (type) {
182 case GL_UNSIGNED_BYTE:
183 for (i=0; i < count; i++) {
184 if(((unsigned char *)indices)[i] < min)
185 min = ((unsigned char *)indices)[i];
186 if(((unsigned char *)indices)[i] > max)
187 max = ((unsigned char *)indices)[i];
188 }
189
190 elt_size = 2;
191
192 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
193 rvb.aos_offset = GET_START(&rvb);
194 ptr = rvb.address + rvb.start;
195
196 for (i=0; i < count; i++)
197 ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
198 break;
199
200 case GL_UNSIGNED_SHORT:
201 for (i=0; i < count; i++) {
202 if(((unsigned short int *)indices)[i] < min)
203 min = ((unsigned short int *)indices)[i];
204 if(((unsigned short int *)indices)[i] > max)
205 max = ((unsigned short int *)indices)[i];
206 }
207
208 elt_size = 2;
209
210 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
211 rvb.aos_offset = GET_START(&rvb);
212 ptr = rvb.address + rvb.start;
213
214 for (i=0; i < count; i++)
215 ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
216 break;
217
218 case GL_UNSIGNED_INT:
219 for (i=0; i < count; i++) {
220 if(((unsigned int *)indices)[i] < min)
221 min = ((unsigned int *)indices)[i];
222 if(((unsigned int *)indices)[i] > max)
223 max = ((unsigned int *)indices)[i];
224 }
225
226 if (max - min <= 65535)
227 elt_size = 2;
228 else
229 elt_size = 4;
230
231 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
232 rvb.aos_offset = GET_START(&rvb);
233 ptr = rvb.address + rvb.start;
234
235
236 if (max - min <= 65535)
237 for (i=0; i < count; i++)
238 ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
239 else
240 for (i=0; i < count; i++)
241 ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
242 break;
243
244 default:
245 WARN_ONCE("Unknown elt type!\n");
246 goto fallback;
247 }
248
249 if (ctx->NewState)
250 _mesa_update_state( ctx );
251
252 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
253 rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
254 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
255 }
256 r300UpdateShaders(rmesa);
257 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
258 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
259 }
260
261 if (rmesa->state.VB.LockCount) {
262 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
263 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
264 return;
265
266 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
267
268 r300ReleaseArrays(ctx);
269 r300EmitArraysVtx(ctx, GL_FALSE);
270
271 rmesa->state.VB.lock_uptodate = GL_TRUE;
272 }
273
274 if (min < rmesa->state.VB.LockFirst) {
275 WARN_ONCE("Out of range min %d vs %d!\n", min, rmesa->state.VB.LockFirst);
276 return;
277 }
278
279 if (max >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) {
280 WARN_ONCE("Out of range max %d vs %d!\n", max, rmesa->state.VB.LockFirst +
281 rmesa->state.VB.LockCount);
282 return;
283 }
284 } else {
285 if (setup_arrays(rmesa, min))
286 goto fallback;
287
288 rmesa->state.VB.Count = max - min + 1;
289 }
290
291 r300UpdateShaderStates(rmesa);
292
293 rmesa->state.VB.Primitive = &prim;
294 rmesa->state.VB.PrimitiveCount = 1;
295
296 prim.mode = mode | PRIM_BEGIN | PRIM_END;
297 if (rmesa->state.VB.LockCount)
298 prim.start = min - rmesa->state.VB.LockFirst;
299 else
300 prim.start = 0;
301 prim.count = count;
302
303 rmesa->state.VB.Elts = ptr;
304 rmesa->state.VB.elt_size = elt_size;
305
306 r300_run_vb_render_vtxfmt_a(ctx, NULL);
307
308 if(rvb.buf)
309 radeon_mm_use(rmesa, rvb.buf->id);
310
311 return;
312
313 fallback:
314 _tnl_array_init(ctx);
315 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
316 CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices));
317 radeon_init_vtxfmt_a(rmesa);
318 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
319 }
320
321 void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices)
322 {
323 GET_CURRENT_CONTEXT(ctx);
324 r300ContextPtr rmesa = R300_CONTEXT(ctx);
325 struct tnl_prim prim;
326 int elt_size;
327 int i;
328 void *ptr = NULL;
329 static struct r300_dma_region rvb;
330 GLvoid *indices;
331
332 if (count > 65535) {
333 WARN_ONCE("Too many verts!\n");
334 goto fallback;
335 }
336
337 if (ctx->Array.ElementArrayBufferObj->Name) {
338 /* use indices in the buffer object */
339 if (!ctx->Array.ElementArrayBufferObj->Data) {
340 _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
341 return;
342 }
343 /* actual address is the sum of pointers */
344 indices = (const GLvoid *)
345 ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
346 }
347
348 if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices ))
349 return;
350
351 FLUSH_CURRENT( ctx, 0 );
352 #ifdef OPTIMIZE_ELTS
353 min = 0;
354 #endif
355 r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
356
357 switch(type){
358 case GL_UNSIGNED_BYTE:
359 elt_size = 2;
360
361 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
362 rvb.aos_offset = GET_START(&rvb);
363 ptr = rvb.address + rvb.start;
364
365 for(i=0; i < count; i++)
366 ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
367 break;
368
369 case GL_UNSIGNED_SHORT:
370 elt_size = 2;
371
372 #ifdef OPTIMIZE_ELTS
373 if (min == 0 && ctx->Array.ElementArrayBufferObj->Name){
374 ptr = indices;
375 break;
376 }
377 #endif
378 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
379 rvb.aos_offset = GET_START(&rvb);
380 ptr = rvb.address + rvb.start;
381
382 for(i=0; i < count; i++)
383 ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
384 break;
385
386 case GL_UNSIGNED_INT:
387 if (max - min <= 65535)
388 elt_size = 2;
389 else
390 elt_size = 4;
391
392 r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
393 rvb.aos_offset = GET_START(&rvb);
394 ptr = rvb.address + rvb.start;
395
396 if (max - min <= 65535)
397 for (i=0; i < count; i++)
398 ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
399 else
400 for (i=0; i < count; i++)
401 ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
402 break;
403
404 default:
405 WARN_ONCE("Unknown elt type!\n");
406 goto fallback;
407 }
408
409 /* XXX: setup_arrays before state update? */
410
411 if (ctx->NewState)
412 _mesa_update_state( ctx );
413
414 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
415 rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
416 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
417 }
418 r300UpdateShaders(rmesa);
419 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
420 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
421 }
422
423 if (rmesa->state.VB.LockCount) {
424 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
425 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
426 goto fallback;
427
428 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
429
430 r300ReleaseArrays(ctx);
431 r300EmitArraysVtx(ctx, GL_FALSE);
432
433 rmesa->state.VB.lock_uptodate = GL_TRUE;
434 }
435
436 if (min < rmesa->state.VB.LockFirst) {
437 WARN_ONCE("Out of range min %d vs %d!\n", min, rmesa->state.VB.LockFirst);
438 goto fallback;
439 }
440
441 /*if (max >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) {
442 WARN_ONCE("Out of range max %d vs %d!\n", max, rmesa->state.VB.LockFirst +
443 rmesa->state.VB.LockCount);
444 return;
445 }*/
446 } else {
447 if (setup_arrays(rmesa, min))
448 goto fallback;
449
450 rmesa->state.VB.Count = max - min + 1;
451 }
452
453 r300UpdateShaderStates(rmesa);
454
455 rmesa->state.VB.Primitive = &prim;
456 rmesa->state.VB.PrimitiveCount = 1;
457
458 prim.mode = mode | PRIM_BEGIN | PRIM_END;
459 if (rmesa->state.VB.LockCount)
460 prim.start = min - rmesa->state.VB.LockFirst;
461 else
462 prim.start = 0;
463 prim.count = count;
464
465 rmesa->state.VB.Elts = ptr;
466 rmesa->state.VB.elt_size = elt_size;
467 rmesa->state.VB.elt_min = min;
468 rmesa->state.VB.elt_max = max;
469
470 r300_run_vb_render_vtxfmt_a(ctx, NULL);
471
472 if(rvb.buf)
473 radeon_mm_use(rmesa, rvb.buf->id);
474
475 return ;
476
477 fallback:
478 _tnl_array_init(ctx);
479 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
480 CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices));
481 radeon_init_vtxfmt_a(rmesa);
482 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
483 }
484
485 void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
486 {
487 GET_CURRENT_CONTEXT(ctx);
488 r300ContextPtr rmesa = R300_CONTEXT(ctx);
489 struct tnl_prim prim;
490 int i;
491
492 if (count > 65535) {
493 WARN_ONCE("Too many verts!\n");
494 goto fallback;
495 }
496
497 if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
498 return;
499
500 FLUSH_CURRENT( ctx, 0 );
501
502 if (ctx->NewState)
503 _mesa_update_state( ctx );
504
505 /* XXX: setup_arrays before state update? */
506
507 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
508 rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
509 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
510 }
511 r300UpdateShaders(rmesa);
512 for (i=_TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
513 TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
514 }
515
516 if (rmesa->state.VB.LockCount) {
517 if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
518 if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
519 return;
520
521 rmesa->state.VB.Count = rmesa->state.VB.LockCount;
522
523 r300ReleaseArrays(ctx);
524 r300EmitArraysVtx(ctx, GL_FALSE);
525
526 rmesa->state.VB.lock_uptodate = GL_TRUE;
527 }
528
529 if (start < rmesa->state.VB.LockFirst) {
530 WARN_ONCE("Out of range min %d vs %d!\n", start, rmesa->state.VB.LockFirst);
531 goto fallback;
532 }
533
534 if (start + count - 1 >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) { /* XXX */
535 WARN_ONCE("Out of range max %d vs %d!\n", start + count - 1, rmesa->state.VB.LockFirst +
536 rmesa->state.VB.LockCount);
537 goto fallback;
538 }
539 } else {
540 if (setup_arrays(rmesa, start))
541 goto fallback;
542
543 rmesa->state.VB.Count = count;
544 }
545
546 r300UpdateShaderStates(rmesa);
547
548 rmesa->state.VB.Primitive = &prim;
549 rmesa->state.VB.PrimitiveCount = 1;
550
551 prim.mode = mode | PRIM_BEGIN | PRIM_END;
552 if (rmesa->state.VB.LockCount)
553 prim.start = start - rmesa->state.VB.LockFirst;
554 else
555 prim.start = 0;
556 prim.count = count;
557
558 rmesa->state.VB.Elts = NULL;
559 rmesa->state.VB.elt_size = 0;
560 rmesa->state.VB.elt_min = 0;
561 rmesa->state.VB.elt_max = 0;
562
563 r300_run_vb_render_vtxfmt_a(ctx, NULL);
564
565 return ;
566
567 fallback:
568 _tnl_array_init(ctx);
569 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
570 CALL_DrawArrays(GET_DISPATCH(), (mode, start, count));
571 radeon_init_vtxfmt_a(rmesa);
572 _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
573 }
574
575 void radeon_init_vtxfmt_a(r300ContextPtr rmesa)
576 {
577 GLcontext *ctx;
578 GLvertexformat *vfmt;
579
580 ctx = rmesa->radeon.glCtx;
581 vfmt = ctx->TnlModule.Current;
582
583 vfmt->DrawElements = radeonDrawElements;
584 vfmt->DrawArrays = radeonDrawArrays;
585 vfmt->DrawRangeElements = radeonDrawRangeElements;
586
587 }
588 #endif
589
590 #ifdef HW_VBOS
591
592 void radeonLockArraysEXT(GLcontext *ctx, GLint first, GLsizei count)
593 {
594 r300ContextPtr rmesa = R300_CONTEXT(ctx);
595 int i;
596
597 /* Only when CB_DPATH is defined.
598 r300Clear tampers over the aos setup without it.
599 (r300ResetHwState cannot call r300EmitArrays)
600 */
601 #ifndef CB_DPATH
602 first = 0; count = 0;
603 #endif
604
605 if (first < 0 || count <= 0) {
606 rmesa->state.VB.LockFirst = 0;
607 rmesa->state.VB.LockCount = 0;
608 rmesa->state.VB.lock_uptodate = GL_FALSE;
609 return ;
610 }
611
612 rmesa->state.VB.LockFirst = first;
613 rmesa->state.VB.LockCount = count;
614 rmesa->state.VB.lock_uptodate = GL_FALSE;
615 }
616
617 void radeonUnlockArraysEXT(GLcontext *ctx)
618 {
619 r300ContextPtr rmesa = R300_CONTEXT(ctx);
620
621 rmesa->state.VB.LockFirst = 0;
622 rmesa->state.VB.LockCount = 0;
623 rmesa->state.VB.lock_uptodate = GL_FALSE;
624 }
625
626 struct gl_buffer_object *
627 r300NewBufferObject(GLcontext *ctx, GLuint name, GLenum target )
628 {
629 struct r300_buffer_object *obj;
630
631 (void) ctx;
632
633 obj = MALLOC_STRUCT(r300_buffer_object);
634 _mesa_initialize_buffer_object(&obj->mesa_obj, name, target);
635 return &obj->mesa_obj;
636 }
637
638 void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
639 const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
640 {
641 r300ContextPtr rmesa = R300_CONTEXT(ctx);
642 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
643 drm_radeon_mem_alloc_t alloc;
644 int offset, ret;
645
646 /* Free previous buffer */
647 if (obj->OnCard) {
648 radeon_mm_free(rmesa, r300_obj->id);
649 obj->OnCard = GL_FALSE;
650 } else {
651 if (obj->Data)
652 _mesa_free(obj->Data);
653 }
654 #ifdef OPTIMIZE_ELTS
655 if (0) {
656 #else
657 if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
658 #endif
659 fallback:
660 obj->Data = malloc(size);
661
662 if (data)
663 _mesa_memcpy(obj->Data, data, size);
664
665 obj->OnCard = GL_FALSE;
666 } else {
667 r300_obj->id = radeon_mm_alloc(rmesa, 4, size);
668 if (r300_obj->id == 0)
669 goto fallback;
670
671 obj->Data = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
672
673 if (data)
674 _mesa_memcpy(obj->Data, data, size);
675
676 radeon_mm_unmap(rmesa, r300_obj->id);
677 obj->OnCard = GL_TRUE;
678 }
679
680 obj->Size = size;
681 obj->Usage = usage;
682 }
683
684 void r300BufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
685 GLsizeiptrARB size, const GLvoid * data, struct gl_buffer_object * bufObj)
686 {
687 r300ContextPtr rmesa = R300_CONTEXT(ctx);
688 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
689 (void) ctx; (void) target;
690 void *ptr;
691
692 if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) {
693 if (bufObj->OnCard){
694 ptr = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
695
696 _mesa_memcpy( (GLubyte *) ptr + offset, data, size );
697
698 radeon_mm_unmap(rmesa, r300_obj->id);
699 } else {
700 _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size );
701 }
702 }
703 }
704
705 void *r300MapBuffer(GLcontext *ctx, GLenum target, GLenum access,
706 struct gl_buffer_object *bufObj)
707 {
708 r300ContextPtr rmesa = R300_CONTEXT(ctx);
709 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
710
711 (void) ctx;
712 (void) target;
713 (void) access;
714 //ASSERT(!bufObj->OnCard);
715 /* Just return a direct pointer to the data */
716 if (bufObj->Pointer) {
717 /* already mapped! */
718 return NULL;
719 }
720
721 if (!bufObj->OnCard) {
722 bufObj->Pointer = bufObj->Data;
723 return bufObj->Pointer;
724 }
725
726 switch (access) {
727 case GL_READ_ONLY:
728 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_R);
729 break;
730
731 case GL_WRITE_ONLY:
732 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
733 break;
734
735 case GL_READ_WRITE:
736 bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_RW);
737 break;
738
739 default:
740 WARN_ONCE("Unknown access type\n");
741 bufObj->Pointer = NULL;
742 break;
743 }
744
745 return bufObj->Pointer;
746 }
747
748 GLboolean r300UnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *bufObj)
749 {
750 r300ContextPtr rmesa = R300_CONTEXT(ctx);
751 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
752
753 (void) ctx;
754 (void) target;
755 //ASSERT(!bufObj->OnCard);
756 /* XXX we might assert here that bufObj->Pointer is non-null */
757 if (!bufObj->OnCard) {
758 bufObj->Pointer = NULL;
759 return GL_TRUE;
760 }
761 radeon_mm_unmap(rmesa, r300_obj->id);
762
763 bufObj->Pointer = NULL;
764 return GL_TRUE;
765 }
766
767 void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
768 {
769 r300ContextPtr rmesa = R300_CONTEXT(ctx);
770 struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
771
772 if (obj->OnCard) {
773 radeon_mm_free(rmesa, r300_obj->id);
774 obj->Data = NULL;
775 }
776 _mesa_delete_buffer_object(ctx, obj);
777 }
778
779 void r300_init_vbo_funcs(struct dd_function_table *functions)
780 {
781 functions->NewBufferObject = r300NewBufferObject;
782 functions->BufferData = r300BufferData;
783 functions->BufferSubData = r300BufferSubData;
784 functions->MapBuffer = r300MapBuffer;
785 functions->UnmapBuffer = r300UnmapBuffer;
786 functions->DeleteBuffer = r300DeleteBuffer;
787
788 /*functions->LockArraysEXT = radeonLockArraysEXT;
789 functions->UnlockArraysEXT = radeonUnlockArraysEXT;*/
790 }
791
792 #endif