OSDN Git Service

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