Home | History | Annotate | Download | only in glx
      1 #ifndef __GLX_packrender_h__
      2 #define __GLX_packrender_h__
      3 
      4 /*
      5  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
      6  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice including the dates of first publication and
     16  * either this permission notice or a reference to
     17  * http://oss.sgi.com/projects/FreeB/
     18  * shall be included in all copies or substantial portions of the Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     23  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     24  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     25  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     26  * SOFTWARE.
     27  *
     28  * Except as contained in this notice, the name of Silicon Graphics, Inc.
     29  * shall not be used in advertising or otherwise to promote the sale, use or
     30  * other dealings in this Software without prior written authorization from
     31  * Silicon Graphics, Inc.
     32  */
     33 
     34 #include "glxclient.h"
     35 
     36 /*
     37 ** The macros in this header convert the client machine's native data types to
     38 ** wire protocol data types.  The header is part of the porting layer of the
     39 ** client library, and it is intended that hardware vendors will rewrite this
     40 ** header to suit their own machines.
     41 */
     42 
     43 /*
     44 ** Pad a count of bytes to the nearest multiple of 4.  The X protocol
     45 ** transfers data in 4 byte quantities, so this macro is used to
     46 ** insure the right amount of data being sent.
     47 */
     48 #define __GLX_PAD(a) (((a)+3) & ~3)
     49 
     50 /*
     51 ** Network size parameters
     52 */
     53 #define sz_double 8
     54 
     55 /* Setup for all commands */
     56 #define __GLX_DECLARE_VARIABLES()               \
     57    struct glx_context *gc;                            \
     58    GLubyte *pc, *pixelHeaderPC;                 \
     59    GLuint compsize, cmdlen
     60 
     61 #define __GLX_LOAD_VARIABLES()     \
     62    gc = __glXGetCurrentContext();  \
     63    pc = gc->pc;                    \
     64    /* Muffle compilers */                  \
     65    cmdlen = 0;         (void)cmdlen;          \
     66    compsize = 0;       (void)compsize;        \
     67    pixelHeaderPC = 0;  (void)pixelHeaderPC
     68 
     69 /*
     70 ** Variable sized command support macro.  This macro is used by calls
     71 ** that are potentially larger than __GLX_SMALL_RENDER_CMD_SIZE.
     72 ** Because of their size, they may not automatically fit in the buffer.
     73 ** If the buffer can't hold the command then it is flushed so that
     74 ** the command will fit in the next buffer.
     75 */
     76 #define __GLX_BEGIN_VARIABLE(opcode,size)       \
     77    if (pc + (size) > gc->bufEnd) {              \
     78       pc = __glXFlushRenderBuffer(gc, pc);      \
     79    }                                            \
     80    __GLX_PUT_SHORT(0,size);                     \
     81    __GLX_PUT_SHORT(2,opcode)
     82 
     83 #define __GLX_BEGIN_VARIABLE_LARGE(opcode,size) \
     84    pc = __glXFlushRenderBuffer(gc, pc);         \
     85    __GLX_PUT_LONG(0,size);                      \
     86    __GLX_PUT_LONG(4,opcode)
     87 
     88 #define __GLX_BEGIN_VARIABLE_WITH_PIXEL(opcode,size)  \
     89    if (pc + (size) > gc->bufEnd) {                    \
     90       pc = __glXFlushRenderBuffer(gc, pc);            \
     91    }                                                  \
     92    __GLX_PUT_SHORT(0,size);                           \
     93    __GLX_PUT_SHORT(2,opcode);                         \
     94    pc += __GLX_RENDER_HDR_SIZE;                       \
     95    pixelHeaderPC = pc;                                \
     96    pc += __GLX_PIXEL_HDR_SIZE
     97 
     98 #define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(opcode,size)  \
     99    pc = __glXFlushRenderBuffer(gc, pc);                     \
    100    __GLX_PUT_LONG(0,size);                                  \
    101    __GLX_PUT_LONG(4,opcode);                                \
    102    pc += __GLX_RENDER_LARGE_HDR_SIZE;                       \
    103    pixelHeaderPC = pc;                                      \
    104    pc += __GLX_PIXEL_HDR_SIZE
    105 
    106 #define __GLX_BEGIN_VARIABLE_WITH_PIXEL_3D(opcode,size)  \
    107    if (pc + (size) > gc->bufEnd) {                       \
    108       pc = __glXFlushRenderBuffer(gc, pc);               \
    109    }                                                     \
    110    __GLX_PUT_SHORT(0,size);                              \
    111    __GLX_PUT_SHORT(2,opcode);                            \
    112    pc += __GLX_RENDER_HDR_SIZE;                          \
    113    pixelHeaderPC = pc;                                   \
    114    pc += __GLX_PIXEL_3D_HDR_SIZE
    115 
    116 #define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL_3D(opcode,size)  \
    117    pc = __glXFlushRenderBuffer(gc, pc);                        \
    118    __GLX_PUT_LONG(0,size);                                     \
    119    __GLX_PUT_LONG(4,opcode);                                   \
    120    pc += __GLX_RENDER_LARGE_HDR_SIZE;                          \
    121    pixelHeaderPC = pc;                                         \
    122    pc += __GLX_PIXEL_3D_HDR_SIZE
    123 
    124 /*
    125 ** Fixed size command support macro.  This macro is used by calls that
    126 ** are never larger than __GLX_SMALL_RENDER_CMD_SIZE.  Because they
    127 ** always fit in the buffer, and because the buffer promises to
    128 ** maintain enough room for them, we don't need to check for space
    129 ** before doing the storage work.
    130 */
    131 #define __GLX_BEGIN(opcode,size) \
    132    __GLX_PUT_SHORT(0,size);      \
    133    __GLX_PUT_SHORT(2,opcode)
    134 
    135 /*
    136 ** Finish a rendering command by advancing the pc.  If the pc is now past
    137 ** the limit pointer then there is no longer room for a
    138 ** __GLX_SMALL_RENDER_CMD_SIZE sized command, which will break the
    139 ** assumptions present in the __GLX_BEGIN macro.  In this case the
    140 ** rendering buffer is flushed out into the X protocol stream (which may
    141 ** or may not do I/O).
    142 */
    143 #define __GLX_END(size)           \
    144    pc += size;                       \
    145    if (pc > gc->limit) {                  \
    146       (void) __glXFlushRenderBuffer(gc, pc);    \
    147    } else {                                     \
    148       gc->pc = pc;                              \
    149    }
    150 
    151 /* Array copy macros */
    152 #define __GLX_MEM_COPY(dest,src,bytes)          \
    153    if (src && dest)                             \
    154       memcpy(dest, src, bytes)
    155 
    156 /* Single item copy macros */
    157 #define __GLX_PUT_CHAR(offset,a)                \
    158    *((INT8 *) (pc + offset)) = a
    159 
    160 #ifndef _CRAY
    161 #define __GLX_PUT_SHORT(offset,a)               \
    162    *((INT16 *) (pc + offset)) = a
    163 
    164 #define __GLX_PUT_LONG(offset,a)                \
    165    *((INT32 *) (pc + offset)) = a
    166 
    167 #define __GLX_PUT_FLOAT(offset,a)               \
    168    *((FLOAT32 *) (pc + offset)) = a
    169 
    170 #else
    171 #define __GLX_PUT_SHORT(offset,a)               \
    172    { GLubyte *cp = (pc+offset);                 \
    173       int shift = (64-16) - ((int)(cp) >> (64-6));                      \
    174       *(int *)cp = (*(int *)cp & ~(0xffff << shift)) | ((a & 0xffff) << shift); }
    175 
    176 #define __GLX_PUT_LONG(offset,a)                \
    177    { GLubyte *cp = (pc+offset);                 \
    178       int shift = (64-32) - ((int)(cp) >> (64-6));                      \
    179       *(int *)cp = (*(int *)cp & ~(0xffffffff << shift)) | ((a & 0xffffffff) << shift); }
    180 
    181 #define __GLX_PUT_FLOAT(offset,a)               \
    182    gl_put_float((pc + offset),a)
    183 
    184 #define __GLX_PUT_DOUBLE(offset,a)              \
    185    gl_put_double(pc + offset, a)
    186 
    187 extern void gl_put_float( /*GLubyte *, struct cray_single */ );
    188 extern void gl_put_double( /*GLubyte *, struct cray_double */ );
    189 #endif
    190 
    191 #ifndef _CRAY
    192 
    193 #ifdef __GLX_ALIGN64
    194 /*
    195 ** This can certainly be done better for a particular machine
    196 ** architecture!
    197 */
    198 #define __GLX_PUT_DOUBLE(offset,a)              \
    199    __GLX_MEM_COPY(pc + offset, &a, 8)
    200 #else
    201 #define __GLX_PUT_DOUBLE(offset,a)              \
    202    *((FLOAT64 *) (pc + offset)) = a
    203 #endif
    204 
    205 #endif
    206 
    207 #define __GLX_PUT_CHAR_ARRAY(offset,a,alen)                 \
    208    __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT8)
    209 
    210 #ifndef _CRAY
    211 #define __GLX_PUT_SHORT_ARRAY(offset,a,alen)                \
    212    __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT16)
    213 
    214 #define __GLX_PUT_LONG_ARRAY(offset,a,alen)                 \
    215    __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT32)
    216 
    217 #define __GLX_PUT_FLOAT_ARRAY(offset,a,alen)                   \
    218    __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT32)
    219 
    220 #define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen)                  \
    221    __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT64)
    222 
    223 #else
    224 #define __GLX_PUT_SHORT_ARRAY(offset,a,alen)                            \
    225    gl_put_short_array((GLubyte *)(pc + offset), a, alen * __GLX_SIZE_INT16)
    226 
    227 #define __GLX_PUT_LONG_ARRAY(offset,a,alen)                             \
    228    gl_put_long_array((GLubyte *)(pc + offset), (long *)a, alen * __GLX_SIZE_INT32)
    229 
    230 #define __GLX_PUT_FLOAT_ARRAY(offset,a,alen)                            \
    231    gl_put_float_array((GLubyte *)(pc + offset), (float *)a, alen * __GLX_SIZE_FLOAT32)
    232 
    233 #define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen)                           \
    234    gl_put_double_array((GLubyte *)(pc + offset), (double *)a, alen * __GLX_SIZE_FLOAT64)
    235 
    236 extern gl_put_short_array(GLubyte *, short *, int);
    237 extern gl_put_long_array(GLubyte *, long *, int);
    238 extern gl_put_float_array(GLubyte *, float *, int);
    239 extern gl_put_double_array(GLubyte *, double *, int);
    240 
    241 #endif /* _CRAY */
    242 
    243 #endif /* !__GLX_packrender_h__ */
    244