1 /*
2  * (C) Copyright IBM Corporation 2004
3  * 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  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \file glx_texture_compression.c
27  * Contains the routines required to implement GLX protocol for
28  * ARB_texture_compression and related extensions.
29  *
30  * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt
31  *
32  * \author Ian Romanick <idr@us.ibm.com>
33  */
34 
35 #include "packrender.h"
36 #include "packsingle.h"
37 #include "indirect.h"
38 
39 #include <assert.h>
40 
41 
42 void
__indirect_glGetCompressedTexImageARB(GLenum target,GLint level,GLvoid * img)43 __indirect_glGetCompressedTexImageARB(GLenum target, GLint level,
44                                       GLvoid * img)
45 {
46    __GLX_SINGLE_DECLARE_VARIABLES();
47    xGLXGetTexImageReply reply;
48    size_t image_bytes;
49 
50    __GLX_SINGLE_LOAD_VARIABLES();
51    __GLX_SINGLE_BEGIN(X_GLsop_GetCompressedTexImage, 8);
52    __GLX_SINGLE_PUT_LONG(0, target);
53    __GLX_SINGLE_PUT_LONG(4, level);
54    __GLX_SINGLE_READ_XREPLY();
55 
56    image_bytes = reply.width;
57    assert(image_bytes <= ((4 * reply.length) - 0));
58    assert(image_bytes >= ((4 * reply.length) - 3));
59 
60    if (image_bytes != 0) {
61       _XRead(dpy, (char *) img, image_bytes);
62       if (image_bytes < (4 * reply.length)) {
63          _XEatData(dpy, (4 * reply.length) - image_bytes);
64       }
65    }
66 
67    __GLX_SINGLE_END();
68 }
69 
70 
71 /**
72  * Internal function used for \c glCompressedTexImage1D and
73  * \c glCompressedTexImage2D.
74  */
75 static void
CompressedTexImage1D2D(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLsizei height,GLint border,GLsizei image_size,const GLvoid * data,CARD32 rop)76 CompressedTexImage1D2D(GLenum target, GLint level,
77                        GLenum internal_format,
78                        GLsizei width, GLsizei height,
79                        GLint border, GLsizei image_size,
80                        const GLvoid * data, CARD32 rop)
81 {
82    __GLX_DECLARE_VARIABLES();
83 
84    __GLX_LOAD_VARIABLES();
85    if (gc->currentDpy == NULL) {
86       return;
87    }
88 
89    if ((target == GL_PROXY_TEXTURE_1D)
90        || (target == GL_PROXY_TEXTURE_2D)
91        || (target == GL_PROXY_TEXTURE_CUBE_MAP)) {
92       compsize = 0;
93    }
94    else {
95       compsize = image_size;
96    }
97 
98    cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + compsize);
99    if (cmdlen <= gc->maxSmallRenderCommandSize) {
100       __GLX_BEGIN_VARIABLE(rop, cmdlen);
101       __GLX_PUT_LONG(4, target);
102       __GLX_PUT_LONG(8, level);
103       __GLX_PUT_LONG(12, internal_format);
104       __GLX_PUT_LONG(16, width);
105       __GLX_PUT_LONG(20, height);
106       __GLX_PUT_LONG(24, border);
107       __GLX_PUT_LONG(28, image_size);
108       if (compsize != 0) {
109          __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE,
110                               data, image_size);
111       }
112       __GLX_END(cmdlen);
113    }
114    else {
115       assert(compsize != 0);
116 
117       __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
118       __GLX_PUT_LONG(8, target);
119       __GLX_PUT_LONG(12, level);
120       __GLX_PUT_LONG(16, internal_format);
121       __GLX_PUT_LONG(20, width);
122       __GLX_PUT_LONG(24, height);
123       __GLX_PUT_LONG(28, border);
124       __GLX_PUT_LONG(32, image_size);
125       __glXSendLargeCommand(gc, gc->pc,
126                             __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4,
127                             data, image_size);
128    }
129 }
130 
131 
132 /**
133  * Internal function used for \c glCompressedTexSubImage1D and
134  * \c glCompressedTexSubImage2D.
135  */
136 static void
CompressedTexSubImage1D2D(GLenum target,GLint level,GLsizei xoffset,GLsizei yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei image_size,const GLvoid * data,CARD32 rop)137 CompressedTexSubImage1D2D(GLenum target, GLint level,
138                           GLsizei xoffset, GLsizei yoffset,
139                           GLsizei width, GLsizei height,
140                           GLenum format, GLsizei image_size,
141                           const GLvoid * data, CARD32 rop)
142 {
143    __GLX_DECLARE_VARIABLES();
144 
145    __GLX_LOAD_VARIABLES();
146    if (gc->currentDpy == NULL) {
147       return;
148    }
149 
150    if (target == GL_PROXY_TEXTURE_3D) {
151       compsize = 0;
152    }
153    else {
154       compsize = image_size;
155    }
156 
157    cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + compsize);
158    if (cmdlen <= gc->maxSmallRenderCommandSize) {
159       __GLX_BEGIN_VARIABLE(rop, cmdlen);
160       __GLX_PUT_LONG(4, target);
161       __GLX_PUT_LONG(8, level);
162       __GLX_PUT_LONG(12, xoffset);
163       __GLX_PUT_LONG(16, yoffset);
164       __GLX_PUT_LONG(20, width);
165       __GLX_PUT_LONG(24, height);
166       __GLX_PUT_LONG(28, format);
167       __GLX_PUT_LONG(32, image_size);
168       if (compsize != 0) {
169          __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE,
170                               data, image_size);
171       }
172       __GLX_END(cmdlen);
173    }
174    else {
175       assert(compsize != 0);
176 
177       __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
178       __GLX_PUT_LONG(8, target);
179       __GLX_PUT_LONG(12, level);
180       __GLX_PUT_LONG(16, xoffset);
181       __GLX_PUT_LONG(20, yoffset);
182       __GLX_PUT_LONG(24, width);
183       __GLX_PUT_LONG(28, height);
184       __GLX_PUT_LONG(32, format);
185       __GLX_PUT_LONG(36, image_size);
186       __glXSendLargeCommand(gc, gc->pc,
187                             __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4,
188                             data, image_size);
189    }
190 }
191 
192 
193 void
__indirect_glCompressedTexImage1DARB(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLint border,GLsizei image_size,const GLvoid * data)194 __indirect_glCompressedTexImage1DARB(GLenum target, GLint level,
195                                      GLenum internal_format, GLsizei width,
196                                      GLint border, GLsizei image_size,
197                                      const GLvoid * data)
198 {
199    CompressedTexImage1D2D(target, level, internal_format, width, 0,
200                           border, image_size, data,
201                           X_GLrop_CompressedTexImage1D);
202 }
203 
204 
205 void
__indirect_glCompressedTexImage2DARB(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLsizei height,GLint border,GLsizei image_size,const GLvoid * data)206 __indirect_glCompressedTexImage2DARB(GLenum target, GLint level,
207                                      GLenum internal_format,
208                                      GLsizei width, GLsizei height,
209                                      GLint border, GLsizei image_size,
210                                      const GLvoid * data)
211 {
212    CompressedTexImage1D2D(target, level, internal_format, width, height,
213                           border, image_size, data,
214                           X_GLrop_CompressedTexImage2D);
215 }
216 
217 
218 void
__indirect_glCompressedTexImage3DARB(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei image_size,const GLvoid * data)219 __indirect_glCompressedTexImage3DARB(GLenum target, GLint level,
220                                      GLenum internal_format,
221                                      GLsizei width, GLsizei height,
222                                      GLsizei depth, GLint border,
223                                      GLsizei image_size, const GLvoid * data)
224 {
225    __GLX_DECLARE_VARIABLES();
226 
227    __GLX_LOAD_VARIABLES();
228    if (gc->currentDpy == NULL) {
229       return;
230    }
231 
232    cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + image_size);
233    if (cmdlen <= gc->maxSmallRenderCommandSize) {
234       __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexImage3D, cmdlen);
235       __GLX_PUT_LONG(4, target);
236       __GLX_PUT_LONG(8, level);
237       __GLX_PUT_LONG(12, internal_format);
238       __GLX_PUT_LONG(16, width);
239       __GLX_PUT_LONG(20, height);
240       __GLX_PUT_LONG(24, depth);
241       __GLX_PUT_LONG(28, border);
242       __GLX_PUT_LONG(32, image_size);
243       if (image_size != 0) {
244          __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE,
245                               data, image_size);
246       }
247       __GLX_END(cmdlen);
248    }
249    else {
250       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexImage3D, cmdlen + 4);
251       __GLX_PUT_LONG(8, target);
252       __GLX_PUT_LONG(12, level);
253       __GLX_PUT_LONG(16, internal_format);
254       __GLX_PUT_LONG(20, width);
255       __GLX_PUT_LONG(24, height);
256       __GLX_PUT_LONG(28, depth);
257       __GLX_PUT_LONG(32, border);
258       __GLX_PUT_LONG(36, image_size);
259       __glXSendLargeCommand(gc, gc->pc,
260                             __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4,
261                             data, image_size);
262    }
263 }
264 
265 
266 void
__indirect_glCompressedTexSubImage1DARB(GLenum target,GLint level,GLint xoffset,GLsizei width,GLenum format,GLsizei image_size,const GLvoid * data)267 __indirect_glCompressedTexSubImage1DARB(GLenum target, GLint level,
268                                         GLint xoffset,
269                                         GLsizei width,
270                                         GLenum format, GLsizei image_size,
271                                         const GLvoid * data)
272 {
273    CompressedTexSubImage1D2D(target, level, xoffset, 0, width, 0,
274                              format, image_size, data,
275                              X_GLrop_CompressedTexSubImage1D);
276 }
277 
278 
279 void
__indirect_glCompressedTexSubImage2DARB(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei image_size,const GLvoid * data)280 __indirect_glCompressedTexSubImage2DARB(GLenum target, GLint level,
281                                         GLint xoffset, GLint yoffset,
282                                         GLsizei width, GLsizei height,
283                                         GLenum format, GLsizei image_size,
284                                         const GLvoid * data)
285 {
286    CompressedTexSubImage1D2D(target, level, xoffset, yoffset, width, height,
287                              format, image_size, data,
288                              X_GLrop_CompressedTexSubImage2D);
289 }
290 
291 
292 void
__indirect_glCompressedTexSubImage3DARB(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei image_size,const GLvoid * data)293 __indirect_glCompressedTexSubImage3DARB(GLenum target, GLint level,
294                                         GLint xoffset, GLint yoffset,
295                                         GLint zoffset, GLsizei width,
296                                         GLsizei height, GLsizei depth,
297                                         GLenum format, GLsizei image_size,
298                                         const GLvoid * data)
299 {
300    __GLX_DECLARE_VARIABLES();
301 
302    __GLX_LOAD_VARIABLES();
303    if (gc->currentDpy == NULL) {
304       return;
305    }
306 
307    cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE
308                       + image_size);
309    if (cmdlen <= gc->maxSmallRenderCommandSize) {
310       __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexSubImage3D, cmdlen);
311       __GLX_PUT_LONG(4, target);
312       __GLX_PUT_LONG(8, level);
313       __GLX_PUT_LONG(12, xoffset);
314       __GLX_PUT_LONG(16, yoffset);
315       __GLX_PUT_LONG(20, zoffset);
316       __GLX_PUT_LONG(24, width);
317       __GLX_PUT_LONG(28, height);
318       __GLX_PUT_LONG(32, depth);
319       __GLX_PUT_LONG(36, format);
320       __GLX_PUT_LONG(40, image_size);
321       if (image_size != 0) {
322          __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE,
323                               data, image_size);
324       }
325       __GLX_END(cmdlen);
326    }
327    else {
328       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexSubImage3D, cmdlen + 4);
329       __GLX_PUT_LONG(8, target);
330       __GLX_PUT_LONG(12, level);
331       __GLX_PUT_LONG(16, xoffset);
332       __GLX_PUT_LONG(20, yoffset);
333       __GLX_PUT_LONG(24, zoffset);
334       __GLX_PUT_LONG(28, width);
335       __GLX_PUT_LONG(32, height);
336       __GLX_PUT_LONG(36, depth);
337       __GLX_PUT_LONG(40, format);
338       __GLX_PUT_LONG(44, image_size);
339       __glXSendLargeCommand(gc, gc->pc,
340                             __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4,
341                             data, image_size);
342    }
343 }
344