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"
49 #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \
50 rvb->AttribPtr[(a)].type = GL_FLOAT, \
51 rvb->AttribPtr[(a)].stride = vb->b->stride, \
52 rvb->AttribPtr[(a)].data = vb->b->data
54 void radeon_vb_to_rvb(r300ContextPtr rmesa
, struct radeon_vertex_buffer
*rvb
, struct vertex_buffer
*vb
)
58 ctx
= rmesa
->radeon
.glCtx
;
60 memset(rvb
, 0, sizeof(*rvb
));
65 rvb
->elt_max
= vb
->Count
;
67 rvb
->Count
= vb
->Count
;
69 CONV_VB(VERT_ATTRIB_POS
, ObjPtr
);
70 CONV_VB(VERT_ATTRIB_NORMAL
, NormalPtr
);
71 CONV_VB(VERT_ATTRIB_COLOR0
, ColorPtr
[0]);
72 CONV_VB(VERT_ATTRIB_COLOR1
, SecondaryColorPtr
[0]);
73 CONV_VB(VERT_ATTRIB_FOG
, FogCoordPtr
);
75 for (i
=0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++)
76 CONV_VB(VERT_ATTRIB_TEX0
+ i
, TexCoordPtr
[i
]);
78 for (i
=0; i
< MAX_VERTEX_PROGRAM_ATTRIBS
; i
++)
79 CONV_VB(VERT_ATTRIB_GENERIC0
+ i
, AttribPtr
[VERT_ATTRIB_GENERIC0
+ i
]);
81 rvb
->Primitive
= vb
->Primitive
;
82 rvb
->PrimitiveCount
= vb
->PrimitiveCount
;
83 rvb
->LockFirst
= rvb
->LockCount
= 0;
84 rvb
->lock_uptodate
= GL_FALSE
;
87 #ifdef RADEON_VTXFMT_A
89 extern void _tnl_array_init( GLcontext
*ctx
);
93 if (ctx->Array.ArrayObj->b.Enabled) { \
94 rmesa->state.VB.AttribPtr[(a)].size = ctx->Array.ArrayObj->b.Size; \
95 rmesa->state.VB.AttribPtr[(a)].data = ctx->Array.ArrayObj->b.BufferObj->Name \
96 ? (void *)ADD_POINTERS(ctx->Array.ArrayObj->b.Ptr, ctx->Array.ArrayObj->b.BufferObj->Data) \
97 : (void *)ctx->Array.ArrayObj->b.Ptr; \
98 rmesa->state.VB.AttribPtr[(a)].stride = ctx->Array.ArrayObj->b.StrideB; \
99 rmesa->state.VB.AttribPtr[(a)].type = ctx->Array.ArrayObj->b.Type; \
100 enabled |= 1 << (a); \
104 static int setup_arrays(r300ContextPtr rmesa
, GLint start
)
107 struct dt def
= { 4, GL_FLOAT
, 0, NULL
};
111 ctx
= rmesa
->radeon
.glCtx
;
112 i
= r300Fallback(ctx
);
116 memset(rmesa
->state
.VB
.AttribPtr
, 0, VERT_ATTRIB_MAX
*sizeof(struct dt
));
118 CONV(VERT_ATTRIB_POS
, Vertex
);
119 CONV(VERT_ATTRIB_NORMAL
, Normal
);
120 CONV(VERT_ATTRIB_COLOR0
, Color
);
121 CONV(VERT_ATTRIB_COLOR1
, SecondaryColor
);
122 CONV(VERT_ATTRIB_FOG
, FogCoord
);
124 for (i
=0; i
< MAX_TEXTURE_COORD_UNITS
; i
++)
125 CONV(VERT_ATTRIB_TEX0
+ i
, TexCoord
[i
]);
127 if (ctx
->VertexProgram
._Enabled
)
128 for (i
=0; i
< VERT_ATTRIB_MAX
; i
++)
129 CONV(i
, VertexAttrib
[i
]);
131 for (i
=0; i
< VERT_ATTRIB_MAX
; i
++) {
132 if (enabled
& (1 << i
)) {
133 rmesa
->state
.VB
.AttribPtr
[i
].data
+= rmesa
->state
.VB
.AttribPtr
[i
].stride
* start
;
135 def
.data
= ctx
->Current
.Attrib
[i
];
136 memcpy(&rmesa
->state
.VB
.AttribPtr
[i
], &def
, sizeof(struct dt
));
139 /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
140 fprintf(stderr, "%d is default coord\n", i);*/
143 for(i
=0; i
< VERT_ATTRIB_MAX
; i
++){
144 if(rmesa
->state
.VB
.AttribPtr
[i
].type
!= GL_UNSIGNED_BYTE
&&
145 #if MESA_LITTLE_ENDIAN
146 rmesa
->state
.VB
.AttribPtr
[i
].type
!= GL_SHORT
&&
148 rmesa
->state
.VB
.AttribPtr
[i
].type
!= GL_FLOAT
){
149 WARN_ONCE("Unsupported format %d at index %d\n", rmesa
->state
.VB
.AttribPtr
[i
].type
, i
);
150 return R300_FALLBACK_TCL
;
153 /*fprintf(stderr, "%d: ", i);
155 switch(rmesa->state.VB.AttribPtr[i].type){
156 case GL_BYTE: fprintf(stderr, "byte "); break;
157 case GL_UNSIGNED_BYTE: fprintf(stderr, "u byte "); break;
158 case GL_SHORT: fprintf(stderr, "short "); break;
159 case GL_UNSIGNED_SHORT: fprintf(stderr, "u short "); break;
160 case GL_INT: fprintf(stderr, "int "); break;
161 case GL_UNSIGNED_INT: fprintf(stderr, "u int "); break;
162 case GL_FLOAT: fprintf(stderr, "float "); break;
163 case GL_2_BYTES: fprintf(stderr, "2 bytes "); break;
164 case GL_3_BYTES: fprintf(stderr, "3 bytes "); break;
165 case GL_4_BYTES: fprintf(stderr, "4 bytes "); break;
166 case GL_DOUBLE: fprintf(stderr, "double "); break;
167 default: fprintf(stderr, "unknown "); break;
170 fprintf(stderr, "Size %d ", rmesa->state.VB.AttribPtr[i].size);
171 fprintf(stderr, "Ptr %p ", rmesa->state.VB.AttribPtr[i].data);
172 fprintf(stderr, "Stride %d ", rmesa->state.VB.AttribPtr[i].stride);
173 fprintf(stderr, "\n");*/
175 return R300_FALLBACK_NONE
;
178 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
);
180 static void radeonDrawElements( GLenum mode
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
182 GET_CURRENT_CONTEXT(ctx
);
183 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
186 unsigned int min
= ~0, max
= 0;
187 struct tnl_prim prim
;
188 static void *ptr
= NULL
;
189 struct r300_dma_region rvb
;
190 const GLvoid
*indices
= c_indices
;
193 WARN_ONCE("Too many verts!\n");
197 if (ctx
->Array
.ElementArrayBufferObj
->Name
) {
198 /* use indices in the buffer object */
199 if (!ctx
->Array
.ElementArrayBufferObj
->Data
) {
200 _mesa_warning(ctx
, "DrawRangeElements with empty vertex elements buffer!");
203 /* actual address is the sum of pointers */
205 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
208 if (!_mesa_validate_DrawElements( ctx
, mode
, count
, type
, indices
))
211 FLUSH_CURRENT( ctx
, 0 );
213 memset(&rvb
, 0, sizeof(rvb
));
215 case GL_UNSIGNED_BYTE
:
216 for (i
=0; i
< count
; i
++) {
217 if(((unsigned char *)indices
)[i
] < min
)
218 min
= ((unsigned char *)indices
)[i
];
219 if(((unsigned char *)indices
)[i
] > max
)
220 max
= ((unsigned char *)indices
)[i
];
223 #ifdef FORCE_32BITS_ELTS
228 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
229 rvb
.aos_offset
= GET_START(&rvb
);
230 ptr
= rvb
.address
+ rvb
.start
;
232 #ifdef FORCE_32BITS_ELTS
233 for (i
=0; i
< count
; i
++)
234 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
236 for (i
=0; i
< count
; i
++)
237 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
241 case GL_UNSIGNED_SHORT
:
242 for (i
=0; i
< count
; i
++) {
243 if(((unsigned short int *)indices
)[i
] < min
)
244 min
= ((unsigned short int *)indices
)[i
];
245 if(((unsigned short int *)indices
)[i
] > max
)
246 max
= ((unsigned short int *)indices
)[i
];
249 #ifdef FORCE_32BITS_ELTS
255 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
256 rvb
.aos_offset
= GET_START(&rvb
);
257 ptr
= rvb
.address
+ rvb
.start
;
259 #ifdef FORCE_32BITS_ELTS
260 for (i
=0; i
< count
; i
++)
261 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
263 for (i
=0; i
< count
; i
++)
264 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
268 case GL_UNSIGNED_INT
:
269 for (i
=0; i
< count
; i
++) {
270 if(((unsigned int *)indices
)[i
] < min
)
271 min
= ((unsigned int *)indices
)[i
];
272 if(((unsigned int *)indices
)[i
] > max
)
273 max
= ((unsigned int *)indices
)[i
];
276 #ifdef FORCE_32BITS_ELTS
279 if (max
- min
<= 65535)
284 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
285 rvb
.aos_offset
= GET_START(&rvb
);
286 ptr
= rvb
.address
+ rvb
.start
;
290 for (i
=0; i
< count
; i
++)
291 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
293 for (i
=0; i
< count
; i
++)
294 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
298 WARN_ONCE("Unknown elt type!\n");
303 _mesa_update_state( ctx
);
305 r300UpdateShaders(rmesa
);
307 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
308 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
312 rmesa
->state
.VB
.Count
= max
- min
+ 1;
314 r300UpdateShaderStates(rmesa
);
316 rmesa
->state
.VB
.Primitive
= &prim
;
317 rmesa
->state
.VB
.PrimitiveCount
= 1;
319 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
320 if (rmesa
->state
.VB
.LockCount
)
321 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
326 rmesa
->state
.VB
.Elts
= ptr
;
327 rmesa
->state
.VB
.elt_size
= elt_size
;
329 if (r300_run_vb_render(ctx
, NULL
)) {
330 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
335 radeon_mm_use(rmesa
, rvb
.buf
->id
);
337 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
341 _tnl_array_init(ctx
);
342 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
343 CALL_DrawElements(GET_DISPATCH(), (mode
, count
, type
, c_indices
));
344 radeon_init_vtxfmt_a(rmesa
);
345 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
348 static void radeonDrawRangeElements(GLenum mode
, GLuint min
, GLuint max
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
350 GET_CURRENT_CONTEXT(ctx
);
351 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
352 struct tnl_prim prim
;
356 struct r300_dma_region rvb
;
357 const GLvoid
*indices
= c_indices
;
361 if (mode
== GL_POINTS
||
364 mode
== GL_TRIANGLES
) {
367 i
= r300_get_num_verts(rmesa
, MIN2(count
, 65535), mode
);
369 radeonDrawRangeElements(mode
, min
, max
, i
, type
, indices
);
371 indices
+= i
* _mesa_sizeof_type(type
);
376 WARN_ONCE("Too many verts!\n");
380 if (ctx
->Array
.ElementArrayBufferObj
->Name
) {
381 /* use indices in the buffer object */
382 if (!ctx
->Array
.ElementArrayBufferObj
->Data
) {
383 _mesa_warning(ctx
, "DrawRangeElements with empty vertex elements buffer!");
386 /* actual address is the sum of pointers */
388 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
391 if (!_mesa_validate_DrawRangeElements( ctx
, mode
, min
, max
, count
, type
, indices
))
394 FLUSH_CURRENT( ctx
, 0 );
399 memset(&rvb
, 0, sizeof(rvb
));
401 case GL_UNSIGNED_BYTE
:
402 #ifdef FORCE_32BITS_ELTS
407 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
408 rvb
.aos_offset
= GET_START(&rvb
);
409 ptr
= rvb
.address
+ rvb
.start
;
411 #ifdef FORCE_32BITS_ELTS
412 for(i
=0; i
< count
; i
++)
413 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
415 for(i
=0; i
< count
; i
++)
416 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
420 case GL_UNSIGNED_SHORT
:
421 #ifdef FORCE_32BITS_ELTS
427 if (min
== 0 && ctx
->Array
.ElementArrayBufferObj
->Name
){
432 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
433 rvb
.aos_offset
= GET_START(&rvb
);
434 ptr
= rvb
.address
+ rvb
.start
;
436 #ifdef FORCE_32BITS_ELTS
437 for(i
=0; i
< count
; i
++)
438 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
440 for(i
=0; i
< count
; i
++)
441 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
445 case GL_UNSIGNED_INT
:
446 #ifdef FORCE_32BITS_ELTS
449 if (max
- min
<= 65535)
454 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
455 rvb
.aos_offset
= GET_START(&rvb
);
456 ptr
= rvb
.address
+ rvb
.start
;
459 for (i
=0; i
< count
; i
++)
460 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
462 for (i
=0; i
< count
; i
++)
463 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
467 WARN_ONCE("Unknown elt type!\n");
471 /* XXX: setup_arrays before state update? */
474 _mesa_update_state( ctx
);
476 r300UpdateShaders(rmesa
);
478 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
479 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
483 rmesa
->state
.VB
.Count
= max
- min
+ 1;
485 r300UpdateShaderStates(rmesa
);
487 rmesa
->state
.VB
.Primitive
= &prim
;
488 rmesa
->state
.VB
.PrimitiveCount
= 1;
490 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
491 if (rmesa
->state
.VB
.LockCount
)
492 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
497 rmesa
->state
.VB
.Elts
= ptr
;
498 rmesa
->state
.VB
.elt_size
= elt_size
;
499 rmesa
->state
.VB
.elt_min
= min
;
500 rmesa
->state
.VB
.elt_max
= max
;
502 if (r300_run_vb_render(ctx
, NULL
)) {
503 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
508 radeon_mm_use(rmesa
, rvb
.buf
->id
);
510 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
514 _tnl_array_init(ctx
);
515 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
516 CALL_DrawRangeElements(GET_DISPATCH(), (mode
, min
, max
, count
, type
, c_indices
));
517 radeon_init_vtxfmt_a(rmesa
);
518 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
521 static void radeonDrawArrays( GLenum mode
, GLint start
, GLsizei count
)
523 GET_CURRENT_CONTEXT(ctx
);
524 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
525 struct tnl_prim prim
;
528 WARN_ONCE("Too many verts!\n");
532 if (!_mesa_validate_DrawArrays( ctx
, mode
, start
, count
))
535 FLUSH_CURRENT( ctx
, 0 );
538 _mesa_update_state( ctx
);
540 /* XXX: setup_arrays before state update? */
542 r300UpdateShaders(rmesa
);
544 if (setup_arrays(rmesa
, start
) >= R300_FALLBACK_TCL
)
547 rmesa
->state
.VB
.Count
= count
;
549 r300UpdateShaderStates(rmesa
);
551 rmesa
->state
.VB
.Primitive
= &prim
;
552 rmesa
->state
.VB
.PrimitiveCount
= 1;
554 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
555 if (rmesa
->state
.VB
.LockCount
)
556 prim
.start
= start
- rmesa
->state
.VB
.LockFirst
;
561 rmesa
->state
.VB
.Elts
= NULL
;
562 rmesa
->state
.VB
.elt_size
= 0;
563 rmesa
->state
.VB
.elt_min
= 0;
564 rmesa
->state
.VB
.elt_max
= 0;
566 if (r300_run_vb_render(ctx
, NULL
))
572 _tnl_array_init(ctx
);
573 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
574 CALL_DrawArrays(GET_DISPATCH(), (mode
, start
, count
));
575 radeon_init_vtxfmt_a(rmesa
);
576 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
579 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
)
582 GLvertexformat
*vfmt
;
584 ctx
= rmesa
->radeon
.glCtx
;
585 vfmt
= (GLvertexformat
*)ctx
->TnlModule
.Current
;
587 vfmt
->DrawElements
= radeonDrawElements
;
588 vfmt
->DrawArrays
= radeonDrawArrays
;
589 vfmt
->DrawRangeElements
= radeonDrawRangeElements
;
596 static struct gl_buffer_object
*
597 r300NewBufferObject(GLcontext
*ctx
, GLuint name
, GLenum target
)
599 struct r300_buffer_object
*obj
;
603 obj
= MALLOC_STRUCT(r300_buffer_object
);
604 _mesa_initialize_buffer_object(&obj
->mesa_obj
, name
, target
);
605 return &obj
->mesa_obj
;
608 static void r300BufferData(GLcontext
*ctx
, GLenum target
, GLsizeiptrARB size
,
609 const GLvoid
*data
, GLenum usage
, struct gl_buffer_object
*obj
)
611 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
612 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
614 /* Free previous buffer */
616 radeon_mm_free(rmesa
, r300_obj
->id
);
617 obj
->OnCard
= GL_FALSE
;
620 _mesa_free(obj
->Data
);
625 if (target
== GL_ELEMENT_ARRAY_BUFFER_ARB
) {
628 obj
->Data
= malloc(size
);
631 _mesa_memcpy(obj
->Data
, data
, size
);
633 obj
->OnCard
= GL_FALSE
;
635 r300_obj
->id
= radeon_mm_alloc(rmesa
, 4, size
);
636 if (r300_obj
->id
== 0)
639 obj
->Data
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
642 _mesa_memcpy(obj
->Data
, data
, size
);
644 radeon_mm_unmap(rmesa
, r300_obj
->id
);
645 obj
->OnCard
= GL_TRUE
;
652 static void r300BufferSubData(GLcontext
*ctx
, GLenum target
, GLintptrARB offset
,
653 GLsizeiptrARB size
, const GLvoid
* data
, struct gl_buffer_object
* bufObj
)
655 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
656 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
657 (void) ctx
; (void) target
;
660 if (bufObj
->Data
&& ((GLuint
) (size
+ offset
) <= bufObj
->Size
)) {
662 ptr
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
664 _mesa_memcpy( (GLubyte
*) ptr
+ offset
, data
, size
);
666 radeon_mm_unmap(rmesa
, r300_obj
->id
);
668 _mesa_memcpy( (GLubyte
*) bufObj
->Data
+ offset
, data
, size
);
673 static void *r300MapBuffer(GLcontext
*ctx
, GLenum target
, GLenum access
,
674 struct gl_buffer_object
*bufObj
)
676 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
677 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
682 //ASSERT(!bufObj->OnCard);
683 /* Just return a direct pointer to the data */
684 if (bufObj
->Pointer
) {
685 /* already mapped! */
689 if (!bufObj
->OnCard
) {
690 bufObj
->Pointer
= bufObj
->Data
;
691 return bufObj
->Pointer
;
696 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_R
);
700 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
704 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_RW
);
708 WARN_ONCE("Unknown access type\n");
709 bufObj
->Pointer
= NULL
;
713 return bufObj
->Pointer
;
716 static GLboolean
r300UnmapBuffer(GLcontext
*ctx
, GLenum target
, struct gl_buffer_object
*bufObj
)
718 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
719 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
723 //ASSERT(!bufObj->OnCard);
724 /* XXX we might assert here that bufObj->Pointer is non-null */
725 if (!bufObj
->OnCard
) {
726 bufObj
->Pointer
= NULL
;
729 radeon_mm_unmap(rmesa
, r300_obj
->id
);
731 bufObj
->Pointer
= NULL
;
735 static void r300DeleteBuffer(GLcontext
*ctx
, struct gl_buffer_object
*obj
)
737 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
738 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
741 radeon_mm_free(rmesa
, r300_obj
->id
);
744 _mesa_delete_buffer_object(ctx
, obj
);
747 void r300_evict_vbos(GLcontext
*ctx
, int amount
)
749 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
750 struct _mesa_HashTable
*hash
= ctx
->Shared
->BufferObjects
;
751 GLuint k
= _mesa_HashFirstEntry(hash
);
753 while (amount
> 0 && k
) {
754 struct gl_buffer_object
*obj
= _mesa_lookup_bufferobj(ctx
, k
);
755 struct r300_buffer_object
*r300_obj
756 = (struct r300_buffer_object
*) obj
;
758 if (obj
->OnCard
&& obj
->Size
) {
760 obj
->Data
= _mesa_malloc(obj
->Size
);
762 data
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_R
);
763 _mesa_memcpy(obj
->Data
, data
, obj
->Size
);
764 radeon_mm_unmap(rmesa
, r300_obj
->id
);
766 radeon_mm_free(rmesa
, r300_obj
->id
);
768 obj
->OnCard
= GL_FALSE
;
773 k
= _mesa_HashNextEntry(hash
, k
);
778 void r300_init_vbo_funcs(struct dd_function_table
*functions
)
780 functions
->NewBufferObject
= r300NewBufferObject
;
781 functions
->BufferData
= r300BufferData
;
782 functions
->BufferSubData
= r300BufferSubData
;
783 functions
->MapBuffer
= r300MapBuffer
;
784 functions
->UnmapBuffer
= r300UnmapBuffer
;
785 functions
->DeleteBuffer
= r300DeleteBuffer
;