Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / glx / x11 / render2.c
1 /* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
2 /*
3 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
4 * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 including the dates of first publication and
14 * either this permission notice or a reference to
15 * http://oss.sgi.com/projects/FreeB/
16 * shall be included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * Except as contained in this notice, the name of Silicon Graphics, Inc.
27 * shall not be used in advertising or otherwise to promote the sale, use or
28 * other dealings in this Software without prior written authorization from
29 * Silicon Graphics, Inc.
30 */
31
32 #include "packrender.h"
33 #include "indirect.h"
34 #include "indirect_size.h"
35
36 /*
37 ** This file contains routines that might need to be transported as
38 ** GLXRender or GLXRenderLarge commands, and these commands don't
39 ** use the pixel header. See renderpix.c for those routines.
40 */
41
42 void
43 __indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
44 GLint order, const GLdouble * pnts)
45 {
46 __GLX_DECLARE_VARIABLES();
47 GLint k;
48
49 __GLX_LOAD_VARIABLES();
50 k = __glMap1d_size(target);
51 if (k == 0) {
52 __glXSetError(gc, GL_INVALID_ENUM);
53 return;
54 }
55 else if (stride < k || order <= 0) {
56 __glXSetError(gc, GL_INVALID_VALUE);
57 return;
58 }
59 compsize = k * order * __GLX_SIZE_FLOAT64;
60 cmdlen = 28 + compsize;
61 if (!gc->currentDpy)
62 return;
63
64 if (cmdlen <= gc->maxSmallRenderCommandSize) {
65 /* Use GLXRender protocol to send small command */
66 __GLX_BEGIN_VARIABLE(X_GLrop_Map1d, cmdlen);
67 __GLX_PUT_DOUBLE(4, u1);
68 __GLX_PUT_DOUBLE(12, u2);
69 __GLX_PUT_LONG(20, target);
70 __GLX_PUT_LONG(24, order);
71 /*
72 ** NOTE: the doubles that follow are not aligned because of 3
73 ** longs preceeding
74 */
75 __glFillMap1d(k, order, stride, pnts, (pc + 28));
76 __GLX_END(cmdlen);
77 }
78 else {
79 /* Use GLXRenderLarge protocol to send command */
80 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d, cmdlen + 4);
81 __GLX_PUT_DOUBLE(8, u1);
82 __GLX_PUT_DOUBLE(16, u2);
83 __GLX_PUT_LONG(24, target);
84 __GLX_PUT_LONG(28, order);
85
86 /*
87 ** NOTE: the doubles that follow are not aligned because of 3
88 ** longs preceeding
89 */
90 if (stride != k) {
91 GLubyte *buf;
92
93 buf = (GLubyte *) Xmalloc(compsize);
94 if (!buf) {
95 __glXSetError(gc, GL_OUT_OF_MEMORY);
96 return;
97 }
98 __glFillMap1d(k, order, stride, pnts, buf);
99 __glXSendLargeCommand(gc, pc, 32, buf, compsize);
100 Xfree((char *) buf);
101 }
102 else {
103 /* Data is already packed. Just send it out */
104 __glXSendLargeCommand(gc, pc, 32, pnts, compsize);
105 }
106 }
107 }
108
109 void
110 __indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
111 GLint order, const GLfloat * pnts)
112 {
113 __GLX_DECLARE_VARIABLES();
114 GLint k;
115
116 __GLX_LOAD_VARIABLES();
117 k = __glMap1f_size(target);
118 if (k == 0) {
119 __glXSetError(gc, GL_INVALID_ENUM);
120 return;
121 }
122 else if (stride < k || order <= 0) {
123 __glXSetError(gc, GL_INVALID_VALUE);
124 return;
125 }
126 compsize = k * order * __GLX_SIZE_FLOAT32;
127 cmdlen = 20 + compsize;
128 if (!gc->currentDpy)
129 return;
130
131 /*
132 ** The order that arguments are packed is different from the order
133 ** for glMap1d.
134 */
135 if (cmdlen <= gc->maxSmallRenderCommandSize) {
136 /* Use GLXRender protocol to send small command */
137 __GLX_BEGIN_VARIABLE(X_GLrop_Map1f, cmdlen);
138 __GLX_PUT_LONG(4, target);
139 __GLX_PUT_FLOAT(8, u1);
140 __GLX_PUT_FLOAT(12, u2);
141 __GLX_PUT_LONG(16, order);
142 __glFillMap1f(k, order, stride, pnts, (GLubyte *) (pc + 20));
143 __GLX_END(cmdlen);
144 }
145 else {
146 /* Use GLXRenderLarge protocol to send command */
147 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f, cmdlen + 4);
148 __GLX_PUT_LONG(8, target);
149 __GLX_PUT_FLOAT(12, u1);
150 __GLX_PUT_FLOAT(16, u2);
151 __GLX_PUT_LONG(20, order);
152
153 if (stride != k) {
154 GLubyte *buf;
155
156 buf = (GLubyte *) Xmalloc(compsize);
157 if (!buf) {
158 __glXSetError(gc, GL_OUT_OF_MEMORY);
159 return;
160 }
161 __glFillMap1f(k, order, stride, pnts, buf);
162 __glXSendLargeCommand(gc, pc, 24, buf, compsize);
163 Xfree((char *) buf);
164 }
165 else {
166 /* Data is already packed. Just send it out */
167 __glXSendLargeCommand(gc, pc, 24, pnts, compsize);
168 }
169 }
170 }
171
172 void
173 __indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr,
174 GLint uord, GLdouble v1, GLdouble v2, GLint vstr,
175 GLint vord, const GLdouble * pnts)
176 {
177 __GLX_DECLARE_VARIABLES();
178 GLint k;
179
180 __GLX_LOAD_VARIABLES();
181 k = __glMap2d_size(target);
182 if (k == 0) {
183 __glXSetError(gc, GL_INVALID_ENUM);
184 return;
185 }
186 else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
187 __glXSetError(gc, GL_INVALID_VALUE);
188 return;
189 }
190 compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
191 cmdlen = 48 + compsize;
192 if (!gc->currentDpy)
193 return;
194
195 if (cmdlen <= gc->maxSmallRenderCommandSize) {
196 /* Use GLXRender protocol to send small command */
197 __GLX_BEGIN_VARIABLE(X_GLrop_Map2d, cmdlen);
198 __GLX_PUT_DOUBLE(4, u1);
199 __GLX_PUT_DOUBLE(12, u2);
200 __GLX_PUT_DOUBLE(20, v1);
201 __GLX_PUT_DOUBLE(28, v2);
202 __GLX_PUT_LONG(36, target);
203 __GLX_PUT_LONG(40, uord);
204 __GLX_PUT_LONG(44, vord);
205 /*
206 ** Pack into a u-major ordering.
207 ** NOTE: the doubles that follow are not aligned because of 5
208 ** longs preceeding
209 */
210 __glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble *) (pc + 48));
211 __GLX_END(cmdlen);
212 }
213 else {
214 /* Use GLXRenderLarge protocol to send command */
215 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d, cmdlen + 4);
216 __GLX_PUT_DOUBLE(8, u1);
217 __GLX_PUT_DOUBLE(16, u2);
218 __GLX_PUT_DOUBLE(24, v1);
219 __GLX_PUT_DOUBLE(32, v2);
220 __GLX_PUT_LONG(40, target);
221 __GLX_PUT_LONG(44, uord);
222 __GLX_PUT_LONG(48, vord);
223
224 /*
225 ** NOTE: the doubles that follow are not aligned because of 5
226 ** longs preceeding
227 */
228 if ((vstr != k) || (ustr != k * vord)) {
229 GLdouble *buf;
230
231 buf = (GLdouble *) Xmalloc(compsize);
232 if (!buf) {
233 __glXSetError(gc, GL_OUT_OF_MEMORY);
234 return;
235 }
236 /*
237 ** Pack into a u-major ordering.
238 */
239 __glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
240 __glXSendLargeCommand(gc, pc, 52, buf, compsize);
241 Xfree((char *) buf);
242 }
243 else {
244 /* Data is already packed. Just send it out */
245 __glXSendLargeCommand(gc, pc, 52, pnts, compsize);
246 }
247 }
248 }
249
250 void
251 __indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr,
252 GLint uord, GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
253 const GLfloat * pnts)
254 {
255 __GLX_DECLARE_VARIABLES();
256 GLint k;
257
258 __GLX_LOAD_VARIABLES();
259 k = __glMap2f_size(target);
260 if (k == 0) {
261 __glXSetError(gc, GL_INVALID_ENUM);
262 return;
263 }
264 else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
265 __glXSetError(gc, GL_INVALID_VALUE);
266 return;
267 }
268 compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
269 cmdlen = 32 + compsize;
270 if (!gc->currentDpy)
271 return;
272
273 /*
274 ** The order that arguments are packed is different from the order
275 ** for glMap2d.
276 */
277 if (cmdlen <= gc->maxSmallRenderCommandSize) {
278 /* Use GLXRender protocol to send small command */
279 __GLX_BEGIN_VARIABLE(X_GLrop_Map2f, cmdlen);
280 __GLX_PUT_LONG(4, target);
281 __GLX_PUT_FLOAT(8, u1);
282 __GLX_PUT_FLOAT(12, u2);
283 __GLX_PUT_LONG(16, uord);
284 __GLX_PUT_FLOAT(20, v1);
285 __GLX_PUT_FLOAT(24, v2);
286 __GLX_PUT_LONG(28, vord);
287 /*
288 ** Pack into a u-major ordering.
289 */
290 __glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat *) (pc + 32));
291 __GLX_END(cmdlen);
292 }
293 else {
294 /* Use GLXRenderLarge protocol to send command */
295 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f, cmdlen + 4);
296 __GLX_PUT_LONG(8, target);
297 __GLX_PUT_FLOAT(12, u1);
298 __GLX_PUT_FLOAT(16, u2);
299 __GLX_PUT_LONG(20, uord);
300 __GLX_PUT_FLOAT(24, v1);
301 __GLX_PUT_FLOAT(28, v2);
302 __GLX_PUT_LONG(32, vord);
303
304 if ((vstr != k) || (ustr != k * vord)) {
305 GLfloat *buf;
306
307 buf = (GLfloat *) Xmalloc(compsize);
308 if (!buf) {
309 __glXSetError(gc, GL_OUT_OF_MEMORY);
310 return;
311 }
312 /*
313 ** Pack into a u-major ordering.
314 */
315 __glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
316 __glXSendLargeCommand(gc, pc, 36, buf, compsize);
317 Xfree((char *) buf);
318 }
319 else {
320 /* Data is already packed. Just send it out */
321 __glXSendLargeCommand(gc, pc, 36, pnts, compsize);
322 }
323 }
324 }
325
326 void
327 __indirect_glEnable(GLenum cap)
328 {
329 __GLX_DECLARE_VARIABLES();
330
331 __GLX_LOAD_VARIABLES();
332 if (!gc->currentDpy)
333 return;
334
335 switch (cap) {
336 case GL_COLOR_ARRAY:
337 case GL_EDGE_FLAG_ARRAY:
338 case GL_INDEX_ARRAY:
339 case GL_NORMAL_ARRAY:
340 case GL_TEXTURE_COORD_ARRAY:
341 case GL_VERTEX_ARRAY:
342 case GL_SECONDARY_COLOR_ARRAY:
343 case GL_FOG_COORD_ARRAY:
344 __indirect_glEnableClientState(cap);
345 return;
346 default:
347 break;
348 }
349
350 __GLX_BEGIN(X_GLrop_Enable, 8);
351 __GLX_PUT_LONG(4, cap);
352 __GLX_END(8);
353 }
354
355 void
356 __indirect_glDisable(GLenum cap)
357 {
358 __GLX_DECLARE_VARIABLES();
359
360 __GLX_LOAD_VARIABLES();
361 if (!gc->currentDpy)
362 return;
363
364 switch (cap) {
365 case GL_COLOR_ARRAY:
366 case GL_EDGE_FLAG_ARRAY:
367 case GL_INDEX_ARRAY:
368 case GL_NORMAL_ARRAY:
369 case GL_TEXTURE_COORD_ARRAY:
370 case GL_VERTEX_ARRAY:
371 case GL_SECONDARY_COLOR_ARRAY:
372 case GL_FOG_COORD_ARRAY:
373 __indirect_glDisableClientState(cap);
374 return;
375 default:
376 break;
377 }
378
379 __GLX_BEGIN(X_GLrop_Disable, 8);
380 __GLX_PUT_LONG(4, cap);
381 __GLX_END(8);
382 }