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 (at) 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 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 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 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 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 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 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 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 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 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