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