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