Home | History | Annotate | Download | only in glx
      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_glGetCompressedTexImage(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_glCompressedTexImage1D(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_glCompressedTexImage2D(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_glCompressedTexImage3D(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_glCompressedTexSubImage1D(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_glCompressedTexSubImage2D(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_glCompressedTexSubImage3D(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