OSDN Git Service

r300: fix the build on big endian
[android-x86/external-mesa.git] / src / mesa / drivers / dri / r300 / r300_draw.c
1 /**************************************************************************
2  *
3  * Copyright 2009 Maciej Cencora
4  *
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:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
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.
24  *
25  **************************************************************************/
26
27 #include <stdlib.h>
28
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
35 #include "r300_reg.h"
36 #include "r300_context.h"
37 #include "r300_emit.h"
38 #include "r300_render.h"
39 #include "r300_state.h"
40 #include "r300_tex.h"
41
42 #include "radeon_buffer_objects.h"
43
44 #include "tnl/tnl.h"
45 #include "tnl/t_vp_build.h"
46 #include "vbo/vbo_context.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49
50
51 static int getTypeSize(GLenum type)
52 {
53         switch (type) {
54                 case GL_DOUBLE:
55                         return sizeof(GLdouble);
56                 case GL_FLOAT:
57                         return sizeof(GLfloat);
58                 case GL_INT:
59                         return sizeof(GLint);
60                 case GL_UNSIGNED_INT:
61                         return sizeof(GLuint);
62                 case GL_SHORT:
63                         return sizeof(GLshort);
64                 case GL_UNSIGNED_SHORT:
65                         return sizeof(GLushort);
66                 case GL_BYTE:
67                         return sizeof(GLbyte);
68                 case GL_UNSIGNED_BYTE:
69                         return sizeof(GLubyte);
70                 default:
71                         assert(0);
72                         return 0;
73         }
74 }
75
76 static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
77 {
78         r300ContextPtr r300 = R300_CONTEXT(ctx);
79         GLvoid *src_ptr;
80         GLuint *out;
81         int i;
82         GLboolean mapped_named_bo = GL_FALSE;
83
84         if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) {
85                 ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
86                 mapped_named_bo = GL_TRUE;
87                 assert(mesa_ind_buf->obj->Pointer != NULL);
88         }
89         src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
90
91         if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) {
92                 GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
93                 GLubyte *in = (GLubyte *)src_ptr;
94
95                 radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
96
97                 assert(r300->ind_buf.bo->ptr != NULL);
98                 out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
99
100                 for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) {
101                         *out++ = in[i] | in[i + 1] << 16;
102                 }
103
104                 if (i < mesa_ind_buf->count) {
105                         *out++ = in[i];
106                 }
107
108 #if MESA_BIG_ENDIAN
109         } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
110                 GLuint size;
111                 GLushort *in = (GLushort *)src_ptr;
112                 size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
113
114                 radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offet, size, 4);
115
116                 assert(r300->ind_buf.bo->ptr != NULL);
117                 out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
118
119                 for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) {
120                         *out++ = in[i] | in[i + 1] << 16;
121                 }
122
123                 if (i < mesa_ind_buf->count) {
124                         *out++ = in[i];
125                 }
126 #endif
127         }
128
129         r300->ind_buf.is_32bit = GL_FALSE;
130         r300->ind_buf.count = mesa_ind_buf->count;
131
132         if (mapped_named_bo) {
133                 ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
134         }
135 }
136
137
138 static void r300SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
139 {
140         r300ContextPtr r300 = R300_CONTEXT(ctx);
141
142         if (!mesa_ind_buf) {
143                 r300->ind_buf.bo = NULL;
144                 return;
145         }
146
147 #if MESA_BIG_ENDIAN
148         if (mesa_ind_buf->type == GL_UNSIGNED_INT) {
149 #else
150         if (mesa_ind_buf->type != GL_UNSIGNED_BYTE) {
151 #endif
152                 const GLvoid *src_ptr;
153                 GLvoid *dst_ptr;
154                 GLboolean mapped_named_bo = GL_FALSE;
155
156                 if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) {
157                         ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
158                         assert(mesa_ind_buf->obj->Pointer != NULL);
159                         mapped_named_bo = GL_TRUE;
160                 }
161
162                 src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
163
164                 const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);
165
166                 radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
167
168                 assert(r300->ind_buf.bo->ptr != NULL);
169                 dst_ptr = ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
170                 _mesa_memcpy(dst_ptr, src_ptr, size);
171
172                 r300->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
173                 r300->ind_buf.count = mesa_ind_buf->count;
174
175                 if (mapped_named_bo) {
176                         ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
177                 }
178         } else {
179                 r300FixupIndexBuffer(ctx, mesa_ind_buf);
180         }
181 }
182
183 #define CONVERT( TYPE, MACRO ) do {             \
184         GLuint i, j, sz;                                \
185         sz = input->Size;                               \
186         if (input->Normalized) {                        \
187                 for (i = 0; i < count; i++) {           \
188                         const TYPE *in = (TYPE *)src_ptr;               \
189                         for (j = 0; j < sz; j++) {              \
190                                 *dst_ptr++ = MACRO(*in);                \
191                                 in++;                           \
192                         }                                       \
193                         src_ptr += stride;                      \
194                 }                                               \
195         } else {                                        \
196                 for (i = 0; i < count; i++) {           \
197                         const TYPE *in = (TYPE *)src_ptr;               \
198                         for (j = 0; j < sz; j++) {              \
199                                 *dst_ptr++ = (GLfloat)(*in);            \
200                                 in++;                           \
201                         }                                       \
202                         src_ptr += stride;                      \
203                 }                                               \
204         }                                               \
205 } while (0)
206
207 /**
208  * Convert attribute data type to float
209  * If the attribute uses named buffer object replace the bo with newly allocated bo
210  */
211 static void r300ConvertAttrib(GLcontext *ctx, int count, const struct gl_client_array *input, struct vertex_attribute *attr)
212 {
213         r300ContextPtr r300 = R300_CONTEXT(ctx);
214         const GLvoid *src_ptr;
215         GLboolean mapped_named_bo = GL_FALSE;
216         GLfloat *dst_ptr;
217         GLuint stride;
218
219         stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB;
220
221         /* Convert value for first element only */
222         if (input->StrideB == 0)
223                 count = 1;
224
225         if (input->BufferObj->Name) {
226                 if (!input->BufferObj->Pointer) {
227                         ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
228                         mapped_named_bo = GL_TRUE;
229                 }
230
231                 src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
232         } else {
233                 src_ptr = input->Ptr;
234         }
235
236         radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, sizeof(GLfloat) * input->Size * count, 32);
237         dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
238
239         if (RADEON_DEBUG & DEBUG_FALLBACKS) {
240                 fprintf(stderr, "%s: Converting vertex attributes, attribute data format %x,", __FUNCTION__, input->Type);
241                 fprintf(stderr, "stride %d, components %d\n", stride, input->Size);
242         }
243
244         assert(src_ptr != NULL);
245
246         switch (input->Type) {
247                 case GL_DOUBLE:
248                         CONVERT(GLdouble, (GLfloat));
249                         break;
250                 case GL_UNSIGNED_INT:
251                         CONVERT(GLuint, UINT_TO_FLOAT);
252                         break;
253                 case GL_INT:
254                         CONVERT(GLint, INT_TO_FLOAT);
255                         break;
256                 case GL_UNSIGNED_SHORT:
257                         CONVERT(GLushort, USHORT_TO_FLOAT);
258                         break;
259                 case GL_SHORT:
260                         CONVERT(GLshort, SHORT_TO_FLOAT);
261                         break;
262                 case GL_UNSIGNED_BYTE:
263                         assert(input->Format != GL_BGRA);
264                         CONVERT(GLubyte, UBYTE_TO_FLOAT);
265                         break;
266                 case GL_BYTE:
267                         CONVERT(GLbyte, BYTE_TO_FLOAT);
268                         break;
269                 default:
270                         assert(0);
271                         break;
272         }
273
274         if (mapped_named_bo) {
275                 ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
276         }
277 }
278
279 static void r300AlignDataToDword(GLcontext *ctx, const struct gl_client_array *input, int count, struct vertex_attribute *attr)
280 {
281         r300ContextPtr r300 = R300_CONTEXT(ctx);
282         const int dst_stride = (input->StrideB + 3) & ~3;
283         const int size = getTypeSize(input->Type) * input->Size * count;
284         GLboolean mapped_named_bo = GL_FALSE;
285
286         radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, size, 32);
287
288         if (!input->BufferObj->Pointer) {
289                 ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
290                 mapped_named_bo = GL_TRUE;
291         }
292
293         {
294                 GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
295                 GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
296                 int i;
297
298                 for (i = 0; i < count; ++i) {
299                         _mesa_memcpy(dst_ptr, src_ptr, input->StrideB);
300                         src_ptr += input->StrideB;
301                         dst_ptr += dst_stride;
302                 }
303         }
304
305         if (mapped_named_bo) {
306                 ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
307         }
308
309         attr->stride = dst_stride;
310 }
311
312 static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const struct gl_client_array *input)
313 {
314         r300ContextPtr r300 = R300_CONTEXT(ctx);
315         struct r300_vertex_buffer *vbuf = &r300->vbuf;
316         struct vertex_attribute r300_attr;
317         GLenum type;
318         GLuint stride;
319
320         stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB;
321
322         if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT ||
323 #if MESA_BIG_ENDIAN
324             getTypeSize(input->Type) != 4 ||
325 #endif
326             stride < 4) {
327
328                 type = GL_FLOAT;
329
330                 r300ConvertAttrib(ctx, count, input, &r300_attr);
331                 if (input->StrideB == 0) {
332                         r300_attr.stride = 0;
333                 } else {
334                         r300_attr.stride = sizeof(GLfloat) * input->Size;
335                 }
336                 r300_attr.dwords = input->Size;
337                 r300_attr.is_named_bo = GL_FALSE;
338         } else {
339                 type = input->Type;
340                 r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4;
341                 if (input->BufferObj->Name) {
342                         if (stride % 4 != 0) {
343                                 assert(((int) input->Ptr) % input->StrideB == 0);
344                                 r300AlignDataToDword(ctx, input, count, &r300_attr);
345                                 r300_attr.is_named_bo = GL_FALSE;
346                         } else {
347                                 r300_attr.stride = input->StrideB;
348                                 r300_attr.bo_offset = (GLuint) input->Ptr;
349                                 r300_attr.bo = get_radeon_buffer_object(input->BufferObj)->bo;
350                                 r300_attr.is_named_bo = GL_TRUE;
351                         }
352                 } else {
353                         int size;
354                         uint32_t *dst;
355
356                         if (input->StrideB == 0) {
357                                 size = getTypeSize(input->Type) * input->Size;
358                                 count = 1;
359                                 r300_attr.stride = 0;
360                         } else {
361                                 size = getTypeSize(input->Type) * input->Size * count;
362                                 r300_attr.stride = (getTypeSize(type) * input->Size + 3) & ~3;
363                         }
364
365                         radeonAllocDmaRegion(&r300->radeon, &r300_attr.bo, &r300_attr.bo_offset, size, 32);
366                         assert(r300_attr.bo->ptr != NULL);
367                         dst = (uint32_t *)ADD_POINTERS(r300_attr.bo->ptr, r300_attr.bo_offset);
368                         switch (r300_attr.dwords) {
369                                 case 1: radeonEmitVec4(dst, input->Ptr, input->StrideB, count); break;
370                                 case 2: radeonEmitVec8(dst, input->Ptr, input->StrideB, count); break;
371                                 case 3: radeonEmitVec12(dst, input->Ptr, input->StrideB, count); break;
372                                 case 4: radeonEmitVec16(dst, input->Ptr, input->StrideB, count); break;
373                                 default: assert(0); break;
374                         }
375
376                         r300_attr.is_named_bo = GL_FALSE;
377                 }
378         }
379
380         r300_attr.size = input->Size;
381         r300_attr.element = attr;
382         r300_attr.dst_loc = vbuf->num_attribs;
383
384         switch (type) {
385                 case GL_FLOAT:
386                         switch (input->Size) {
387                                 case 1: r300_attr.data_type = R300_DATA_TYPE_FLOAT_1; break;
388                                 case 2: r300_attr.data_type = R300_DATA_TYPE_FLOAT_2; break;
389                                 case 3: r300_attr.data_type = R300_DATA_TYPE_FLOAT_3; break;
390                                 case 4: r300_attr.data_type = R300_DATA_TYPE_FLOAT_4; break;
391                         }
392                         r300_attr._signed = 0;
393                         r300_attr.normalize = 0;
394                         break;
395                 case GL_SHORT:
396                         r300_attr._signed = 1;
397                         r300_attr.normalize = input->Normalized;
398                         switch (input->Size) {
399                                 case 1:
400                                 case 2:
401                                         r300_attr.data_type = R300_DATA_TYPE_SHORT_2;
402                                         break;
403                                 case 3:
404                                 case 4:
405                                         r300_attr.data_type = R300_DATA_TYPE_SHORT_4;
406                                         break;
407                         }
408                         break;
409                 case GL_BYTE:
410                         r300_attr._signed = 1;
411                         r300_attr.normalize = input->Normalized;
412                         r300_attr.data_type = R300_DATA_TYPE_BYTE;
413                         break;
414                 case GL_UNSIGNED_SHORT:
415                         r300_attr._signed = 0;
416                         r300_attr.normalize = input->Normalized;
417                         switch (input->Size) {
418                                 case 1:
419                                 case 2:
420                                         r300_attr.data_type = R300_DATA_TYPE_SHORT_2;
421                                         break;
422                                 case 3:
423                                 case 4:
424                                         r300_attr.data_type = R300_DATA_TYPE_SHORT_4;
425                                         break;
426                         }
427                         break;
428                 case GL_UNSIGNED_BYTE:
429                         r300_attr._signed = 0;
430                         r300_attr.normalize = input->Normalized;
431                         if (input->Format == GL_BGRA)
432                                 r300_attr.data_type = R300_DATA_TYPE_D3DCOLOR;
433                         else
434                                 r300_attr.data_type = R300_DATA_TYPE_BYTE;
435                         break;
436
437                 default:
438                 case GL_DOUBLE:
439                 case GL_INT:
440                 case GL_UNSIGNED_INT:
441                         assert(0);
442                         break;
443         }
444
445         switch (input->Size) {
446                 case 4:
447                         r300_attr.swizzle = SWIZZLE_XYZW;
448                         break;
449                 case 3:
450                         r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
451                         break;
452                 case 2:
453                         r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
454                         break;
455                 case 1:
456                         r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
457                         break;
458         }
459
460         r300_attr.write_mask = MASK_XYZW;
461
462         vbuf->attribs[vbuf->num_attribs] = r300_attr;
463         ++vbuf->num_attribs;
464 }
465
466 static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count)
467 {
468         r300ContextPtr r300 = R300_CONTEXT(ctx);
469         struct r300_vertex_buffer *vbuf = &r300->vbuf;
470         int ret;
471         {
472                 int i, tmp;
473
474                 tmp = r300->selected_vp->code.InputsRead;
475                 i = 0;
476                 vbuf->num_attribs = 0;
477                 while (tmp) {
478                         /* find first enabled bit */
479                         while (!(tmp & 1)) {
480                                 tmp >>= 1;
481                                 ++i;
482                         }
483
484                         r300TranslateAttrib(ctx, i, count, arrays[i]);
485
486                         tmp >>= 1;
487                         ++i;
488                 }
489         }
490
491         r300SwitchFallback(ctx, R300_FALLBACK_AOS_LIMIT, vbuf->num_attribs > R300_MAX_AOS_ARRAYS);
492         if (r300->fallback)
493                 return;
494
495         {
496                 int i;
497
498                 for (i = 0; i < vbuf->num_attribs; i++) {
499                         struct radeon_aos *aos = &r300->radeon.tcl.aos[i];
500
501                         aos->count = vbuf->attribs[i].stride == 0 ? 1 : count;
502                         aos->stride = vbuf->attribs[i].stride / sizeof(float);
503                         aos->offset = vbuf->attribs[i].bo_offset;
504                         aos->components = vbuf->attribs[i].dwords;
505                         aos->bo = vbuf->attribs[i].bo;
506
507                         if (vbuf->attribs[i].is_named_bo) {
508                                 radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, r300->vbuf.attribs[i].bo, RADEON_GEM_DOMAIN_GTT, 0);
509                         }
510                 }
511
512                 r300->radeon.tcl.aos_count = vbuf->num_attribs;
513                 ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, r300->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
514                 if (ret)
515                         r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, GL_TRUE);
516         }
517 }
518
519 static void r300FreeData(GLcontext *ctx)
520 {
521         /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
522          * to prevent double unref in radeonReleaseArrays
523          * called during context destroy
524          */
525         r300ContextPtr r300 = R300_CONTEXT(ctx);
526         {
527                 int i;
528
529                 for (i = 0; i < r300->vbuf.num_attribs; i++) {
530                         if (!r300->vbuf.attribs[i].is_named_bo) {
531                                 radeon_bo_unref(r300->vbuf.attribs[i].bo);
532                         }
533                         r300->radeon.tcl.aos[i].bo = NULL;
534                 }
535         }
536
537         {
538                 if (r300->ind_buf.bo != NULL) {
539                         radeon_bo_unref(r300->ind_buf.bo);
540                 }
541         }
542 }
543
544 static GLboolean r300TryDrawPrims(GLcontext *ctx,
545                                          const struct gl_client_array *arrays[],
546                                          const struct _mesa_prim *prim,
547                                          GLuint nr_prims,
548                                          const struct _mesa_index_buffer *ib,
549                                          GLuint min_index,
550                                          GLuint max_index )
551 {
552         struct r300_context *r300 = R300_CONTEXT(ctx);
553         GLuint i;
554
555         if (ctx->NewState)
556                 _mesa_update_state( ctx );
557
558         if (r300->options.hw_tcl_enabled)
559                 _tnl_UpdateFixedFunctionProgram(ctx);
560
561         r300UpdateShaders(r300);
562
563         r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx));
564
565         /* ensure we have the cmd buf space in advance to cover
566          * the state + DMA AOS pointers */
567         rcommonEnsureCmdBufSpace(&r300->radeon,
568                            r300->radeon.hw.max_state_size + (60*sizeof(int)),
569                           __FUNCTION__);
570
571         r300SetupIndexBuffer(ctx, ib);
572
573         r300SetVertexFormat(ctx, arrays, max_index + 1);
574
575         if (r300->fallback)
576                 return GL_FALSE;
577
578         r300SetupVAP(ctx, r300->selected_vp->code.InputsRead, r300->selected_vp->code.OutputsWritten);
579
580         r300UpdateShaderStates(r300);
581
582         r300EmitCacheFlush(r300);
583         radeonEmitState(&r300->radeon);
584
585         for (i = 0; i < nr_prims; ++i) {
586                 r300RunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode);
587         }
588
589         r300EmitCacheFlush(r300);
590
591         r300FreeData(ctx);
592
593         return GL_TRUE;
594 }
595
596 static void r300DrawPrims(GLcontext *ctx,
597                          const struct gl_client_array *arrays[],
598                          const struct _mesa_prim *prim,
599                          GLuint nr_prims,
600                          const struct _mesa_index_buffer *ib,
601                          GLboolean index_bounds_valid,
602                          GLuint min_index,
603                          GLuint max_index)
604 {
605         GLboolean retval;
606
607         /* This check should get folded into just the places that
608          * min/max index are really needed.
609          */
610         if (!index_bounds_valid) {
611                 vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
612         }
613
614         if (min_index) {
615                 vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
616                 return;
617         }
618
619         /* Make an attempt at drawing */
620         retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
621
622         /* If failed run tnl pipeline - it should take care of fallbacks */
623         if (!retval)
624                 _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
625 }
626
627 void r300InitDraw(GLcontext *ctx)
628 {
629         struct vbo_context *vbo = vbo_context(ctx);
630
631         vbo->draw_prims = r300DrawPrims;
632 }