117158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca/* 217158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca * (C) Copyright IBM Corporation 2004 3df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * All Rights Reserved. 4df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 5df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 6df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * copy of this software and associated documentation files (the "Software"), 7df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * to deal in the Software without restriction, including without limitation 8df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * on the rights to use, copy, modify, merge, publish, distribute, sub 9df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * license, and/or sell copies of the Software, and to permit persons to whom 10df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * the Software is furnished to do so, subject to the following conditions: 11df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 12df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * The above copyright notice and this permission notice (including the next 13df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * paragraph) shall be included in all copies or substantial portions of the 14df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * Software. 15df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 16df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2217158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca * USE OR OTHER DEALINGS IN THE SOFTWARE. 2317158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca */ 24df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 25df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca/** 26df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * \file glx_texture_compression.c 2717158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca * Contains the routines required to implement GLX protocol for 28df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * ARB_texture_compression and related extensions. 29df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 30df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt 31df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 32df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * \author Ian Romanick <idr@us.ibm.com> 3317158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca */ 3417158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca 35df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca#include "packrender.h" 36df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca#include "packsingle.h" 37df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca#include "indirect.h" 38df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 39df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca#include <assert.h> 40df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 41df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 42df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecavoid 43df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca__indirect_glGetCompressedTexImageARB(GLenum target, GLint level, 44df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca GLvoid * img) 45df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 46df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_DECLARE_VARIABLES(); 47df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca xGLXGetTexImageReply reply; 48df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca size_t image_bytes; 49df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 50df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_LOAD_VARIABLES(); 51df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_BEGIN(X_GLsop_GetCompressedTexImage, 8); 523ad56968f09397a8dd417eae025b9506efaf8414Brian Paul __GLX_SINGLE_PUT_LONG(0, target); 53df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_PUT_LONG(4, level); 54df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_READ_XREPLY(); 55df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 56df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca image_bytes = reply.width; 57df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca assert(image_bytes <= ((4 * reply.length) - 0)); 58df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca assert(image_bytes >= ((4 * reply.length) - 3)); 59df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 60df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (image_bytes != 0) { 61df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca _XRead(dpy, (char *) img, image_bytes); 62df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (image_bytes < (4 * reply.length)) { 63df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca _XEatData(dpy, (4 * reply.length) - image_bytes); 643ad56968f09397a8dd417eae025b9506efaf8414Brian Paul } 65df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 66df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 67df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_SINGLE_END(); 68df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 69df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 70df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 71df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca/** 723ad56968f09397a8dd417eae025b9506efaf8414Brian Paul * Internal function used for \c glCompressedTexImage1D and 73df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * \c glCompressedTexImage2D. 74df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca */ 75df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastatic void 76df8ab3140ce05599e1dc983ac211a30fc845d9b5José FonsecaCompressedTexImage1D2D(GLenum target, GLint level, 77df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca GLenum internal_format, 78df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca GLsizei width, GLsizei height, 793ad56968f09397a8dd417eae025b9506efaf8414Brian Paul GLint border, GLsizei image_size, 80df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca const GLvoid * data, CARD32 rop) 81df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 82df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca __GLX_DECLARE_VARIABLES(); 83df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 843ad56968f09397a8dd417eae025b9506efaf8414Brian Paul __GLX_LOAD_VARIABLES(); 85df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (gc->currentDpy == NULL) { 86df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return; 8794726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul } 88df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 893ad56968f09397a8dd417eae025b9506efaf8414Brian Paul if ((target == GL_PROXY_TEXTURE_1D) 90df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca || (target == GL_PROXY_TEXTURE_2D) 91df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca || (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