2 * Copyright (C) 2005 Aapo Tahkola.
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:
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.
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.
30 * Aapo Tahkola <aet@rasterburn.org>
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"
43 #include "bufferobj.h"
45 #include "api_validate.h"
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
53 void radeon_vb_to_rvb(r300ContextPtr rmesa
, struct radeon_vertex_buffer
*rvb
, struct vertex_buffer
*vb
)
57 ctx
= rmesa
->radeon
.glCtx
;
59 memset(rvb
, 0, sizeof(*rvb
));
64 rvb
->elt_max
= vb
->Count
;
66 rvb
->Count
= vb
->Count
;
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
);
74 for (i
=0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++)
75 CONV_VB(VERT_ATTRIB_TEX0
+ i
, TexCoordPtr
[i
]);
77 for (i
=0; i
< MAX_VERTEX_PROGRAM_ATTRIBS
; i
++)
78 CONV_VB(VERT_ATTRIB_GENERIC0
+ i
, AttribPtr
[VERT_ATTRIB_GENERIC0
+ i
]);
80 rvb
->Primitive
= vb
->Primitive
;
81 rvb
->PrimitiveCount
= vb
->PrimitiveCount
;
82 rvb
->LockFirst
= rvb
->LockCount
= 0;
83 rvb
->lock_uptodate
= GL_FALSE
;
86 #ifdef RADEON_VTXFMT_A
88 extern void _tnl_array_init( GLcontext
*ctx
);
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); \
103 static int setup_arrays(r300ContextPtr rmesa
, GLint start
)
106 struct dt def
= { 4, GL_FLOAT
, 0, NULL
};
110 ctx
= rmesa
->radeon
.glCtx
;
111 i
= r300Fallback(ctx
);
115 memset(rmesa
->state
.VB
.AttribPtr
, 0, VERT_ATTRIB_MAX
*sizeof(struct dt
));
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
);
123 for (i
=0; i
< MAX_TEXTURE_COORD_UNITS
; i
++)
124 CONV(VERT_ATTRIB_TEX0
+ i
, TexCoord
[i
]);
126 if (ctx
->VertexProgram
._Enabled
)
127 for (i
=0; i
< VERT_ATTRIB_MAX
; i
++)
128 CONV(i
, VertexAttrib
[i
]);
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
;
134 def
.data
= ctx
->Current
.Attrib
[i
];
135 memcpy(&rmesa
->state
.VB
.AttribPtr
[i
], &def
, sizeof(struct dt
));
138 /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
139 fprintf(stderr, "%d is default coord\n", i);*/
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
;
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
;
154 /*fprintf(stderr, "%d: ", i);
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;
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");*/
176 return R300_FALLBACK_NONE
;
179 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
);
181 static void radeonDrawElements( GLenum mode
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
183 GET_CURRENT_CONTEXT(ctx
);
184 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
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
;
194 WARN_ONCE("Too many verts!\n");
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!");
204 /* actual address is the sum of pointers */
206 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
209 if (!_mesa_validate_DrawElements( ctx
, mode
, count
, type
, indices
))
212 FLUSH_CURRENT( ctx
, 0 );
214 memset(&rvb
, 0, sizeof(rvb
));
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
];
224 #ifdef FORCE_32BITS_ELTS
229 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
230 rvb
.aos_offset
= GET_START(&rvb
);
231 ptr
= rvb
.address
+ rvb
.start
;
233 #ifdef FORCE_32BITS_ELTS
234 for (i
=0; i
< count
; i
++)
235 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
237 for (i
=0; i
< count
; i
++)
238 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
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
];
250 #ifdef FORCE_32BITS_ELTS
256 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
257 rvb
.aos_offset
= GET_START(&rvb
);
258 ptr
= rvb
.address
+ rvb
.start
;
260 #ifdef FORCE_32BITS_ELTS
261 for (i
=0; i
< count
; i
++)
262 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
264 for (i
=0; i
< count
; i
++)
265 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
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
];
277 #ifdef FORCE_32BITS_ELTS
280 if (max
- min
<= 65535)
285 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
286 rvb
.aos_offset
= GET_START(&rvb
);
287 ptr
= rvb
.address
+ rvb
.start
;
291 for (i
=0; i
< count
; i
++)
292 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
294 for (i
=0; i
< count
; i
++)
295 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
299 WARN_ONCE("Unknown elt type!\n");
304 _mesa_update_state( ctx
);
306 r300UpdateShaders(rmesa
);
308 if (rmesa
->state
.VB
.LockCount
) {
309 if (rmesa
->state
.VB
.lock_uptodate
== GL_FALSE
) {
310 if (setup_arrays(rmesa
, rmesa
->state
.VB
.LockFirst
))
313 rmesa
->state
.VB
.Count
= rmesa
->state
.VB
.LockCount
;
315 r300ReleaseArrays(ctx
);
316 r300EmitArrays(ctx
, GL_FALSE
);
318 rmesa
->state
.VB
.lock_uptodate
= GL_TRUE
;
321 if (min
< rmesa
->state
.VB
.LockFirst
) {
322 WARN_ONCE("Out of range min %d vs %d!\n", min
, rmesa
->state
.VB
.LockFirst
);
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
);
332 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
333 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
337 rmesa
->state
.VB
.Count
= max
- min
+ 1;
340 r300UpdateShaderStates(rmesa
);
342 rmesa
->state
.VB
.Primitive
= &prim
;
343 rmesa
->state
.VB
.PrimitiveCount
= 1;
345 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
346 if (rmesa
->state
.VB
.LockCount
)
347 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
352 rmesa
->state
.VB
.Elts
= ptr
;
353 rmesa
->state
.VB
.elt_size
= elt_size
;
355 r300_run_vb_render(ctx
, NULL
);
358 radeon_mm_use(rmesa
, rvb
.buf
->id
);
360 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
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
);
371 static void radeonDrawRangeElements(GLenum mode
, GLuint min
, GLuint max
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
373 GET_CURRENT_CONTEXT(ctx
);
374 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
375 struct tnl_prim prim
;
379 struct r300_dma_region rvb
;
380 const GLvoid
*indices
= c_indices
;
383 WARN_ONCE("Too many verts!\n");
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!");
393 /* actual address is the sum of pointers */
395 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
398 if (!_mesa_validate_DrawRangeElements( ctx
, mode
, min
, max
, count
, type
, indices
))
401 FLUSH_CURRENT( ctx
, 0 );
406 memset(&rvb
, 0, sizeof(rvb
));
408 case GL_UNSIGNED_BYTE
:
409 #ifdef FORCE_32BITS_ELTS
414 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
415 rvb
.aos_offset
= GET_START(&rvb
);
416 ptr
= rvb
.address
+ rvb
.start
;
418 #ifdef FORCE_32BITS_ELTS
419 for(i
=0; i
< count
; i
++)
420 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
422 for(i
=0; i
< count
; i
++)
423 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
427 case GL_UNSIGNED_SHORT
:
428 #ifdef FORCE_32BITS_ELTS
434 if (min
== 0 && ctx
->Array
.ElementArrayBufferObj
->Name
){
439 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
440 rvb
.aos_offset
= GET_START(&rvb
);
441 ptr
= rvb
.address
+ rvb
.start
;
443 #ifdef FORCE_32BITS_ELTS
444 for(i
=0; i
< count
; i
++)
445 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
447 for(i
=0; i
< count
; i
++)
448 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
452 case GL_UNSIGNED_INT
:
453 #ifdef FORCE_32BITS_ELTS
456 if (max
- min
<= 65535)
461 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
462 rvb
.aos_offset
= GET_START(&rvb
);
463 ptr
= rvb
.address
+ rvb
.start
;
466 for (i
=0; i
< count
; i
++)
467 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
469 for (i
=0; i
< count
; i
++)
470 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
474 WARN_ONCE("Unknown elt type!\n");
478 /* XXX: setup_arrays before state update? */
481 _mesa_update_state( ctx
);
483 r300UpdateShaders(rmesa
);
485 if (rmesa
->state
.VB
.LockCount
) {
486 if (rmesa
->state
.VB
.lock_uptodate
== GL_FALSE
) {
487 if (setup_arrays(rmesa
, rmesa
->state
.VB
.LockFirst
))
490 rmesa
->state
.VB
.Count
= rmesa
->state
.VB
.LockCount
;
492 r300ReleaseArrays(ctx
);
493 r300EmitArrays(ctx
, GL_FALSE
);
495 rmesa
->state
.VB
.lock_uptodate
= GL_TRUE
;
498 if (min
< rmesa
->state
.VB
.LockFirst
) {
499 WARN_ONCE("Out of range min %d vs %d!\n", min
, rmesa
->state
.VB
.LockFirst
);
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);
509 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
510 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
514 rmesa
->state
.VB
.Count
= max
- min
+ 1;
517 r300UpdateShaderStates(rmesa
);
519 rmesa
->state
.VB
.Primitive
= &prim
;
520 rmesa
->state
.VB
.PrimitiveCount
= 1;
522 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
523 if (rmesa
->state
.VB
.LockCount
)
524 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
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
;
534 r300_run_vb_render(ctx
, NULL
);
537 radeon_mm_use(rmesa
, rvb
.buf
->id
);
539 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
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
);
550 static void radeonDrawArrays( GLenum mode
, GLint start
, GLsizei count
)
552 GET_CURRENT_CONTEXT(ctx
);
553 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
554 struct tnl_prim prim
;
558 WARN_ONCE("Too many verts!\n");
562 if (!_mesa_validate_DrawArrays( ctx
, mode
, start
, count
))
565 FLUSH_CURRENT( ctx
, 0 );
568 _mesa_update_state( ctx
);
570 /* XXX: setup_arrays before state update? */
572 r300UpdateShaders(rmesa
);
574 if (rmesa
->state
.VB
.LockCount
) {
575 if (rmesa
->state
.VB
.lock_uptodate
== GL_FALSE
) {
576 if (setup_arrays(rmesa
, rmesa
->state
.VB
.LockFirst
))
579 rmesa
->state
.VB
.Count
= rmesa
->state
.VB
.LockCount
;
581 r300ReleaseArrays(ctx
);
582 r300EmitArrays(ctx
, GL_FALSE
);
584 rmesa
->state
.VB
.lock_uptodate
= GL_TRUE
;
587 if (start
< rmesa
->state
.VB
.LockFirst
) {
588 WARN_ONCE("Out of range min %d vs %d!\n", start
, rmesa
->state
.VB
.LockFirst
);
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
);
598 if (setup_arrays(rmesa
, start
) >= R300_FALLBACK_TCL
)
601 rmesa
->state
.VB
.Count
= count
;
604 r300UpdateShaderStates(rmesa
);
606 rmesa
->state
.VB
.Primitive
= &prim
;
607 rmesa
->state
.VB
.PrimitiveCount
= 1;
609 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
610 if (rmesa
->state
.VB
.LockCount
)
611 prim
.start
= start
- rmesa
->state
.VB
.LockFirst
;
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;
621 r300_run_vb_render(ctx
, NULL
);
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
);
633 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
)
636 GLvertexformat
*vfmt
;
638 ctx
= rmesa
->radeon
.glCtx
;
639 vfmt
= (GLvertexformat
*)ctx
->TnlModule
.Current
;
641 vfmt
->DrawElements
= radeonDrawElements
;
642 vfmt
->DrawArrays
= radeonDrawArrays
;
643 vfmt
->DrawRangeElements
= radeonDrawRangeElements
;
651 static void radeonLockArraysEXT(GLcontext
*ctx
, GLint first
, GLsizei count
)
653 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
655 /* Only when CB_DPATH is defined.
656 r300Clear tampers over the aos setup without it.
657 (r300ResetHwState cannot call r300EmitArrays)
660 first
= 0; count
= 0;
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
;
670 rmesa
->state
.VB
.LockFirst
= first
;
671 rmesa
->state
.VB
.LockCount
= count
;
672 rmesa
->state
.VB
.lock_uptodate
= GL_FALSE
;
675 static void radeonUnlockArraysEXT(GLcontext
*ctx
)
677 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
679 rmesa
->state
.VB
.LockFirst
= 0;
680 rmesa
->state
.VB
.LockCount
= 0;
681 rmesa
->state
.VB
.lock_uptodate
= GL_FALSE
;
685 static struct gl_buffer_object
*
686 r300NewBufferObject(GLcontext
*ctx
, GLuint name
, GLenum target
)
688 struct r300_buffer_object
*obj
;
692 obj
= MALLOC_STRUCT(r300_buffer_object
);
693 _mesa_initialize_buffer_object(&obj
->mesa_obj
, name
, target
);
694 return &obj
->mesa_obj
;
697 static void r300BufferData(GLcontext
*ctx
, GLenum target
, GLsizeiptrARB size
,
698 const GLvoid
*data
, GLenum usage
, struct gl_buffer_object
*obj
)
700 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
701 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
703 /* Free previous buffer */
705 radeon_mm_free(rmesa
, r300_obj
->id
);
706 obj
->OnCard
= GL_FALSE
;
709 _mesa_free(obj
->Data
);
714 if (target
== GL_ELEMENT_ARRAY_BUFFER_ARB
) {
717 obj
->Data
= malloc(size
);
720 _mesa_memcpy(obj
->Data
, data
, size
);
722 obj
->OnCard
= GL_FALSE
;
724 r300_obj
->id
= radeon_mm_alloc(rmesa
, 4, size
);
725 if (r300_obj
->id
== 0)
728 obj
->Data
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
731 _mesa_memcpy(obj
->Data
, data
, size
);
733 radeon_mm_unmap(rmesa
, r300_obj
->id
);
734 obj
->OnCard
= GL_TRUE
;
741 static void r300BufferSubData(GLcontext
*ctx
, GLenum target
, GLintptrARB offset
,
742 GLsizeiptrARB size
, const GLvoid
* data
, struct gl_buffer_object
* bufObj
)
744 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
745 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
746 (void) ctx
; (void) target
;
749 if (bufObj
->Data
&& ((GLuint
) (size
+ offset
) <= bufObj
->Size
)) {
751 ptr
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
753 _mesa_memcpy( (GLubyte
*) ptr
+ offset
, data
, size
);
755 radeon_mm_unmap(rmesa
, r300_obj
->id
);
757 _mesa_memcpy( (GLubyte
*) bufObj
->Data
+ offset
, data
, size
);
762 static void *r300MapBuffer(GLcontext
*ctx
, GLenum target
, GLenum access
,
763 struct gl_buffer_object
*bufObj
)
765 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
766 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
771 //ASSERT(!bufObj->OnCard);
772 /* Just return a direct pointer to the data */
773 if (bufObj
->Pointer
) {
774 /* already mapped! */
778 if (!bufObj
->OnCard
) {
779 bufObj
->Pointer
= bufObj
->Data
;
780 return bufObj
->Pointer
;
785 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_R
);
789 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
793 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_RW
);
797 WARN_ONCE("Unknown access type\n");
798 bufObj
->Pointer
= NULL
;
802 return bufObj
->Pointer
;
805 static GLboolean
r300UnmapBuffer(GLcontext
*ctx
, GLenum target
, struct gl_buffer_object
*bufObj
)
807 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
808 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
812 //ASSERT(!bufObj->OnCard);
813 /* XXX we might assert here that bufObj->Pointer is non-null */
814 if (!bufObj
->OnCard
) {
815 bufObj
->Pointer
= NULL
;
818 radeon_mm_unmap(rmesa
, r300_obj
->id
);
820 bufObj
->Pointer
= NULL
;
824 static void r300DeleteBuffer(GLcontext
*ctx
, struct gl_buffer_object
*obj
)
826 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
827 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
830 radeon_mm_free(rmesa
, r300_obj
->id
);
833 _mesa_delete_buffer_object(ctx
, obj
);
836 void r300_evict_vbos(GLcontext
*ctx
, int amount
)
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
;
845 while (amount
> 0 && k
) {
846 obj
= (struct gl_buffer_object
*) _mesa_HashLookup(hash
, k
);
847 r300_obj
= (struct r300_buffer_object
*) obj
;
849 if (obj
->OnCard
&& obj
->Size
) {
850 obj
->Data
= _mesa_malloc(obj
->Size
);
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
);
856 radeon_mm_free(rmesa
, r300_obj
->id
);
858 obj
->OnCard
= GL_FALSE
;
863 k
= _mesa_HashNextEntry(hash
, k
);
868 void r300_init_vbo_funcs(struct dd_function_table
*functions
)
870 functions
->NewBufferObject
= r300NewBufferObject
;
871 functions
->BufferData
= r300BufferData
;
872 functions
->BufferSubData
= r300BufferSubData
;
873 functions
->MapBuffer
= r300MapBuffer
;
874 functions
->UnmapBuffer
= r300UnmapBuffer
;
875 functions
->DeleteBuffer
= r300DeleteBuffer
;
877 /*functions->LockArraysEXT = radeonLockArraysEXT;
878 functions->UnlockArraysEXT = radeonUnlockArraysEXT;*/