11a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**************************************************************************
21a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007 VMware, Inc.
41a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * All Rights Reserved.
51a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
61a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
71a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * copy of this software and associated documentation files (the
81a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * "Software"), to deal in the Software without restriction, including
91a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * without limitation the rights to use, copy, modify, merge, publish,
101a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * distribute, sub license, and/or sell copies of the Software, and to
111a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * permit persons to whom the Software is furnished to do so, subject to
121a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * the following conditions:
131a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
141a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * The above copyright notice and this permission notice (including the
151a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * next paragraph) shall be included in all copies or substantial portions
161a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * of the Software.
171a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
181a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
191a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
201a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
221a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
231a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
241a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
261a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca **************************************************************************/
271a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
281a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
291a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * \file
301a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Vertex buffer drawing stage.
311a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca *
32877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * \author Jose Fonseca <jfonseca@vmware.com>
33877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * \author Keith Whitwell <keithw@vmware.com>
341a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
351a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
361a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
37ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h"
384f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
394f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
401a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
4109059259bed779360158664625e41a67f7496a74José Fonseca#include "draw_vbuf.h"
4209059259bed779360158664625e41a67f7496a74José Fonseca#include "draw_private.h"
4309059259bed779360158664625e41a67f7496a74José Fonseca#include "draw_vertex.h"
44507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
45cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell#include "translate/translate.h"
461a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell#include "translate/translate_cache.h"
4709059259bed779360158664625e41a67f7496a74José Fonseca
481a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
491a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
501a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Vertex buffer emit stage.
511a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
521a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastruct vbuf_stage {
531a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct draw_stage stage; /**< This must be first (base class) */
541a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
551a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct vbuf_render *render;
561a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
573b93c74a8d6e36039b79ddf38c11e27aa0bd3b9bJosé Fonseca   const struct vertex_info *vinfo;
583b93c74a8d6e36039b79ddf38c11e27aa0bd3b9bJosé Fonseca
591a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   /** Vertex size in bytes */
601a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned vertex_size;
611a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
62cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   struct translate *translate;
6309059259bed779360158664625e41a67f7496a74José Fonseca
641a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   /* FIXME: we have no guarantee that 'unsigned' is 32bit */
651a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
661a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   /** Vertices in hardware format */
671a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned *vertices;
681a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned *vertex_ptr;
691a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned max_vertices;
701a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned nr_vertices;
711a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
721a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   /** Indices */
731a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   ushort *indices;
741a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned max_indices;
751a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned nr_indices;
761a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
77afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   /* Cache point size somewhere its address won't change:
78cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    */
79cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   float point_size;
80afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   float zero4[4];
811a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell
821a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell   struct translate_cache *cache;
831a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca};
841a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
851a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
861a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
871a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Basically a cast wrapper.
881a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
89a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline struct vbuf_stage *
901a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_stage( struct draw_stage *stage )
911a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
921a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   assert(stage);
931a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   return (struct vbuf_stage *)stage;
941a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
951a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
961a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
97c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonsecastatic void vbuf_flush_vertices( struct vbuf_stage *vbuf );
98c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonsecastatic void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
991a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1001a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
101a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline boolean
1021a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecaoverflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )
1031a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
1041a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned long used = (unsigned long) ((char *)ptr - (char *)map);
1051a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   return (used + bytes) > bufsz;
1061a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
1071a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1081a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
109a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1101a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecacheck_space( struct vbuf_stage *vbuf, unsigned nr )
1111a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
112befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if (vbuf->nr_vertices + nr > vbuf->max_vertices ||
113befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell       vbuf->nr_indices + nr > vbuf->max_indices)
114befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   {
115befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      vbuf_flush_vertices( vbuf );
116befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      vbuf_alloc_vertices( vbuf );
117d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul   }
1181a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
1191a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1201a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
121f94425b316b57ad19ce067a449b20ebee50064f9José Fonseca
122f94425b316b57ad19ce067a449b20ebee50064f9José Fonseca
1231a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
12459e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * Extract the needed fields from post-transformed vertex and emit
12559e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * a hardware(driver) vertex.
1261a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Recall that the vertices are constructed by the 'draw' module and
1271a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * have a couple of slots at the beginning (1-dword header, 4-dword
12859e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * clip pos) that we ignore here.  We only use the vertex->data[] fields.
1291a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
130a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline ushort
1311a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecaemit_vertex( struct vbuf_stage *vbuf,
1321a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca             struct vertex_header *vertex )
1331a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
134aa661306828b8c76c1511f05e0fae577f06477b8Brian Paul   if (vertex->vertex_id == UNDEFINED_VERTEX_ID && vbuf->vertex_ptr) {
135cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      /* Hmm - vertices are emitted one at a time - better make sure
136cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell       * set_buffer is efficient.  Consider a special one-shot mode for
137cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell       * translate.
138cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell       */
1392161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      /* Note: we really do want data[0] here, not data[pos]:
1402161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell       */
1412a30d3d74a0b87f8066659952628ccd072a4e2b0José Fonseca      vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0, ~0);
1421c2e5c223da28cdffe156b6b430fcdf638909021Zack Rusin      vbuf->translate->run(vbuf->translate, 0, 1, 0, 0, vbuf->vertex_ptr);
143cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
14443be7a4819ad342e1cb3f8e3fb966a8a78dc2c1bKeith Whitwell      if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr);
1451a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
146cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      vbuf->vertex_ptr += vbuf->vertex_size/4;
147cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      vertex->vertex_id = vbuf->nr_vertices++;
148cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   }
149909e8ce543a6c1e97d55791d2069cbdc56ea9db6Keith Whitwell
1508808d62f608d1397ee75d0087301d0b0a0278244José Fonseca   return (ushort)vertex->vertex_id;
15109059259bed779360158664625e41a67f7496a74José Fonseca}
15209059259bed779360158664625e41a67f7496a74José Fonseca
15309059259bed779360158664625e41a67f7496a74José Fonseca
1541a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
1551a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_tri( struct draw_stage *stage,
1561a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca          struct prim_header *prim )
1571a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
1581a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
1591a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned i;
1601a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1611a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   check_space( vbuf, 3 );
1621a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
163cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   for (i = 0; i < 3; i++) {
164cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
1651a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   }
1661a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
1671a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1681a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1691a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
1701a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_line( struct draw_stage *stage,
1711a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca           struct prim_header *prim )
1721a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
1731a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
1741a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   unsigned i;
1751a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1761a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   check_space( vbuf, 2 );
1771a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1781a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   for (i = 0; i < 2; i++) {
179cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
1801a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   }
1811a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
1821a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1831a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1841a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
1851a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_point( struct draw_stage *stage,
1861a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca            struct prim_header *prim )
1871a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
1881a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
1891a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1901a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   check_space( vbuf, 1 );
1911a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
192cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] );
1931a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
1941a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
1951a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
196cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
197cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
19859e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul/**
19959e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * Set the prim type for subsequent vertices.
20059e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * This may result in a new vertex size.  The existing vbuffer (if any)
20159e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul * will be flushed if needed and a new one allocated.
20259e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul */
20359e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paulstatic void
204befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwellvbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
20559e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul{
206cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   struct translate_key hw_key;
207cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   unsigned dst_offset;
208cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   unsigned i;
209afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   const struct vertex_info *vinfo;
21059e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul
211cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   vbuf->render->set_primitive(vbuf->render, prim);
21259e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul
213cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   /* Must do this after set_primitive() above:
214cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    *
215cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    * XXX: need some state managment to track when this needs to be
216cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    * recalculated.  The driver should tell us whether there was a
217cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    * state change.
218cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    */
219cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
220afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   vinfo = vbuf->vinfo;
221afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   vbuf->vertex_size = vinfo->size * sizeof(float);
22259e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul
223cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   /* Translate from pipeline vertices to hw vertices.
224cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    */
225cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   dst_offset = 0;
226cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
227afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   for (i = 0; i < vinfo->num_attribs; i++) {
228cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      unsigned emit_sz = 0;
229cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      unsigned src_buffer = 0;
230b609cfc7c9c38f26e7e6d6f7dd5dd6d38f4ed209José Fonseca      enum pipe_format output_format;
231afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
232cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
233afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
234afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
23584a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz
23684a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz      /* doesn't handle EMIT_OMIT */
23784a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz      assert(emit_sz != 0);
23884a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz
239afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
240afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger         src_buffer = 1;
241afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger         src_offset = 0;
242afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      }
243afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      else if (vinfo->attrib[i].src_index == DRAW_ATTR_NONEXIST) {
244afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger         /* elements which don't exist will get assigned zeros */
245afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger         src_buffer = 2;
246afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger         src_offset = 0;
247cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      }
248543b9566bdaa48fea2df1866fa1310c1cdbcde27Michal Krol
249543b9566bdaa48fea2df1866fa1310c1cdbcde27Michal Krol      hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
250cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
251cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      hw_key.element[i].input_buffer = src_buffer;
252cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      hw_key.element[i].input_offset = src_offset;
2537ca0ce38340144794267609646048b3820d594abMichal Krol      hw_key.element[i].instance_divisor = 0;
254cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      hw_key.element[i].output_format = output_format;
255cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      hw_key.element[i].output_offset = dst_offset;
256cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
257cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell      dst_offset += emit_sz;
258cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   }
259cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
260afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   hw_key.nr_elements = vinfo->num_attribs;
2612e46a1dcb33618f2873ebaaeb3ffe238f11a31a3Zack Rusin   hw_key.output_stride = vbuf->vertex_size;
262cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
263cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   /* Don't bother with caching at this stage:
264cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    */
265cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   if (!vbuf->translate ||
2661a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell       translate_key_compare(&vbuf->translate->key, &hw_key) != 0)
267cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   {
2681a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell      translate_key_sanitize(&hw_key);
2691a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell      vbuf->translate = translate_cache_find(vbuf->cache, &hw_key);
270cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
2712a30d3d74a0b87f8066659952628ccd072a4e2b0José Fonseca      vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0, ~0);
272afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger      vbuf->translate->set_buffer(vbuf->translate, 2, &vbuf->zero4[0], 0, ~0);
273cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   }
274cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
275cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   vbuf->point_size = vbuf->stage.draw->rasterizer->point_size;
276cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell
277cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell   /* Allocate new buffer?
278cb9f0a589623397c3437911aeef39f189213527aKeith Whitwell    */
279befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   assert(vbuf->vertices == NULL);
280befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_alloc_vertices(vbuf);
28159e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul}
28259e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul
28359e8f3e5e91f27c5d12b810375247fb1ddea68feBrian Paul
2841a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
2851a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_first_tri( struct draw_stage *stage,
2861a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca                struct prim_header *prim )
2871a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
288c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
289c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca
290befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_flush_vertices( vbuf );
291befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_start_prim(vbuf, PIPE_PRIM_TRIANGLES);
2921a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   stage->tri = vbuf_tri;
293d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul   stage->tri( stage, prim );
2941a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
2951a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
2961a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
2971a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
2981a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_first_line( struct draw_stage *stage,
2991a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca                 struct prim_header *prim )
3001a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
301c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
302c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca
303befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_flush_vertices( vbuf );
304befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_start_prim(vbuf, PIPE_PRIM_LINES);
3051a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   stage->line = vbuf_line;
306d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul   stage->line( stage, prim );
3071a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
3081a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3091a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3101a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
3111a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_first_point( struct draw_stage *stage,
3121a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca                  struct prim_header *prim )
3131a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
314c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
315c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca
316befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_flush_vertices(vbuf);
317befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_start_prim(vbuf, PIPE_PRIM_POINTS);
3181a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   stage->point = vbuf_point;
319d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul   stage->point( stage, prim );
3201a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
3211a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3221a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3231a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3241a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
3251a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Flush existing vertex buffer and allocate a new one.
3261a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
3271a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
328c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonsecavbuf_flush_vertices( struct vbuf_stage *vbuf )
3291a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
330befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if(vbuf->vertices) {
331befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
3321c4f67b980b6bec5788336a9cdd18c4fcec5e492Keith Whitwell      vbuf->render->unmap_vertices( vbuf->render, 0, vbuf->nr_vertices - 1 );
333befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
334befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      if (vbuf->nr_indices)
335befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      {
336740e50c60f03d194aafab93d5251699964800979Brian Paul         vbuf->render->draw_elements(vbuf->render,
337740e50c60f03d194aafab93d5251699964800979Brian Paul                                     vbuf->indices,
338740e50c60f03d194aafab93d5251699964800979Brian Paul                                     vbuf->nr_indices );
339befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
340befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell         vbuf->nr_indices = 0;
341befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      }
342befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
3431a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca      /* Reset temporary vertices ids */
3441a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca      if(vbuf->nr_vertices)
3451a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca	 draw_reset_vertex_ids( vbuf->stage.draw );
3461a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3471a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca      /* Free the vertex buffer */
348befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      vbuf->render->release_vertices( vbuf->render );
349befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
3503b93c74a8d6e36039b79ddf38c11e27aa0bd3b9bJosé Fonseca      vbuf->max_vertices = vbuf->nr_vertices = 0;
3511a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca      vbuf->vertex_ptr = vbuf->vertices = NULL;
3521a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   }
353931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul
354931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul   /* Reset point/line/tri function pointers.
355931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul    * If (for example) we transition from points to tris and back to points
356931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul    * again, we need to call the vbuf_first_point() function again to flush
357931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul    * the triangles before drawing more points.  This can happen when drawing
358931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul    * with front polygon mode = filled and back polygon mode = line or point.
359931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul    */
360931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul   vbuf->stage.point = vbuf_first_point;
361931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul   vbuf->stage.line = vbuf_first_line;
362931432fea69c29b4029ff23613468c8ad2c0181eBrian Paul   vbuf->stage.tri = vbuf_first_tri;
363d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul}
3641a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
365d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul
366d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paulstatic void
367c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonsecavbuf_alloc_vertices( struct vbuf_stage *vbuf )
368d11fd189ff84ec24df0fb988e5c3e1a9260e038cBrian Paul{
369aa661306828b8c76c1511f05e0fae577f06477b8Brian Paul   if (vbuf->vertex_ptr) {
370aa661306828b8c76c1511f05e0fae577f06477b8Brian Paul      assert(!vbuf->nr_indices);
371aa661306828b8c76c1511f05e0fae577f06477b8Brian Paul      assert(!vbuf->vertices);
372aa661306828b8c76c1511f05e0fae577f06477b8Brian Paul   }
3731a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3741a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   /* Allocate a new vertex buffer */
3751a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
3760a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell
377874f364e9ea3a03d29ae4b6e1c7e2843ef8b9e79José Fonseca   if(vbuf->max_vertices >= UNDEFINED_VERTEX_ID)
378874f364e9ea3a03d29ae4b6e1c7e2843ef8b9e79José Fonseca      vbuf->max_vertices = UNDEFINED_VERTEX_ID - 1;
379874f364e9ea3a03d29ae4b6e1c7e2843ef8b9e79José Fonseca
3800a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell   /* Must always succeed -- driver gives us a
3810a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell    * 'max_vertex_buffer_bytes' which it guarantees it can allocate,
3820a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell    * and it will flush itself if necessary to do so.  If this does
3830a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell    * fail, we are basically without usable hardware.
3840a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell    */
385befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf->render->allocate_vertices(vbuf->render,
386befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                   (ushort) vbuf->vertex_size,
387befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                   (ushort) vbuf->max_vertices);
388befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
389befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf->vertices = (uint *) vbuf->render->map_vertices( vbuf->render );
390befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
3911a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->vertex_ptr = vbuf->vertices;
3921a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
3931a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3941a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3951a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
3961a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
3970bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulvbuf_flush( struct draw_stage *stage, unsigned flags )
3981a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
399c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca   struct vbuf_stage *vbuf = vbuf_stage( stage );
400c3f10aef386e0af90f8735d8b9598959c17a590fJosé Fonseca
401befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   vbuf_flush_vertices( vbuf );
4021a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
4031a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
4041a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
4051a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastatic void
4061a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecavbuf_reset_stipple_counter( struct draw_stage *stage )
4071a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
4081603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul   /* XXX: Need to do something here for hardware with linestipple.
4091603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    */
410f1fb69a6e52260193ec16a9820a66e3e4bb03eddBrian Paul   (void) stage;
4111a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
4121a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
4131a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
414d75454840672f462de933724daae24a839aac48eMichal Krolstatic void vbuf_destroy( struct draw_stage *stage )
415d75454840672f462de933724daae24a839aac48eMichal Krol{
416d75454840672f462de933724daae24a839aac48eMichal Krol   struct vbuf_stage *vbuf = vbuf_stage( stage );
417d75454840672f462de933724daae24a839aac48eMichal Krol
41809059259bed779360158664625e41a67f7496a74José Fonseca   if(vbuf->indices)
41909059259bed779360158664625e41a67f7496a74José Fonseca      align_free( vbuf->indices );
42009059259bed779360158664625e41a67f7496a74José Fonseca
42119780237ff0e6a89f31ecb9079781568bc2d3fdcMichal Krol   if (vbuf->render)
42219780237ff0e6a89f31ecb9079781568bc2d3fdcMichal Krol      vbuf->render->destroy( vbuf->render );
42319780237ff0e6a89f31ecb9079781568bc2d3fdcMichal Krol
4241a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell   if (vbuf->cache)
4251a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell      translate_cache_destroy(vbuf->cache);
4261a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell
427d75454840672f462de933724daae24a839aac48eMichal Krol   FREE( stage );
428d75454840672f462de933724daae24a839aac48eMichal Krol}
429d75454840672f462de933724daae24a839aac48eMichal Krol
430d75454840672f462de933724daae24a839aac48eMichal Krol
4311a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca/**
4321a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca * Create a new primitive vbuf/render stage.
4331a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca */
4341a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonsecastruct draw_stage *draw_vbuf_stage( struct draw_context *draw,
4351a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca                                    struct vbuf_render *render )
4361a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca{
4371a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
438150c289f6067cb1ba4572f9124948a94ef94c839Edward O'Callaghan   if (!vbuf)
439d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell      goto fail;
440afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
4411a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->stage.draw = draw;
442eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   vbuf->stage.name = "vbuf";
4431a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->stage.point = vbuf_first_point;
4441a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->stage.line = vbuf_first_line;
4451a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->stage.tri = vbuf_first_tri;
4460bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   vbuf->stage.flush = vbuf_flush;
4471a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
448d75454840672f462de933724daae24a839aac48eMichal Krol   vbuf->stage.destroy = vbuf_destroy;
449afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
4501a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->render = render;
4513c56280d330f50025fc948041f1413af55c50581Kurt Daverman   vbuf->max_indices = MIN2(render->max_indices, UNDEFINED_VERTEX_ID-1);
4521a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca
453afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   vbuf->indices = (ushort *) align_malloc(vbuf->max_indices *
454afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger                    sizeof(vbuf->indices[0]),
455afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger                    16);
4560d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (!vbuf->indices)
457d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell      goto fail;
4581a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell
4591a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell   vbuf->cache = translate_cache_create();
460afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   if (!vbuf->cache)
4611a03812fb57e956b438cd42ac68978facb49a99dKeith Whitwell      goto fail;
462afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
4631a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->vertices = NULL;
4641a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   vbuf->vertex_ptr = vbuf->vertices;
465afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
466afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger   vbuf->zero4[0] = vbuf->zero4[1] = vbuf->zero4[2] = vbuf->zero4[3] = 0.0f;
467afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
4681a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca   return &vbuf->stage;
469d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell
470afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheideggerfail:
471d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell   if (vbuf)
472d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell      vbuf_destroy(&vbuf->stage);
473afa035031ff9e0c07a2297d864e46c76f7bfff58Roland Scheidegger
474d8c389171872b69af3c94ebab02ad5f4bcd2d4dfKeith Whitwell   return NULL;
4751a8daf0627dde44aaa7c40786782618d4d5a6a36José Fonseca}
476