/* * (C) Copyright IBM Corporation 2004 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file glx_texture_compression.c * Contains the routines required to implement GLX protocol for * ARB_texture_compression and related extensions. * * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt * * \author Ian Romanick <idr@us.ibm.com> */ #include "packrender.h" #include "packsingle.h" #include "indirect.h" #include <assert.h> void __indirect_glGetCompressedTexImageARB(GLenum target, GLint level, GLvoid * img) { __GLX_SINGLE_DECLARE_VARIABLES(); xGLXGetTexImageReply reply; size_t image_bytes; __GLX_SINGLE_LOAD_VARIABLES(); __GLX_SINGLE_BEGIN(X_GLsop_GetCompressedTexImage, 8); __GLX_SINGLE_PUT_LONG(0, target); __GLX_SINGLE_PUT_LONG(4, level); __GLX_SINGLE_READ_XREPLY(); image_bytes = reply.width; assert(image_bytes <= ((4 * reply.length) - 0)); assert(image_bytes >= ((4 * reply.length) - 3)); if (image_bytes != 0) { _XRead(dpy, (char *) img, image_bytes); if (image_bytes < (4 * reply.length)) { _XEatData(dpy, (4 * reply.length) - image_bytes); } } __GLX_SINGLE_END(); } /** * Internal function used for \c glCompressedTexImage1D and * \c glCompressedTexImage2D. */ static void CompressedTexImage1D2D(GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, GLsizei image_size, const GLvoid * data, CARD32 rop) { __GLX_DECLARE_VARIABLES(); __GLX_LOAD_VARIABLES(); if (gc->currentDpy == NULL) { return; } if ((target == GL_PROXY_TEXTURE_1D) || (target == GL_PROXY_TEXTURE_2D) || (target == GL_PROXY_TEXTURE_CUBE_MAP)) { compsize = 0; } else { compsize = image_size; } cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + compsize); if (cmdlen <= gc->maxSmallRenderCommandSize) { __GLX_BEGIN_VARIABLE(rop, cmdlen); __GLX_PUT_LONG(4, target); __GLX_PUT_LONG(8, level); __GLX_PUT_LONG(12, internal_format); __GLX_PUT_LONG(16, width); __GLX_PUT_LONG(20, height); __GLX_PUT_LONG(24, border); __GLX_PUT_LONG(28, image_size); if (compsize != 0) { __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE, data, image_size); } __GLX_END(cmdlen); } else { assert(compsize != 0); __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4); __GLX_PUT_LONG(8, target); __GLX_PUT_LONG(12, level); __GLX_PUT_LONG(16, internal_format); __GLX_PUT_LONG(20, width); __GLX_PUT_LONG(24, height); __GLX_PUT_LONG(28, border); __GLX_PUT_LONG(32, image_size); __glXSendLargeCommand(gc, gc->pc, __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4, data, image_size); } } /** * Internal function used for \c glCompressedTexSubImage1D and * \c glCompressedTexSubImage2D. */ 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) { __GLX_DECLARE_VARIABLES(); __GLX_LOAD_VARIABLES(); if (gc->currentDpy == NULL) { return; } if (target == GL_PROXY_TEXTURE_3D) { compsize = 0; } else { compsize = image_size; } cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + compsize); if (cmdlen <= gc->maxSmallRenderCommandSize) { __GLX_BEGIN_VARIABLE(rop, cmdlen); __GLX_PUT_LONG(4, target); __GLX_PUT_LONG(8, level); __GLX_PUT_LONG(12, xoffset); __GLX_PUT_LONG(16, yoffset); __GLX_PUT_LONG(20, width); __GLX_PUT_LONG(24, height); __GLX_PUT_LONG(28, format); __GLX_PUT_LONG(32, image_size); if (compsize != 0) { __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE, data, image_size); } __GLX_END(cmdlen); } else { assert(compsize != 0); __GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4); __GLX_PUT_LONG(8, target); __GLX_PUT_LONG(12, level); __GLX_PUT_LONG(16, xoffset); __GLX_PUT_LONG(20, yoffset); __GLX_PUT_LONG(24, width); __GLX_PUT_LONG(28, height); __GLX_PUT_LONG(32, format); __GLX_PUT_LONG(36, image_size); __glXSendLargeCommand(gc, gc->pc, __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4, data, image_size); } } void __indirect_glCompressedTexImage1DARB(GLenum target, GLint level, GLenum internal_format, GLsizei width, GLint border, GLsizei image_size, const GLvoid * data) { CompressedTexImage1D2D(target, level, internal_format, width, 0, border, image_size, data, X_GLrop_CompressedTexImage1D); } void __indirect_glCompressedTexImage2DARB(GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, GLsizei image_size, const GLvoid * data) { CompressedTexImage1D2D(target, level, internal_format, width, height, border, image_size, data, X_GLrop_CompressedTexImage2D); } void __indirect_glCompressedTexImage3DARB(GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei image_size, const GLvoid * data) { __GLX_DECLARE_VARIABLES(); __GLX_LOAD_VARIABLES(); if (gc->currentDpy == NULL) { return; } cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + image_size); if (cmdlen <= gc->maxSmallRenderCommandSize) { __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexImage3D, cmdlen); __GLX_PUT_LONG(4, target); __GLX_PUT_LONG(8, level); __GLX_PUT_LONG(12, internal_format); __GLX_PUT_LONG(16, width); __GLX_PUT_LONG(20, height); __GLX_PUT_LONG(24, depth); __GLX_PUT_LONG(28, border); __GLX_PUT_LONG(32, image_size); if (image_size != 0) { __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE, data, image_size); } __GLX_END(cmdlen); } else { __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexImage3D, cmdlen + 4); __GLX_PUT_LONG(8, target); __GLX_PUT_LONG(12, level); __GLX_PUT_LONG(16, internal_format); __GLX_PUT_LONG(20, width); __GLX_PUT_LONG(24, height); __GLX_PUT_LONG(28, depth); __GLX_PUT_LONG(32, border); __GLX_PUT_LONG(36, image_size); __glXSendLargeCommand(gc, gc->pc, __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4, data, image_size); } } void __indirect_glCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei image_size, const GLvoid * data) { CompressedTexSubImage1D2D(target, level, xoffset, 0, width, 0, format, image_size, data, X_GLrop_CompressedTexSubImage1D); } void __indirect_glCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei image_size, const GLvoid * data) { CompressedTexSubImage1D2D(target, level, xoffset, yoffset, width, height, format, image_size, data, X_GLrop_CompressedTexSubImage2D); } 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) { __GLX_DECLARE_VARIABLES(); __GLX_LOAD_VARIABLES(); if (gc->currentDpy == NULL) { return; } cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + image_size); if (cmdlen <= gc->maxSmallRenderCommandSize) { __GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexSubImage3D, cmdlen); __GLX_PUT_LONG(4, target); __GLX_PUT_LONG(8, level); __GLX_PUT_LONG(12, xoffset); __GLX_PUT_LONG(16, yoffset); __GLX_PUT_LONG(20, zoffset); __GLX_PUT_LONG(24, width); __GLX_PUT_LONG(28, height); __GLX_PUT_LONG(32, depth); __GLX_PUT_LONG(36, format); __GLX_PUT_LONG(40, image_size); if (image_size != 0) { __GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE, data, image_size); } __GLX_END(cmdlen); } else { __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexSubImage3D, cmdlen + 4); __GLX_PUT_LONG(8, target); __GLX_PUT_LONG(12, level); __GLX_PUT_LONG(16, xoffset); __GLX_PUT_LONG(20, yoffset); __GLX_PUT_LONG(24, zoffset); __GLX_PUT_LONG(28, width); __GLX_PUT_LONG(32, height); __GLX_PUT_LONG(36, depth); __GLX_PUT_LONG(40, format); __GLX_PUT_LONG(44, image_size); __glXSendLargeCommand(gc, gc->pc, __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4, data, image_size); } }