Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / glx / x11 / render2.c
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 #include "packrender.h"
32 #include "indirect.h"
33 #include "indirect_size.h"
34
35 /*
36 ** This file contains routines that might need to be transported as
37 ** GLXRender or GLXRenderLarge commands, and these commands don't
38 ** use the pixel header. See renderpix.c for those routines.
39 */
40
41 void __indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
42 GLint order, const GLdouble *pnts)
43 {
44 __GLX_DECLARE_VARIABLES();
45 GLint k;
46
47 __GLX_LOAD_VARIABLES();
48 k = __glMap1d_size(target);
49 if (k == 0) {
50 __glXSetError(gc, GL_INVALID_ENUM);
51 return;
52 } else if (stride < k || order <= 0) {
53 __glXSetError(gc, GL_INVALID_VALUE);
54 return;
55 }
56 compsize = k * order * __GLX_SIZE_FLOAT64;
57 cmdlen = 28+compsize;
58 if (!gc->currentDpy) return;
59
60 if (cmdlen <= gc->maxSmallRenderCommandSize) {
61 /* Use GLXRender protocol to send small command */
62 __GLX_BEGIN_VARIABLE(X_GLrop_Map1d,cmdlen);
63 __GLX_PUT_DOUBLE(4,u1);
64 __GLX_PUT_DOUBLE(12,u2);
65 __GLX_PUT_LONG(20,target);
66 __GLX_PUT_LONG(24,order);
67 /*
68 ** NOTE: the doubles that follow are not aligned because of 3
69 ** longs preceeding
70 */
71 __glFillMap1d(k, order, stride, pnts, (pc+28));
72 __GLX_END(cmdlen);
73 } else {
74 /* Use GLXRenderLarge protocol to send command */
75 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d,cmdlen+4);
76 __GLX_PUT_DOUBLE(8,u1);
77 __GLX_PUT_DOUBLE(16,u2);
78 __GLX_PUT_LONG(24,target);
79 __GLX_PUT_LONG(28,order);
80
81 /*
82 ** NOTE: the doubles that follow are not aligned because of 3
83 ** longs preceeding
84 */
85 if (stride != k) {
86 GLubyte *buf;
87
88 buf = (GLubyte *) Xmalloc(compsize);
89 if (!buf) {
90 __glXSetError(gc, GL_OUT_OF_MEMORY);
91 return;
92 }
93 __glFillMap1d(k, order, stride, pnts, buf);
94 __glXSendLargeCommand(gc, pc, 32, buf, compsize);
95 Xfree((char*) buf);
96 } else {
97 /* Data is already packed. Just send it out */
98 __glXSendLargeCommand(gc, pc, 32, pnts, compsize);
99 }
100 }
101 }
102
103 void __indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
104 GLint order, const GLfloat *pnts)
105 {
106 __GLX_DECLARE_VARIABLES();
107 GLint k;
108
109 __GLX_LOAD_VARIABLES();
110 k = __glMap1f_size(target);
111 if (k == 0) {
112 __glXSetError(gc, GL_INVALID_ENUM);
113 return;
114 } else if (stride < k || order <= 0) {
115 __glXSetError(gc, GL_INVALID_VALUE);
116 return;
117 }
118 compsize = k * order * __GLX_SIZE_FLOAT32;
119 cmdlen = 20+compsize;
120 if (!gc->currentDpy) return;
121
122 /*
123 ** The order that arguments are packed is different from the order
124 ** for glMap1d.
125 */
126 if (cmdlen <= gc->maxSmallRenderCommandSize) {
127 /* Use GLXRender protocol to send small command */
128 __GLX_BEGIN_VARIABLE(X_GLrop_Map1f,cmdlen);
129 __GLX_PUT_LONG(4,target);
130 __GLX_PUT_FLOAT(8,u1);
131 __GLX_PUT_FLOAT(12,u2);
132 __GLX_PUT_LONG(16,order);
133 __glFillMap1f(k, order, stride, pnts, (GLubyte*) (pc+20));
134 __GLX_END(cmdlen);
135 } else {
136 /* Use GLXRenderLarge protocol to send command */
137 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f,cmdlen+4);
138 __GLX_PUT_LONG(8,target);
139 __GLX_PUT_FLOAT(12,u1);
140 __GLX_PUT_FLOAT(16,u2);
141 __GLX_PUT_LONG(20,order);
142
143 if (stride != k) {
144 GLubyte *buf;
145
146 buf = (GLubyte *) Xmalloc(compsize);
147 if (!buf) {
148 __glXSetError(gc, GL_OUT_OF_MEMORY);
149 return;
150 }
151 __glFillMap1f(k, order, stride, pnts, buf);
152 __glXSendLargeCommand(gc, pc, 24, buf, compsize);
153 Xfree((char*) buf);
154 } else {
155 /* Data is already packed. Just send it out */
156 __glXSendLargeCommand(gc, pc, 24, pnts, compsize);
157 }
158 }
159 }
160
161 void __indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr, GLint uord,
162 GLdouble v1, GLdouble v2, GLint vstr, GLint vord,
163 const GLdouble *pnts)
164 {
165 __GLX_DECLARE_VARIABLES();
166 GLint k;
167
168 __GLX_LOAD_VARIABLES();
169 k = __glMap2d_size(target);
170 if (k == 0) {
171 __glXSetError(gc, GL_INVALID_ENUM);
172 return;
173 } else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
174 __glXSetError(gc, GL_INVALID_VALUE);
175 return;
176 }
177 compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
178 cmdlen = 48+compsize;
179 if (!gc->currentDpy) return;
180
181 if (cmdlen <= gc->maxSmallRenderCommandSize) {
182 /* Use GLXRender protocol to send small command */
183 __GLX_BEGIN_VARIABLE(X_GLrop_Map2d,cmdlen);
184 __GLX_PUT_DOUBLE(4,u1);
185 __GLX_PUT_DOUBLE(12,u2);
186 __GLX_PUT_DOUBLE(20,v1);
187 __GLX_PUT_DOUBLE(28,v2);
188 __GLX_PUT_LONG(36,target);
189 __GLX_PUT_LONG(40,uord);
190 __GLX_PUT_LONG(44,vord);
191 /*
192 ** Pack into a u-major ordering.
193 ** NOTE: the doubles that follow are not aligned because of 5
194 ** longs preceeding
195 */
196 __glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble*) (pc+48));
197 __GLX_END(cmdlen);
198 } else {
199 /* Use GLXRenderLarge protocol to send command */
200 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d,cmdlen+4);
201 __GLX_PUT_DOUBLE(8,u1);
202 __GLX_PUT_DOUBLE(16,u2);
203 __GLX_PUT_DOUBLE(24,v1);
204 __GLX_PUT_DOUBLE(32,v2);
205 __GLX_PUT_LONG(40,target);
206 __GLX_PUT_LONG(44,uord);
207 __GLX_PUT_LONG(48,vord);
208
209 /*
210 ** NOTE: the doubles that follow are not aligned because of 5
211 ** longs preceeding
212 */
213 if ((vstr != k) || (ustr != k*vord)) {
214 GLdouble *buf;
215
216 buf = (GLdouble *) Xmalloc(compsize);
217 if (!buf) {
218 __glXSetError(gc, GL_OUT_OF_MEMORY);
219 return;
220 }
221 /*
222 ** Pack into a u-major ordering.
223 */
224 __glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
225 __glXSendLargeCommand(gc, pc, 52, buf, compsize);
226 Xfree((char*) buf);
227 } else {
228 /* Data is already packed. Just send it out */
229 __glXSendLargeCommand(gc, pc, 52, pnts, compsize);
230 }
231 }
232 }
233
234 void __indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr, GLint uord,
235 GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
236 const GLfloat *pnts)
237 {
238 __GLX_DECLARE_VARIABLES();
239 GLint k;
240
241 __GLX_LOAD_VARIABLES();
242 k = __glMap2f_size(target);
243 if (k == 0) {
244 __glXSetError(gc, GL_INVALID_ENUM);
245 return;
246 } else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
247 __glXSetError(gc, GL_INVALID_VALUE);
248 return;
249 }
250 compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
251 cmdlen = 32+compsize;
252 if (!gc->currentDpy) return;
253
254 /*
255 ** The order that arguments are packed is different from the order
256 ** for glMap2d.
257 */
258 if (cmdlen <= gc->maxSmallRenderCommandSize) {
259 /* Use GLXRender protocol to send small command */
260 __GLX_BEGIN_VARIABLE(X_GLrop_Map2f,cmdlen);
261 __GLX_PUT_LONG(4,target);
262 __GLX_PUT_FLOAT(8,u1);
263 __GLX_PUT_FLOAT(12,u2);
264 __GLX_PUT_LONG(16,uord);
265 __GLX_PUT_FLOAT(20,v1);
266 __GLX_PUT_FLOAT(24,v2);
267 __GLX_PUT_LONG(28,vord);
268 /*
269 ** Pack into a u-major ordering.
270 */
271 __glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat*) (pc+32));
272 __GLX_END(cmdlen);
273 } else {
274 /* Use GLXRenderLarge protocol to send command */
275 __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f,cmdlen+4);
276 __GLX_PUT_LONG(8,target);
277 __GLX_PUT_FLOAT(12,u1);
278 __GLX_PUT_FLOAT(16,u2);
279 __GLX_PUT_LONG(20,uord);
280 __GLX_PUT_FLOAT(24,v1);
281 __GLX_PUT_FLOAT(28,v2);
282 __GLX_PUT_LONG(32,vord);
283
284 if ((vstr != k) || (ustr != k*vord)) {
285 GLfloat *buf;
286
287 buf = (GLfloat *) Xmalloc(compsize);
288 if (!buf) {
289 __glXSetError(gc, GL_OUT_OF_MEMORY);
290 return;
291 }
292 /*
293 ** Pack into a u-major ordering.
294 */
295 __glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
296 __glXSendLargeCommand(gc, pc, 36, buf, compsize);
297 Xfree((char*) buf);
298 } else {
299 /* Data is already packed. Just send it out */
300 __glXSendLargeCommand(gc, pc, 36, pnts, compsize);
301 }
302 }
303 }
304
305 void __indirect_glEnable(GLenum cap)
306 {
307 __GLX_DECLARE_VARIABLES();
308
309 __GLX_LOAD_VARIABLES();
310 if (!gc->currentDpy) return;
311
312 switch(cap) {
313 case GL_COLOR_ARRAY:
314 case GL_EDGE_FLAG_ARRAY:
315 case GL_INDEX_ARRAY:
316 case GL_NORMAL_ARRAY:
317 case GL_TEXTURE_COORD_ARRAY:
318 case GL_VERTEX_ARRAY:
319 case GL_SECONDARY_COLOR_ARRAY:
320 case GL_FOG_COORD_ARRAY:
321 __indirect_glEnableClientState(cap);
322 return;
323 default:
324 break;
325 }
326
327 __GLX_BEGIN(X_GLrop_Enable,8);
328 __GLX_PUT_LONG(4,cap);
329 __GLX_END(8);
330 }
331
332 void __indirect_glDisable(GLenum cap)
333 {
334 __GLX_DECLARE_VARIABLES();
335
336 __GLX_LOAD_VARIABLES();
337 if (!gc->currentDpy) return;
338
339 switch(cap) {
340 case GL_COLOR_ARRAY:
341 case GL_EDGE_FLAG_ARRAY:
342 case GL_INDEX_ARRAY:
343 case GL_NORMAL_ARRAY:
344 case GL_TEXTURE_COORD_ARRAY:
345 case GL_VERTEX_ARRAY:
346 case GL_SECONDARY_COLOR_ARRAY:
347 case GL_FOG_COORD_ARRAY:
348 __indirect_glDisableClientState(cap);
349 return;
350 default:
351 break;
352 }
353
354 __GLX_BEGIN(X_GLrop_Disable,8);
355 __GLX_PUT_LONG(4,cap);
356 __GLX_END(8);
357 }