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
42void
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 */
75static void
76CompressedTexImage1D2D(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 */
136static void
137CompressedTexSubImage1D2D(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
193void
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
205void
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
218void
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
266void
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
279void
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
292void
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