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
 * indices starting somewhere above zero.  Typically the application
30
 * is issuing multiple DrawArrays() or DrawElements() to draw
31
 * successive primitives layed out linearly in the vertex arrays.
32
 * Unless the vertex arrays are all in a VBO, the OpenGL semantics
33
 * imply that we need to re-upload the vertex data on each draw call.
34
 * In that case, we want to avoid starting the upload at zero, as it
35
 * will mean every draw call uploads an increasing amount of not-used
36
 * vertex data.  Worse - in the software tnl module, all those
37
 * vertices will be transformed and lit.
38
 *
39
 * If we just upload the new data, however, the indices will be
40
 * incorrect as we tend to upload each set of vertex data to a new
41
 * region.
42
 *
43
 * This file provides a helper to adjust the arrays, primitives and
44
 * indices of a draw call so that it can be re-issued with a min_index
45
 * of zero.
46
 */
47
48
 
49
#include "main/imports.h"
50
#include "main/mtypes.h"
51
52
 
53
54
 
55
 
56
static void *rebase_##TYPE( const void *ptr,			\
57
			  GLuint count, 			\
58
			  TYPE min_index )			\
59
{								\
60
   const TYPE *in = (TYPE *)ptr;				\
61
   TYPE *tmp_indices = malloc(count * sizeof(TYPE));	\
62
   GLuint i;							\
63
								\
64
   for (i = 0; i < count; i++)  				\
65
      tmp_indices[i] = in[i] - min_index;			\
66
								\
67
   return (void *)tmp_indices;					\
68
}
69
70
 
71
 
72
REBASE(GLushort)
73
REBASE(GLubyte)
74
75
 
76
{
77
   GLuint i;
78
79
 
80
      if (arrays[i]->StrideB &&
81
	  arrays[i]->BufferObj->Name == 0)
82
	 return GL_FALSE;
83
84
 
85
}
86
87
 
88
{
89
   GLuint i;
90
91
 
92
      if (arrays[i]->StrideB &&
93
	  arrays[i]->BufferObj->Name != 0)
94
	 return GL_TRUE;
95
96
 
97
}
98
99
 
100
 * becomes zero. There are lots of reasons for wanting to do this, eg:
101
 *
102
 * Software tnl:
103
 *    - any time min_index != 0, otherwise unused vertices lower than
104
 *      min_index will be transformed.
105
 *
106
 * Hardware tnl:
107
 *    - if ib != NULL and min_index != 0, otherwise vertices lower than
108
 *      min_index will be uploaded.  Requires adjusting index values.
109
 *
110
 *    - if ib == NULL and min_index != 0, just for convenience so this doesn't
111
 *      have to be handled within the driver.
112
 *
113
 * Hardware tnl with VBO support:
114
 *    - as above, but only when vertices are not (all?) in VBO's.
115
 *    - can't save time by trying to upload half a vbo - typically it is
116
 *      all or nothing.
117
 */
118
void vbo_rebase_prims( struct gl_context *ctx,
119
		       const struct gl_client_array *arrays[],
120
		       const struct _mesa_prim *prim,
121
		       GLuint nr_prims,
122
		       const struct _mesa_index_buffer *ib,
123
		       GLuint min_index,
124
		       GLuint max_index,
125
		       vbo_draw_func draw )
126
{
127
   struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX];
128
   const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX];
129
130
 
131
   struct _mesa_prim *tmp_prims = NULL;
132
   void *tmp_indices = NULL;
133
   GLuint i;
134
135
 
136
137
 
138
      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
139
140
 
141
 
142
    * There's rendering corruption in some apps when it's enabled.
143
    */
144
   if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) {
145
      /* If we can just tell the hardware or the TNL to interpret our
146
       * indices with a different base, do so.
147
       */
148
      tmp_prims = (struct _mesa_prim *)malloc(sizeof(*prim) * nr_prims);
149
150
 
151
	 tmp_prims[i] = prim[i];
152
	 tmp_prims[i].basevertex -= min_index;
153
      }
154
155
 
156
   } else if (ib) {
157
      /* Unfortunately need to adjust each index individually.
158
       */
159
      GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
160
      void *ptr;
161
162
 
163
	 ctx->Driver.MapBuffer(ctx,
164
			       GL_ELEMENT_ARRAY_BUFFER,
165
			       GL_READ_ONLY_ARB,
166
			       ib->obj);
167
168
 
169
 
170
171
 
172
       * GLuints here.  Others wouldn't...
173
       */
174
      switch (ib->type) {
175
      case GL_UNSIGNED_INT:
176
	 tmp_indices = rebase_GLuint( ptr, ib->count, min_index );
177
	 break;
178
      case GL_UNSIGNED_SHORT:
179
	 tmp_indices = rebase_GLushort( ptr, ib->count, min_index );
180
	 break;
181
      case GL_UNSIGNED_BYTE:
182
	 tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );
183
	 break;
184
      }
185
186
 
187
	 ctx->Driver.UnmapBuffer(ctx,
188
				 GL_ELEMENT_ARRAY_BUFFER,
189
				 ib->obj);
190
191
 
192
      tmp_ib.ptr = tmp_indices;
193
      tmp_ib.count = ib->count;
194
      tmp_ib.type = ib->type;
195
196
 
197
   }
198
   else {
199
      /* Otherwise the primitives need adjustment.
200
       */
201
      tmp_prims = (struct _mesa_prim *)malloc(sizeof(*prim) * nr_prims);
202
203
 
204
	 /* If this fails, it could indicate an application error:
205
	  */
206
	 assert(prim[i].start >= min_index);
207
208
 
209
	 tmp_prims[i].start -= min_index;
210
      }
211
212
 
213
   }
214
215
 
216
    * This works for VBO and non-vbo rendering and shouldn't pesimize
217
    * VBO-based upload schemes.  However this may still not be a fast
218
    * path for hardware tnl for VBO based rendering as most machines
219
    * will be happier if you just specify a starting vertex value in
220
    * each primitive.
221
    *
222
    * For drivers with hardware tnl, you only want to do this if you
223
    * are forced to, eg non-VBO indexed rendering with start != 0.
224
    */
225
   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
226
      tmp_arrays[i] = *arrays[i];
227
      tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;
228
      tmp_array_pointers[i] = &tmp_arrays[i];
229
   }
230
231
 
232
    */
233
   draw( ctx,
234
	 tmp_array_pointers,
235
	 prim,
236
	 nr_prims,
237
	 ib,
238
	 GL_TRUE,
239
	 0,
240
	 max_index - min_index );
241
242
 
243
      free(tmp_indices);
244
245
 
246
      free(tmp_prims);
247
}
248