1848b8605Smrg/*
2848b8605Smrg * (C) Copyright IBM Corporation 2004
3848b8605Smrg * All Rights Reserved.
4848b8605Smrg *
5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6848b8605Smrg * copy of this software and associated documentation files (the "Software"),
7848b8605Smrg * to deal in the Software without restriction, including without limitation
8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom
10848b8605Smrg * the Software is furnished to do so, subject to the following conditions:
11848b8605Smrg *
12848b8605Smrg * The above copyright notice and this permission notice (including the next
13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
14848b8605Smrg * Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24848b8605Smrg
25848b8605Smrg/**
26848b8605Smrg * \file glx_texture_compression.c
27848b8605Smrg * Contains the routines required to implement GLX protocol for
28848b8605Smrg * ARB_texture_compression and related extensions.
29848b8605Smrg *
30848b8605Smrg * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt
31848b8605Smrg *
32848b8605Smrg * \author Ian Romanick <idr@us.ibm.com>
33848b8605Smrg */
34848b8605Smrg
35848b8605Smrg#include "packrender.h"
36848b8605Smrg#include "packsingle.h"
37848b8605Smrg#include "indirect.h"
38848b8605Smrg
39848b8605Smrg#include <assert.h>
40848b8605Smrg
41848b8605Smrg
42848b8605Smrgvoid
43848b8605Smrg__indirect_glGetCompressedTexImage(GLenum target, GLint level,
44848b8605Smrg                                      GLvoid * img)
45848b8605Smrg{
46848b8605Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
47848b8605Smrg   xGLXGetTexImageReply reply;
48848b8605Smrg   size_t image_bytes;
49848b8605Smrg
50848b8605Smrg   __GLX_SINGLE_LOAD_VARIABLES();
51848b8605Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetCompressedTexImage, 8);
52848b8605Smrg   __GLX_SINGLE_PUT_LONG(0, target);
53848b8605Smrg   __GLX_SINGLE_PUT_LONG(4, level);
54848b8605Smrg   __GLX_SINGLE_READ_XREPLY();
55848b8605Smrg
56848b8605Smrg   image_bytes = reply.width;
57848b8605Smrg   assert(image_bytes <= ((4 * reply.length) - 0));
58848b8605Smrg   assert(image_bytes >= ((4 * reply.length) - 3));
59848b8605Smrg
60848b8605Smrg   if (image_bytes != 0) {
61848b8605Smrg      _XRead(dpy, (char *) img, image_bytes);
62848b8605Smrg      if (image_bytes < (4 * reply.length)) {
63848b8605Smrg         _XEatData(dpy, (4 * reply.length) - image_bytes);
64848b8605Smrg      }
65848b8605Smrg   }
66848b8605Smrg
67848b8605Smrg   __GLX_SINGLE_END();
68848b8605Smrg}
69848b8605Smrg
70848b8605Smrg
71848b8605Smrg/**
72848b8605Smrg * Internal function used for \c glCompressedTexImage1D and
73848b8605Smrg * \c glCompressedTexImage2D.
74848b8605Smrg */
75848b8605Smrgstatic void
76848b8605SmrgCompressedTexImage1D2D(GLenum target, GLint level,
77848b8605Smrg                       GLenum internal_format,
78848b8605Smrg                       GLsizei width, GLsizei height,
79848b8605Smrg                       GLint border, GLsizei image_size,
80848b8605Smrg                       const GLvoid * data, CARD32 rop)
81848b8605Smrg{
82848b8605Smrg   __GLX_DECLARE_VARIABLES();
83848b8605Smrg
84848b8605Smrg   __GLX_LOAD_VARIABLES();
85848b8605Smrg   if (gc->currentDpy == NULL) {
86848b8605Smrg      return;
87848b8605Smrg   }
88848b8605Smrg
89848b8605Smrg   if ((target == GL_PROXY_TEXTURE_1D)
90848b8605Smrg       || (target == GL_PROXY_TEXTURE_2D)
91848b8605Smrg       || (target == GL_PROXY_TEXTURE_CUBE_MAP)) {
92848b8605Smrg      compsize = 0;
93848b8605Smrg   }
94848b8605Smrg   else {
95848b8605Smrg      compsize = image_size;
96848b8605Smrg   }
97848b8605Smrg
98848b8605Smrg   cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + compsize);
99848b8605Smrg   if (cmdlen <= gc->maxSmallRenderCommandSize) {
100848b8605Smrg      __GLX_BEGIN_VARIABLE(rop, cmdlen);
101848b8605Smrg      __GLX_PUT_LONG(4, target);
102848b8605Smrg      __GLX_PUT_LONG(8, level);
103848b8605Smrg      __GLX_PUT_LONG(12, internal_format);
104848b8605Smrg      __GLX_PUT_LONG(16, width);
105848b8605Smrg      __GLX_PUT_LONG(20, height);
106848b8605Smrg      __GLX_PUT_LONG(24, border);
107848b8605Smrg      __GLX_PUT_LONG(28, image_size);
108848b8605Smrg      if (compsize != 0) {
109848b8605Smrg         __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE,
110848b8605Smrg                              data, image_size);
111848b8605Smrg      }
112848b8605Smrg      __GLX_END(cmdlen);
113848b8605Smrg   }
114848b8605Smrg   else {
115848b8605Smrg      assert(compsize != 0);
116848b8605Smrg
117848b8605Smrg      __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
118848b8605Smrg      __GLX_PUT_LONG(8, target);
119848b8605Smrg      __GLX_PUT_LONG(12, level);
120848b8605Smrg      __GLX_PUT_LONG(16, internal_format);
121848b8605Smrg      __GLX_PUT_LONG(20, width);
122848b8605Smrg      __GLX_PUT_LONG(24, height);
123848b8605Smrg      __GLX_PUT_LONG(28, border);
124848b8605Smrg      __GLX_PUT_LONG(32, image_size);
125848b8605Smrg      __glXSendLargeCommand(gc, gc->pc,
126848b8605Smrg                            __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4,
127848b8605Smrg                            data, image_size);
128848b8605Smrg   }
129848b8605Smrg}
130848b8605Smrg
131848b8605Smrg
132848b8605Smrg/**
133848b8605Smrg * Internal function used for \c glCompressedTexSubImage1D and
134848b8605Smrg * \c glCompressedTexSubImage2D.
135848b8605Smrg */
136848b8605Smrgstatic void
137848b8605SmrgCompressedTexSubImage1D2D(GLenum target, GLint level,
138848b8605Smrg                          GLsizei xoffset, GLsizei yoffset,
139848b8605Smrg                          GLsizei width, GLsizei height,
140848b8605Smrg                          GLenum format, GLsizei image_size,
141848b8605Smrg                          const GLvoid * data, CARD32 rop)
142848b8605Smrg{
143848b8605Smrg   __GLX_DECLARE_VARIABLES();
144848b8605Smrg
145848b8605Smrg   __GLX_LOAD_VARIABLES();
146848b8605Smrg   if (gc->currentDpy == NULL) {
147848b8605Smrg      return;
148848b8605Smrg   }
149848b8605Smrg
150848b8605Smrg   if (target == GL_PROXY_TEXTURE_3D) {
151848b8605Smrg      compsize = 0;
152848b8605Smrg   }
153848b8605Smrg   else {
154848b8605Smrg      compsize = image_size;
155848b8605Smrg   }
156848b8605Smrg
157848b8605Smrg   cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + compsize);
158848b8605Smrg   if (cmdlen <= gc->maxSmallRenderCommandSize) {
159848b8605Smrg      __GLX_BEGIN_VARIABLE(rop, cmdlen);
160848b8605Smrg      __GLX_PUT_LONG(4, target);
161848b8605Smrg      __GLX_PUT_LONG(8, level);
162848b8605Smrg      __GLX_PUT_LONG(12, xoffset);
163848b8605Smrg      __GLX_PUT_LONG(16, yoffset);
164848b8605Smrg      __GLX_PUT_LONG(20, width);
165848b8605Smrg      __GLX_PUT_LONG(24, height);
166848b8605Smrg      __GLX_PUT_LONG(28, format);
167848b8605Smrg      __GLX_PUT_LONG(32, image_size);
168848b8605Smrg      if (compsize != 0) {
169848b8605Smrg         __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE,
170848b8605Smrg                              data, image_size);
171848b8605Smrg      }
172848b8605Smrg      __GLX_END(cmdlen);
173848b8605Smrg   }
174848b8605Smrg   else {
175848b8605Smrg      assert(compsize != 0);
176848b8605Smrg
177848b8605Smrg      __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
178848b8605Smrg      __GLX_PUT_LONG(8, target);
179848b8605Smrg      __GLX_PUT_LONG(12, level);
180848b8605Smrg      __GLX_PUT_LONG(16, xoffset);
181848b8605Smrg      __GLX_PUT_LONG(20, yoffset);
182848b8605Smrg      __GLX_PUT_LONG(24, width);
183848b8605Smrg      __GLX_PUT_LONG(28, height);
184848b8605Smrg      __GLX_PUT_LONG(32, format);
185848b8605Smrg      __GLX_PUT_LONG(36, image_size);
186848b8605Smrg      __glXSendLargeCommand(gc, gc->pc,
187848b8605Smrg                            __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4,
188848b8605Smrg                            data, image_size);
189848b8605Smrg   }
190848b8605Smrg}
191848b8605Smrg
192848b8605Smrg
193848b8605Smrgvoid
194848b8605Smrg__indirect_glCompressedTexImage1D(GLenum target, GLint level,
195848b8605Smrg                                     GLenum internal_format, GLsizei width,
196848b8605Smrg                                     GLint border, GLsizei image_size,
197848b8605Smrg                                     const GLvoid * data)
198848b8605Smrg{
199848b8605Smrg   CompressedTexImage1D2D(target, level, internal_format, width, 0,
200848b8605Smrg                          border, image_size, data,
201848b8605Smrg                          X_GLrop_CompressedTexImage1D);
202848b8605Smrg}
203848b8605Smrg
204848b8605Smrg
205848b8605Smrgvoid
206848b8605Smrg__indirect_glCompressedTexImage2D(GLenum target, GLint level,
207848b8605Smrg                                     GLenum internal_format,
208848b8605Smrg                                     GLsizei width, GLsizei height,
209848b8605Smrg                                     GLint border, GLsizei image_size,
210848b8605Smrg                                     const GLvoid * data)
211848b8605Smrg{
212848b8605Smrg   CompressedTexImage1D2D(target, level, internal_format, width, height,
213848b8605Smrg                          border, image_size, data,
214848b8605Smrg                          X_GLrop_CompressedTexImage2D);
215848b8605Smrg}
216848b8605Smrg
217848b8605Smrg
218848b8605Smrgvoid
219848b8605Smrg__indirect_glCompressedTexImage3D(GLenum target, GLint level,
220848b8605Smrg                                     GLenum internal_format,
221848b8605Smrg                                     GLsizei width, GLsizei height,
222848b8605Smrg                                     GLsizei depth, GLint border,
223848b8605Smrg                                     GLsizei image_size, const GLvoid * data)
224848b8605Smrg{
225848b8605Smrg   __GLX_DECLARE_VARIABLES();
226848b8605Smrg
227848b8605Smrg   __GLX_LOAD_VARIABLES();
228848b8605Smrg   if (gc->currentDpy == NULL) {
229848b8605Smrg      return;
230848b8605Smrg   }
231848b8605Smrg
232848b8605Smrg   cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + image_size);
233848b8605Smrg   if (cmdlen <= gc->maxSmallRenderCommandSize) {
234848b8605Smrg      __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexImage3D, cmdlen);
235848b8605Smrg      __GLX_PUT_LONG(4, target);
236848b8605Smrg      __GLX_PUT_LONG(8, level);
237848b8605Smrg      __GLX_PUT_LONG(12, internal_format);
238848b8605Smrg      __GLX_PUT_LONG(16, width);
239848b8605Smrg      __GLX_PUT_LONG(20, height);
240848b8605Smrg      __GLX_PUT_LONG(24, depth);
241848b8605Smrg      __GLX_PUT_LONG(28, border);
242848b8605Smrg      __GLX_PUT_LONG(32, image_size);
243848b8605Smrg      if (image_size != 0) {
244848b8605Smrg         __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE,
245848b8605Smrg                              data, image_size);
246848b8605Smrg      }
247848b8605Smrg      __GLX_END(cmdlen);
248848b8605Smrg   }
249848b8605Smrg   else {
250848b8605Smrg      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexImage3D, cmdlen + 4);
251848b8605Smrg      __GLX_PUT_LONG(8, target);
252848b8605Smrg      __GLX_PUT_LONG(12, level);
253848b8605Smrg      __GLX_PUT_LONG(16, internal_format);
254848b8605Smrg      __GLX_PUT_LONG(20, width);
255848b8605Smrg      __GLX_PUT_LONG(24, height);
256848b8605Smrg      __GLX_PUT_LONG(28, depth);
257848b8605Smrg      __GLX_PUT_LONG(32, border);
258848b8605Smrg      __GLX_PUT_LONG(36, image_size);
259848b8605Smrg      __glXSendLargeCommand(gc, gc->pc,
260848b8605Smrg                            __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4,
261848b8605Smrg                            data, image_size);
262848b8605Smrg   }
263848b8605Smrg}
264848b8605Smrg
265848b8605Smrg
266848b8605Smrgvoid
267848b8605Smrg__indirect_glCompressedTexSubImage1D(GLenum target, GLint level,
268848b8605Smrg                                        GLint xoffset,
269848b8605Smrg                                        GLsizei width,
270848b8605Smrg                                        GLenum format, GLsizei image_size,
271848b8605Smrg                                        const GLvoid * data)
272848b8605Smrg{
273848b8605Smrg   CompressedTexSubImage1D2D(target, level, xoffset, 0, width, 0,
274848b8605Smrg                             format, image_size, data,
275848b8605Smrg                             X_GLrop_CompressedTexSubImage1D);
276848b8605Smrg}
277848b8605Smrg
278848b8605Smrg
279848b8605Smrgvoid
280848b8605Smrg__indirect_glCompressedTexSubImage2D(GLenum target, GLint level,
281848b8605Smrg                                        GLint xoffset, GLint yoffset,
282848b8605Smrg                                        GLsizei width, GLsizei height,
283848b8605Smrg                                        GLenum format, GLsizei image_size,
284848b8605Smrg                                        const GLvoid * data)
285848b8605Smrg{
286848b8605Smrg   CompressedTexSubImage1D2D(target, level, xoffset, yoffset, width, height,
287848b8605Smrg                             format, image_size, data,
288848b8605Smrg                             X_GLrop_CompressedTexSubImage2D);
289848b8605Smrg}
290848b8605Smrg
291848b8605Smrg
292848b8605Smrgvoid
293848b8605Smrg__indirect_glCompressedTexSubImage3D(GLenum target, GLint level,
294848b8605Smrg                                        GLint xoffset, GLint yoffset,
295848b8605Smrg                                        GLint zoffset, GLsizei width,
296848b8605Smrg                                        GLsizei height, GLsizei depth,
297848b8605Smrg                                        GLenum format, GLsizei image_size,
298848b8605Smrg                                        const GLvoid * data)
299848b8605Smrg{
300848b8605Smrg   __GLX_DECLARE_VARIABLES();
301848b8605Smrg
302848b8605Smrg   __GLX_LOAD_VARIABLES();
303848b8605Smrg   if (gc->currentDpy == NULL) {
304848b8605Smrg      return;
305848b8605Smrg   }
306848b8605Smrg
307848b8605Smrg   cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE
308848b8605Smrg                      + image_size);
309848b8605Smrg   if (cmdlen <= gc->maxSmallRenderCommandSize) {
310848b8605Smrg      __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexSubImage3D, cmdlen);
311848b8605Smrg      __GLX_PUT_LONG(4, target);
312848b8605Smrg      __GLX_PUT_LONG(8, level);
313848b8605Smrg      __GLX_PUT_LONG(12, xoffset);
314848b8605Smrg      __GLX_PUT_LONG(16, yoffset);
315848b8605Smrg      __GLX_PUT_LONG(20, zoffset);
316848b8605Smrg      __GLX_PUT_LONG(24, width);
317848b8605Smrg      __GLX_PUT_LONG(28, height);
318848b8605Smrg      __GLX_PUT_LONG(32, depth);
319848b8605Smrg      __GLX_PUT_LONG(36, format);
320848b8605Smrg      __GLX_PUT_LONG(40, image_size);
321848b8605Smrg      if (image_size != 0) {
322848b8605Smrg         __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE,
323848b8605Smrg                              data, image_size);
324848b8605Smrg      }
325848b8605Smrg      __GLX_END(cmdlen);
326848b8605Smrg   }
327848b8605Smrg   else {
328848b8605Smrg      __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexSubImage3D, cmdlen + 4);
329848b8605Smrg      __GLX_PUT_LONG(8, target);
330848b8605Smrg      __GLX_PUT_LONG(12, level);
331848b8605Smrg      __GLX_PUT_LONG(16, xoffset);
332848b8605Smrg      __GLX_PUT_LONG(20, yoffset);
333848b8605Smrg      __GLX_PUT_LONG(24, zoffset);
334848b8605Smrg      __GLX_PUT_LONG(28, width);
335848b8605Smrg      __GLX_PUT_LONG(32, height);
336848b8605Smrg      __GLX_PUT_LONG(36, depth);
337848b8605Smrg      __GLX_PUT_LONG(40, format);
338848b8605Smrg      __GLX_PUT_LONG(44, image_size);
339848b8605Smrg      __glXSendLargeCommand(gc, gc->pc,
340848b8605Smrg                            __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4,
341848b8605Smrg                            data, image_size);
342848b8605Smrg   }
343848b8605Smrg}
344