1dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca/**************************************************************************
2dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
3dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * All Rights Reserved.
5dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
6dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
7dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * copy of this software and associated documentation files (the
8dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * "Software"), to deal in the Software without restriction, including
9dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish,
10dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to
11dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to
12dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * the following conditions:
13dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
14dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * The above copyright notice and this permission notice (including the
15dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * next paragraph) shall be included in all copies or substantial portions
16dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * of the Software.
17dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
18dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
26dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca **************************************************************************/
27dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
28dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca/**
29dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * \file
30dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * Build post-transformation, post-clipping vertex buffers and element
31dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * lists by hooking into the end of the primitive pipeline and
32dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * manipulating the vertex_id field in the vertex headers.
33dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
34dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * XXX: work in progress
35dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca *
36dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * \author José Fonseca <jrfonseca@tungstengraphics.com>
37dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * \author Keith Whitwell <keith@tungstengraphics.com>
38dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca */
39dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
40dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
419b3c1582befd0c64d9b48f7ed39566f9ae2e24d9Michal Krol#include "draw/draw_context.h"
426acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "draw/draw_vbuf.h"
43ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h"
4428486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
464f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
47d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz#include "util/u_fifo.h"
48dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
49dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca#include "i915_context.h"
5046aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca#include "i915_reg.h"
5146aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca#include "i915_batch.h"
5246aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca#include "i915_state.h"
53dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
54dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
55ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz#define VBUF_MAP_BUFFER
56030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz
57dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca/**
589924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca * Primitive renderer for i915.
59dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca */
609924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastruct i915_vbuf_render {
619924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct vbuf_render base;
629924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca
63bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   struct i915_context *i915;
64dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
6513acc263859a4b4689f519be8b5519c784baf3baJosé Fonseca   /** Vertex size in bytes */
6616a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   size_t vertex_size;
6713acc263859a4b4689f519be8b5519c784baf3baJosé Fonseca
6808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   /** Software primitive */
6908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned prim;
7008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
719924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   /** Hardware primitive */
729924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   unsigned hwprim;
7308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
7408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   /** Genereate a vertex list */
7508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned fallback;
76cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
77cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz   /* Stuff for the vbo */
78bc88c95990f871a206a8fe93e7541f1f41841f7eJakob Bornecrantz   struct i915_winsys_buffer *vbo;
79030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   size_t vbo_size; /**< current size of allocated buffer */
80030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   size_t vbo_alloc_size; /**< minimum buffer size to allocate */
81ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   size_t vbo_hw_offset; /**< offset that we program the hardware with */
82ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   size_t vbo_sw_offset; /**< offset that we work with */
83ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   size_t vbo_index; /**< index offset to be added to all indices */
84cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz   void *vbo_ptr;
8516a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   size_t vbo_max_used;
86ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   size_t vbo_max_index; /**< index offset to be added to all indices */
87d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz
880f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#ifndef VBUF_MAP_BUFFER
890f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   size_t map_used_start;
900f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   size_t map_used_end;
910f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   size_t map_size;
920f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#endif
93dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca};
94dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
95dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
96dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca/**
97dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * Basically a cast wrapper.
98dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca */
999924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic INLINE struct i915_vbuf_render *
100bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render(struct vbuf_render *render)
101dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
1029924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   assert(render);
1039924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   return (struct i915_vbuf_render *)render;
104dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
105dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
106ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
107ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * If vbo state differs between renderer and context
108ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * push state to the context. This function pushes
109ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * hw_offset to i915->vbo_offset and vbo to i915->vbo.
110ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
111ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
112ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    May updates context vbo_offset and vbo fields.
113ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
1144dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantzstatic void
1154dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantzi915_vbuf_update_vbo_state(struct vbuf_render *render)
1164dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz{
1174dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
1184dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
1194dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz
1204dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   if (i915->vbo != i915_render->vbo ||
121ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz       i915->vbo_offset != i915_render->vbo_hw_offset) {
1224dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz      i915->vbo = i915_render->vbo;
123ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      i915->vbo_offset = i915_render->vbo_hw_offset;
1244dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz      i915->dirty |= I915_NEW_VBO;
1254dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   }
1264dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz}
1274dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz
128ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
129ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Callback exported to the draw module.
130ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Returns the current vertex_info.
131ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
132ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
133ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    If state is dirty update derived state.
134ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
1359924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic const struct vertex_info *
136bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_get_vertex_info(struct vbuf_render *render)
137dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
1389924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
1399924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_context *i915 = i915_render->i915;
14092650aeaddd1bd729f3a90383f05c8148f678066Brian
14192650aeaddd1bd729f3a90383f05c8148f678066Brian   if (i915->dirty) {
14292650aeaddd1bd729f3a90383f05c8148f678066Brian      /* make sure we have up to date vertex layout */
143bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_update_derived(i915);
14492650aeaddd1bd729f3a90383f05c8148f678066Brian   }
14592650aeaddd1bd729f3a90383f05c8148f678066Brian
1469924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   return &i915->current.vertex_info;
147dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
148dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
149ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
150ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Reserve space in the vbo for vertices.
151ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
152ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
153ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    None.
154ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
15516a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantzstatic boolean
156d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantzi915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
157d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz{
158d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
159d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
160ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   if (i915_render->vbo_size < size + i915_render->vbo_sw_offset)
161d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz      return FALSE;
162d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
163d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   if (i915->vbo_flushed)
164d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz      return FALSE;
165d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
166d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   return TRUE;
167d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz}
168d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
169ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
170ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Allocate a new vbo buffer should there not be enough space for
171ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * the requested number of vertices by the draw module.
172ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
173ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
174ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    Updates hw_offset, sw_offset, index and allocates a new buffer.
175de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz *    Will set i915->vbo to null on buffer allocation.
176ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
177d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantzstatic void
178d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantzi915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
179d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz{
180d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
181bc88c95990f871a206a8fe93e7541f1f41841f7eJakob Bornecrantz   struct i915_winsys *iws = i915->iws;
182d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
183de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz   if (i915_render->vbo) {
1848af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz      iws->buffer_unmap(iws, i915_render->vbo);
185030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz      iws->buffer_destroy(iws, i915_render->vbo);
186de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz      /*
187de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz       * XXX If buffers where referenced then this should be done in
188de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz       * update_vbo_state but since they arn't and malloc likes to reuse
189de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz       * memory we need to set it to null
190de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz       */
191de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz      i915->vbo = NULL;
192de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz      i915_render->vbo = NULL;
193de3ff5af49369d187d88e5399f388c6e48c5384fJakob Bornecrantz   }
194d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
195d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   i915->vbo_flushed = 0;
196d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
197030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
198ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_hw_offset = 0;
199ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_sw_offset = 0;
200ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_index = 0;
201d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
2020f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#ifndef VBUF_MAP_BUFFER
2030f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   if (i915_render->vbo_size > i915_render->map_size) {
2040f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz      i915_render->map_size = i915_render->vbo_size;
2050f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz      FREE(i915_render->vbo_ptr);
2060f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz      i915_render->vbo_ptr = MALLOC(i915_render->map_size);
2070f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   }
2080f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#endif
2090f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz
210030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
211c62f5c7e7bc3ed84677805b3800fbcfa93c419eaDaniel Vetter                                         I915_NEW_VERTEX);
2128af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
213d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz}
214d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
215ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
216ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Callback exported to the draw module.
217ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
218ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
219ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    Updates hw_offset, sw_offset, index and may allocate
220ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    a new buffer. Also updates may update the vbo state
221ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    on the i915 context.
222ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
223d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantzstatic boolean
224bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_allocate_vertices(struct vbuf_render *render,
225bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                                   ushort vertex_size,
226bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                                   ushort nr_vertices)
227dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
2289924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
2299924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   size_t size = (size_t)vertex_size * (size_t)nr_vertices;
230ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   size_t offset;
231ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
232ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   /*
233ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * Align sw_offset with first multiple of vertex size from hw_offset.
234ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * Set index to be the multiples from from hw_offset to sw_offset.
235ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * i915_vbuf_render_new_buf will reset index, sw_offset, hw_offset
236ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * when it allocates a new buffer this is correct.
237ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    */
238ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   {
239ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      offset = i915_render->vbo_sw_offset - i915_render->vbo_hw_offset;
240ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      offset = util_align_npot(offset, vertex_size);
241ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      i915_render->vbo_sw_offset = i915_render->vbo_hw_offset + offset;
242ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      i915_render->vbo_index = offset / vertex_size;
243ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   }
244dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
245255d4f24e063d18cdfbd186b7bcc8a2298d93369Jakob Bornecrantz   if (!i915_vbuf_render_reserve(i915_render, size))
246d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz      i915_vbuf_render_new_buf(i915_render, size);
247cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
248ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   /*
249ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * If a new buffer has been alocated sw_offset,
250ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    * hw_offset & index will be reset by new_buf
251ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz    */
252ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
25316a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   i915_render->vertex_size = vertex_size;
2544dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz
2554dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   i915_vbuf_update_vbo_state(render);
25608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
25716a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   if (!i915_render->vbo)
25816a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz      return FALSE;
25916a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   return TRUE;
26016a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz}
26116a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz
26216a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantzstatic void *
263bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_map_vertices(struct vbuf_render *render)
26416a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz{
26516a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
26616a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
26716a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz
26816a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   if (i915->vbo_flushed)
26960f3f22a52422b11cc71149a28e24a14a9251205Vinson Lee      debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__);
27016a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz
2710f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#ifdef VBUF_MAP_BUFFER
272ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_sw_offset;
2730f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#else
2740f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   return (unsigned char *)i915_render->vbo_ptr;
2750f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#endif
276dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
277dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
27816a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantzstatic void
279bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_unmap_vertices(struct vbuf_render *render,
280bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                                ushort min_index,
281bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                                ushort max_index)
28216a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz{
28316a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
28416a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
285bc88c95990f871a206a8fe93e7541f1f41841f7eJakob Bornecrantz   struct i915_winsys *iws = i915->iws;
28616a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz
287ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_max_index = max_index;
28816a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
2890f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#ifdef VBUF_MAP_BUFFER
2908af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   (void)iws;
2910f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#else
2920f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->map_used_start = i915_render->vertex_size * min_index;
2930f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->map_used_end = i915_render->vertex_size * (max_index + 1);
2940f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   iws->buffer_write(iws, i915_render->vbo,
295ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz                     i915_render->map_used_start + i915_render->vbo_sw_offset,
2960f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz                     i915_render->map_used_end - i915_render->map_used_start,
2970083d2e40a8b0aa9ea36f98d4b6b7981d5dca0e3Vinson Lee                     (unsigned char *)i915_render->vbo_ptr + i915_render->map_used_start);
2980f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz
2990f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#endif
30016a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz}
301dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
302ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz/**
303ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Ensure that the given max_index given is not larger ushort max.
304ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * If it is larger then ushort max it advanced the hw_offset to the
305ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * same position in the vbo as sw_offset and set index to zero.
306ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *
307ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz * Side effects:
308ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz *    On failure update hw_offset and index.
309ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz */
310ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantzstatic void
311ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantzi915_vbuf_ensure_index_bounds(struct vbuf_render *render,
312ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz                              unsigned max_index)
313ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz{
314ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
315ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
316ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   if (max_index + i915_render->vbo_index < ((1 << 17) - 1))
317ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      return;
318ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
319ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_hw_offset = i915_render->vbo_sw_offset;
320ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_index = 0;
321ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
322ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_vbuf_update_vbo_state(render);
323ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz}
324ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
325488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paulstatic void
326bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_set_primitive(struct vbuf_render *render,
327bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                               unsigned prim)
328dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
3299924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
33008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   i915_render->prim = prim;
33108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
3329924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   switch(prim) {
33346aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   case PIPE_PRIM_POINTS:
3349924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      i915_render->hwprim = PRIM3D_POINTLIST;
33508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = 0;
336488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
33746aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   case PIPE_PRIM_LINES:
3389924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      i915_render->hwprim = PRIM3D_LINELIST;
33908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = 0;
340488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
341e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_LINE_LOOP:
342e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->hwprim = PRIM3D_LINELIST;
343e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->fallback = PIPE_PRIM_LINE_LOOP;
344488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
34508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_LINE_STRIP:
34608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->hwprim = PRIM3D_LINESTRIP;
34708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = 0;
348488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
34946aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   case PIPE_PRIM_TRIANGLES:
3509924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      i915_render->hwprim = PRIM3D_TRILIST;
35108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = 0;
352488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
35308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_TRIANGLE_STRIP:
35408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->hwprim = PRIM3D_TRISTRIP;
35508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = 0;
356488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
357e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_TRIANGLE_FAN:
358e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->hwprim = PRIM3D_TRIFAN;
359e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->fallback = 0;
360488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
36108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUADS:
36208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->hwprim = PRIM3D_TRILIST;
36308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = PIPE_PRIM_QUADS;
364488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
36508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUAD_STRIP:
36608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->hwprim = PRIM3D_TRILIST;
36708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      i915_render->fallback = PIPE_PRIM_QUAD_STRIP;
368488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
369e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_POLYGON:
370e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->hwprim = PRIM3D_POLY;
371e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      i915_render->fallback = 0;
372488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      break;
37346aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   default:
37443d70a12d4cc2b930cc7e1bb1eb68326ed3697e9José Fonseca      /* FIXME: Actually, can handle a lot more just fine... */
375488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul      assert(0 && "unexpected prim in i915_vbuf_render_set_primitive()");
37646aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   }
3779924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca}
3789924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca
37908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz/**
38008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz * Used for fallbacks in draw_arrays
38108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz */
38208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic void
383bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzdraw_arrays_generate_indices(struct vbuf_render *render,
384bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                             unsigned start, uint nr,
385bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                             unsigned type)
38608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
38708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
38808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
38908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned i;
390ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   unsigned end = start + nr + i915_render->vbo_index;
391ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   start += i915_render->vbo_index;
392ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
39308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   switch(type) {
39408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case 0:
39508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = start; i+1 < end; i += 2)
396bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+0) | (i+1) << 16);
39708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      if (i < end)
398bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH(i);
39908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
400e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_LINE_LOOP:
401e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      if (nr >= 2) {
402bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         for (i = start + 1; i < end; i++)
40313632e64a0da67149d81bef2da42f159f8ddb1eaFatih Aşıcı            OUT_BATCH((i-1) | (i+0) << 16);
40413632e64a0da67149d81bef2da42f159f8ddb1eaFatih Aşıcı         OUT_BATCH((i-1) | ( start) << 16);
405e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      }
406e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      break;
40708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUADS:
40808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = start; i + 3 < end; i += 4) {
409bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+0) | (i+1) << 16);
410bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+3) | (i+1) << 16);
411bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+2) | (i+3) << 16);
41208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
41308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
41408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUAD_STRIP:
41508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = start; i + 3 < end; i += 2) {
416bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+0) | (i+1) << 16);
417bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+3) | (i+2) << 16);
418bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         OUT_BATCH((i+0) | (i+3) << 16);
41908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
42008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
42108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   default:
42208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      assert(0);
42308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
42408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
42508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
42608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic unsigned
427bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzdraw_arrays_calc_nr_indices(uint nr, unsigned type)
42808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
42908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   switch (type) {
43008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case 0:
43108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return nr;
432e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_LINE_LOOP:
433e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      if (nr >= 2)
434bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         return nr * 2;
435e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      else
436bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         return 0;
43708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUADS:
43808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return (nr / 4) * 6;
43908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUAD_STRIP:
44008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return ((nr - 2) / 2) * 6;
44108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   default:
44208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      assert(0);
44308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return 0;
44408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
44508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
44608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
44708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic void
448bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzdraw_arrays_fallback(struct vbuf_render *render,
449bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                     unsigned start,
450bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                     uint nr)
45108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
45208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
45308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
45408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned nr_indices;
45508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
456ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback);
457ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   if (!nr_indices)
458ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz      return;
459ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
460ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_vbuf_ensure_index_bounds(render, start + nr_indices);
461ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
46208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   if (i915->dirty)
463bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_update_derived(i915);
46408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
46508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   if (i915->hardware_dirty)
466bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_emit_hardware_state(i915);
46708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
4688f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter   if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
46908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      FLUSH_BATCH(NULL);
47008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
47108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      /* Make sure state is re-emitted after a flush:
47208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz       */
473bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_emit_hardware_state(i915);
474cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz      i915->vbo_flushed = 1;
47508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
4768f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter      if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
477bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         assert(0);
478bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         goto out;
47908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
48008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
4814dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz
482bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   OUT_BATCH(_3DPRIMITIVE |
483bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             PRIM_INDIRECT |
484bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             i915_render->hwprim |
485bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             PRIM_INDIRECT_ELTS |
486bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             nr_indices);
48708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
488bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   draw_arrays_generate_indices(render, start, nr, i915_render->fallback);
489cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
49008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzout:
491cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz   return;
49208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
49308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
49408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic void
495bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_draw_arrays(struct vbuf_render *render,
496bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                             unsigned start,
497bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                             uint nr)
49808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
49908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
50048c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
50108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
50208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   if (i915_render->fallback) {
503bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      draw_arrays_fallback(render, start, nr);
50408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return;
50508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
50608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
507ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_vbuf_ensure_index_bounds(render, start + nr);
508ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   start += i915_render->vbo_index;
509ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
51048c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   if (i915->dirty)
51148c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      i915_update_derived(i915);
51248c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
51348c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   if (i915->hardware_dirty)
51448c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      i915_emit_hardware_state(i915);
51548c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
5168f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter   if (!BEGIN_BATCH(2)) {
51748c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      FLUSH_BATCH(NULL);
51848c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
51948c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      /* Make sure state is re-emitted after a flush:
52048c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz       */
52148c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      i915_emit_hardware_state(i915);
52248c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      i915->vbo_flushed = 1;
52348c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
5248f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter      if (!BEGIN_BATCH(2)) {
52548c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz         assert(0);
52648c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz         goto out;
52748c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz      }
52848c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   }
52948c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
53048c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   OUT_BATCH(_3DPRIMITIVE |
53148c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz             PRIM_INDIRECT |
53248c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz             PRIM_INDIRECT_SEQUENTIAL |
53348c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz             i915_render->hwprim |
53448c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz             nr);
53548c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   OUT_BATCH(start); /* Beginning vertex index */
53648c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz
53748c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantzout:
53848c45959ee106727fe9dd2d57bc0ca278710aab8Jakob Bornecrantz   return;
53908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
54008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
54108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz/**
54208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz * Used for normal and fallback emitting of indices
54308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz * If type is zero normal operation assumed.
54408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz */
54508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic void
546bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzdraw_generate_indices(struct vbuf_render *render,
547bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                      const ushort *indices,
548bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                      uint nr_indices,
549bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                      unsigned type)
55008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
55108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
55208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
55308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned i;
554ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   unsigned o = i915_render->vbo_index;
55508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
55608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   switch(type) {
55708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case 0:
55808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = 0; i + 1 < nr_indices; i += 2) {
559ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i]) | (o+indices[i+1]) << 16);
56008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
56108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      if (i < nr_indices) {
562ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i]));
56308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
56408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
565e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_LINE_LOOP:
566e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      if (nr_indices >= 2) {
567bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         for (i = 1; i < nr_indices; i++)
568ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz            OUT_BATCH((o+indices[i-1]) | (o+indices[i]) << 16);
569ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i-1]) | (o+indices[0]) << 16);
570e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      }
571e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      break;
57208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUADS:
57308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = 0; i + 3 < nr_indices; i += 4) {
574ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16);
575ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+3]) | (o+indices[i+1]) << 16);
576ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+2]) | (o+indices[i+3]) << 16);
57708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
57808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
57908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUAD_STRIP:
58008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      for (i = 0; i + 3 < nr_indices; i += 2) {
581ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16);
582ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+3]) | (o+indices[i+2]) << 16);
583ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz         OUT_BATCH((o+indices[i+0]) | (o+indices[i+3]) << 16);
58408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      }
58508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
58608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   default:
58708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      assert(0);
58808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      break;
58908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
59008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
59108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
59208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzstatic unsigned
593bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzdraw_calc_nr_indices(uint nr_indices, unsigned type)
59408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz{
59508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   switch (type) {
59608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case 0:
59708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return nr_indices;
598e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   case PIPE_PRIM_LINE_LOOP:
599e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      if (nr_indices >= 2)
600bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         return nr_indices * 2;
601e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      else
602bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         return 0;
60308130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUADS:
60408130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return (nr_indices / 4) * 6;
60508130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   case PIPE_PRIM_QUAD_STRIP:
60608130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return ((nr_indices - 2) / 2) * 6;
60708130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   default:
60808130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      assert(0);
60908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz      return 0;
61008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   }
61108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz}
61208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
6139924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic void
614740e50c60f03d194aafab93d5251699964800979Brian Pauli915_vbuf_render_draw_elements(struct vbuf_render *render,
615740e50c60f03d194aafab93d5251699964800979Brian Paul                               const ushort *indices,
616740e50c60f03d194aafab93d5251699964800979Brian Paul                               uint nr_indices)
6179924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca{
6189924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
6199924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_context *i915 = i915_render->i915;
62008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   unsigned save_nr_indices;
62108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
62208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   save_nr_indices = nr_indices;
6239924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca
624bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback);
625e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz   if (!nr_indices)
626e9b8df69b40c55953e1b3503690b54f993773223Jakob Bornecrantz      return;
62713acc263859a4b4689f519be8b5519c784baf3baJosé Fonseca
628ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_vbuf_ensure_index_bounds(render, i915_render->vbo_max_index);
629ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz
63046aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   if (i915->dirty)
631bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_update_derived(i915);
63246aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca
63346aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   if (i915->hardware_dirty)
634bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_emit_hardware_state(i915);
63546aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca
6368f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter   if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
6374abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4Michel Dänzer      FLUSH_BATCH(NULL);
63846aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca
63946aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca      /* Make sure state is re-emitted after a flush:
64046aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca       */
641bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz      i915_emit_hardware_state(i915);
642cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz      i915->vbo_flushed = 1;
64346aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca
6448f9e546fde27db75ea87bcf8ae333bc70616deb4Daniel Vetter      if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
645bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         assert(0);
646bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz         goto out;
64746aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca      }
64846aeff5814ae16544874ceafa5bd1e9d6577ca9dJosé Fonseca   }
6493c393b8df302493c4f48a750bfd7bd1c6aadbabbJosé Fonseca
650bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   OUT_BATCH(_3DPRIMITIVE |
651bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             PRIM_INDIRECT |
652bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             i915_render->hwprim |
653bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             PRIM_INDIRECT_ELTS |
654bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz             nr_indices);
655bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   draw_generate_indices(render,
656bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                         indices,
657bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                         save_nr_indices,
658bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz                         i915_render->fallback);
65908130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
66008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantzout:
66108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   return;
662dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
663dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
6649924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic void
665bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_release_vertices(struct vbuf_render *render)
666dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
6679924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
668cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
669ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_sw_offset += i915_render->vbo_max_used;
67016a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   i915_render->vbo_max_used = 0;
6714dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz
6724dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   /*
6734dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz    * Micro optimization, by calling update here we the offset change
6744dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz    * will be picked up on the next pipe_context::draw_*.
6754dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz    */
6764dd742cec38e771a5ac22fb0eae2d413c3174753Jakob Bornecrantz   i915_vbuf_update_vbo_state(render);
677dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
678dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
6799924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic void
680bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_destroy(struct vbuf_render *render)
681dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
6829924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
6838af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   struct i915_context *i915 = i915_render->i915;
6848af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   struct i915_winsys *iws = i915->iws;
6858af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz
6868af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   if (i915_render->vbo) {
6878af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz      i915->vbo = NULL;
6888af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz      iws->buffer_unmap(iws, i915_render->vbo);
6898af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz      iws->buffer_destroy(iws, i915_render->vbo);
6908af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz   }
6918af583f6e844ef2d173eb3c5c2e378cd1da018a8Jakob Bornecrantz
692271f9dac79a9247de9a57f4d248e404bf1652a13José Fonseca   FREE(i915_render);
693dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
694dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
6959924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca/**
6969924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca * Create a new primitive render.
6979924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca */
6989924f208cf3f45424b6464d2cca9698da206816eJosé Fonsecastatic struct vbuf_render *
699bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzi915_vbuf_render_create(struct i915_context *i915)
700dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
7019924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
702bc88c95990f871a206a8fe93e7541f1f41841f7eJakob Bornecrantz   struct i915_winsys *iws = i915->iws;
703d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz   int i;
7049924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca
7059924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->i915 = i915;
706ce3c2b51a23c1f674b7a6e862d238c3935d72ca3Jakob Bornecrantz
707ce3c2b51a23c1f674b7a6e862d238c3935d72ca3Jakob Bornecrantz   i915_render->base.max_vertex_buffer_bytes = 16*4096;
708ce3c2b51a23c1f674b7a6e862d238c3935d72ca3Jakob Bornecrantz
7099924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   /* NOTE: it must be such that state and vertices indices fit in a single
7109924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca    * batch buffer.
711dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca    */
7129924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.max_indices = 16*1024;
713cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
7149924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;
7159924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
71616a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   i915_render->base.map_vertices = i915_vbuf_render_map_vertices;
71716a440f326a77b0834392eebc5c56c136059b7c9Jakob Bornecrantz   i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices;
7189924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
719740e50c60f03d194aafab93d5251699964800979Brian Paul   i915_render->base.draw_elements = i915_vbuf_render_draw_elements;
72008130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
7219924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
7229924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   i915_render->base.destroy = i915_vbuf_render_destroy;
723cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
7240f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#ifndef VBUF_MAP_BUFFER
7250f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->map_size = 0;
7260f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->map_used_start = 0;
7270f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->map_used_end = 0;
7280f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz#endif
729d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz
730d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   i915_render->vbo = NULL;
7310f0127f6f9ee6c976c707cd406bf392aea978976Jakob Bornecrantz   i915_render->vbo_ptr = NULL;
732d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   i915_render->vbo_size = 0;
733ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_hw_offset = 0;
734ca43b6ec9df68b22a88667542757ad70fcb04470Jakob Bornecrantz   i915_render->vbo_sw_offset = 0;
735030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   i915_render->vbo_alloc_size = i915_render->base.max_vertex_buffer_bytes * 4;
736d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz
737030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz#ifdef VBUF_USE_POOL
738d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz   i915_render->pool_used = FALSE;
739030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   i915_render->pool_buffer_size = i915_render->vbo_alloc_size;
740d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz   i915_render->pool_fifo = u_fifo_create(6);
741d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz   for (i = 0; i < 6; i++)
742d585616f5bb950b3ed0b1142498e06f4dca98559Jakob Bornecrantz      u_fifo_add(i915_render->pool_fifo,
743c62f5c7e7bc3ed84677805b3800fbcfa93c419eaDaniel Vetter                 iws->buffer_create(iws, i915_render->pool_buffer_size,
744bc88c95990f871a206a8fe93e7541f1f41841f7eJakob Bornecrantz                                    I915_NEW_VERTEX));
745030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz#else
746030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   (void)i;
747030723fc5d3faa919cac245fc7b13430ca201826Jakob Bornecrantz   (void)iws;
748d1121328402dc2e9480ca69bcfd9e3aac5f024a4Jakob Bornecrantz#endif
749cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz
7509924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   return &i915_render->base;
751dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
752dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
753dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca/**
754dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca * Create a new primitive vbuf/render stage.
755dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca */
756bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantzstruct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915)
757dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca{
7589924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct vbuf_render *render;
7599924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   struct draw_stage *stage;
760dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
7619924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   render = i915_vbuf_render_create(i915);
7629924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   if(!render)
7639924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      return NULL;
764dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca
765bd0c51874f6dc7610b87d55c182b696517358dbeJakob Bornecrantz   stage = draw_vbuf_stage(i915->draw, render);
7669924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   if(!stage) {
7679924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      render->destroy(render);
7689924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca      return NULL;
7699924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   }
770c1949e2bd3acc45c23cc434eef2b0d6aae9092caJakob Bornecrantz   /** TODO JB: this shouldn't be here */
77108130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz   draw_set_render(i915->draw, render);
77208130512b9961da76a6385403d56387125df5e8cJakob Bornecrantz
7739924f208cf3f45424b6464d2cca9698da206816eJosé Fonseca   return stage;
774dbb33a9710e64243ba8c69f44a149376300da2aaJosé Fonseca}
775