13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**********************************************************
23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2008-2009 VMware, Inc.  All rights reserved.
33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person
53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation
63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without
73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy,
83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies
93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is
103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions:
113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be
133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software.
143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE.
233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/
253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "draw/draw_vbuf.h"
273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "draw/draw_context.h"
283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "draw/draw_vertex.h"
293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_debug.h"
3128486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_math.h"
333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h"
343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_context.h"
363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_state.h"
373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_swtnl.h"
383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_types.h"
403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_reg.h"
413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga3d_reg.h"
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_draw.h"
433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_swtnl_private.h"
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic const struct vertex_info *
473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_get_vertex_info( struct vbuf_render *render )
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_swtnl_update_vdecl(svga);
533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return &svga_render->vertex_info;
553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_allocate_vertices( struct vbuf_render *render,
603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                    ushort vertex_size,
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                    ushort nr_vertices )
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pipe_screen *screen = svga->pipe.screen;
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   size_t size = (size_t)nr_vertices * (size_t)vertex_size;
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean new_vbuf = FALSE;
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean new_ibuf = FALSE;
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga_render->vertex_size != vertex_size)
713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->swtnl.new_vdecl = TRUE;
723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->vertex_size = (size_t)vertex_size;
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga->swtnl.new_vbuf)
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      new_ibuf = new_vbuf = TRUE;
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga->swtnl.new_vbuf = FALSE;
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga_render->vbuf_size < svga_render->vbuf_offset + svga_render->vbuf_used + size)
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      new_vbuf = TRUE;
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (new_vbuf)
82287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&svga_render->vbuf, NULL);
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (new_ibuf)
84287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&svga_render->ibuf, NULL);
853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!svga_render->vbuf) {
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size);
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->vbuf = pipe_buffer_create(screen,
89287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                             PIPE_BIND_VERTEX_BUFFER,
90eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák                                             PIPE_USAGE_STREAM,
913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                             svga_render->vbuf_size);
923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(!svga_render->vbuf) {
933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         svga_context_flush(svga, NULL);
949d4488e4a8bba2bce89d2c348ddc57ced2c6f6cdJosé Fonseca         assert(!svga_render->vbuf);
953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         svga_render->vbuf = pipe_buffer_create(screen,
96287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                                PIPE_BIND_VERTEX_BUFFER,
97eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák                                                PIPE_USAGE_STREAM,
983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                                svga_render->vbuf_size);
99871dc64869fa371debf03735e215a12cf2ec1742Brian Paul         /* The buffer allocation may fail if we run out of memory.
100871dc64869fa371debf03735e215a12cf2ec1742Brian Paul          * The draw module's vbuf code should handle that without crashing.
101871dc64869fa371debf03735e215a12cf2ec1742Brian Paul          */
1023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
1033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->swtnl.new_vdecl = TRUE;
1053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->vbuf_offset = 0;
1063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } else {
1073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->vbuf_offset += svga_render->vbuf_used;
1083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->vbuf_used = 0;
1113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga->swtnl.new_vdecl)
1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->vdecl_offset = svga_render->vbuf_offset;
1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void *
1193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_map_vertices( struct vbuf_render *render )
1203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
1223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
1233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
124871dc64869fa371debf03735e215a12cf2ec1742Brian Paul   if (svga_render->vbuf) {
125871dc64869fa371debf03735e215a12cf2ec1742Brian Paul      char *ptr = (char*)pipe_buffer_map(&svga->pipe,
126871dc64869fa371debf03735e215a12cf2ec1742Brian Paul                                         svga_render->vbuf,
127871dc64869fa371debf03735e215a12cf2ec1742Brian Paul                                         PIPE_TRANSFER_WRITE |
128871dc64869fa371debf03735e215a12cf2ec1742Brian Paul                                         PIPE_TRANSFER_FLUSH_EXPLICIT |
1297cd1c62b6be88072e3d937b67c499592490927f1Marek Olšák                                         PIPE_TRANSFER_DISCARD_RANGE |
130871dc64869fa371debf03735e215a12cf2ec1742Brian Paul                                         PIPE_TRANSFER_UNSYNCHRONIZED,
131871dc64869fa371debf03735e215a12cf2ec1742Brian Paul                                         &svga_render->vbuf_transfer);
132871dc64869fa371debf03735e215a12cf2ec1742Brian Paul      if (ptr)
133871dc64869fa371debf03735e215a12cf2ec1742Brian Paul         return ptr + svga_render->vbuf_offset;
134871dc64869fa371debf03735e215a12cf2ec1742Brian Paul      else
135871dc64869fa371debf03735e215a12cf2ec1742Brian Paul         return NULL;
136871dc64869fa371debf03735e215a12cf2ec1742Brian Paul   }
137871dc64869fa371debf03735e215a12cf2ec1742Brian Paul   else {
138871dc64869fa371debf03735e215a12cf2ec1742Brian Paul      /* we probably ran out of memory when allocating the vertex buffer */
139871dc64869fa371debf03735e215a12cf2ec1742Brian Paul      return NULL;
140871dc64869fa371debf03735e215a12cf2ec1742Brian Paul   }
1413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
1443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_unmap_vertices( struct vbuf_render *render,
1453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                 ushort min_index,
1463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                 ushort max_index )
1473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
1493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
1503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned offset, length;
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   size_t used = svga_render->vertex_size * ((size_t)max_index + 1);
1523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index;
1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   length = svga_render->vertex_size * (max_index + 1 - min_index);
155287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_buffer_flush_mapped_range(&svga->pipe,
156287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  svga_render->vbuf_transfer,
157287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  offset, length);
158ec51092a72e2dff1e9b1362d813fe4691cda89b7Marek Olšák   pipe_buffer_unmap(&svga->pipe, svga_render->vbuf_transfer);
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->min_index = min_index;
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->max_index = max_index;
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used);
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
164488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paulstatic void
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_set_primitive( struct vbuf_render *render,
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                unsigned prim )
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->prim = prim;
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
173486da2cfc096d333cd5d1d9d5bd9ca8fa72045e4Jakob Bornecrantzsvga_vbuf_submit_state( struct svga_vbuf_render *svga_render )
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* if the vdecl or vbuf hasn't changed do nothing */
1813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!svga->swtnl.new_vdecl)
1823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return;
1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memcpy(vdecl, svga_render->vdecl, sizeof(vdecl));
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* flush the hw state */
1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = svga_hwtnl_flush(svga->hwtnl);
1885f053bf4ae092df9e5ff6ab38caf9867e6fe46bfBrian Paul   if (ret != PIPE_OK) {
1893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_context_flush(svga, NULL);
1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = svga_hwtnl_flush(svga->hwtnl);
1913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* if we hit this path we might become synced with hw */
1923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->swtnl.new_vbuf = TRUE;
1933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(ret == 0);
1943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_hwtnl_reset_vdecl(svga->hwtnl, svga_render->vdecl_count);
1973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < svga_render->vdecl_count; i++) {
1993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      vdecl[i].array.offset += svga_render->vdecl_offset;
2003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_hwtnl_vdecl( svga->hwtnl,
2023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        i,
2033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        &vdecl[i],
2043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        svga_render->vbuf );
2053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* We have already taken care of flatshading, so let the hwtnl
2083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * module use whatever is most convenient:
2093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
2103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga->state.sw.need_pipeline) {
2113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_hwtnl_set_flatshade(svga->hwtnl, FALSE, FALSE);
2123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_hwtnl_set_unfilled(svga->hwtnl, PIPE_POLYGON_MODE_FILL);
2133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
2153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_hwtnl_set_flatshade( svga->hwtnl,
2163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                svga->curr.rast->templ.flatshade,
2173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                svga->curr.rast->templ.flatshade_first );
2183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_hwtnl_set_unfilled( svga->hwtnl,
2203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               svga->curr.rast->hw_unfilled );
2213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga->swtnl.new_vdecl = FALSE;
2243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
2273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_draw_arrays( struct vbuf_render *render,
2283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              unsigned start,
2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              uint nr )
2303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
2323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
2333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
2345f053bf4ae092df9e5ff6ab38caf9867e6fe46bfBrian Paul   enum pipe_error ret = PIPE_OK;
2353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
236486da2cfc096d333cd5d1d9d5bd9ca8fa72045e4Jakob Bornecrantz   /* off to hardware */
237486da2cfc096d333cd5d1d9d5bd9ca8fa72045e4Jakob Bornecrantz   svga_vbuf_submit_state(svga_render);
2383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to call update_state() again as the draw module may have
2403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * altered some of our state behind our backs.  Testcase:
2413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * redbook/polys.c
2423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
2463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret != PIPE_OK) {
2473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_context_flush(svga, NULL);
2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->swtnl.new_vbuf = TRUE;
2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(ret == PIPE_OK);
2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
256740e50c60f03d194aafab93d5251699964800979Brian Paulsvga_vbuf_render_draw_elements( struct vbuf_render *render,
257740e50c60f03d194aafab93d5251699964800979Brian Paul                                const ushort *indices,
258740e50c60f03d194aafab93d5251699964800979Brian Paul                                uint nr_indices)
2593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_context *svga = svga_render->svga;
2623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pipe_screen *screen = svga->pipe.screen;
2639515b78859b52b4532cc9e06366428f2c49c7869José Fonseca   int bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean ret;
2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   size_t size = 2 * nr_indices;
2663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0);
2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga_render->ibuf_size < svga_render->ibuf_offset + size)
270287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&svga_render->ibuf, NULL);
2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!svga_render->ibuf) {
2733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size);
2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->ibuf = pipe_buffer_create(screen,
275287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                             PIPE_BIND_INDEX_BUFFER,
276eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák                                             PIPE_USAGE_STREAM,
2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                             svga_render->ibuf_size);
2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_render->ibuf_offset = 0;
2793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
281287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_buffer_write_nooverlap(&svga->pipe, svga_render->ibuf,
282287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			       svga_render->ibuf_offset, 2 * nr_indices, indices);
2833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* off to hardware */
285486da2cfc096d333cd5d1d9d5bd9ca8fa72045e4Jakob Bornecrantz   svga_vbuf_submit_state(svga_render);
2863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to call update_state() again as the draw module may have
2883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * altered some of our state behind our backs.  Testcase:
2893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * redbook/polys.c
2903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
2913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
2923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
2943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                        svga_render->ibuf,
2953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                        2,
2969515b78859b52b4532cc9e06366428f2c49c7869José Fonseca                                        bias,
2973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                        svga_render->min_index,
2983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                        svga_render->max_index,
2993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                        svga_render->prim,
3009515b78859b52b4532cc9e06366428f2c49c7869José Fonseca                                        svga_render->ibuf_offset / 2, nr_indices);
3013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(ret != PIPE_OK) {
3023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga_context_flush(svga, NULL);
3033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
3043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                           svga_render->ibuf,
3053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                           2,
3069515b78859b52b4532cc9e06366428f2c49c7869José Fonseca                                           bias,
3073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                           svga_render->min_index,
3083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                           svga_render->max_index,
3093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                           svga_render->prim,
3109515b78859b52b4532cc9e06366428f2c49c7869José Fonseca                                           svga_render->ibuf_offset / 2, nr_indices);
3113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->swtnl.new_vbuf = TRUE;
3123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(ret == PIPE_OK);
3133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->ibuf_offset += size;
3163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
3203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_release_vertices( struct vbuf_render *render )
3213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
3273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_destroy( struct vbuf_render *render )
3283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
3303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
331287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&svga_render->vbuf, NULL);
332287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&svga_render->ibuf, NULL);
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   FREE(svga_render);
3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**
3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Create a new primitive render.
3393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
3403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vbuf_render *
3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_vbuf_render_create( struct svga_context *svga )
3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_vbuf_render *svga_render = CALLOC_STRUCT(svga_vbuf_render);
3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->svga = svga;
3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->ibuf_size = 0;
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->vbuf_size = 0;
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->ibuf_alloc_size = 4*1024;
3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->vbuf_alloc_size = 64*1024;
3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.max_vertex_buffer_bytes = 64*1024/10;
3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.max_indices = 65536;
3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.get_vertex_info = svga_vbuf_render_get_vertex_info;
3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.allocate_vertices = svga_vbuf_render_allocate_vertices;
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.map_vertices = svga_vbuf_render_map_vertices;
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.unmap_vertices = svga_vbuf_render_unmap_vertices;
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.set_primitive = svga_vbuf_render_set_primitive;
357740e50c60f03d194aafab93d5251699964800979Brian Paul   svga_render->base.draw_elements = svga_vbuf_render_draw_elements;
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.draw_arrays = svga_vbuf_render_draw_arrays;
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.release_vertices = svga_vbuf_render_release_vertices;
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   svga_render->base.destroy = svga_vbuf_render_destroy;
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return &svga_render->base;
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
364