1 /**************************************************************************
3 * Copyright 2009 Maciej Cencora
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHOR(S) AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/state.h"
32 #include "main/api_validate.h"
33 #include "main/enums.h"
34 #include "main/simple_list.h"
37 #include "r300_context.h"
38 #include "r300_emit.h"
39 #include "r300_render.h"
40 #include "r300_state.h"
42 #include "r300_cmdbuf.h"
44 #include "radeon_buffer_objects.h"
47 #include "tnl/t_vp_build.h"
48 #include "vbo/vbo_context.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
53 static int getTypeSize(GLenum type
)
57 return sizeof(GLdouble
);
59 return sizeof(GLfloat
);
63 return sizeof(GLuint
);
65 return sizeof(GLshort
);
66 case GL_UNSIGNED_SHORT
:
67 return sizeof(GLushort
);
69 return sizeof(GLbyte
);
70 case GL_UNSIGNED_BYTE
:
71 return sizeof(GLubyte
);
78 static void r300FixupIndexBuffer(GLcontext
*ctx
, const struct _mesa_index_buffer
*mesa_ind_buf
)
80 r300ContextPtr r300
= R300_CONTEXT(ctx
);
84 GLboolean mapped_named_bo
= GL_FALSE
;
86 if (mesa_ind_buf
->obj
->Name
&& !mesa_ind_buf
->obj
->Pointer
) {
87 ctx
->Driver
.MapBuffer(ctx
, GL_ELEMENT_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, mesa_ind_buf
->obj
);
88 mapped_named_bo
= GL_TRUE
;
89 assert(mesa_ind_buf
->obj
->Pointer
!= NULL
);
91 src_ptr
= ADD_POINTERS(mesa_ind_buf
->obj
->Pointer
, mesa_ind_buf
->ptr
);
93 if (mesa_ind_buf
->type
== GL_UNSIGNED_BYTE
) {
94 GLuint size
= sizeof(GLushort
) * ((mesa_ind_buf
->count
+ 1) & ~1);
95 GLubyte
*in
= (GLubyte
*)src_ptr
;
97 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
, &r300
->ind_buf
.bo_offset
, size
, 4);
99 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
100 out
= (GLuint
*)ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
102 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
103 *out
++ = in
[i
] | in
[i
+ 1] << 16;
106 if (i
< mesa_ind_buf
->count
) {
111 } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
112 GLushort
*in
= (GLushort
*)src_ptr
;
113 GLuint size
= sizeof(GLushort
) * ((mesa_ind_buf
->count
+ 1) & ~1);
115 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
,
116 &r300
->ind_buf
.bo_offset
, size
, 4);
118 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
119 out
= (GLuint
*)ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
121 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
122 *out
++ = in
[i
] | in
[i
+ 1] << 16;
125 if (i
< mesa_ind_buf
->count
) {
131 r300
->ind_buf
.is_32bit
= GL_FALSE
;
132 r300
->ind_buf
.count
= mesa_ind_buf
->count
;
134 if (mapped_named_bo
) {
135 ctx
->Driver
.UnmapBuffer(ctx
, GL_ELEMENT_ARRAY_BUFFER
, mesa_ind_buf
->obj
);
140 static void r300SetupIndexBuffer(GLcontext
*ctx
, const struct _mesa_index_buffer
*mesa_ind_buf
)
142 r300ContextPtr r300
= R300_CONTEXT(ctx
);
145 r300
->ind_buf
.bo
= NULL
;
150 if (mesa_ind_buf
->type
== GL_UNSIGNED_INT
) {
152 if (mesa_ind_buf
->type
!= GL_UNSIGNED_BYTE
) {
154 const GLvoid
*src_ptr
;
156 GLboolean mapped_named_bo
= GL_FALSE
;
158 if (mesa_ind_buf
->obj
->Name
&& !mesa_ind_buf
->obj
->Pointer
) {
159 ctx
->Driver
.MapBuffer(ctx
, GL_ELEMENT_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, mesa_ind_buf
->obj
);
160 assert(mesa_ind_buf
->obj
->Pointer
!= NULL
);
161 mapped_named_bo
= GL_TRUE
;
164 src_ptr
= ADD_POINTERS(mesa_ind_buf
->obj
->Pointer
, mesa_ind_buf
->ptr
);
166 const GLuint size
= mesa_ind_buf
->count
* getTypeSize(mesa_ind_buf
->type
);
168 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
, &r300
->ind_buf
.bo_offset
, size
, 4);
170 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
171 dst_ptr
= ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
172 _mesa_memcpy(dst_ptr
, src_ptr
, size
);
174 r300
->ind_buf
.is_32bit
= (mesa_ind_buf
->type
== GL_UNSIGNED_INT
);
175 r300
->ind_buf
.count
= mesa_ind_buf
->count
;
177 if (mapped_named_bo
) {
178 ctx
->Driver
.UnmapBuffer(ctx
, GL_ELEMENT_ARRAY_BUFFER
, mesa_ind_buf
->obj
);
181 r300FixupIndexBuffer(ctx
, mesa_ind_buf
);
185 #define CONVERT( TYPE, MACRO ) do { \
188 if (input->Normalized) { \
189 for (i = 0; i < count; i++) { \
190 const TYPE *in = (TYPE *)src_ptr; \
191 for (j = 0; j < sz; j++) { \
192 *dst_ptr++ = MACRO(*in); \
198 for (i = 0; i < count; i++) { \
199 const TYPE *in = (TYPE *)src_ptr; \
200 for (j = 0; j < sz; j++) { \
201 *dst_ptr++ = (GLfloat)(*in); \
210 * Convert attribute data type to float
211 * If the attribute uses named buffer object replace the bo with newly allocated bo
213 static void r300ConvertAttrib(GLcontext
*ctx
, int count
, const struct gl_client_array
*input
, struct vertex_attribute
*attr
)
215 r300ContextPtr r300
= R300_CONTEXT(ctx
);
216 const GLvoid
*src_ptr
;
217 GLboolean mapped_named_bo
= GL_FALSE
;
221 stride
= (input
->StrideB
== 0) ? getTypeSize(input
->Type
) * input
->Size
: input
->StrideB
;
223 /* Convert value for first element only */
224 if (input
->StrideB
== 0)
227 if (input
->BufferObj
->Name
) {
228 if (!input
->BufferObj
->Pointer
) {
229 ctx
->Driver
.MapBuffer(ctx
, GL_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, input
->BufferObj
);
230 mapped_named_bo
= GL_TRUE
;
233 src_ptr
= ADD_POINTERS(input
->BufferObj
->Pointer
, input
->Ptr
);
235 src_ptr
= input
->Ptr
;
238 radeonAllocDmaRegion(&r300
->radeon
, &attr
->bo
, &attr
->bo_offset
, sizeof(GLfloat
) * input
->Size
* count
, 32);
239 dst_ptr
= (GLfloat
*)ADD_POINTERS(attr
->bo
->ptr
, attr
->bo_offset
);
241 if (RADEON_DEBUG
& DEBUG_FALLBACKS
) {
242 fprintf(stderr
, "%s: Converting vertex attributes, attribute data format %x,", __FUNCTION__
, input
->Type
);
243 fprintf(stderr
, "stride %d, components %d\n", stride
, input
->Size
);
246 assert(src_ptr
!= NULL
);
248 switch (input
->Type
) {
250 CONVERT(GLdouble
, (GLfloat
));
252 case GL_UNSIGNED_INT
:
253 CONVERT(GLuint
, UINT_TO_FLOAT
);
256 CONVERT(GLint
, INT_TO_FLOAT
);
258 case GL_UNSIGNED_SHORT
:
259 CONVERT(GLushort
, USHORT_TO_FLOAT
);
262 CONVERT(GLshort
, SHORT_TO_FLOAT
);
264 case GL_UNSIGNED_BYTE
:
265 assert(input
->Format
!= GL_BGRA
);
266 CONVERT(GLubyte
, UBYTE_TO_FLOAT
);
269 CONVERT(GLbyte
, BYTE_TO_FLOAT
);
276 if (mapped_named_bo
) {
277 ctx
->Driver
.UnmapBuffer(ctx
, GL_ARRAY_BUFFER
, input
->BufferObj
);
281 static void r300AlignDataToDword(GLcontext
*ctx
, const struct gl_client_array
*input
, int count
, struct vertex_attribute
*attr
)
283 r300ContextPtr r300
= R300_CONTEXT(ctx
);
284 const int dst_stride
= (input
->StrideB
+ 3) & ~3;
285 const int size
= getTypeSize(input
->Type
) * input
->Size
* count
;
286 GLboolean mapped_named_bo
= GL_FALSE
;
288 radeonAllocDmaRegion(&r300
->radeon
, &attr
->bo
, &attr
->bo_offset
, size
, 32);
290 if (!input
->BufferObj
->Pointer
) {
291 ctx
->Driver
.MapBuffer(ctx
, GL_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, input
->BufferObj
);
292 mapped_named_bo
= GL_TRUE
;
296 GLvoid
*src_ptr
= ADD_POINTERS(input
->BufferObj
->Pointer
, input
->Ptr
);
297 GLvoid
*dst_ptr
= ADD_POINTERS(attr
->bo
->ptr
, attr
->bo_offset
);
300 for (i
= 0; i
< count
; ++i
) {
301 _mesa_memcpy(dst_ptr
, src_ptr
, input
->StrideB
);
302 src_ptr
+= input
->StrideB
;
303 dst_ptr
+= dst_stride
;
307 if (mapped_named_bo
) {
308 ctx
->Driver
.UnmapBuffer(ctx
, GL_ARRAY_BUFFER
, input
->BufferObj
);
311 attr
->stride
= dst_stride
;
314 static void r300TranslateAttrib(GLcontext
*ctx
, GLuint attr
, int count
, const struct gl_client_array
*input
)
316 r300ContextPtr r300
= R300_CONTEXT(ctx
);
317 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
318 struct vertex_attribute r300_attr
;
322 stride
= (input
->StrideB
== 0) ? getTypeSize(input
->Type
) * input
->Size
: input
->StrideB
;
324 if (input
->Type
== GL_DOUBLE
|| input
->Type
== GL_UNSIGNED_INT
|| input
->Type
== GL_INT
||
326 getTypeSize(input
->Type
) != 4 ||
332 if (input
->StrideB
== 0) {
333 r300_attr
.stride
= 0;
335 r300_attr
.stride
= sizeof(GLfloat
) * input
->Size
;
337 r300_attr
.dwords
= input
->Size
;
338 r300_attr
.is_named_bo
= GL_FALSE
;
341 r300_attr
.dwords
= (getTypeSize(type
) * input
->Size
+ 3)/ 4;
342 if (!input
->BufferObj
->Name
) {
344 if (input
->StrideB
== 0) {
345 r300_attr
.stride
= 0;
347 r300_attr
.stride
= (getTypeSize(type
) * input
->Size
+ 3) & ~3;
350 r300_attr
.is_named_bo
= GL_FALSE
;
354 r300_attr
.size
= input
->Size
;
355 r300_attr
.element
= attr
;
356 r300_attr
.dst_loc
= vbuf
->num_attribs
;
360 switch (input
->Size
) {
361 case 1: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_1
; break;
362 case 2: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_2
; break;
363 case 3: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_3
; break;
364 case 4: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_4
; break;
366 r300_attr
._signed
= 0;
367 r300_attr
.normalize
= 0;
370 r300_attr
._signed
= 1;
371 r300_attr
.normalize
= input
->Normalized
;
372 switch (input
->Size
) {
375 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
379 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
384 r300_attr
._signed
= 1;
385 r300_attr
.normalize
= input
->Normalized
;
386 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
388 case GL_UNSIGNED_SHORT
:
389 r300_attr
._signed
= 0;
390 r300_attr
.normalize
= input
->Normalized
;
391 switch (input
->Size
) {
394 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
398 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
402 case GL_UNSIGNED_BYTE
:
403 r300_attr
._signed
= 0;
404 r300_attr
.normalize
= input
->Normalized
;
405 if (input
->Format
== GL_BGRA
)
406 r300_attr
.data_type
= R300_DATA_TYPE_D3DCOLOR
;
408 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
414 case GL_UNSIGNED_INT
:
419 switch (input
->Size
) {
421 r300_attr
.swizzle
= SWIZZLE_XYZW
;
424 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
427 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
430 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
434 r300_attr
.write_mask
= MASK_XYZW
;
436 vbuf
->attribs
[vbuf
->num_attribs
] = r300_attr
;
440 static void r300SetVertexFormat(GLcontext
*ctx
, const struct gl_client_array
*arrays
[], int count
)
442 r300ContextPtr r300
= R300_CONTEXT(ctx
);
443 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
447 tmp
= r300
->selected_vp
->code
.InputsRead
;
449 vbuf
->num_attribs
= 0;
451 /* find first enabled bit */
457 r300TranslateAttrib(ctx
, i
, count
, arrays
[i
]);
464 r300SwitchFallback(ctx
, R300_FALLBACK_AOS_LIMIT
, vbuf
->num_attribs
> R300_MAX_AOS_ARRAYS
);
469 static void r300AllocDmaRegions(GLcontext
*ctx
, const struct gl_client_array
*input
[], int count
)
471 r300ContextPtr r300
= R300_CONTEXT(ctx
);
472 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
477 for (index
= 0; index
< vbuf
->num_attribs
; index
++) {
478 struct radeon_aos
*aos
= &r300
->radeon
.tcl
.aos
[index
];
479 i
= vbuf
->attribs
[index
].element
;
481 stride
= (input
[i
]->StrideB
== 0) ? getTypeSize(input
[i
]->Type
) * input
[i
]->Size
: input
[i
]->StrideB
;
483 if (input
[i
]->Type
== GL_DOUBLE
|| input
[i
]->Type
== GL_UNSIGNED_INT
|| input
[i
]->Type
== GL_INT
||
485 getTypeSize(input
[i
]->Type
) != 4 ||
489 r300ConvertAttrib(ctx
, count
, input
[i
], &vbuf
->attribs
[index
]);
491 if (input
[i
]->BufferObj
->Name
) {
492 if (stride
% 4 != 0) {
493 assert(((intptr_t) input
[i
]->Ptr
) % input
[i
]->StrideB
== 0);
494 r300AlignDataToDword(ctx
, input
[i
], count
, &vbuf
->attribs
[index
]);
495 vbuf
->attribs
[index
].is_named_bo
= GL_FALSE
;
497 vbuf
->attribs
[index
].stride
= input
[i
]->StrideB
;
498 vbuf
->attribs
[index
].bo_offset
= (intptr_t) input
[i
]->Ptr
;
499 vbuf
->attribs
[index
].bo
= get_radeon_buffer_object(input
[i
]->BufferObj
)->bo
;
500 vbuf
->attribs
[index
].is_named_bo
= GL_TRUE
;
505 int local_count
= count
;
508 if (input
[i
]->StrideB
== 0) {
509 size
= getTypeSize(input
[i
]->Type
) * input
[i
]->Size
;
512 size
= getTypeSize(input
[i
]->Type
) * input
[i
]->Size
* local_count
;
515 radeonAllocDmaRegion(&r300
->radeon
, &vbuf
->attribs
[index
].bo
, &vbuf
->attribs
[index
].bo_offset
, size
, 32);
516 assert(vbuf
->attribs
[index
].bo
->ptr
!= NULL
);
517 dst
= (uint32_t *)ADD_POINTERS(vbuf
->attribs
[index
].bo
->ptr
, vbuf
->attribs
[index
].bo_offset
);
518 switch (vbuf
->attribs
[index
].dwords
) {
519 case 1: radeonEmitVec4(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
520 case 2: radeonEmitVec8(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
521 case 3: radeonEmitVec12(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
522 case 4: radeonEmitVec16(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
523 default: assert(0); break;
529 aos
->count
= vbuf
->attribs
[index
].stride
== 0 ? 1 : count
;
530 aos
->stride
= vbuf
->attribs
[index
].stride
/ sizeof(float);
531 aos
->components
= vbuf
->attribs
[index
].dwords
;
532 aos
->bo
= vbuf
->attribs
[index
].bo
;
533 aos
->offset
= vbuf
->attribs
[index
].bo_offset
;
535 if (vbuf
->attribs
[index
].is_named_bo
) {
536 radeon_cs_space_add_persistent_bo(r300
->radeon
.cmdbuf
.cs
, r300
->vbuf
.attribs
[index
].bo
, RADEON_GEM_DOMAIN_GTT
, 0);
540 r300
->radeon
.tcl
.aos_count
= vbuf
->num_attribs
;
541 ret
= radeon_cs_space_check_with_bo(r300
->radeon
.cmdbuf
.cs
, first_elem(&r300
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
542 r300SwitchFallback(ctx
, R300_FALLBACK_INVALID_BUFFERS
, ret
);
546 static void r300FreeData(GLcontext
*ctx
)
548 /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
549 * to prevent double unref in radeonReleaseArrays
550 * called during context destroy
552 r300ContextPtr r300
= R300_CONTEXT(ctx
);
556 for (i
= 0; i
< r300
->vbuf
.num_attribs
; i
++) {
557 if (!r300
->vbuf
.attribs
[i
].is_named_bo
) {
558 radeon_bo_unref(r300
->vbuf
.attribs
[i
].bo
);
560 r300
->radeon
.tcl
.aos
[i
].bo
= NULL
;
565 if (r300
->ind_buf
.bo
!= NULL
) {
566 radeon_bo_unref(r300
->ind_buf
.bo
);
571 static GLuint
r300PredictTryDrawPrimsSize(GLcontext
*ctx
, GLuint nr_prims
)
573 struct r300_context
*r300
= R300_CONTEXT(ctx
);
574 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
579 dwords
= 2*CACHE_FLUSH_BUFSZ
;
580 dwords
+= PRE_EMIT_STATE_BUFSZ
;
581 dwords
+= (AOS_BUFSZ(vbuf
->num_attribs
)
583 + FIREAOS_BUFSZ
)*nr_prims
;
585 state_size
= radeonCountStateEmitSize(&r300
->radeon
);
586 flushed
= rcommonEnsureCmdBufSpace(&r300
->radeon
,
590 dwords
+= radeonCountStateEmitSize(&r300
->radeon
);
592 dwords
+= state_size
;
594 if (RADEON_DEBUG
& DEBUG_PRIMS
)
595 fprintf(stderr
, "%s: total prediction size is %d.\n", __FUNCTION__
, dwords
);
599 static GLboolean
r300TryDrawPrims(GLcontext
*ctx
,
600 const struct gl_client_array
*arrays
[],
601 const struct _mesa_prim
*prim
,
603 const struct _mesa_index_buffer
*ib
,
607 struct r300_context
*r300
= R300_CONTEXT(ctx
);
610 if (RADEON_DEBUG
& DEBUG_PRIMS
)
611 fprintf(stderr
, "%s: %u (%d-%d) cs begin at %d\n",
612 __FUNCTION__
, nr_prims
, min_index
, max_index
, r300
->radeon
.cmdbuf
.cs
->cdw
);
615 _mesa_update_state( ctx
);
617 if (r300
->options
.hw_tcl_enabled
)
618 _tnl_UpdateFixedFunctionProgram(ctx
);
620 r300UpdateShaders(r300
);
622 r300SwitchFallback(ctx
, R300_FALLBACK_INVALID_BUFFERS
, !r300ValidateBuffers(ctx
));
624 r300SetVertexFormat(ctx
, arrays
, max_index
+ 1);
629 r300SetupVAP(ctx
, r300
->selected_vp
->code
.InputsRead
, r300
->selected_vp
->code
.OutputsWritten
);
631 r300UpdateShaderStates(r300
);
633 /* ensure we have the cmd buf space in advance to cover
634 * the state + DMA AOS pointers */
635 r300PredictTryDrawPrimsSize(ctx
, nr_prims
);
637 r300SetupIndexBuffer(ctx
, ib
);
639 r300AllocDmaRegions(ctx
, arrays
, max_index
+ 1);
644 r300EmitCacheFlush(r300
);
645 radeonEmitState(&r300
->radeon
);
647 for (i
= 0; i
< nr_prims
; ++i
) {
648 r300RunRenderPrimitive(ctx
, prim
[i
].start
, prim
[i
].start
+ prim
[i
].count
, prim
[i
].mode
);
651 r300EmitCacheFlush(r300
);
655 if (RADEON_DEBUG
& DEBUG_PRIMS
)
656 fprintf(stderr
, "%s: %u (%d-%d) cs ending at %d\n",
657 __FUNCTION__
, nr_prims
, min_index
, max_index
, r300
->radeon
.cmdbuf
.cs
->cdw
);
662 static void r300DrawPrims(GLcontext
*ctx
,
663 const struct gl_client_array
*arrays
[],
664 const struct _mesa_prim
*prim
,
666 const struct _mesa_index_buffer
*ib
,
667 GLboolean index_bounds_valid
,
673 /* This check should get folded into just the places that
674 * min/max index are really needed.
676 if (!index_bounds_valid
) {
677 vbo_get_minmax_index(ctx
, prim
, ib
, &min_index
, &max_index
);
681 vbo_rebase_prims( ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
, r300DrawPrims
);
685 /* Make an attempt at drawing */
686 retval
= r300TryDrawPrims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
688 /* If failed run tnl pipeline - it should take care of fallbacks */
690 _tnl_draw_prims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
693 void r300InitDraw(GLcontext
*ctx
)
695 struct vbo_context
*vbo
= vbo_context(ctx
);
697 vbo
->draw_prims
= r300DrawPrims
;