Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4358 Serge 1
 
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * 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]->BufferObj->Name != 0)
93
	 return GL_TRUE;
94
95
 
96
}
97
98
 
99
 * becomes zero. There are lots of reasons for wanting to do this, eg:
100
 *
101
 * Software tnl:
102
 *    - any time min_index != 0, otherwise unused vertices lower than
103
 *      min_index will be transformed.
104
 *
105
 * Hardware tnl:
106
 *    - if ib != NULL and min_index != 0, otherwise vertices lower than
107
 *      min_index will be uploaded.  Requires adjusting index values.
108
 *
109
 *    - if ib == NULL and min_index != 0, just for convenience so this doesn't
110
 *      have to be handled within the driver.
111
 *
112
 * Hardware tnl with VBO support:
113
 *    - as above, but only when vertices are not (all?) in VBO's.
114
 *    - can't save time by trying to upload half a vbo - typically it is
115
 *      all or nothing.
116
 */
117
void vbo_rebase_prims( struct gl_context *ctx,
118
		       const struct gl_client_array *arrays[],
119
		       const struct _mesa_prim *prim,
120
		       GLuint nr_prims,
121
		       const struct _mesa_index_buffer *ib,
122
		       GLuint min_index,
123
		       GLuint max_index,
124
		       vbo_draw_func draw )
125
{
126
   struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX];
127
   const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX];
128
129
 
130
   struct _mesa_prim *tmp_prims = NULL;
131
   const struct gl_client_array **saved_arrays = ctx->Array._DrawArrays;
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 = 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.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT,
164
				    ib->obj);
165
166
 
167
 
168
169
 
170
       * GLuints here.  Others wouldn't...
171
       */
172
      switch (ib->type) {
173
      case GL_UNSIGNED_INT:
174
	 tmp_indices = rebase_GLuint( ptr, ib->count, min_index );
175
	 break;
176
      case GL_UNSIGNED_SHORT:
177
	 tmp_indices = rebase_GLushort( ptr, ib->count, min_index );
178
	 break;
179
      case GL_UNSIGNED_BYTE:
180
	 tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );
181
	 break;
182
      }
183
184
 
185
	 ctx->Driver.UnmapBuffer(ctx, ib->obj);
186
187
 
188
      tmp_ib.ptr = tmp_indices;
189
      tmp_ib.count = ib->count;
190
      tmp_ib.type = ib->type;
191
192
 
193
   }
194
   else {
195
      /* Otherwise the primitives need adjustment.
196
       */
197
      tmp_prims = malloc(sizeof(*prim) * nr_prims);
198
199
 
200
	 /* If this fails, it could indicate an application error:
201
	  */
202
	 assert(prim[i].start >= min_index);
203
204
 
205
	 tmp_prims[i].start -= min_index;
206
      }
207
208
 
209
   }
210
211
 
212
    * This works for VBO and non-vbo rendering and shouldn't pesimize
213
    * VBO-based upload schemes.  However this may still not be a fast
214
    * path for hardware tnl for VBO based rendering as most machines
215
    * will be happier if you just specify a starting vertex value in
216
    * each primitive.
217
    *
218
    * For drivers with hardware tnl, you only want to do this if you
219
    * are forced to, eg non-VBO indexed rendering with start != 0.
220
    */
221
   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
222
      tmp_arrays[i] = *arrays[i];
223
      tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;
224
      tmp_array_pointers[i] = &tmp_arrays[i];
225
   }
226
227
 
228
    */
229
   ctx->Array._DrawArrays = tmp_array_pointers;
230
   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
231
232
 
233
	 prim,
234
	 nr_prims,
235
	 ib,
236
	 GL_TRUE,
237
	 0,
238
	 max_index - min_index,
239
	 NULL );
240
241
 
242
   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
243
244
 
245
246
 
247
}
248