~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 *
4
 
 * Copyright 2007-2008 VMware, Inc.
5
 
 * Copyright (C) 2010 LunarG Inc.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the "Software"),
9
 
 * to deal in the Software without restriction, including without limitation
10
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 
 * and/or sell copies of the Software, and to permit persons to whom the
12
 
 * Software is furnished to do so, subject to the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice shall be included
15
 
 * in all copies or substantial portions of the Software.
16
 
 *
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 
 * DEALINGS IN THE SOFTWARE.
24
 
 */
25
 
 
26
 
#define CONCAT2(name, elt_type) name ## elt_type
27
 
#define CONCAT(name, elt_type) CONCAT2(name, elt_type)
28
 
 
29
 
#ifdef ELT_TYPE
30
 
 
31
 
/**
32
 
 * Fetch all elements in [min_index, max_index] with bias, and use the
33
 
 * (rebased) index buffer as the draw elements.
34
 
 */
35
 
static boolean
36
 
CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
37
 
                                    unsigned istart, unsigned icount)
38
 
{
39
 
   struct draw_context *draw = vsplit->draw;
40
 
   const ELT_TYPE *ib = (const ELT_TYPE *) draw->pt.user.elts;
41
 
   const unsigned min_index = draw->pt.user.min_index;
42
 
   const unsigned max_index = draw->pt.user.max_index;
43
 
   const int elt_bias = draw->pt.user.eltBias;
44
 
   unsigned fetch_start, fetch_count;
45
 
   const ushort *draw_elts = NULL;
46
 
   unsigned i;
47
 
   const unsigned start = istart;
48
 
   const unsigned end = istart + icount;
49
 
 
50
 
   /* If the index buffer overflows we'll need to run
51
 
    * through the normal paths */
52
 
   if (end >= draw->pt.user.eltMax ||
53
 
       end < istart)
54
 
      return FALSE;
55
 
 
56
 
   /* use the ib directly */
57
 
   if (min_index == 0 && sizeof(ib[0]) == sizeof(draw_elts[0])) {
58
 
      if (icount > vsplit->max_vertices)
59
 
         return FALSE;
60
 
 
61
 
      for (i = 0; i < icount; i++) {
62
 
         ELT_TYPE idx = DRAW_GET_IDX(ib, start + i);
63
 
         if (idx < min_index || idx > max_index) {
64
 
            debug_printf("warning: index out of range\n");
65
 
         }
66
 
      }
67
 
      draw_elts = (const ushort *) (ib + istart);
68
 
   }
69
 
   else {
70
 
      /* have to go through vsplit->draw_elts */
71
 
      if (icount > vsplit->segment_size)
72
 
         return FALSE;
73
 
   }
74
 
 
75
 
   /* this is faster only when we fetch less elements than the normal path */
76
 
   if (max_index - min_index > icount - 1)
77
 
      return FALSE;
78
 
 
79
 
   if (elt_bias < 0 && (int) min_index < -elt_bias)
80
 
      return FALSE;
81
 
 
82
 
   /* why this check? */
83
 
   for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
84
 
      if (draw->pt.vertex_element[i].instance_divisor)
85
 
         return FALSE;
86
 
   }
87
 
 
88
 
   fetch_start = min_index + elt_bias;
89
 
   fetch_count = max_index - min_index + 1;
90
 
 
91
 
   /* Check for overflow in the fetch_start */
92
 
   if (fetch_start < min_index || fetch_start < elt_bias)
93
 
      return FALSE;
94
 
 
95
 
   if (!draw_elts) {
96
 
      if (min_index == 0) {
97
 
         for (i = 0; i < icount; i++) {
98
 
            ELT_TYPE idx = DRAW_GET_IDX(ib, i + start);
99
 
 
100
 
            if (idx < min_index || idx > max_index) {
101
 
               debug_printf("warning: index out of range\n");
102
 
            }
103
 
            vsplit->draw_elts[i] = (ushort) idx;
104
 
         }
105
 
      }
106
 
      else {
107
 
         for (i = 0; i < icount; i++) {
108
 
            ELT_TYPE idx = DRAW_GET_IDX(ib, i + start);
109
 
 
110
 
            if (idx < min_index || idx > max_index) {
111
 
               debug_printf("warning: index out of range\n");
112
 
            }
113
 
            vsplit->draw_elts[i] = (ushort) (idx - min_index);
114
 
         }
115
 
      }
116
 
 
117
 
      draw_elts = vsplit->draw_elts;
118
 
   }
119
 
 
120
 
   return vsplit->middle->run_linear_elts(vsplit->middle,
121
 
                                          fetch_start, fetch_count,
122
 
                                          draw_elts, icount, 0x0);
123
 
}
124
 
 
125
 
/**
126
 
 * Use the cache to prepare the fetch and draw elements, and flush.
127
 
 *
128
 
 * When spoken is TRUE, ispoken replaces istart;  When close is TRUE, iclose is
129
 
 * appended.
130
 
 */
131
 
static inline void
132
 
CONCAT(vsplit_segment_cache_, ELT_TYPE)(struct vsplit_frontend *vsplit,
133
 
                                        unsigned flags,
134
 
                                        unsigned istart, unsigned icount,
135
 
                                        boolean spoken, unsigned ispoken,
136
 
                                        boolean close, unsigned iclose)
137
 
{
138
 
   struct draw_context *draw = vsplit->draw;
139
 
   const ELT_TYPE *ib = (const ELT_TYPE *) draw->pt.user.elts;
140
 
   const int ibias = draw->pt.user.eltBias;
141
 
   unsigned i;
142
 
 
143
 
   assert(icount + !!close <= vsplit->segment_size);
144
 
 
145
 
   vsplit_clear_cache(vsplit);
146
 
 
147
 
   spoken = !!spoken;
148
 
   if (ibias == 0) {
149
 
      if (spoken)
150
 
         ADD_CACHE(vsplit, ib, 0, ispoken, 0);
151
 
 
152
 
      for (i = spoken; i < icount; i++) {
153
 
         ADD_CACHE(vsplit, ib, istart, i, 0);
154
 
      }
155
 
 
156
 
      if (close)
157
 
         ADD_CACHE(vsplit, ib, 0, iclose, 0);
158
 
   }
159
 
   else {
160
 
      if (spoken)
161
 
         ADD_CACHE(vsplit, ib, 0, ispoken, ibias);
162
 
 
163
 
      for (i = spoken; i < icount; i++)
164
 
         ADD_CACHE(vsplit, ib, istart, i, ibias);
165
 
 
166
 
      if (close)
167
 
         ADD_CACHE(vsplit, ib, 0, iclose, ibias);
168
 
   }
169
 
 
170
 
   vsplit_flush_cache(vsplit, flags);
171
 
}
172
 
 
173
 
static void
174
 
CONCAT(vsplit_segment_simple_, ELT_TYPE)(struct vsplit_frontend *vsplit,
175
 
                                         unsigned flags,
176
 
                                         unsigned istart,
177
 
                                         unsigned icount)
178
 
{
179
 
   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
180
 
         flags, istart, icount, FALSE, 0, FALSE, 0);
181
 
}
182
 
 
183
 
static void
184
 
CONCAT(vsplit_segment_loop_, ELT_TYPE)(struct vsplit_frontend *vsplit,
185
 
                                       unsigned flags,
186
 
                                       unsigned istart,
187
 
                                       unsigned icount,
188
 
                                       unsigned i0)
189
 
{
190
 
   const boolean close_loop = ((flags) == DRAW_SPLIT_BEFORE);
191
 
 
192
 
   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
193
 
         flags, istart, icount, FALSE, 0, close_loop, i0);
194
 
}
195
 
 
196
 
static void
197
 
CONCAT(vsplit_segment_fan_, ELT_TYPE)(struct vsplit_frontend *vsplit,
198
 
                                      unsigned flags,
199
 
                                      unsigned istart,
200
 
                                      unsigned icount,
201
 
                                      unsigned i0)
202
 
{
203
 
   const boolean use_spoken = (((flags) & DRAW_SPLIT_BEFORE) != 0);
204
 
 
205
 
   CONCAT(vsplit_segment_cache_, ELT_TYPE)(vsplit,
206
 
         flags, istart, icount, use_spoken, i0, FALSE, 0);
207
 
}
208
 
 
209
 
#define LOCAL_VARS                                                         \
210
 
   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;   \
211
 
   const unsigned prim = vsplit->prim;                                     \
212
 
   const unsigned max_count_simple = vsplit->segment_size;                 \
213
 
   const unsigned max_count_loop = vsplit->segment_size - 1;               \
214
 
   const unsigned max_count_fan = vsplit->segment_size;
215
 
 
216
 
#define PRIMITIVE(istart, icount)   \
217
 
   CONCAT(vsplit_primitive_, ELT_TYPE)(vsplit, istart, icount)
218
 
 
219
 
#else /* ELT_TYPE */
220
 
 
221
 
static void
222
 
vsplit_segment_simple_linear(struct vsplit_frontend *vsplit, unsigned flags,
223
 
                             unsigned istart, unsigned icount)
224
 
{
225
 
   assert(icount <= vsplit->max_vertices);
226
 
   vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
227
 
}
228
 
 
229
 
static void
230
 
vsplit_segment_loop_linear(struct vsplit_frontend *vsplit, unsigned flags,
231
 
                           unsigned istart, unsigned icount, unsigned i0)
232
 
{
233
 
   boolean close_loop = (flags == DRAW_SPLIT_BEFORE);
234
 
   unsigned nr;
235
 
 
236
 
   assert(icount + !!close_loop <= vsplit->segment_size);
237
 
 
238
 
   /* need to draw the sections of the line loop as line strips */
239
 
   flags |= DRAW_LINE_LOOP_AS_STRIP;
240
 
 
241
 
   if (close_loop) {
242
 
      for (nr = 0; nr < icount; nr++)
243
 
         vsplit->fetch_elts[nr] = istart + nr;
244
 
      vsplit->fetch_elts[nr++] = i0;
245
 
 
246
 
      vsplit->middle->run(vsplit->middle, vsplit->fetch_elts, nr,
247
 
            vsplit->identity_draw_elts, nr, flags);
248
 
   }
249
 
   else {
250
 
      vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
251
 
   }
252
 
}
253
 
 
254
 
static void
255
 
vsplit_segment_fan_linear(struct vsplit_frontend *vsplit, unsigned flags,
256
 
                          unsigned istart, unsigned icount, unsigned i0)
257
 
{
258
 
   boolean use_spoken = ((flags & DRAW_SPLIT_BEFORE) != 0);
259
 
   unsigned nr = 0, i;
260
 
 
261
 
   assert(icount <= vsplit->segment_size);
262
 
 
263
 
   if (use_spoken) {
264
 
      /* replace istart by i0 */
265
 
      vsplit->fetch_elts[nr++] = i0;
266
 
      for (i = 1 ; i < icount; i++)
267
 
         vsplit->fetch_elts[nr++] = istart + i;
268
 
 
269
 
      vsplit->middle->run(vsplit->middle, vsplit->fetch_elts, nr,
270
 
            vsplit->identity_draw_elts, nr, flags);
271
 
   }
272
 
   else {
273
 
      vsplit->middle->run_linear(vsplit->middle, istart, icount, flags);
274
 
   }
275
 
}
276
 
 
277
 
#define LOCAL_VARS                                                         \
278
 
   struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend;   \
279
 
   const unsigned prim = vsplit->prim;                                     \
280
 
   const unsigned max_count_simple = vsplit->max_vertices;                 \
281
 
   const unsigned max_count_loop = vsplit->segment_size - 1;               \
282
 
   const unsigned max_count_fan = vsplit->segment_size;
283
 
 
284
 
#define PRIMITIVE(istart, icount) FALSE
285
 
 
286
 
#define ELT_TYPE linear
287
 
 
288
 
#endif /* ELT_TYPE */
289
 
 
290
 
#define FUNC_VARS                      \
291
 
   struct draw_pt_front_end *frontend, \
292
 
   unsigned start,                     \
293
 
   unsigned count
294
 
 
295
 
#define SEGMENT_SIMPLE(flags, istart, icount)   \
296
 
   CONCAT(vsplit_segment_simple_, ELT_TYPE)(vsplit, flags, istart, icount)
297
 
 
298
 
#define SEGMENT_LOOP(flags, istart, icount, i0) \
299
 
   CONCAT(vsplit_segment_loop_, ELT_TYPE)(vsplit, flags, istart, icount, i0)
300
 
 
301
 
#define SEGMENT_FAN(flags, istart, icount, i0)  \
302
 
   CONCAT(vsplit_segment_fan_, ELT_TYPE)(vsplit, flags, istart, icount, i0)
303
 
 
304
 
#include "draw_split_tmp.h"
305
 
 
306
 
#undef CONCAT2
307
 
#undef CONCAT
308
 
 
309
 
#undef ELT_TYPE
310
 
#undef ADD_CACHE