17c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell/**************************************************************************
2994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007 VMware, Inc.
47c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * All Rights Reserved.
5994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul *
67c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
77c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * copy of this software and associated documentation files (the
87c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * "Software"), to deal in the Software without restriction, including
97c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
107c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
117c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
127c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * the following conditions:
13994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul *
147c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * The above copyright notice and this permission notice (including the
157c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
167c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * of the Software.
17994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul *
187c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
227c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
237c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
247c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul *
267c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell **************************************************************************/
277c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
287c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell /*
297c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell  * Authors:
30877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca  *   Keith Whitwell <keithw@vmware.com>
317c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell  */
327c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
337c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
344f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
354f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
367c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_context.h"
377c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_private.h"
387c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_vbuf.h"
397c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_vertex.h"
407c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_pt.h"
417c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell#include "draw/draw_vs.h"
427c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
437c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
447c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwellstruct fetch_shade_emit;
457c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
467c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
477c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell/* Prototype fetch, shade, emit-hw-verts all in one go.
487c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell */
497c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwellstruct fetch_shade_emit {
507c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct draw_pt_middle_end base;
517c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct draw_context *draw;
527c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
537c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* Temporaries:
547c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
557c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   const float *constants;
567c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   unsigned pitch[PIPE_MAX_ATTRIBS];
577c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   const ubyte *src[PIPE_MAX_ATTRIBS];
587c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   unsigned prim;
597c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
60b7e150605d402224cdd8fa3d186924bdee3c6c49Brian Paul   struct draw_vs_variant_key key;
61b7e150605d402224cdd8fa3d186924bdee3c6c49Brian Paul   struct draw_vs_variant *active;
62fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell
63fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   const struct vertex_info *vinfo;
647c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell};
657c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
667c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
677c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
68994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulstatic void
69994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulfse_prepare(struct draw_pt_middle_end *middle,
70994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul            unsigned prim,
71994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul            unsigned opt,
72994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul            unsigned *max_vertices)
737c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
747c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
757c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct draw_context *draw = fse->draw;
767c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs;
777c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   const struct vertex_info *vinfo;
787c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   unsigned i;
79af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   unsigned nr_vbs = 0;
807c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
8164682da8ab7aff7b4ce651db99a32ed1fd8b178cKeith Whitwell   /* Can't support geometry shader on this path.
8264682da8ab7aff7b4ce651db99a32ed1fd8b178cKeith Whitwell    */
8364682da8ab7aff7b4ce651db99a32ed1fd8b178cKeith Whitwell   assert(!draw->gs.geometry_shader);
84d4ef0f6c67aefe06d8dd647acf8d9005df39a709Zack Rusin
85488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paul   draw->render->set_primitive(draw->render, prim);
867c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
877c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* Must do this after set_primitive() above:
887c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
89fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   fse->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
907c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
91889473b3f5a216bd753c357974d6bae29fe3c41dKeith Whitwell   fse->key.output_stride = vinfo->size * 4;
92f8762ba5234fd1b44e11e76bb5f58d2305c90572Keith Whitwell   fse->key.nr_outputs = vinfo->num_attribs;
93f8762ba5234fd1b44e11e76bb5f58d2305c90572Keith Whitwell   fse->key.nr_inputs = num_vs_inputs;
94f8762ba5234fd1b44e11e76bb5f58d2305c90572Keith Whitwell
95f8762ba5234fd1b44e11e76bb5f58d2305c90572Keith Whitwell   fse->key.nr_elements = MAX2(fse->key.nr_outputs,     /* outputs - translate to hw format */
96f8762ba5234fd1b44e11e76bb5f58d2305c90572Keith Whitwell                               fse->key.nr_inputs);     /* inputs - fetch from api format */
977c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
9865ef78e8611556780fce0bee1feba805347ec627Marek Olšák   fse->key.viewport = !draw->bypass_viewport;
996c0dc4bafbdbdc0cb4b6e5934fe064226dbd47ecKeith Whitwell   fse->key.clip = draw->clip_xy || draw->clip_z || draw->clip_user;
100af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   fse->key.const_vbuffers = 0;
101889473b3f5a216bd753c357974d6bae29fe3c41dKeith Whitwell
102994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   memset(fse->key.element, 0,
1037c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell          fse->key.nr_elements * sizeof(fse->key.element[0]));
1047c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1057c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   for (i = 0; i < num_vs_inputs; i++) {
1067c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      const struct pipe_vertex_element *src = &draw->pt.vertex_element[i];
1077c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      fse->key.element[i].in.format = src->src_format;
1087c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1097c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      /* Consider ignoring these, ie make generated programs
1107c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell       * independent of this state:
1117c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell       */
1127c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      fse->key.element[i].in.buffer = src->vertex_buffer_index;
1137c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      fse->key.element[i].in.offset = src->src_offset;
114af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell      nr_vbs = MAX2(nr_vbs, src->vertex_buffer_index + 1);
1157c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   }
116994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
117af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   for (i = 0; i < 5 && i < nr_vbs; i++) {
118872b515e8f0bb1be5bad85fd9d01529c71f07ba2Zack Rusin      if (draw->pt.vertex_buffer[i].stride == 0)
119af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell         fse->key.const_vbuffers |= (1<<i);
120af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   }
1217c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
122af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   if (0) debug_printf("%s: lookup const_vbuffers: %x\n", __FUNCTION__, fse->key.const_vbuffers);
123994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
1247c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   {
1257c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      unsigned dst_offset = 0;
1267c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1277c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      for (i = 0; i < vinfo->num_attribs; i++) {
12884a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz         unsigned emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
12984a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz
13084a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz         /* doesn't handle EMIT_OMIT */
13184a8347b9f6ef0c1b2519e9bd5fef2ce3c85afb7Jakob Bornecrantz         assert(emit_sz != 0);
1327c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1337c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell         /* The elements in the key correspond to vertex shader output
1347c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell          * numbers, not to positions in the hw vertex description --
1357c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell          * that's handled by the output_offset field.
1367c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell          */
13753d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell         fse->key.element[i].out.format = vinfo->attrib[i].emit;
13853d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell         fse->key.element[i].out.vs_output = vinfo->attrib[i].src_index;
1397b85ea19de09d4e7e077ca147528e90e52683690Keith Whitwell         fse->key.element[i].out.offset = dst_offset;
140994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
1417c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell         dst_offset += emit_sz;
1427c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell         assert(fse->key.output_stride >= dst_offset);
1437c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      }
1447c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   }
1457c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
146994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   fse->active = draw_vs_lookup_variant( draw->vs.vertex_shader,
1477c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                                         &fse->key );
1487c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1497c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   if (!fse->active) {
1507c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      assert(0);
1517c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      return ;
1527c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   }
1537c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
154994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   if (0) debug_printf("%s: found const_vbuffers: %x\n", __FUNCTION__,
155af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell                       fse->active->key.const_vbuffers);
156af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell
1577c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* Now set buffer pointers:
1587c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
159af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell   for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
160994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul      fse->active->set_buffer( fse->active,
161994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                               i,
16229853ab7b8656cee9b92a53bec43f6e9f1e49691Zack Rusin                               ((const ubyte *) draw->pt.user.vbuffer[i].map +
163af9cfea9cc80411351f9879d8eeb525bf7b4ca50Keith Whitwell                                draw->pt.vertex_buffer[i].buffer_offset),
1642a30d3d74a0b87f8066659952628ccd072a4e2b0José Fonseca                              draw->pt.vertex_buffer[i].stride,
1653733da31e8b4405b65e1b6ca3b6599ecc5af5fe7José Fonseca                              draw->pt.max_index );
1667c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   }
1677c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
168994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   *max_vertices = (draw->render->max_vertex_buffer_bytes /
1690a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell                    (vinfo->size * 4));
1700a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21Keith Whitwell
171463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell   /* Probably need to do this somewhere (or fix exec shader not to
172463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell    * need it):
173463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell    */
174463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell   if (1) {
175463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell      struct draw_vertex_shader *vs = draw->vs.vertex_shader;
176463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell      vs->prepare(vs, draw);
177463a47bf59398e850d5a6537da1186d855bd2919Keith Whitwell   }
1787c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
1797c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1807c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1812ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonsecastatic void
1822ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonsecafse_bind_parameters(struct draw_pt_middle_end *middle)
1832ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonseca{
1842ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonseca   /* No-op? */
1852ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonseca}
1862ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonseca
1877c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
188994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulstatic void
189994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulfse_run_linear(struct draw_pt_middle_end *middle,
190994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul               unsigned start,
191994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul               unsigned count,
192994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul               unsigned prim_flags)
1937c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
1947c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
1957c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct draw_context *draw = fse->draw;
1967c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   char *hw_verts;
1977c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
1987c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* XXX: need to flush to get prim_vbuf.c to release its allocation??
1997c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
2007c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
2017c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
202befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if (!draw->render->allocate_vertices( draw->render,
203befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)fse->key.output_stride,
204befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)count ))
205befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      goto fail;
2067c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
207befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   hw_verts = draw->render->map_vertices( draw->render );
208befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if (!hw_verts)
209befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      goto fail;
2107c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
2117c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* Single routine to fetch vertices, run shader and emit HW verts.
212a5c3b499fa40f46298389900e74f1db04f99166aKeith Whitwell    * Clipping is done elsewhere -- either by the API or on hardware,
213a5c3b499fa40f46298389900e74f1db04f99166aKeith Whitwell    * or for some other reason not required...
2147c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
215994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   fse->active->run_linear( fse->active,
2167c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                            start, count,
2177c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                            hw_verts );
2187c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
219fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   if (0) {
220fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      unsigned i;
221fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      for (i = 0; i < count; i++) {
222fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell         debug_printf("\n\n%s vertex %d: (stride %d, offset %d)\n", __FUNCTION__, i,
223fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell                      fse->key.output_stride,
224fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell                      fse->key.output_stride * i);
225fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell
226994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul         draw_dump_emitted_vertex( fse->vinfo,
227fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell                                   (const uint8_t *)hw_verts + fse->key.output_stride * i );
228fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      }
229fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   }
230994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
2311c4f67b980b6bec5788336a9cdd18c4fcec5e492Keith Whitwell   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
232fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell
233befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   /* Draw arrays path to avoid re-emitting index list again and
234befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell    * again.
235befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell    */
236befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   draw->render->draw_arrays( draw->render,
237befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                              0,
238befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                              count );
239befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
240befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   draw->render->release_vertices( draw->render );
241befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
242befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   return;
2437c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
244befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwellfail:
245f0f623a9075107461438468e1aea6bca3a3234f3Brian Paul   debug_warn_once("allocate or map of vertex buffer failed (out of memory?)");
246befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   return;
2477c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
2487c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
2497c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
2507c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwellstatic void
2517c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwellfse_run(struct draw_pt_middle_end *middle,
2527c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell        const unsigned *fetch_elts,
2537c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell        unsigned fetch_count,
2547c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell        const ushort *draw_elts,
255f132498347c41294042db0cc6830abe928d827deChia-I Wu        unsigned draw_count,
256f132498347c41294042db0cc6830abe928d827deChia-I Wu        unsigned prim_flags )
2577c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
2587c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
2597c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct draw_context *draw = fse->draw;
2607c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   void *hw_verts;
261994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
262994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   /* XXX: need to flush to get prim_vbuf.c to release its allocation??
2637c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
2647c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
2657c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
266befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if (!draw->render->allocate_vertices( draw->render,
267befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)fse->key.output_stride,
268befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)fetch_count ))
269befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      goto fail;
270befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
271994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   hw_verts = draw->render->map_vertices( draw->render );
272994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   if (!hw_verts)
273befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      goto fail;
274994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
2757c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   /* Single routine to fetch vertices, run shader and emit HW verts.
2767c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell    */
277994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   fse->active->run_elts( fse->active,
2787c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                          fetch_elts,
2797c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                          fetch_count,
2807c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell                          hw_verts );
2817c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
282fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   if (0) {
283fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      unsigned i;
284fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      for (i = 0; i < fetch_count; i++) {
285fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell         debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
286994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul         draw_dump_emitted_vertex( fse->vinfo,
287994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                                   (const uint8_t *)hw_verts +
288fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell                                   fse->key.output_stride * i );
289fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell      }
290fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell   }
291fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell
2921c4f67b980b6bec5788336a9cdd18c4fcec5e492Keith Whitwell   draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) );
293befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell
294994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   draw->render->draw_elements( draw->render,
295994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                                draw_elts,
296994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                                draw_count );
297fd20d1c7e8bbe2f40d73679b1514023772cfd8f6Keith Whitwell
298befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   draw->render->release_vertices( draw->render );
299befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   return;
3007c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
301befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwellfail:
302f0f623a9075107461438468e1aea6bca3a3234f3Brian Paul   debug_warn_once("allocate or map of vertex buffer failed (out of memory?)");
303befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   return;
3047c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
3057c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
3067c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
30782605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
308994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulstatic boolean
309994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulfse_run_linear_elts(struct draw_pt_middle_end *middle,
310994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                    unsigned start,
311994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                    unsigned count,
312994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                    const ushort *draw_elts,
313994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                    unsigned draw_count,
314994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                    unsigned prim_flags)
31582605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell{
31682605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
31782605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   struct draw_context *draw = fse->draw;
31882605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   char *hw_verts;
31982605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
32082605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   /* XXX: need to flush to get prim_vbuf.c to release its allocation??
32182605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell    */
32282605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
32382605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
324befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   if (!draw->render->allocate_vertices( draw->render,
325befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)fse->key.output_stride,
326befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell                                         (ushort)count ))
327befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell      return FALSE;
32882605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
329befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   hw_verts = draw->render->map_vertices( draw->render );
330994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   if (!hw_verts)
331e6887a5752774c18cf527477fdd3e57e4893ff3bKeith Whitwell      return FALSE;
33282605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
33382605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   /* Single routine to fetch vertices, run shader and emit HW verts.
33482605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell    * Clipping is done elsewhere -- either by the API or on hardware,
33582605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell    * or for some other reason not required...
33682605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell    */
337994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   fse->active->run_linear( fse->active,
33882605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell                            start, count,
33982605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell                            hw_verts );
34082605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
341994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul   draw->render->draw_elements( draw->render,
342994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul                                draw_elts,
343740e50c60f03d194aafab93d5251699964800979Brian Paul                                draw_count );
34482605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
3451c4f67b980b6bec5788336a9cdd18c4fcec5e492Keith Whitwell   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
34682605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
347befa4ff50ec4728de70c04532f8c7342fbd70147Keith Whitwell   draw->render->release_vertices( draw->render );
348e6887a5752774c18cf527477fdd3e57e4893ff3bKeith Whitwell
349e6887a5752774c18cf527477fdd3e57e4893ff3bKeith Whitwell   return TRUE;
35082605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell}
35182605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
35282605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
35382605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell
354994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulstatic void
355994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulfse_finish(struct draw_pt_middle_end *middle)
3567c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
3577c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
3587c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
3597c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
3607c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwellstatic void
361994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulfse_destroy(struct draw_pt_middle_end *middle)
3627c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
3637c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   FREE(middle);
3647c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
3657c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
366994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paul
367994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Paulstruct draw_pt_middle_end *
368994c33db875c6af2f5b535a7a173ff3bfa24fc32Brian Pauldraw_pt_middle_fse(struct draw_context *draw)
3697c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell{
3707c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit);
3717c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   if (!fse)
3727c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell      return NULL;
3737c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
3747c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->base.prepare = fse_prepare;
3752ab4e1d1e6091f2170b1395b8d1bb30d42f133a7José Fonseca   fse->base.bind_parameters = fse_bind_parameters;
3767c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->base.run = fse_run;
3777c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->base.run_linear = fse_run_linear;
37882605d7bcd533d7c96cc619c45970efd7229dc3bKeith Whitwell   fse->base.run_linear_elts = fse_run_linear_elts;
3797c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->base.finish = fse_finish;
3807c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->base.destroy = fse_destroy;
3817c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   fse->draw = draw;
3827c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell
3837c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell   return &fse->base;
3847c99d7fe60e7bb0b7cf103a851aeef4614278ca6Keith Whitwell}
385