1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc.
3bf215546Sopenharmony_ci * All Rights Reserved.
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci/*
27bf215546Sopenharmony_ci * NOTE: This file is not compiled by itself.  It's actually #included
28bf215546Sopenharmony_ci * by the generated u_unfilled_gen.c file!
29bf215546Sopenharmony_ci */
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "u_indices.h"
32bf215546Sopenharmony_ci#include "u_indices_priv.h"
33bf215546Sopenharmony_ci#include "util/u_prim.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_cistatic void translate_ubyte_ushort( const void *in,
37bf215546Sopenharmony_ci                                    unsigned start,
38bf215546Sopenharmony_ci                                    unsigned in_nr,
39bf215546Sopenharmony_ci                                    unsigned out_nr,
40bf215546Sopenharmony_ci                                    unsigned restart_index,
41bf215546Sopenharmony_ci                                    void *out )
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   const ubyte *in_ub = (const ubyte *)in;
44bf215546Sopenharmony_ci   ushort *out_us = (ushort *)out;
45bf215546Sopenharmony_ci   unsigned i;
46bf215546Sopenharmony_ci   for (i = 0; i < out_nr; i++)
47bf215546Sopenharmony_ci      out_us[i] = (ushort) in_ub[i+start];
48bf215546Sopenharmony_ci}
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_cistatic void translate_memcpy_ushort( const void *in,
51bf215546Sopenharmony_ci                                     unsigned start,
52bf215546Sopenharmony_ci                                     unsigned in_nr,
53bf215546Sopenharmony_ci                                     unsigned out_nr,
54bf215546Sopenharmony_ci                                     unsigned restart_index,
55bf215546Sopenharmony_ci                                     void *out )
56bf215546Sopenharmony_ci{
57bf215546Sopenharmony_ci   memcpy(out, &((short *)in)[start], out_nr*sizeof(short));
58bf215546Sopenharmony_ci}
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_cistatic void translate_memcpy_uint( const void *in,
61bf215546Sopenharmony_ci                                   unsigned start,
62bf215546Sopenharmony_ci                                   unsigned in_nr,
63bf215546Sopenharmony_ci                                   unsigned out_nr,
64bf215546Sopenharmony_ci                                   unsigned restart_index,
65bf215546Sopenharmony_ci                                   void *out )
66bf215546Sopenharmony_ci{
67bf215546Sopenharmony_ci   memcpy(out, &((int *)in)[start], out_nr*sizeof(int));
68bf215546Sopenharmony_ci}
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_cistatic void generate_linear_ushort( unsigned start,
72bf215546Sopenharmony_ci                                    unsigned nr,
73bf215546Sopenharmony_ci                                    void *out )
74bf215546Sopenharmony_ci{
75bf215546Sopenharmony_ci   ushort *out_us = (ushort *)out;
76bf215546Sopenharmony_ci   unsigned i;
77bf215546Sopenharmony_ci   for (i = 0; i < nr; i++)
78bf215546Sopenharmony_ci      out_us[i] = (ushort)(i + start);
79bf215546Sopenharmony_ci}
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_cistatic void generate_linear_uint( unsigned start,
82bf215546Sopenharmony_ci                                  unsigned nr,
83bf215546Sopenharmony_ci                                  void *out )
84bf215546Sopenharmony_ci{
85bf215546Sopenharmony_ci   unsigned *out_ui = (unsigned *)out;
86bf215546Sopenharmony_ci   unsigned i;
87bf215546Sopenharmony_ci   for (i = 0; i < nr; i++)
88bf215546Sopenharmony_ci      out_ui[i] = i + start;
89bf215546Sopenharmony_ci}
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci/**
93bf215546Sopenharmony_ci * Given a primitive type and number of vertices, return the number of vertices
94bf215546Sopenharmony_ci * needed to draw the primitive with fill mode = PIPE_POLYGON_MODE_LINE using
95bf215546Sopenharmony_ci * separate lines (PIPE_PRIM_LINES).
96bf215546Sopenharmony_ci */
97bf215546Sopenharmony_cistatic unsigned
98bf215546Sopenharmony_cinr_lines(enum pipe_prim_type prim, unsigned nr)
99bf215546Sopenharmony_ci{
100bf215546Sopenharmony_ci   switch (prim) {
101bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLES:
102bf215546Sopenharmony_ci      return (nr / 3) * 6;
103bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_STRIP:
104bf215546Sopenharmony_ci      return (nr - 2) * 6;
105bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_FAN:
106bf215546Sopenharmony_ci      return (nr - 2)  * 6;
107bf215546Sopenharmony_ci   case PIPE_PRIM_QUADS:
108bf215546Sopenharmony_ci      return (nr / 4) * 8;
109bf215546Sopenharmony_ci   case PIPE_PRIM_QUAD_STRIP:
110bf215546Sopenharmony_ci      return (nr - 2) / 2 * 8;
111bf215546Sopenharmony_ci   case PIPE_PRIM_POLYGON:
112bf215546Sopenharmony_ci      return 2 * nr; /* a line (two verts) for each polygon edge */
113bf215546Sopenharmony_ci   /* Note: these cases can't really be handled since drawing lines instead
114bf215546Sopenharmony_ci    * of triangles would also require changing the GS.  But if there's no GS,
115bf215546Sopenharmony_ci    * this should work.
116bf215546Sopenharmony_ci    */
117bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLES_ADJACENCY:
118bf215546Sopenharmony_ci      return (nr / 6) * 6;
119bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
120bf215546Sopenharmony_ci      return ((nr - 4) / 2) * 6;
121bf215546Sopenharmony_ci   default:
122bf215546Sopenharmony_ci      assert(0);
123bf215546Sopenharmony_ci      return 0;
124bf215546Sopenharmony_ci   }
125bf215546Sopenharmony_ci}
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_cienum indices_mode
129bf215546Sopenharmony_ciu_unfilled_translator(enum pipe_prim_type prim,
130bf215546Sopenharmony_ci                      unsigned in_index_size,
131bf215546Sopenharmony_ci                      unsigned nr,
132bf215546Sopenharmony_ci                      unsigned unfilled_mode,
133bf215546Sopenharmony_ci                      enum pipe_prim_type *out_prim,
134bf215546Sopenharmony_ci                      unsigned *out_index_size,
135bf215546Sopenharmony_ci                      unsigned *out_nr,
136bf215546Sopenharmony_ci                      u_translate_func *out_translate)
137bf215546Sopenharmony_ci{
138bf215546Sopenharmony_ci   unsigned in_idx;
139bf215546Sopenharmony_ci   unsigned out_idx;
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   assert(u_reduced_prim(prim) == PIPE_PRIM_TRIANGLES);
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   u_unfilled_init();
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   in_idx = in_size_idx(in_index_size);
146bf215546Sopenharmony_ci   *out_index_size = (in_index_size == 4) ? 4 : 2;
147bf215546Sopenharmony_ci   out_idx = out_size_idx(*out_index_size);
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci   if (unfilled_mode == PIPE_POLYGON_MODE_POINT) {
150bf215546Sopenharmony_ci      *out_prim = PIPE_PRIM_POINTS;
151bf215546Sopenharmony_ci      *out_nr = nr;
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci      switch (in_index_size) {
154bf215546Sopenharmony_ci      case 1:
155bf215546Sopenharmony_ci         *out_translate = translate_ubyte_ushort;
156bf215546Sopenharmony_ci         return U_TRANSLATE_NORMAL;
157bf215546Sopenharmony_ci      case 2:
158bf215546Sopenharmony_ci         *out_translate = translate_memcpy_uint;
159bf215546Sopenharmony_ci         return U_TRANSLATE_MEMCPY;
160bf215546Sopenharmony_ci      case 4:
161bf215546Sopenharmony_ci         *out_translate = translate_memcpy_ushort;
162bf215546Sopenharmony_ci         return U_TRANSLATE_MEMCPY;
163bf215546Sopenharmony_ci      default:
164bf215546Sopenharmony_ci         *out_translate = translate_memcpy_uint;
165bf215546Sopenharmony_ci         *out_nr = 0;
166bf215546Sopenharmony_ci         assert(0);
167bf215546Sopenharmony_ci         return U_TRANSLATE_ERROR;
168bf215546Sopenharmony_ci      }
169bf215546Sopenharmony_ci   }
170bf215546Sopenharmony_ci   else {
171bf215546Sopenharmony_ci      assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
172bf215546Sopenharmony_ci      *out_prim = PIPE_PRIM_LINES;
173bf215546Sopenharmony_ci      *out_translate = translate_line[in_idx][out_idx][prim];
174bf215546Sopenharmony_ci      *out_nr = nr_lines( prim, nr );
175bf215546Sopenharmony_ci      return U_TRANSLATE_NORMAL;
176bf215546Sopenharmony_ci   }
177bf215546Sopenharmony_ci}
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci/**
181bf215546Sopenharmony_ci * Utility for converting unfilled polygons into points, lines, triangles.
182bf215546Sopenharmony_ci * Few drivers have direct support for OpenGL's glPolygonMode.
183bf215546Sopenharmony_ci * This function helps with converting triangles into points or lines
184bf215546Sopenharmony_ci * when the front and back fill modes are the same.  When there's
185bf215546Sopenharmony_ci * different front/back fill modes, that can be handled with the
186bf215546Sopenharmony_ci * 'draw' module.
187bf215546Sopenharmony_ci */
188bf215546Sopenharmony_cienum indices_mode
189bf215546Sopenharmony_ciu_unfilled_generator(enum pipe_prim_type prim,
190bf215546Sopenharmony_ci                     unsigned start,
191bf215546Sopenharmony_ci                     unsigned nr,
192bf215546Sopenharmony_ci                     unsigned unfilled_mode,
193bf215546Sopenharmony_ci                     enum pipe_prim_type *out_prim,
194bf215546Sopenharmony_ci                     unsigned *out_index_size,
195bf215546Sopenharmony_ci                     unsigned *out_nr,
196bf215546Sopenharmony_ci                     u_generate_func *out_generate)
197bf215546Sopenharmony_ci{
198bf215546Sopenharmony_ci   unsigned out_idx;
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   assert(u_reduced_prim(prim) == PIPE_PRIM_TRIANGLES);
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   u_unfilled_init();
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
205bf215546Sopenharmony_ci   out_idx = out_size_idx(*out_index_size);
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   if (unfilled_mode == PIPE_POLYGON_MODE_POINT) {
208bf215546Sopenharmony_ci      if (*out_index_size == 4)
209bf215546Sopenharmony_ci         *out_generate = generate_linear_uint;
210bf215546Sopenharmony_ci      else
211bf215546Sopenharmony_ci         *out_generate = generate_linear_ushort;
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci      *out_prim = PIPE_PRIM_POINTS;
214bf215546Sopenharmony_ci      *out_nr = nr;
215bf215546Sopenharmony_ci      return U_GENERATE_LINEAR;
216bf215546Sopenharmony_ci   }
217bf215546Sopenharmony_ci   else {
218bf215546Sopenharmony_ci      assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
219bf215546Sopenharmony_ci      *out_prim = PIPE_PRIM_LINES;
220bf215546Sopenharmony_ci      *out_generate = generate_line[out_idx][prim];
221bf215546Sopenharmony_ci      *out_nr = nr_lines( prim, nr );
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci      return U_GENERATE_REUSABLE;
224bf215546Sopenharmony_ci   }
225bf215546Sopenharmony_ci}
226