Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 1
 
2
 * Mesa 3-D graphics library
3
 * Version:  6.5
4
 *
5
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
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
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Keith Whitwell 
26
 */
27
28
 
29
 
30
#include "main/macros.h"
31
#include "main/enums.h"
32
#include "main/image.h"
33
#include "vbo_split.h"
34
35
 
36
 
37
38
 
39
 * too large indexed vertex buffers: In general you need to copy to do
40
 * that.
41
 */
42
struct split_context {
43
   struct gl_context *ctx;
44
   const struct gl_client_array **array;
45
   const struct _mesa_prim *prim;
46
   GLuint nr_prims;
47
   const struct _mesa_index_buffer *ib;
48
   GLuint min_index;
49
   GLuint max_index;
50
   vbo_draw_func draw;
51
52
 
53
   GLuint limit;
54
55
 
56
   GLuint dstprim_nr;
57
};
58
59
 
60
 
61
 
62
 
63
{
64
   struct _mesa_index_buffer ib;
65
   GLuint i;
66
67
 
68
      return;
69
70
 
71
      ib = *split->ib;
72
73
 
74
      ib.ptr = (const void *)((const char *)ib.ptr +
75
                              split->min_index * _mesa_sizeof_type(ib.type));
76
77
 
78
      for (i = 0; i < split->dstprim_nr; i++)
79
	 split->dstprim[i].start -= split->min_index;
80
   }
81
82
 
83
84
 
85
	       split->array,
86
	       split->dstprim,
87
	       split->dstprim_nr,
88
	       split->ib ? &ib : NULL,
89
	       !split->ib,
90
	       split->min_index,
91
	       split->max_index);
92
93
 
94
   split->min_index = ~0;
95
   split->max_index = 0;
96
}
97
98
 
99
 
100
{
101
   if (split->dstprim_nr == MAX_PRIM-1) {
102
      flush_vertex(split);
103
   }
104
105
 
106
      struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++];
107
      memset(prim, 0, sizeof(*prim));
108
      return prim;
109
   }
110
}
111
112
 
113
				const struct _mesa_prim *prim)
114
{
115
   split->min_index = MIN2(split->min_index, prim->start);
116
   split->max_index = MAX2(split->max_index, prim->start + prim->count - 1);
117
}
118
119
 
120
 * primitive starting at 'prim->start', depending on the previous
121
 * index bounds.
122
 */
123
static GLuint get_max_vertices(struct split_context *split,
124
			       const struct _mesa_prim *prim)
125
{
126
   if ((prim->start > split->min_index &&
127
	prim->start - split->min_index >= split->limit) ||
128
       (prim->start < split->max_index &&
129
        split->max_index - prim->start >= split->limit))
130
      /* "prim" starts too far away from the old range. */
131
      return 0;
132
133
 
134
}
135
136
 
137
 * the primitive to indexed and pass to split_elts().
138
 */
139
static void split_prims( struct split_context *split)
140
{
141
   GLuint i;
142
143
 
144
      const struct _mesa_prim *prim = &split->prim[i];
145
      GLuint first, incr;
146
      GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr);
147
      GLuint available = get_max_vertices(split, prim);
148
      GLuint count = prim->count - (prim->count - first) % incr;
149
150
 
151
	 continue;
152
153
 
154
	  (available < first && split_inplace)) {
155
	 flush_vertex(split);
156
	 available = get_max_vertices(split, prim);
157
      }
158
159
 
160
	 struct _mesa_prim *outprim = next_outprim(split);
161
162
 
163
	 update_index_bounds(split, outprim);
164
      }
165
      else if (split_inplace) {
166
	 GLuint j, nr;
167
168
 
169
	    GLuint remaining = count - j;
170
	    struct _mesa_prim *outprim = next_outprim(split);
171
172
 
173
	    nr -= (nr - first) % incr;
174
175
 
176
	    outprim->begin = (j == 0 && prim->begin);
177
	    outprim->end = (nr == remaining && prim->end);
178
	    outprim->start = prim->start + j;
179
	    outprim->count = nr;
180
181
 
182
183
 
184
	       /* Finished.
185
		*/
186
	       j += nr;
187
	    }
188
	    else {
189
	       /* Wrapped the primitive:
190
		*/
191
	       j += nr - (first - incr);
192
	       flush_vertex(split);
193
	       available = get_max_vertices(split, prim);
194
	    }
195
	 }
196
      }
197
      else if (split->ib == NULL) {
198
	 /* XXX: could at least send the first max_verts off from the
199
	  * inplace buffers.
200
	  */
201
202
 
203
	  * which will do the necessary copying and turn it back into a
204
	  * vertex primitive for rendering...
205
	  */
206
	 struct _mesa_index_buffer ib;
207
	 struct _mesa_prim tmpprim;
208
	 GLuint *elts = malloc(count * sizeof(GLuint));
209
	 GLuint j;
210
211
 
212
	    elts[j] = prim->start + j;
213
214
 
215
	 ib.type = GL_UNSIGNED_INT;
216
	 ib.obj = split->ctx->Shared->NullBufferObj;
217
	 ib.ptr = elts;
218
219
 
220
	 tmpprim.indexed = 1;
221
	 tmpprim.start = 0;
222
	 tmpprim.count = count;
223
224
 
225
226
 
227
			split->array,
228
			&tmpprim, 1,
229
			&ib,
230
			split->draw,
231
			split->limits);
232
233
 
234
      }
235
      else {
236
	 flush_vertex(split);
237
238
 
239
			split->array,
240
			prim, 1,
241
			split->ib,
242
			split->draw,
243
			split->limits);
244
      }
245
   }
246
247
 
248
}
249
250
 
251
 
252
			const struct gl_client_array *arrays[],
253
			const struct _mesa_prim *prim,
254
			GLuint nr_prims,
255
			const struct _mesa_index_buffer *ib,
256
			GLuint min_index,
257
			GLuint max_index,
258
			vbo_draw_func draw,
259
			const struct split_limits *limits )
260
{
261
   struct split_context split;
262
263
 
264
265
 
266
   split.array = arrays;
267
   split.prim = prim;
268
   split.nr_prims = nr_prims;
269
   split.ib = ib;
270
271
 
272
   split.min_index = ~0;
273
   split.max_index = 0;
274
275
 
276
   split.limits = limits;
277
   split.limit = ib ? limits->max_indices : limits->max_verts;
278
279
 
280
}
281