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 #if MESA_LITTLE_ENDIAN
145 rmesa
->state
.VB
.AttribPtr
[i
].type
!= GL_SHORT
&&
147 rmesa
->state
.VB
.AttribPtr
[i
].type
!= GL_FLOAT
){
148 WARN_ONCE("Unsupported format %d at index %d\n", rmesa
->state
.VB
.AttribPtr
[i
].type
, i
);
149 return R300_FALLBACK_TCL
;
152 /*fprintf(stderr, "%d: ", i);
154 switch(rmesa->state.VB.AttribPtr[i].type){
155 case GL_BYTE: fprintf(stderr, "byte "); break;
156 case GL_UNSIGNED_BYTE: fprintf(stderr, "u byte "); break;
157 case GL_SHORT: fprintf(stderr, "short "); break;
158 case GL_UNSIGNED_SHORT: fprintf(stderr, "u short "); break;
159 case GL_INT: fprintf(stderr, "int "); break;
160 case GL_UNSIGNED_INT: fprintf(stderr, "u int "); break;
161 case GL_FLOAT: fprintf(stderr, "float "); break;
162 case GL_2_BYTES: fprintf(stderr, "2 bytes "); break;
163 case GL_3_BYTES: fprintf(stderr, "3 bytes "); break;
164 case GL_4_BYTES: fprintf(stderr, "4 bytes "); break;
165 case GL_DOUBLE: fprintf(stderr, "double "); break;
166 default: fprintf(stderr, "unknown "); break;
169 fprintf(stderr, "Size %d ", rmesa->state.VB.AttribPtr[i].size);
170 fprintf(stderr, "Ptr %p ", rmesa->state.VB.AttribPtr[i].data);
171 fprintf(stderr, "Stride %d ", rmesa->state.VB.AttribPtr[i].stride);
172 fprintf(stderr, "\n");*/
174 return R300_FALLBACK_NONE
;
177 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
);
179 static void radeonDrawElements( GLenum mode
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
181 GET_CURRENT_CONTEXT(ctx
);
182 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
185 unsigned int min
= ~0, max
= 0;
186 struct tnl_prim prim
;
187 static void *ptr
= NULL
;
188 struct r300_dma_region rvb
;
189 const GLvoid
*indices
= c_indices
;
192 WARN_ONCE("Too many verts!\n");
196 if (ctx
->Array
.ElementArrayBufferObj
->Name
) {
197 /* use indices in the buffer object */
198 if (!ctx
->Array
.ElementArrayBufferObj
->Data
) {
199 _mesa_warning(ctx
, "DrawRangeElements with empty vertex elements buffer!");
202 /* actual address is the sum of pointers */
204 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
207 if (!_mesa_validate_DrawElements( ctx
, mode
, count
, type
, indices
))
210 FLUSH_CURRENT( ctx
, 0 );
212 memset(&rvb
, 0, sizeof(rvb
));
214 case GL_UNSIGNED_BYTE
:
215 for (i
=0; i
< count
; i
++) {
216 if(((unsigned char *)indices
)[i
] < min
)
217 min
= ((unsigned char *)indices
)[i
];
218 if(((unsigned char *)indices
)[i
] > max
)
219 max
= ((unsigned char *)indices
)[i
];
222 #ifdef FORCE_32BITS_ELTS
227 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
228 rvb
.aos_offset
= GET_START(&rvb
);
229 ptr
= rvb
.address
+ rvb
.start
;
231 #ifdef FORCE_32BITS_ELTS
232 for (i
=0; i
< count
; i
++)
233 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
235 for (i
=0; i
< count
; i
++)
236 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
240 case GL_UNSIGNED_SHORT
:
241 for (i
=0; i
< count
; i
++) {
242 if(((unsigned short int *)indices
)[i
] < min
)
243 min
= ((unsigned short int *)indices
)[i
];
244 if(((unsigned short int *)indices
)[i
] > max
)
245 max
= ((unsigned short int *)indices
)[i
];
248 #ifdef FORCE_32BITS_ELTS
254 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
255 rvb
.aos_offset
= GET_START(&rvb
);
256 ptr
= rvb
.address
+ rvb
.start
;
258 #ifdef FORCE_32BITS_ELTS
259 for (i
=0; i
< count
; i
++)
260 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
262 for (i
=0; i
< count
; i
++)
263 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
267 case GL_UNSIGNED_INT
:
268 for (i
=0; i
< count
; i
++) {
269 if(((unsigned int *)indices
)[i
] < min
)
270 min
= ((unsigned int *)indices
)[i
];
271 if(((unsigned int *)indices
)[i
] > max
)
272 max
= ((unsigned int *)indices
)[i
];
275 #ifdef FORCE_32BITS_ELTS
278 if (max
- min
<= 65535)
283 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
284 rvb
.aos_offset
= GET_START(&rvb
);
285 ptr
= rvb
.address
+ rvb
.start
;
289 for (i
=0; i
< count
; i
++)
290 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
292 for (i
=0; i
< count
; i
++)
293 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
297 WARN_ONCE("Unknown elt type!\n");
302 _mesa_update_state( ctx
);
304 r300UpdateShaders(rmesa
);
306 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
307 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
311 rmesa
->state
.VB
.Count
= max
- min
+ 1;
313 r300UpdateShaderStates(rmesa
);
315 rmesa
->state
.VB
.Primitive
= &prim
;
316 rmesa
->state
.VB
.PrimitiveCount
= 1;
318 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
319 if (rmesa
->state
.VB
.LockCount
)
320 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
325 rmesa
->state
.VB
.Elts
= ptr
;
326 rmesa
->state
.VB
.elt_size
= elt_size
;
328 if (r300_run_vb_render(ctx
, NULL
)) {
329 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
334 radeon_mm_use(rmesa
, rvb
.buf
->id
);
336 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
340 _tnl_array_init(ctx
);
341 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
342 CALL_DrawElements(GET_DISPATCH(), (mode
, count
, type
, c_indices
));
343 radeon_init_vtxfmt_a(rmesa
);
344 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
347 static int elt_bytes(GLenum type
)
350 case GL_UNSIGNED_BYTE
:
352 case GL_UNSIGNED_SHORT
:
354 case GL_UNSIGNED_INT
:
357 _mesa_problem(NULL
, "bad elt type in %s", __FUNCTION__
);
363 static void radeonDrawRangeElements(GLenum mode
, GLuint min
, GLuint max
, GLsizei count
, GLenum type
, const GLvoid
*c_indices
)
365 GET_CURRENT_CONTEXT(ctx
);
366 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
367 struct tnl_prim prim
;
371 struct r300_dma_region rvb
;
372 const GLvoid
*indices
= c_indices
;
376 if (mode
== GL_POINTS
||
379 mode
== GL_TRIANGLES
) {
381 if (!_mesa_validate_DrawRangeElements( ctx
, mode
, min
, max
, count
, type
, indices
))
385 i
= r300_get_num_verts(rmesa
, MIN2(count
, 65535), mode
);
387 radeonDrawRangeElements(mode
, min
, max
, i
, type
, indices
);
389 indices
+= i
* elt_bytes(type
);
394 WARN_ONCE("Too many verts!\n");
398 if (ctx
->Array
.ElementArrayBufferObj
->Name
) {
399 /* use indices in the buffer object */
400 if (!ctx
->Array
.ElementArrayBufferObj
->Data
) {
401 _mesa_warning(ctx
, "DrawRangeElements with empty vertex elements buffer!");
404 /* actual address is the sum of pointers */
406 ADD_POINTERS(ctx
->Array
.ElementArrayBufferObj
->Data
, (const GLubyte
*) c_indices
);
409 if (!_mesa_validate_DrawRangeElements( ctx
, mode
, min
, max
, count
, type
, indices
))
412 FLUSH_CURRENT( ctx
, 0 );
417 memset(&rvb
, 0, sizeof(rvb
));
419 case GL_UNSIGNED_BYTE
:
420 #ifdef FORCE_32BITS_ELTS
425 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
426 rvb
.aos_offset
= GET_START(&rvb
);
427 ptr
= rvb
.address
+ rvb
.start
;
429 #ifdef FORCE_32BITS_ELTS
430 for(i
=0; i
< count
; i
++)
431 ((unsigned int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
433 for(i
=0; i
< count
; i
++)
434 ((unsigned short int *)ptr
)[i
] = ((unsigned char *)indices
)[i
] - min
;
438 case GL_UNSIGNED_SHORT
:
439 #ifdef FORCE_32BITS_ELTS
445 if (min
== 0 && ctx
->Array
.ElementArrayBufferObj
->Name
){
450 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
451 rvb
.aos_offset
= GET_START(&rvb
);
452 ptr
= rvb
.address
+ rvb
.start
;
454 #ifdef FORCE_32BITS_ELTS
455 for(i
=0; i
< count
; i
++)
456 ((unsigned int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
458 for(i
=0; i
< count
; i
++)
459 ((unsigned short int *)ptr
)[i
] = ((unsigned short int *)indices
)[i
] - min
;
463 case GL_UNSIGNED_INT
:
464 #ifdef FORCE_32BITS_ELTS
467 if (max
- min
<= 65535)
472 r300AllocDmaRegion(rmesa
, &rvb
, count
* elt_size
, elt_size
);
473 rvb
.aos_offset
= GET_START(&rvb
);
474 ptr
= rvb
.address
+ rvb
.start
;
477 for (i
=0; i
< count
; i
++)
478 ((unsigned short int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
480 for (i
=0; i
< count
; i
++)
481 ((unsigned int *)ptr
)[i
] = ((unsigned int *)indices
)[i
] - min
;
485 WARN_ONCE("Unknown elt type!\n");
489 /* XXX: setup_arrays before state update? */
492 _mesa_update_state( ctx
);
494 r300UpdateShaders(rmesa
);
496 if (setup_arrays(rmesa
, min
) >= R300_FALLBACK_TCL
) {
497 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
501 rmesa
->state
.VB
.Count
= max
- min
+ 1;
503 r300UpdateShaderStates(rmesa
);
505 rmesa
->state
.VB
.Primitive
= &prim
;
506 rmesa
->state
.VB
.PrimitiveCount
= 1;
508 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
509 if (rmesa
->state
.VB
.LockCount
)
510 prim
.start
= min
- rmesa
->state
.VB
.LockFirst
;
515 rmesa
->state
.VB
.Elts
= ptr
;
516 rmesa
->state
.VB
.elt_size
= elt_size
;
517 rmesa
->state
.VB
.elt_min
= min
;
518 rmesa
->state
.VB
.elt_max
= max
;
520 if (r300_run_vb_render(ctx
, NULL
)) {
521 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
526 radeon_mm_use(rmesa
, rvb
.buf
->id
);
528 r300ReleaseDmaRegion(rmesa
, &rvb
, __FUNCTION__
);
532 _tnl_array_init(ctx
);
533 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
534 CALL_DrawRangeElements(GET_DISPATCH(), (mode
, min
, max
, count
, type
, c_indices
));
535 radeon_init_vtxfmt_a(rmesa
);
536 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
539 static void radeonDrawArrays( GLenum mode
, GLint start
, GLsizei count
)
541 GET_CURRENT_CONTEXT(ctx
);
542 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
543 struct tnl_prim prim
;
546 WARN_ONCE("Too many verts!\n");
550 if (!_mesa_validate_DrawArrays( ctx
, mode
, start
, count
))
553 FLUSH_CURRENT( ctx
, 0 );
556 _mesa_update_state( ctx
);
558 /* XXX: setup_arrays before state update? */
560 r300UpdateShaders(rmesa
);
562 if (setup_arrays(rmesa
, start
) >= R300_FALLBACK_TCL
)
565 rmesa
->state
.VB
.Count
= count
;
567 r300UpdateShaderStates(rmesa
);
569 rmesa
->state
.VB
.Primitive
= &prim
;
570 rmesa
->state
.VB
.PrimitiveCount
= 1;
572 prim
.mode
= mode
| PRIM_BEGIN
| PRIM_END
;
573 if (rmesa
->state
.VB
.LockCount
)
574 prim
.start
= start
- rmesa
->state
.VB
.LockFirst
;
579 rmesa
->state
.VB
.Elts
= NULL
;
580 rmesa
->state
.VB
.elt_size
= 0;
581 rmesa
->state
.VB
.elt_min
= 0;
582 rmesa
->state
.VB
.elt_max
= 0;
584 if (r300_run_vb_render(ctx
, NULL
))
590 _tnl_array_init(ctx
);
591 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
592 CALL_DrawArrays(GET_DISPATCH(), (mode
, start
, count
));
593 radeon_init_vtxfmt_a(rmesa
);
594 _mesa_install_exec_vtxfmt( ctx
, &TNL_CONTEXT(ctx
)->exec_vtxfmt
);
597 void radeon_init_vtxfmt_a(r300ContextPtr rmesa
)
600 GLvertexformat
*vfmt
;
602 ctx
= rmesa
->radeon
.glCtx
;
603 vfmt
= (GLvertexformat
*)ctx
->TnlModule
.Current
;
605 vfmt
->DrawElements
= radeonDrawElements
;
606 vfmt
->DrawArrays
= radeonDrawArrays
;
607 vfmt
->DrawRangeElements
= radeonDrawRangeElements
;
614 static struct gl_buffer_object
*
615 r300NewBufferObject(GLcontext
*ctx
, GLuint name
, GLenum target
)
617 struct r300_buffer_object
*obj
;
621 obj
= MALLOC_STRUCT(r300_buffer_object
);
622 _mesa_initialize_buffer_object(&obj
->mesa_obj
, name
, target
);
623 return &obj
->mesa_obj
;
626 static void r300BufferData(GLcontext
*ctx
, GLenum target
, GLsizeiptrARB size
,
627 const GLvoid
*data
, GLenum usage
, struct gl_buffer_object
*obj
)
629 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
630 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
632 /* Free previous buffer */
634 radeon_mm_free(rmesa
, r300_obj
->id
);
635 obj
->OnCard
= GL_FALSE
;
638 _mesa_free(obj
->Data
);
643 if (target
== GL_ELEMENT_ARRAY_BUFFER_ARB
) {
646 obj
->Data
= malloc(size
);
649 _mesa_memcpy(obj
->Data
, data
, size
);
651 obj
->OnCard
= GL_FALSE
;
653 r300_obj
->id
= radeon_mm_alloc(rmesa
, 4, size
);
654 if (r300_obj
->id
== 0)
657 obj
->Data
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
660 _mesa_memcpy(obj
->Data
, data
, size
);
662 radeon_mm_unmap(rmesa
, r300_obj
->id
);
663 obj
->OnCard
= GL_TRUE
;
670 static void r300BufferSubData(GLcontext
*ctx
, GLenum target
, GLintptrARB offset
,
671 GLsizeiptrARB size
, const GLvoid
* data
, struct gl_buffer_object
* bufObj
)
673 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
674 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
675 (void) ctx
; (void) target
;
678 if (bufObj
->Data
&& ((GLuint
) (size
+ offset
) <= bufObj
->Size
)) {
680 ptr
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
682 _mesa_memcpy( (GLubyte
*) ptr
+ offset
, data
, size
);
684 radeon_mm_unmap(rmesa
, r300_obj
->id
);
686 _mesa_memcpy( (GLubyte
*) bufObj
->Data
+ offset
, data
, size
);
691 static void *r300MapBuffer(GLcontext
*ctx
, GLenum target
, GLenum access
,
692 struct gl_buffer_object
*bufObj
)
694 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
695 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
700 //ASSERT(!bufObj->OnCard);
701 /* Just return a direct pointer to the data */
702 if (bufObj
->Pointer
) {
703 /* already mapped! */
707 if (!bufObj
->OnCard
) {
708 bufObj
->Pointer
= bufObj
->Data
;
709 return bufObj
->Pointer
;
714 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_R
);
718 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_W
);
722 bufObj
->Pointer
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_RW
);
726 WARN_ONCE("Unknown access type\n");
727 bufObj
->Pointer
= NULL
;
731 return bufObj
->Pointer
;
734 static GLboolean
r300UnmapBuffer(GLcontext
*ctx
, GLenum target
, struct gl_buffer_object
*bufObj
)
736 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
737 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)bufObj
;
741 //ASSERT(!bufObj->OnCard);
742 /* XXX we might assert here that bufObj->Pointer is non-null */
743 if (!bufObj
->OnCard
) {
744 bufObj
->Pointer
= NULL
;
747 radeon_mm_unmap(rmesa
, r300_obj
->id
);
749 bufObj
->Pointer
= NULL
;
753 static void r300DeleteBuffer(GLcontext
*ctx
, struct gl_buffer_object
*obj
)
755 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
756 struct r300_buffer_object
*r300_obj
= (struct r300_buffer_object
*)obj
;
759 radeon_mm_free(rmesa
, r300_obj
->id
);
762 _mesa_delete_buffer_object(ctx
, obj
);
765 void r300_evict_vbos(GLcontext
*ctx
, int amount
)
767 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
768 struct _mesa_HashTable
*hash
= ctx
->Shared
->BufferObjects
;
769 GLuint k
= _mesa_HashFirstEntry(hash
);
770 struct gl_buffer_object
*obj
;
771 struct r300_buffer_object
*r300_obj
;
774 while (amount
> 0 && k
) {
775 obj
= (struct gl_buffer_object
*) _mesa_HashLookup(hash
, k
);
776 r300_obj
= (struct r300_buffer_object
*) obj
;
778 if (obj
->OnCard
&& obj
->Size
) {
779 obj
->Data
= _mesa_malloc(obj
->Size
);
781 data
= radeon_mm_map(rmesa
, r300_obj
->id
, RADEON_MM_R
);
782 _mesa_memcpy(obj
->Data
, data
, obj
->Size
);
783 radeon_mm_unmap(rmesa
, r300_obj
->id
);
785 radeon_mm_free(rmesa
, r300_obj
->id
);
787 obj
->OnCard
= GL_FALSE
;
792 k
= _mesa_HashNextEntry(hash
, k
);
797 void r300_init_vbo_funcs(struct dd_function_table
*functions
)
799 functions
->NewBufferObject
= r300NewBufferObject
;
800 functions
->BufferData
= r300BufferData
;
801 functions
->BufferSubData
= r300BufferSubData
;
802 functions
->MapBuffer
= r300MapBuffer
;
803 functions
->UnmapBuffer
= r300UnmapBuffer
;
804 functions
->DeleteBuffer
= r300DeleteBuffer
;