Imported Upstream version 1.15.1
[deb_xorg-server.git] / glx / rensize.c
CommitLineData
a09e091a
JB
1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included 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 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#ifdef HAVE_DIX_CONFIG_H
32#include <dix-config.h>
33#endif
34
35#include <GL/gl.h>
36#include "glxserver.h"
37#include "GL/glxproto.h"
38#include "unpack.h"
39#include "indirect_size.h"
40#include "indirect_reqsize.h"
41
42#define SWAPL(a) \
43 (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
44 ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
45
46static int
47Map1Size(GLint k, GLint order)
48{
49 if (order <= 0 || k < 0)
50 return -1;
51 return k * order;
52}
53
54int
55__glXMap1dReqSize(const GLbyte * pc, Bool swap)
56{
57 GLenum target;
58 GLint order, k;
59
60 target = *(GLenum *) (pc + 16);
61 order = *(GLint *) (pc + 20);
62 if (swap) {
63 target = SWAPL(target);
64 order = SWAPL(order);
65 }
66 k = __glMap1d_size(target);
67 return 8 * Map1Size(k, order);
68}
69
70int
71__glXMap1fReqSize(const GLbyte * pc, Bool swap)
72{
73 GLenum target;
74 GLint order, k;
75
76 target = *(GLenum *) (pc + 0);
77 order = *(GLint *) (pc + 12);
78 if (swap) {
79 target = SWAPL(target);
80 order = SWAPL(order);
81 }
82 k = __glMap1f_size(target);
83 return 4 * Map1Size(k, order);
84}
85
86static int
87Map2Size(int k, int majorOrder, int minorOrder)
88{
89 if (majorOrder <= 0 || minorOrder <= 0 || k < 0)
90 return -1;
91 return k * majorOrder * minorOrder;
92}
93
94int
95__glXMap2dReqSize(const GLbyte * pc, Bool swap)
96{
97 GLenum target;
98 GLint uorder, vorder, k;
99
100 target = *(GLenum *) (pc + 32);
101 uorder = *(GLint *) (pc + 36);
102 vorder = *(GLint *) (pc + 40);
103 if (swap) {
104 target = SWAPL(target);
105 uorder = SWAPL(uorder);
106 vorder = SWAPL(vorder);
107 }
108 k = __glMap2d_size(target);
109 return 8 * Map2Size(k, uorder, vorder);
110}
111
112int
113__glXMap2fReqSize(const GLbyte * pc, Bool swap)
114{
115 GLenum target;
116 GLint uorder, vorder, k;
117
118 target = *(GLenum *) (pc + 0);
119 uorder = *(GLint *) (pc + 12);
120 vorder = *(GLint *) (pc + 24);
121 if (swap) {
122 target = SWAPL(target);
123 uorder = SWAPL(uorder);
124 vorder = SWAPL(vorder);
125 }
126 k = __glMap2f_size(target);
127 return 4 * Map2Size(k, uorder, vorder);
128}
129
130/**
131 * Calculate the size of an image.
132 *
133 * The size of an image sent to the server from the client or sent from the
134 * server to the client is calculated. The size is based on the dimensions
135 * of the image, the type of pixel data, padding in the image, and the
136 * alignment requirements of the image.
137 *
138 * \param format Format of the pixels. Same as the \c format parameter
139 * to \c glTexImage1D
140 * \param type Type of the pixel data. Same as the \c type parameter
141 * to \c glTexImage1D
142 * \param target Typically the texture target of the image. If the
143 * target is one of \c GL_PROXY_*, the size returned is
144 * always zero. For uses that do not have a texture target
145 * (e.g, glDrawPixels), zero should be specified.
146 * \param w Width of the image data. Must be >= 1.
147 * \param h Height of the image data. Must be >= 1, even for 1D
148 * images.
149 * \param d Depth of the image data. Must be >= 1, even for 1D or
150 * 2D images.
151 * \param imageHeight If non-zero, defines the true height of a volumetric
152 * image. This value will be used instead of \c h for
153 * calculating the size of the image.
154 * \param rowLength If non-zero, defines the true width of an image. This
155 * value will be used instead of \c w for calculating the
156 * size of the image.
157 * \param skipImages Number of extra layers of image data in a volumtric
158 * image that are to be skipped before the real data.
159 * \param skipRows Number of extra rows of image data in an image that are
160 * to be skipped before the real data.
161 * \param alignment Specifies the alignment for the start of each pixel row
162 * in memory. This value must be one of 1, 2, 4, or 8.
163 *
164 * \returns
165 * The size of the image is returned. If the specified \c format and \c type
166 * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero
167 * is returned.
168 */
169int
170__glXImageSize(GLenum format, GLenum type, GLenum target,
171 GLsizei w, GLsizei h, GLsizei d,
172 GLint imageHeight, GLint rowLength,
173 GLint skipImages, GLint skipRows, GLint alignment)
174{
175 GLint bytesPerElement, elementsPerGroup, groupsPerRow;
176 GLint groupSize, rowSize, padding, imageSize;
177
178 if (w < 0 || h < 0 || d < 0 ||
179 (type == GL_BITMAP &&
180 (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
181 return -1;
182 }
183 if (w == 0 || h == 0 || d == 0)
184 return 0;
185
186 switch (target) {
187 case GL_PROXY_TEXTURE_1D:
188 case GL_PROXY_TEXTURE_2D:
189 case GL_PROXY_TEXTURE_3D:
190 case GL_PROXY_TEXTURE_4D_SGIS:
191 case GL_PROXY_TEXTURE_CUBE_MAP:
192 case GL_PROXY_TEXTURE_RECTANGLE_ARB:
193 case GL_PROXY_HISTOGRAM:
194 case GL_PROXY_COLOR_TABLE:
195 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
196 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
197 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
198 case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
199 return 0;
200 }
201
202 if (type == GL_BITMAP) {
203 if (rowLength > 0) {
204 groupsPerRow = rowLength;
205 }
206 else {
207 groupsPerRow = w;
208 }
209 rowSize = bits_to_bytes(groupsPerRow);
210 padding = (rowSize % alignment);
211 if (padding) {
212 rowSize += alignment - padding;
213 }
214 return ((h + skipRows) * rowSize);
215 }
216 else {
217 switch (format) {
218 case GL_COLOR_INDEX:
219 case GL_STENCIL_INDEX:
220 case GL_DEPTH_COMPONENT:
221 case GL_RED:
222 case GL_GREEN:
223 case GL_BLUE:
224 case GL_ALPHA:
225 case GL_LUMINANCE:
226 case GL_INTENSITY:
227 elementsPerGroup = 1;
228 break;
229 case GL_422_EXT:
230 case GL_422_REV_EXT:
231 case GL_422_AVERAGE_EXT:
232 case GL_422_REV_AVERAGE_EXT:
233 case GL_DEPTH_STENCIL_NV:
234 case GL_DEPTH_STENCIL_MESA:
235 case GL_YCBCR_MESA:
236 case GL_LUMINANCE_ALPHA:
237 elementsPerGroup = 2;
238 break;
239 case GL_RGB:
240 case GL_BGR:
241 elementsPerGroup = 3;
242 break;
243 case GL_RGBA:
244 case GL_BGRA:
245 case GL_ABGR_EXT:
246 elementsPerGroup = 4;
247 break;
248 default:
249 return -1;
250 }
251 switch (type) {
252 case GL_UNSIGNED_BYTE:
253 case GL_BYTE:
254 bytesPerElement = 1;
255 break;
256 case GL_UNSIGNED_BYTE_3_3_2:
257 case GL_UNSIGNED_BYTE_2_3_3_REV:
258 bytesPerElement = 1;
259 elementsPerGroup = 1;
260 break;
261 case GL_UNSIGNED_SHORT:
262 case GL_SHORT:
263 bytesPerElement = 2;
264 break;
265 case GL_UNSIGNED_SHORT_5_6_5:
266 case GL_UNSIGNED_SHORT_5_6_5_REV:
267 case GL_UNSIGNED_SHORT_4_4_4_4:
268 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
269 case GL_UNSIGNED_SHORT_5_5_5_1:
270 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
271 case GL_UNSIGNED_SHORT_8_8_APPLE:
272 case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
273 case GL_UNSIGNED_SHORT_15_1_MESA:
274 case GL_UNSIGNED_SHORT_1_15_REV_MESA:
275 bytesPerElement = 2;
276 elementsPerGroup = 1;
277 break;
278 case GL_INT:
279 case GL_UNSIGNED_INT:
280 case GL_FLOAT:
281 bytesPerElement = 4;
282 break;
283 case GL_UNSIGNED_INT_8_8_8_8:
284 case GL_UNSIGNED_INT_8_8_8_8_REV:
285 case GL_UNSIGNED_INT_10_10_10_2:
286 case GL_UNSIGNED_INT_2_10_10_10_REV:
287 case GL_UNSIGNED_INT_24_8_NV:
288 case GL_UNSIGNED_INT_24_8_MESA:
289 case GL_UNSIGNED_INT_8_24_REV_MESA:
290 bytesPerElement = 4;
291 elementsPerGroup = 1;
292 break;
293 default:
294 return -1;
295 }
296 groupSize = bytesPerElement * elementsPerGroup;
297 if (rowLength > 0) {
298 groupsPerRow = rowLength;
299 }
300 else {
301 groupsPerRow = w;
302 }
303 rowSize = groupsPerRow * groupSize;
304 padding = (rowSize % alignment);
305 if (padding) {
306 rowSize += alignment - padding;
307 }
308 if (imageHeight > 0) {
309 imageSize = (imageHeight + skipRows) * rowSize;
310 }
311 else {
312 imageSize = (h + skipRows) * rowSize;
313 }
314 return ((d + skipImages) * imageSize);
315 }
316}
317
318/* XXX this is used elsewhere - should it be exported from glxserver.h? */
319int
320__glXTypeSize(GLenum enm)
321{
322 switch (enm) {
323 case GL_BYTE:
324 return sizeof(GLbyte);
325 case GL_UNSIGNED_BYTE:
326 return sizeof(GLubyte);
327 case GL_SHORT:
328 return sizeof(GLshort);
329 case GL_UNSIGNED_SHORT:
330 return sizeof(GLushort);
331 case GL_INT:
332 return sizeof(GLint);
333 case GL_UNSIGNED_INT:
334 return sizeof(GLint);
335 case GL_FLOAT:
336 return sizeof(GLfloat);
337 case GL_DOUBLE:
338 return sizeof(GLdouble);
339 default:
340 return -1;
341 }
342}
343
344int
345__glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
346{
347 __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
348 __GLXdispatchDrawArraysComponentHeader *compHeader;
349 GLint numVertexes = hdr->numVertexes;
350 GLint numComponents = hdr->numComponents;
351 GLint arrayElementSize = 0;
352 int i;
353
354 if (swap) {
355 numVertexes = SWAPL(numVertexes);
356 numComponents = SWAPL(numComponents);
357 }
358
359 pc += sizeof(__GLXdispatchDrawArraysHeader);
360 compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
361
362 for (i = 0; i < numComponents; i++) {
363 GLenum datatype = compHeader[i].datatype;
364 GLint numVals = compHeader[i].numVals;
365 GLint component = compHeader[i].component;
366
367 if (swap) {
368 datatype = SWAPL(datatype);
369 numVals = SWAPL(numVals);
370 component = SWAPL(component);
371 }
372
373 switch (component) {
374 case GL_VERTEX_ARRAY:
375 case GL_COLOR_ARRAY:
376 case GL_TEXTURE_COORD_ARRAY:
377 break;
378 case GL_SECONDARY_COLOR_ARRAY:
379 case GL_NORMAL_ARRAY:
380 if (numVals != 3) {
381 /* bad size */
382 return -1;
383 }
384 break;
385 case GL_FOG_COORD_ARRAY:
386 case GL_INDEX_ARRAY:
387 if (numVals != 1) {
388 /* bad size */
389 return -1;
390 }
391 break;
392 case GL_EDGE_FLAG_ARRAY:
393 if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) {
394 /* bad size or bad type */
395 return -1;
396 }
397 break;
398 default:
399 /* unknown component type */
400 return -1;
401 }
402
403 arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype));
404
405 pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
406 }
407
408 return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) +
409 (numVertexes * arrayElementSize));
410}
411
412int
413__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap)
414{
415 __GLXdispatchConvolutionFilterHeader *hdr =
416 (__GLXdispatchConvolutionFilterHeader *) pc;
417
418 GLint image1size, image2size;
419 GLenum format = hdr->format;
420 GLenum type = hdr->type;
421 GLint w = hdr->width;
422 GLint h = hdr->height;
423 GLint rowLength = hdr->rowLength;
424 GLint alignment = hdr->alignment;
425
426 if (swap) {
427 format = SWAPL(format);
428 type = SWAPL(type);
429 w = SWAPL(w);
430 h = SWAPL(h);
431 rowLength = SWAPL(rowLength);
432 alignment = SWAPL(alignment);
433 }
434
435 /* XXX Should rowLength be used for either or both image? */
436 image1size = __glXImageSize(format, type, 0, w, 1, 1,
437 0, rowLength, 0, 0, alignment);
438 image1size = __GLX_PAD(image1size);
439 image2size = __glXImageSize(format, type, 0, h, 1, 1,
440 0, rowLength, 0, 0, alignment);
441 return image1size + image2size;
442
443}