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