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