Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
Brian Paul | 9440868 | 2006-10-11 17:45:06 +0000 | [diff] [blame] | 3 | * Version: 6.5.2 |
Jouk Jansen | 5e3bc0c | 2000-11-22 07:32:16 +0000 | [diff] [blame] | 4 | * |
Brian Paul | ee2339f | 2006-02-24 17:58:48 +0000 | [diff] [blame] | 5 | * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. |
Jouk Jansen | 5e3bc0c | 2000-11-22 07:32:16 +0000 | [diff] [blame] | 6 | * |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 7 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 8 | * copy of this software and associated documentation files (the "Software"), |
| 9 | * to deal in the Software without restriction, including without limitation |
| 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 11 | * and/or sell copies of the Software, and to permit persons to whom the |
| 12 | * Software is furnished to do so, subject to the following conditions: |
Jouk Jansen | 5e3bc0c | 2000-11-22 07:32:16 +0000 | [diff] [blame] | 13 | * |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 14 | * The above copyright notice and this permission notice shall be included |
| 15 | * in all copies or substantial portions of the Software. |
Jouk Jansen | 5e3bc0c | 2000-11-22 07:32:16 +0000 | [diff] [blame] | 16 | * |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 20 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 21 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 23 | */ |
Brian Paul | 98fc9b3 | 2003-03-27 17:51:33 +0000 | [diff] [blame] | 24 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 25 | |
Brian Paul | d21fa9c | 2006-10-14 22:52:17 +0000 | [diff] [blame] | 26 | /** |
| 27 | * \file xm_dd.h |
| 28 | * General device driver functions for Xlib driver. |
| 29 | */ |
| 30 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 31 | #include "glxheader.h" |
Brian Paul | 374e7fd | 2008-09-18 13:46:47 -0600 | [diff] [blame] | 32 | #include "main/bufferobj.h" |
| 33 | #include "main/buffers.h" |
| 34 | #include "main/context.h" |
| 35 | #include "main/colormac.h" |
| 36 | #include "main/depth.h" |
| 37 | #include "main/drawpix.h" |
| 38 | #include "main/extensions.h" |
| 39 | #include "main/framebuffer.h" |
| 40 | #include "main/macros.h" |
| 41 | #include "main/image.h" |
| 42 | #include "main/imports.h" |
| 43 | #include "main/mtypes.h" |
Brian Paul | b70610b | 2011-02-28 18:24:35 -0700 | [diff] [blame] | 44 | #include "main/pbo.h" |
Brian Paul | 374e7fd | 2008-09-18 13:46:47 -0600 | [diff] [blame] | 45 | #include "main/state.h" |
| 46 | #include "main/texobj.h" |
| 47 | #include "main/teximage.h" |
| 48 | #include "main/texstore.h" |
| 49 | #include "main/texformat.h" |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 50 | #include "swrast/swrast.h" |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 51 | #include "swrast/s_context.h" |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 52 | #include "swrast_setup/swrast_setup.h" |
Keith Whitwell | 23caf20 | 2000-11-16 21:05:34 +0000 | [diff] [blame] | 53 | #include "tnl/tnl.h" |
Keith Whitwell | 7098924 | 2001-03-19 02:25:35 +0000 | [diff] [blame] | 54 | #include "tnl/t_context.h" |
Brian Paul | 8126dfa | 2009-08-31 19:29:24 -0600 | [diff] [blame] | 55 | #include "drivers/common/meta.h" |
Brian Paul | 374e7fd | 2008-09-18 13:46:47 -0600 | [diff] [blame] | 56 | #include "xmesaP.h" |
Brian Paul | 8e39ad2 | 2001-02-06 21:42:48 +0000 | [diff] [blame] | 57 | |
Brian Paul | d5e4f29 | 2004-03-04 16:22:01 +0000 | [diff] [blame] | 58 | |
| 59 | |
| 60 | /* |
| 61 | * Dithering kernels and lookup tables. |
| 62 | */ |
| 63 | |
| 64 | const int xmesa_kernel8[DITH_DY * DITH_DX] = { |
| 65 | 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC, |
| 66 | 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC, |
| 67 | 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC, |
| 68 | 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC, |
| 69 | }; |
| 70 | |
| 71 | const short xmesa_HPCR_DRGB[3][2][16] = { |
| 72 | { |
| 73 | { 16, -4, 1,-11, 14, -6, 3, -9, 15, -5, 2,-10, 13, -7, 4, -8}, |
| 74 | {-15, 5, 0, 12,-13, 7, -2, 10,-14, 6, -1, 11,-12, 8, -3, 9} |
| 75 | }, |
| 76 | { |
| 77 | {-11, 15, -7, 3, -8, 14, -4, 2,-10, 16, -6, 4, -9, 13, -5, 1}, |
| 78 | { 12,-14, 8, -2, 9,-13, 5, -1, 11,-15, 7, -3, 10,-12, 6, 0} |
| 79 | }, |
| 80 | { |
| 81 | { 6,-18, 26,-14, 2,-22, 30,-10, 8,-16, 28,-12, 4,-20, 32, -8}, |
| 82 | { -4, 20,-24, 16, 0, 24,-28, 12, -6, 18,-26, 14, -2, 22,-30, 10} |
| 83 | } |
| 84 | }; |
| 85 | |
| 86 | const int xmesa_kernel1[16] = { |
| 87 | 0*47, 9*47, 4*47, 12*47, /* 47 = (255*3)/16 */ |
| 88 | 6*47, 2*47, 14*47, 8*47, |
| 89 | 10*47, 1*47, 5*47, 11*47, |
| 90 | 7*47, 13*47, 3*47, 15*47 |
| 91 | }; |
| 92 | |
| 93 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 94 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 95 | finish_or_flush( struct gl_context *ctx ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 96 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 97 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 98 | if (xmesa) { |
| 99 | _glthread_LOCK_MUTEX(_xmesa_lock); |
| 100 | XSync( xmesa->display, False ); |
| 101 | _glthread_UNLOCK_MUTEX(_xmesa_lock); |
| 102 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 103 | } |
| 104 | |
| 105 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 106 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 107 | clear_color( struct gl_context *ctx, const GLfloat color[4] ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 108 | { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 109 | if (ctx->DrawBuffer->Name == 0) { |
| 110 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 111 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 112 | |
| 113 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); |
| 114 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); |
| 115 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); |
| 116 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); |
| 117 | xmesa->clearpixel = xmesa_color_to_pixel( ctx, |
| 118 | xmesa->clearcolor[0], |
| 119 | xmesa->clearcolor[1], |
| 120 | xmesa->clearcolor[2], |
| 121 | xmesa->clearcolor[3], |
| 122 | xmesa->xm_visual->undithered_pf ); |
| 123 | _glthread_LOCK_MUTEX(_xmesa_lock); |
| 124 | XMesaSetForeground( xmesa->display, xmbuf->cleargc, |
| 125 | xmesa->clearpixel ); |
| 126 | _glthread_UNLOCK_MUTEX(_xmesa_lock); |
| 127 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | |
| 131 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 132 | /* Implements glColorMask() */ |
| 133 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 134 | color_mask(struct gl_context *ctx, |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 135 | GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) |
| 136 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 137 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | c7a5d52 | 2006-03-28 15:21:44 +0000 | [diff] [blame] | 138 | XMesaBuffer xmbuf; |
Brian Paul | c3ed27e | 2010-10-13 08:32:08 -0600 | [diff] [blame] | 139 | const int xclass = xmesa->xm_visual->visualType; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 140 | (void) amask; |
| 141 | |
Brian Paul | c7a5d52 | 2006-03-28 15:21:44 +0000 | [diff] [blame] | 142 | if (ctx->DrawBuffer->Name != 0) |
| 143 | return; |
| 144 | |
| 145 | xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 146 | |
Ian Romanick | 304d3aa | 2004-02-19 00:57:04 +0000 | [diff] [blame] | 147 | if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 148 | unsigned long m; |
| 149 | if (rmask && gmask && bmask) { |
| 150 | m = ((unsigned long)~0L); |
| 151 | } |
| 152 | else { |
| 153 | m = 0; |
| 154 | if (rmask) m |= GET_REDMASK(xmesa->xm_visual); |
| 155 | if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); |
| 156 | if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); |
| 157 | } |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 158 | XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 159 | } |
| 160 | } |
| 161 | |
| 162 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 163 | |
| 164 | /**********************************************************************/ |
| 165 | /*** glClear implementations ***/ |
| 166 | /**********************************************************************/ |
| 167 | |
| 168 | |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 169 | /** |
| 170 | * Clear the front or back color buffer, if it's implemented with a pixmap. |
| 171 | */ |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 172 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 173 | clear_pixmap(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 174 | GLint x, GLint y, GLint width, GLint height) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 175 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 176 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 177 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 178 | |
Brian Paul | b1d0ac6 | 2005-05-06 15:23:54 +0000 | [diff] [blame] | 179 | assert(xmbuf); |
| 180 | assert(xrb->pixmap); |
| 181 | assert(xmesa); |
| 182 | assert(xmesa->display); |
| 183 | assert(xrb->pixmap); |
| 184 | assert(xmbuf->cleargc); |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 185 | |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 186 | XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, |
| 187 | x, xrb->Base.Height - y - height, |
| 188 | width, height ); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 189 | } |
| 190 | |
| 191 | |
| 192 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 193 | clear_8bit_ximage( struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 194 | GLint x, GLint y, GLint width, GLint height ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 195 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 196 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 197 | GLint i; |
| 198 | for (i = 0; i < height; i++) { |
| 199 | GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i); |
Brian Paul | 2240ba1 | 2010-02-19 08:12:31 -0700 | [diff] [blame] | 200 | memset( ptr, xmesa->clearpixel, width ); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 201 | } |
| 202 | } |
| 203 | |
| 204 | |
| 205 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 206 | clear_HPCR_ximage( struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 207 | GLint x, GLint y, GLint width, GLint height ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 208 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 209 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 210 | GLint i; |
| 211 | for (i = y; i < y + height; i++) { |
| 212 | GLubyte *ptr = PIXEL_ADDR1( xrb, x, i ); |
| 213 | int j; |
| 214 | const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; |
| 215 | if (i & 1) { |
| 216 | sptr += 16; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 217 | } |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 218 | for (j = x; j < x + width; j++) { |
| 219 | *ptr = sptr[j&15]; |
| 220 | ptr++; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | |
| 226 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 227 | clear_16bit_ximage( struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 228 | GLint x, GLint y, GLint width, GLint height) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 229 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 230 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 231 | GLuint pixel = (GLuint) xmesa->clearpixel; |
| 232 | GLint i, j; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 233 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 234 | if (xmesa->swapbytes) { |
| 235 | pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); |
| 236 | } |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 237 | |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 238 | for (j = 0; j < height; j++) { |
| 239 | GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j); |
| 240 | for (i = 0; i < width; i++) { |
| 241 | ptr2[i] = pixel; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 242 | } |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | |
| 247 | /* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */ |
| 248 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 249 | clear_24bit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 250 | GLint x, GLint y, GLint width, GLint height) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 251 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 252 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 253 | const GLubyte r = xmesa->clearcolor[0]; |
| 254 | const GLubyte g = xmesa->clearcolor[1]; |
| 255 | const GLubyte b = xmesa->clearcolor[2]; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 256 | |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 257 | if (r == g && g == b) { |
| 258 | /* same value for all three components (gray) */ |
| 259 | GLint j; |
| 260 | for (j = 0; j < height; j++) { |
| 261 | bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); |
Brian Paul | 2240ba1 | 2010-02-19 08:12:31 -0700 | [diff] [blame] | 262 | memset(ptr3, r, 3 * width); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 263 | } |
| 264 | } |
| 265 | else { |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 266 | /* non-gray clear color */ |
| 267 | GLint i, j; |
| 268 | for (j = 0; j < height; j++) { |
| 269 | bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); |
| 270 | for (i = 0; i < width; i++) { |
| 271 | ptr3->r = r; |
| 272 | ptr3->g = g; |
| 273 | ptr3->b = b; |
| 274 | ptr3++; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 275 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 276 | } |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | |
| 281 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 282 | clear_32bit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 283 | GLint x, GLint y, GLint width, GLint height) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 284 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 285 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | 9d205e3 | 2001-04-03 16:19:54 +0000 | [diff] [blame] | 286 | register GLuint pixel = (GLuint) xmesa->clearpixel; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 287 | |
Brian Paul | 41b9756 | 2006-01-09 16:59:30 +0000 | [diff] [blame] | 288 | if (!xrb->ximage) |
| 289 | return; |
| 290 | |
Brian Paul | 9d205e3 | 2001-04-03 16:19:54 +0000 | [diff] [blame] | 291 | if (xmesa->swapbytes) { |
| 292 | pixel = ((pixel >> 24) & 0x000000ff) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 293 | | ((pixel >> 8) & 0x0000ff00) |
| 294 | | ((pixel << 8) & 0x00ff0000) |
| 295 | | ((pixel << 24) & 0xff000000); |
Brian Paul | 9d205e3 | 2001-04-03 16:19:54 +0000 | [diff] [blame] | 296 | } |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 297 | |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 298 | if (width == xrb->Base.Width && height == xrb->Base.Height) { |
| 299 | /* clearing whole buffer */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 300 | const GLuint n = xrb->Base.Width * xrb->Base.Height; |
| 301 | GLuint *ptr4 = (GLuint *) xrb->ximage->data; |
| 302 | if (pixel == 0) { |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 303 | /* common case */ |
Kenneth Graunke | 26f8fad | 2010-02-18 23:51:00 -0800 | [diff] [blame] | 304 | memset(ptr4, pixel, 4 * n); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 305 | } |
| 306 | else { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 307 | GLuint i; |
| 308 | for (i = 0; i < n; i++) |
| 309 | ptr4[i] = pixel; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 310 | } |
| 311 | } |
| 312 | else { |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 313 | /* clearing scissored region */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 314 | GLint i, j; |
| 315 | for (j = 0; j < height; j++) { |
| 316 | GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y + j); |
| 317 | for (i = 0; i < width; i++) { |
| 318 | ptr4[i] = pixel; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 319 | } |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | |
| 325 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 326 | clear_nbit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 327 | GLint x, GLint y, GLint width, GLint height) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 328 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 329 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 330 | XMesaImage *img = xrb->ximage; |
| 331 | GLint i, j; |
Brian Paul | 29926a1 | 2004-11-27 21:20:37 +0000 | [diff] [blame] | 332 | |
Brian Paul | 29926a1 | 2004-11-27 21:20:37 +0000 | [diff] [blame] | 333 | /* TODO: optimize this */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 334 | y = YFLIP(xrb, y); |
Brian Paul | 29926a1 | 2004-11-27 21:20:37 +0000 | [diff] [blame] | 335 | for (j = 0; j < height; j++) { |
| 336 | for (i = 0; i < width; i++) { |
| 337 | XMesaPutPixel(img, x+i, y-j, xmesa->clearpixel); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 338 | } |
| 339 | } |
| 340 | } |
| 341 | |
| 342 | |
| 343 | |
Keith Whitwell | d98fdad | 2001-01-29 20:56:32 +0000 | [diff] [blame] | 344 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 345 | clear_buffers(struct gl_context *ctx, GLbitfield buffers) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 346 | { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 347 | if (ctx->DrawBuffer->Name == 0) { |
| 348 | /* this is a window system framebuffer */ |
Brian Paul | fd5511d | 2009-12-29 16:17:14 -0700 | [diff] [blame] | 349 | const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0]; |
Brian Paul | 444cd29 | 2006-04-27 02:47:50 +0000 | [diff] [blame] | 350 | XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer); |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 351 | const GLint x = ctx->DrawBuffer->_Xmin; |
| 352 | const GLint y = ctx->DrawBuffer->_Ymin; |
| 353 | const GLint width = ctx->DrawBuffer->_Xmax - x; |
| 354 | const GLint height = ctx->DrawBuffer->_Ymax - y; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 355 | |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 356 | /* we can't handle color or index masking */ |
| 357 | if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { |
Alan Hourihane | 6d104cb | 2006-11-02 12:02:13 +0000 | [diff] [blame] | 358 | if (buffers & BUFFER_BIT_FRONT_LEFT) { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 359 | /* clear front color buffer */ |
Brian Paul | 444cd29 | 2006-04-27 02:47:50 +0000 | [diff] [blame] | 360 | struct gl_renderbuffer *frontRb |
| 361 | = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; |
| 362 | if (b->frontxrb == xmesa_renderbuffer(frontRb)) { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 363 | /* renderbuffer is not wrapped - great! */ |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 364 | b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height); |
Alan Hourihane | 6d104cb | 2006-11-02 12:02:13 +0000 | [diff] [blame] | 365 | buffers &= ~BUFFER_BIT_FRONT_LEFT; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 366 | } |
| 367 | else { |
| 368 | /* we can't directly clear an alpha-wrapped color buffer */ |
| 369 | } |
| 370 | } |
Alan Hourihane | 6d104cb | 2006-11-02 12:02:13 +0000 | [diff] [blame] | 371 | if (buffers & BUFFER_BIT_BACK_LEFT) { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 372 | /* clear back color buffer */ |
Brian Paul | 444cd29 | 2006-04-27 02:47:50 +0000 | [diff] [blame] | 373 | struct gl_renderbuffer *backRb |
| 374 | = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; |
| 375 | if (b->backxrb == xmesa_renderbuffer(backRb)) { |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 376 | /* renderbuffer is not wrapped - great! */ |
Brian Paul | ec99e71 | 2006-10-18 20:03:20 +0000 | [diff] [blame] | 377 | b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); |
Alan Hourihane | 6d104cb | 2006-11-02 12:02:13 +0000 | [diff] [blame] | 378 | buffers &= ~BUFFER_BIT_BACK_LEFT; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 379 | } |
| 380 | } |
Keith Whitwell | d98fdad | 2001-01-29 20:56:32 +0000 | [diff] [blame] | 381 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 382 | } |
Alan Hourihane | 6d104cb | 2006-11-02 12:02:13 +0000 | [diff] [blame] | 383 | if (buffers) |
| 384 | _swrast_Clear(ctx, buffers); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 388 | /* XXX these functions haven't been tested in the Xserver environment */ |
| 389 | |
| 390 | |
| 391 | /** |
| 392 | * Check if we can do an optimized glDrawPixels into an 8R8G8B visual. |
| 393 | */ |
| 394 | static GLboolean |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 395 | can_do_DrawPixels_8R8G8B(struct gl_context *ctx, GLenum format, GLenum type) |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 396 | { |
| 397 | if (format == GL_BGRA && |
| 398 | type == GL_UNSIGNED_BYTE && |
| 399 | ctx->DrawBuffer && |
| 400 | ctx->DrawBuffer->Name == 0 && |
| 401 | ctx->Pixel.ZoomX == 1.0 && /* no zooming */ |
| 402 | ctx->Pixel.ZoomY == 1.0 && |
| 403 | ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { |
| 404 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
| 405 | |
| 406 | if (swrast->NewState) |
| 407 | _swrast_validate_derived( ctx ); |
| 408 | |
| 409 | if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { |
| 410 | struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; |
| 411 | if (rb) { |
| 412 | struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped); |
| 413 | if (xrb && |
| 414 | xrb->pixmap && /* drawing to pixmap or window */ |
Brian Paul | 45e76d2 | 2009-10-08 20:27:27 -0600 | [diff] [blame] | 415 | _mesa_get_format_bits(xrb->Base.Format, GL_ALPHA_BITS) == 0) { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 416 | return GL_TRUE; |
| 417 | } |
| 418 | } |
| 419 | } |
| 420 | } |
| 421 | return GL_FALSE; |
| 422 | } |
| 423 | |
Brian Paul | 1d7b75c | 2003-12-04 15:29:10 +0000 | [diff] [blame] | 424 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 425 | /** |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 426 | * This function implements glDrawPixels() with an XPutImage call when |
| 427 | * drawing to the front buffer (X Window drawable). |
| 428 | * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 429 | */ |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 430 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 431 | xmesa_DrawPixels_8R8G8B( struct gl_context *ctx, |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 432 | GLint x, GLint y, GLsizei width, GLsizei height, |
| 433 | GLenum format, GLenum type, |
| 434 | const struct gl_pixelstore_attrib *unpack, |
| 435 | const GLvoid *pixels ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 436 | { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 437 | if (can_do_DrawPixels_8R8G8B(ctx, format, type)) { |
| 438 | const SWcontext *swrast = SWRAST_CONTEXT( ctx ); |
| 439 | struct gl_pixelstore_attrib clippedUnpack = *unpack; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 440 | int dstX = x; |
| 441 | int dstY = y; |
| 442 | int w = width; |
| 443 | int h = height; |
Brian Paul | 7a6b71e | 2004-03-13 18:21:40 +0000 | [diff] [blame] | 444 | |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 445 | if (swrast->NewState) |
| 446 | _swrast_validate_derived( ctx ); |
Brian Paul | 9440868 | 2006-10-11 17:45:06 +0000 | [diff] [blame] | 447 | |
Brian Paul | 6b329b9 | 2011-04-26 14:54:41 -0600 | [diff] [blame] | 448 | if (_mesa_is_bufferobj(unpack->BufferObj)) { |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 449 | /* unpack from PBO */ |
| 450 | GLubyte *buf; |
Brian Paul | 6090938 | 2004-11-10 15:46:52 +0000 | [diff] [blame] | 451 | if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, |
Brian Paul | 6b329b9 | 2011-04-26 14:54:41 -0600 | [diff] [blame] | 452 | format, type, INT_MAX, pixels)) { |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 453 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 454 | "glDrawPixels(invalid PBO access)"); |
| 455 | return; |
| 456 | } |
Ian Romanick | 28249bd | 2011-08-21 18:34:27 -0700 | [diff] [blame] | 457 | buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, |
| 458 | unpack->BufferObj->Size, |
| 459 | GL_MAP_READ_BIT, |
| 460 | unpack->BufferObj); |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 461 | if (!buf) { |
| 462 | /* buffer is already mapped - that's an error */ |
| 463 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 464 | "glDrawPixels(PBO is mapped)"); |
| 465 | return; |
| 466 | } |
| 467 | pixels = ADD_POINTERS(buf, pixels); |
| 468 | } |
Brian Paul | 7a6b71e | 2004-03-13 18:21:40 +0000 | [diff] [blame] | 469 | |
Brian Paul | 1ad7b99 | 2005-09-28 02:29:50 +0000 | [diff] [blame] | 470 | if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 471 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 472 | XMesaDisplay *dpy = xmesa->xm_visual->display; |
| 473 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 474 | const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ |
| 475 | struct xmesa_renderbuffer *xrb |
| 476 | = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); |
| 477 | const int srcX = clippedUnpack.SkipPixels; |
| 478 | const int srcY = clippedUnpack.SkipRows; |
| 479 | const int rowLength = clippedUnpack.RowLength; |
| 480 | XMesaImage ximage; |
| 481 | |
| 482 | ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); |
| 483 | ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); |
| 484 | ASSERT(dpy); |
| 485 | ASSERT(gc); |
| 486 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 487 | /* This is a little tricky since all coordinates up to now have |
| 488 | * been in the OpenGL bottom-to-top orientation. X is top-to-bottom |
| 489 | * so we have to carefully compute the Y coordinates/addresses here. |
| 490 | */ |
Brian Paul | 2240ba1 | 2010-02-19 08:12:31 -0700 | [diff] [blame] | 491 | memset(&ximage, 0, sizeof(XMesaImage)); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 492 | ximage.width = width; |
| 493 | ximage.height = height; |
| 494 | ximage.format = ZPixmap; |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 495 | ximage.data = (char *) pixels |
| 496 | + ((srcY + h - 1) * rowLength + srcX) * 4; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 497 | ximage.byte_order = LSBFirst; |
| 498 | ximage.bitmap_unit = 32; |
| 499 | ximage.bitmap_bit_order = LSBFirst; |
| 500 | ximage.bitmap_pad = 32; |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 501 | ximage.depth = 32; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 502 | ximage.bits_per_pixel = 32; |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 503 | ximage.bytes_per_line = -rowLength * 4; /* negative to flip image */ |
Brian Paul | 1d7b75c | 2003-12-04 15:29:10 +0000 | [diff] [blame] | 504 | /* it seems we don't need to set the ximage.red/green/blue_mask fields */ |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 505 | /* flip Y axis for dest position */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 506 | dstY = YFLIP(xrb, dstY) - h + 1; |
| 507 | XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 508 | } |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 509 | |
Brian Paul | 6b329b9 | 2011-04-26 14:54:41 -0600 | [diff] [blame] | 510 | if (_mesa_is_bufferobj(unpack->BufferObj)) { |
Ian Romanick | 56f0c00 | 2011-08-21 16:59:30 -0700 | [diff] [blame] | 511 | ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj); |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 512 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 513 | } |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 514 | else { |
| 515 | /* software fallback */ |
| 516 | _swrast_DrawPixels(ctx, x, y, width, height, |
| 517 | format, type, unpack, pixels); |
| 518 | } |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 519 | } |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 520 | |
| 521 | |
| 522 | |
| 523 | /** |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 524 | * Check if we can do an optimized glDrawPixels into an 5R6G5B visual. |
| 525 | */ |
| 526 | static GLboolean |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 527 | can_do_DrawPixels_5R6G5B(struct gl_context *ctx, GLenum format, GLenum type) |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 528 | { |
| 529 | if (format == GL_RGB && |
| 530 | type == GL_UNSIGNED_SHORT_5_6_5 && |
| 531 | !ctx->Color.DitherFlag && /* no dithering */ |
| 532 | ctx->DrawBuffer && |
| 533 | ctx->DrawBuffer->Name == 0 && |
| 534 | ctx->Pixel.ZoomX == 1.0 && /* no zooming */ |
| 535 | ctx->Pixel.ZoomY == 1.0 && |
| 536 | ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { |
| 537 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
| 538 | |
| 539 | if (swrast->NewState) |
| 540 | _swrast_validate_derived( ctx ); |
| 541 | |
| 542 | if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { |
| 543 | struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; |
| 544 | if (rb) { |
| 545 | struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped); |
| 546 | if (xrb && |
| 547 | xrb->pixmap && /* drawing to pixmap or window */ |
Brian Paul | 45e76d2 | 2009-10-08 20:27:27 -0600 | [diff] [blame] | 548 | _mesa_get_format_bits(xrb->Base.Format, GL_ALPHA_BITS) == 0) { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 549 | return GL_TRUE; |
| 550 | } |
| 551 | } |
| 552 | } |
| 553 | } |
| 554 | return GL_FALSE; |
| 555 | } |
| 556 | |
| 557 | |
| 558 | /** |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 559 | * This function implements glDrawPixels() with an XPutImage call when |
| 560 | * drawing to the front buffer (X Window drawable). The image format |
| 561 | * must be GL_RGB and image type must be GL_UNSIGNED_SHORT_5_6_5 to |
| 562 | * match the PF_5R6G5B pixel format. |
| 563 | */ |
| 564 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 565 | xmesa_DrawPixels_5R6G5B( struct gl_context *ctx, |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 566 | GLint x, GLint y, GLsizei width, GLsizei height, |
| 567 | GLenum format, GLenum type, |
| 568 | const struct gl_pixelstore_attrib *unpack, |
| 569 | const GLvoid *pixels ) |
| 570 | { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 571 | if (can_do_DrawPixels_5R6G5B(ctx, format, type)) { |
| 572 | const SWcontext *swrast = SWRAST_CONTEXT( ctx ); |
| 573 | struct gl_pixelstore_attrib clippedUnpack = *unpack; |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 574 | int dstX = x; |
| 575 | int dstY = y; |
| 576 | int w = width; |
| 577 | int h = height; |
Brian Paul | 7a6b71e | 2004-03-13 18:21:40 +0000 | [diff] [blame] | 578 | |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 579 | if (swrast->NewState) |
| 580 | _swrast_validate_derived( ctx ); |
| 581 | |
Brian Paul | 6b329b9 | 2011-04-26 14:54:41 -0600 | [diff] [blame] | 582 | if (_mesa_is_bufferobj(unpack->BufferObj)) { |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 583 | /* unpack from PBO */ |
| 584 | GLubyte *buf; |
Brian Paul | 6090938 | 2004-11-10 15:46:52 +0000 | [diff] [blame] | 585 | if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, |
Brian Paul | 6b329b9 | 2011-04-26 14:54:41 -0600 | [diff] [blame] | 586 | format, type, INT_MAX, pixels)) { |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 587 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 588 | "glDrawPixels(invalid PBO access)"); |
| 589 | return; |
| 590 | } |
Brian Paul | c3ad95e | 2011-08-24 07:55:04 -0600 | [diff] [blame^] | 591 | buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, |
Ian Romanick | 28249bd | 2011-08-21 18:34:27 -0700 | [diff] [blame] | 592 | unpack->BufferObj->Size, |
| 593 | GL_MAP_READ_BIT, |
| 594 | unpack->BufferObj); |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 595 | if (!buf) { |
| 596 | /* buffer is already mapped - that's an error */ |
| 597 | _mesa_error(ctx, GL_INVALID_OPERATION, |
| 598 | "glDrawPixels(PBO is mapped)"); |
| 599 | return; |
| 600 | } |
| 601 | pixels = ADD_POINTERS(buf, pixels); |
| 602 | } |
Brian Paul | 7a6b71e | 2004-03-13 18:21:40 +0000 | [diff] [blame] | 603 | |
Brian Paul | 1ad7b99 | 2005-09-28 02:29:50 +0000 | [diff] [blame] | 604 | if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 605 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 606 | XMesaDisplay *dpy = xmesa->xm_visual->display; |
| 607 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 608 | const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ |
| 609 | struct xmesa_renderbuffer *xrb |
| 610 | = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); |
| 611 | const int srcX = clippedUnpack.SkipPixels; |
| 612 | const int srcY = clippedUnpack.SkipRows; |
| 613 | const int rowLength = clippedUnpack.RowLength; |
| 614 | XMesaImage ximage; |
| 615 | |
| 616 | ASSERT(xmesa->xm_visual->undithered_pf == PF_5R6G5B); |
| 617 | ASSERT(dpy); |
| 618 | ASSERT(gc); |
| 619 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 620 | /* This is a little tricky since all coordinates up to now have |
| 621 | * been in the OpenGL bottom-to-top orientation. X is top-to-bottom |
| 622 | * so we have to carefully compute the Y coordinates/addresses here. |
| 623 | */ |
Brian Paul | 2240ba1 | 2010-02-19 08:12:31 -0700 | [diff] [blame] | 624 | memset(&ximage, 0, sizeof(XMesaImage)); |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 625 | ximage.width = width; |
| 626 | ximage.height = height; |
| 627 | ximage.format = ZPixmap; |
| 628 | ximage.data = (char *) pixels |
| 629 | + ((srcY + h - 1) * rowLength + srcX) * 2; |
| 630 | ximage.byte_order = LSBFirst; |
Brian Paul | 1d7b75c | 2003-12-04 15:29:10 +0000 | [diff] [blame] | 631 | ximage.bitmap_unit = 16; |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 632 | ximage.bitmap_bit_order = LSBFirst; |
Brian Paul | 1d7b75c | 2003-12-04 15:29:10 +0000 | [diff] [blame] | 633 | ximage.bitmap_pad = 16; |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 634 | ximage.depth = 16; |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 635 | ximage.bits_per_pixel = 16; |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 636 | ximage.bytes_per_line = -rowLength * 2; /* negative to flip image */ |
Brian Paul | 1d7b75c | 2003-12-04 15:29:10 +0000 | [diff] [blame] | 637 | /* it seems we don't need to set the ximage.red/green/blue_mask fields */ |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 638 | /* flip Y axis for dest position */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 639 | dstY = YFLIP(xrb, dstY) - h + 1; |
| 640 | XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 641 | } |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 642 | |
| 643 | if (unpack->BufferObj->Name) { |
Ian Romanick | 56f0c00 | 2011-08-21 16:59:30 -0700 | [diff] [blame] | 644 | ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj); |
Brian Paul | ba164c4 | 2004-10-31 15:49:59 +0000 | [diff] [blame] | 645 | } |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 646 | } |
| 647 | else { |
| 648 | /* software fallback */ |
| 649 | _swrast_DrawPixels(ctx, x, y, width, height, |
| 650 | format, type, unpack, pixels); |
| 651 | } |
| 652 | } |
| 653 | |
| 654 | |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 655 | /** |
| 656 | * Determine if we can do an optimized glCopyPixels. |
| 657 | */ |
| 658 | static GLboolean |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 659 | can_do_CopyPixels(struct gl_context *ctx, GLenum type) |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 660 | { |
| 661 | if (type == GL_COLOR && |
| 662 | ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ |
| 663 | ctx->Pixel.ZoomX == 1.0 && /* no zooming */ |
| 664 | ctx->Pixel.ZoomY == 1.0 && |
| 665 | ctx->Color.DrawBuffer[0] == GL_FRONT && /* copy to front buf */ |
| 666 | ctx->Pixel.ReadBuffer == GL_FRONT && /* copy from front buf */ |
| 667 | ctx->ReadBuffer->_ColorReadBuffer && |
| 668 | ctx->DrawBuffer->_ColorDrawBuffers[0]) { |
| 669 | const SWcontext *swrast = SWRAST_CONTEXT( ctx ); |
| 670 | |
| 671 | if (swrast->NewState) |
| 672 | _swrast_validate_derived( ctx ); |
| 673 | |
| 674 | if ((swrast->_RasterMask & ~CLIP_BIT) == 0x0 && |
| 675 | ctx->ReadBuffer && |
| 676 | ctx->ReadBuffer->_ColorReadBuffer && |
| 677 | ctx->DrawBuffer && |
| 678 | ctx->DrawBuffer->_ColorDrawBuffers[0]) { |
| 679 | struct xmesa_renderbuffer *srcXrb |
| 680 | = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); |
| 681 | struct xmesa_renderbuffer *dstXrb |
| 682 | = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); |
| 683 | if (srcXrb->pixmap && dstXrb->pixmap) { |
| 684 | return GL_TRUE; |
| 685 | } |
| 686 | } |
| 687 | } |
| 688 | return GL_FALSE; |
| 689 | } |
| 690 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 691 | |
| 692 | /** |
| 693 | * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) |
| 694 | * for the color buffer. Don't support zooming, pixel transfer, etc. |
| 695 | * We do support copying from one window to another, ala glXMakeCurrentRead. |
| 696 | */ |
| 697 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 698 | xmesa_CopyPixels( struct gl_context *ctx, |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 699 | GLint srcx, GLint srcy, GLsizei width, GLsizei height, |
| 700 | GLint destx, GLint desty, GLenum type ) |
| 701 | { |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 702 | if (can_do_CopyPixels(ctx, type)) { |
| 703 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 704 | XMesaDisplay *dpy = xmesa->xm_visual->display; |
| 705 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
| 706 | const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ |
| 707 | struct xmesa_renderbuffer *srcXrb |
| 708 | = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); |
| 709 | struct xmesa_renderbuffer *dstXrb |
| 710 | = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped); |
Brian | 2a07750 | 2008-01-22 21:11:55 -0700 | [diff] [blame] | 711 | |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 712 | ASSERT(dpy); |
| 713 | ASSERT(gc); |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 714 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 715 | /* Note: we don't do any special clipping work here. We could, |
| 716 | * but X will do it for us. |
| 717 | */ |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 718 | srcy = YFLIP(srcXrb, srcy) - height + 1; |
| 719 | desty = YFLIP(dstXrb, desty) - height + 1; |
| 720 | XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 721 | srcx, srcy, width, height, destx, desty); |
| 722 | } |
| 723 | else { |
| 724 | _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); |
| 725 | } |
| 726 | } |
Brian | 15f0015 | 2008-02-16 09:56:54 -0700 | [diff] [blame] | 727 | |
Brian Paul | de0dd65 | 2003-11-29 19:36:08 +0000 | [diff] [blame] | 728 | |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 729 | |
| 730 | |
Brian Paul | 57d882b | 2003-09-17 16:06:49 +0000 | [diff] [blame] | 731 | /* |
| 732 | * Every driver should implement a GetString function in order to |
| 733 | * return a meaningful GL_RENDERER string. |
| 734 | */ |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 735 | static const GLubyte * |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 736 | get_string( struct gl_context *ctx, GLenum name ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 737 | { |
| 738 | (void) ctx; |
| 739 | switch (name) { |
| 740 | case GL_RENDERER: |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 741 | return (const GLubyte *) "Mesa X11"; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 742 | case GL_VENDOR: |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 743 | return NULL; |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 744 | default: |
| 745 | return NULL; |
| 746 | } |
| 747 | } |
| 748 | |
| 749 | |
Brian Paul | 57d882b | 2003-09-17 16:06:49 +0000 | [diff] [blame] | 750 | /* |
| 751 | * We implement the glEnable function only because we care about |
| 752 | * dither enable/disable. |
| 753 | */ |
Brian Paul | 7f7b205 | 2000-09-08 21:44:55 +0000 | [diff] [blame] | 754 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 755 | enable( struct gl_context *ctx, GLenum pname, GLboolean state ) |
Brian Paul | 7f7b205 | 2000-09-08 21:44:55 +0000 | [diff] [blame] | 756 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 757 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | 7f7b205 | 2000-09-08 21:44:55 +0000 | [diff] [blame] | 758 | |
| 759 | switch (pname) { |
| 760 | case GL_DITHER: |
| 761 | if (state) |
| 762 | xmesa->pixelformat = xmesa->xm_visual->dithered_pf; |
| 763 | else |
| 764 | xmesa->pixelformat = xmesa->xm_visual->undithered_pf; |
| 765 | break; |
| 766 | default: |
| 767 | ; /* silence compiler warning */ |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 772 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 773 | clear_color_HPCR_ximage( struct gl_context *ctx, const GLfloat color[4] ) |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 774 | { |
| 775 | int i; |
| 776 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 777 | |
| 778 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); |
| 779 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); |
| 780 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); |
| 781 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); |
| 782 | |
| 783 | if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { |
| 784 | /* black is black */ |
Brian Paul | 2240ba1 | 2010-02-19 08:12:31 -0700 | [diff] [blame] | 785 | memset( xmesa->xm_visual->hpcr_clear_ximage_pattern, 0x0 , |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 786 | sizeof(xmesa->xm_visual->hpcr_clear_ximage_pattern)); |
| 787 | } |
| 788 | else { |
| 789 | /* build clear pattern */ |
| 790 | for (i=0; i<16; i++) { |
| 791 | xmesa->xm_visual->hpcr_clear_ximage_pattern[0][i] = |
| 792 | DITHER_HPCR(i, 0, |
| 793 | xmesa->clearcolor[0], |
| 794 | xmesa->clearcolor[1], |
| 795 | xmesa->clearcolor[2]); |
| 796 | xmesa->xm_visual->hpcr_clear_ximage_pattern[1][i] = |
| 797 | DITHER_HPCR(i, 1, |
| 798 | xmesa->clearcolor[0], |
| 799 | xmesa->clearcolor[1], |
| 800 | xmesa->clearcolor[2]); |
| 801 | } |
| 802 | } |
| 803 | } |
| 804 | |
| 805 | |
| 806 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 807 | clear_color_HPCR_pixmap( struct gl_context *ctx, const GLfloat color[4] ) |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 808 | { |
| 809 | int i; |
| 810 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
| 811 | |
| 812 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); |
| 813 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); |
| 814 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); |
| 815 | CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); |
| 816 | |
| 817 | if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { |
| 818 | /* black is black */ |
| 819 | for (i=0; i<16; i++) { |
| 820 | XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 0); |
| 821 | XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, 0); |
| 822 | } |
| 823 | } |
| 824 | else { |
| 825 | for (i=0; i<16; i++) { |
| 826 | XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, |
| 827 | DITHER_HPCR(i, 0, |
| 828 | xmesa->clearcolor[0], |
| 829 | xmesa->clearcolor[1], |
| 830 | xmesa->clearcolor[2])); |
| 831 | XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, |
| 832 | DITHER_HPCR(i, 1, |
| 833 | xmesa->clearcolor[0], |
| 834 | xmesa->clearcolor[1], |
| 835 | xmesa->clearcolor[2])); |
| 836 | } |
| 837 | } |
| 838 | /* change tile pixmap content */ |
| 839 | XMesaPutImage(xmesa->display, |
| 840 | (XMesaDrawable)xmesa->xm_visual->hpcr_clear_pixmap, |
| 841 | XMESA_BUFFER(ctx->DrawBuffer)->cleargc, |
| 842 | xmesa->xm_visual->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); |
| 843 | } |
| 844 | |
| 845 | |
| 846 | /** |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 847 | * Called when the driver should update its state, based on the new_state |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 848 | * flags. |
| 849 | */ |
| 850 | void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 851 | xmesa_update_state( struct gl_context *ctx, GLbitfield new_state ) |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 852 | { |
Brian Paul | 1e24d33 | 2003-04-01 17:28:10 +0000 | [diff] [blame] | 853 | const XMesaContext xmesa = XMESA_CONTEXT(ctx); |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 854 | |
Brian Paul | f905145 | 2005-04-18 17:48:25 +0000 | [diff] [blame] | 855 | /* Propagate statechange information to swrast and swrast_setup |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 856 | * modules. The X11 driver has no internal GL-dependent state. |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 857 | */ |
Keith Whitwell | cab974c | 2000-12-26 05:09:27 +0000 | [diff] [blame] | 858 | _swrast_InvalidateState( ctx, new_state ); |
Keith Whitwell | cab974c | 2000-12-26 05:09:27 +0000 | [diff] [blame] | 859 | _tnl_InvalidateState( ctx, new_state ); |
Keith Whitwell | 48f5dea | 2006-10-30 16:56:56 +0000 | [diff] [blame] | 860 | _vbo_InvalidateState( ctx, new_state ); |
Keith Whitwell | cab974c | 2000-12-26 05:09:27 +0000 | [diff] [blame] | 861 | _swsetup_InvalidateState( ctx, new_state ); |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 862 | |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 863 | if (ctx->DrawBuffer->Name != 0) |
| 864 | return; |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 865 | |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 866 | /* |
Brian Paul | ee2339f | 2006-02-24 17:58:48 +0000 | [diff] [blame] | 867 | * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect |
| 868 | * renderbuffer span/clear funcs. |
Brian Paul | 62043b2 | 2009-05-01 18:31:04 -0600 | [diff] [blame] | 869 | * Check _NEW_COLOR to detect dither enable/disable. |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 870 | */ |
Brian Paul | 62043b2 | 2009-05-01 18:31:04 -0600 | [diff] [blame] | 871 | if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) { |
Brian Paul | faee3f0 | 2006-04-26 03:19:54 +0000 | [diff] [blame] | 872 | XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 873 | struct xmesa_renderbuffer *front_xrb, *back_xrb; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 874 | |
Brian Paul | faee3f0 | 2006-04-26 03:19:54 +0000 | [diff] [blame] | 875 | front_xrb = xmbuf->frontxrb; |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 876 | if (front_xrb) { |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 877 | xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat, |
| 878 | xmesa->xm_visual->BitsPerPixel); |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 879 | front_xrb->clearFunc = clear_pixmap; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 880 | } |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 881 | |
Brian Paul | faee3f0 | 2006-04-26 03:19:54 +0000 | [diff] [blame] | 882 | back_xrb = xmbuf->backxrb; |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 883 | if (back_xrb) { |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 884 | xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat, |
| 885 | xmesa->xm_visual->BitsPerPixel); |
Brian Paul | c2901e4 | 2006-01-09 17:56:55 +0000 | [diff] [blame] | 886 | if (xmbuf->backxrb->pixmap) { |
| 887 | back_xrb->clearFunc = clear_pixmap; |
| 888 | } |
| 889 | else { |
| 890 | switch (xmesa->xm_visual->BitsPerPixel) { |
| 891 | case 8: |
| 892 | if (xmesa->xm_visual->hpcr_clear_flag) { |
| 893 | back_xrb->clearFunc = clear_HPCR_ximage; |
| 894 | } |
| 895 | else { |
| 896 | back_xrb->clearFunc = clear_8bit_ximage; |
| 897 | } |
| 898 | break; |
| 899 | case 16: |
| 900 | back_xrb->clearFunc = clear_16bit_ximage; |
| 901 | break; |
| 902 | case 24: |
| 903 | back_xrb->clearFunc = clear_24bit_ximage; |
| 904 | break; |
| 905 | case 32: |
| 906 | back_xrb->clearFunc = clear_32bit_ximage; |
| 907 | break; |
| 908 | default: |
| 909 | back_xrb->clearFunc = clear_nbit_ximage; |
| 910 | break; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 911 | } |
Brian Paul | f905145 | 2005-04-18 17:48:25 +0000 | [diff] [blame] | 912 | } |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 913 | } |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 914 | } |
| 915 | |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 916 | if (xmesa->xm_visual->hpcr_clear_flag) { |
| 917 | /* this depends on whether we're drawing to the front or back buffer */ |
| 918 | /* XXX FIX THIS! */ |
| 919 | #if 0 |
| 920 | if (pixmap) { |
| 921 | ctx->Driver.ClearColor = clear_color_HPCR_pixmap; |
| 922 | } |
| 923 | else { |
| 924 | ctx->Driver.ClearColor = clear_color_HPCR_ximage; |
| 925 | } |
| 926 | #else |
| 927 | (void) clear_color_HPCR_pixmap; |
| 928 | (void) clear_color_HPCR_ximage; |
| 929 | #endif |
| 930 | } |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 931 | } |
| 932 | |
| 933 | |
| 934 | |
Brian Paul | 738318b | 2003-04-04 17:17:50 +0000 | [diff] [blame] | 935 | /** |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 936 | * In SW, we don't really compress GL_COMPRESSED_RGB[A] textures! |
| 937 | */ |
Brian Paul | 1f7c914 | 2009-09-30 20:28:45 -0600 | [diff] [blame] | 938 | static gl_format |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 939 | choose_tex_format( struct gl_context *ctx, GLint internalFormat, |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 940 | GLenum format, GLenum type ) |
| 941 | { |
| 942 | switch (internalFormat) { |
| 943 | case GL_COMPRESSED_RGB_ARB: |
Brian Paul | 3fa7dbf | 2009-09-30 21:00:16 -0600 | [diff] [blame] | 944 | return MESA_FORMAT_RGB888; |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 945 | case GL_COMPRESSED_RGBA_ARB: |
Brian Paul | 3fa7dbf | 2009-09-30 21:00:16 -0600 | [diff] [blame] | 946 | return MESA_FORMAT_RGBA8888; |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 947 | default: |
| 948 | return _mesa_choose_tex_format(ctx, internalFormat, format, type); |
| 949 | } |
| 950 | } |
| 951 | |
| 952 | |
| 953 | /** |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 954 | * Called by glViewport. |
| 955 | * This is a good time for us to poll the current X window size and adjust |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 956 | * our renderbuffers to match the current window size. |
| 957 | * Remember, we have no opportunity to respond to conventional |
| 958 | * X Resize/StructureNotify events since the X driver has no event loop. |
| 959 | * Thus, we poll. |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 960 | * Note that this trick isn't fool-proof. If the application never calls |
| 961 | * glViewport, our notion of the current window size may be incorrect. |
Brian Paul | 444cd29 | 2006-04-27 02:47:50 +0000 | [diff] [blame] | 962 | * That problem led to the GLX_MESA_resize_buffers extension. |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 963 | */ |
| 964 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 965 | xmesa_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h) |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 966 | { |
Brian Paul | d21fa9c | 2006-10-14 22:52:17 +0000 | [diff] [blame] | 967 | XMesaContext xmctx = XMESA_CONTEXT(ctx); |
| 968 | XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer); |
| 969 | XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer); |
| 970 | xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf); |
| 971 | xmesa_check_and_update_buffer_size(xmctx, xmreadbuf); |
Brian Paul | 444cd29 | 2006-04-27 02:47:50 +0000 | [diff] [blame] | 972 | (void) x; |
| 973 | (void) y; |
| 974 | (void) w; |
| 975 | (void) h; |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 976 | } |
| 977 | |
| 978 | |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 979 | #if ENABLE_EXT_timer_query |
| 980 | |
| 981 | /* |
| 982 | * The GL_EXT_timer_query extension is not enabled for the XServer |
| 983 | * indirect renderer. Not sure about how/if wrapping of gettimeofday() |
| 984 | * is done, etc. |
| 985 | */ |
| 986 | |
| 987 | struct xmesa_query_object |
| 988 | { |
| 989 | struct gl_query_object Base; |
| 990 | struct timeval StartTime; |
| 991 | }; |
| 992 | |
| 993 | |
| 994 | static struct gl_query_object * |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 995 | xmesa_new_query_object(struct gl_context *ctx, GLuint id) |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 996 | { |
| 997 | struct xmesa_query_object *q = CALLOC_STRUCT(xmesa_query_object); |
| 998 | if (q) { |
| 999 | q->Base.Id = id; |
| 1000 | q->Base.Ready = GL_TRUE; |
| 1001 | } |
| 1002 | return &q->Base; |
| 1003 | } |
| 1004 | |
| 1005 | |
| 1006 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 1007 | xmesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1008 | { |
Keith Whitwell | 7ce5975 | 2008-09-20 06:34:23 -0700 | [diff] [blame] | 1009 | if (q->Target == GL_TIME_ELAPSED_EXT) { |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1010 | struct xmesa_query_object *xq = (struct xmesa_query_object *) q; |
| 1011 | (void) gettimeofday(&xq->StartTime, NULL); |
| 1012 | } |
| 1013 | } |
| 1014 | |
| 1015 | |
| 1016 | /** |
| 1017 | * Return the difference between the two given times in microseconds. |
| 1018 | */ |
Jouk Jansen | 21ed295 | 2005-09-08 10:05:37 +0000 | [diff] [blame] | 1019 | #ifdef __VMS |
| 1020 | #define suseconds_t unsigned int |
| 1021 | #endif |
Brian Paul | 0fa8c59 | 2005-12-07 14:48:19 +0000 | [diff] [blame] | 1022 | static GLuint64EXT |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1023 | time_diff(const struct timeval *t0, const struct timeval *t1) |
| 1024 | { |
Brian Paul | 0fa8c59 | 2005-12-07 14:48:19 +0000 | [diff] [blame] | 1025 | GLuint64EXT seconds0 = t0->tv_sec & 0xff; /* 0 .. 255 seconds */ |
| 1026 | GLuint64EXT seconds1 = t1->tv_sec & 0xff; /* 0 .. 255 seconds */ |
| 1027 | GLuint64EXT nanosec0 = (seconds0 * 1000000 + t0->tv_usec) * 1000; |
| 1028 | GLuint64EXT nanosec1 = (seconds1 * 1000000 + t1->tv_usec) * 1000; |
| 1029 | return nanosec1 - nanosec0; |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1030 | } |
| 1031 | |
| 1032 | |
| 1033 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 1034 | xmesa_end_query(struct gl_context *ctx, struct gl_query_object *q) |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1035 | { |
Keith Whitwell | 7ce5975 | 2008-09-20 06:34:23 -0700 | [diff] [blame] | 1036 | if (q->Target == GL_TIME_ELAPSED_EXT) { |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1037 | struct xmesa_query_object *xq = (struct xmesa_query_object *) q; |
| 1038 | struct timeval endTime; |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1039 | (void) gettimeofday(&endTime, NULL); |
Brian Paul | 0fa8c59 | 2005-12-07 14:48:19 +0000 | [diff] [blame] | 1040 | /* result is in nanoseconds! */ |
| 1041 | q->Result = time_diff(&xq->StartTime, &endTime); |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1042 | } |
| 1043 | q->Ready = GL_TRUE; |
| 1044 | } |
| 1045 | |
| 1046 | #endif /* ENABLE_timer_query */ |
| 1047 | |
| 1048 | |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 1049 | /** |
Brian Paul | d3fd7ba | 2004-01-20 02:49:27 +0000 | [diff] [blame] | 1050 | * Initialize the device driver function table with the functions |
| 1051 | * we implement in this driver. |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 1052 | */ |
Brian Paul | 29926a1 | 2004-11-27 21:20:37 +0000 | [diff] [blame] | 1053 | void |
| 1054 | xmesa_init_driver_functions( XMesaVisual xmvisual, |
| 1055 | struct dd_function_table *driver ) |
Keith Whitwell | ec05858 | 2000-11-05 18:26:12 +0000 | [diff] [blame] | 1056 | { |
Brian Paul | d3fd7ba | 2004-01-20 02:49:27 +0000 | [diff] [blame] | 1057 | driver->GetString = get_string; |
| 1058 | driver->UpdateState = xmesa_update_state; |
Brian Paul | 42b26f6 | 2006-10-17 17:51:39 +0000 | [diff] [blame] | 1059 | driver->GetBufferSize = NULL; /* OBSOLETE */ |
Brian Paul | d3fd7ba | 2004-01-20 02:49:27 +0000 | [diff] [blame] | 1060 | driver->Flush = finish_or_flush; |
| 1061 | driver->Finish = finish_or_flush; |
Brian Paul | d3fd7ba | 2004-01-20 02:49:27 +0000 | [diff] [blame] | 1062 | driver->ClearColor = clear_color; |
Brian Paul | d3fd7ba | 2004-01-20 02:49:27 +0000 | [diff] [blame] | 1063 | driver->ColorMask = color_mask; |
| 1064 | driver->Enable = enable; |
Brian Paul | 65a66f5 | 2004-11-27 22:47:59 +0000 | [diff] [blame] | 1065 | driver->Viewport = xmesa_viewport; |
Brian Paul | 8126dfa | 2009-08-31 19:29:24 -0600 | [diff] [blame] | 1066 | if (TEST_META_FUNCS) { |
Brian Paul | 4de8e21 | 2009-09-19 17:06:15 -0600 | [diff] [blame] | 1067 | driver->Clear = _mesa_meta_Clear; |
| 1068 | driver->CopyPixels = _mesa_meta_CopyPixels; |
| 1069 | driver->BlitFramebuffer = _mesa_meta_BlitFramebuffer; |
| 1070 | driver->DrawPixels = _mesa_meta_DrawPixels; |
| 1071 | driver->Bitmap = _mesa_meta_Bitmap; |
Brian Paul | 8126dfa | 2009-08-31 19:29:24 -0600 | [diff] [blame] | 1072 | } |
Brian Paul | ae5d781 | 2009-08-31 21:14:50 -0600 | [diff] [blame] | 1073 | else { |
| 1074 | driver->Clear = clear_buffers; |
Brian Paul | ae5d781 | 2009-08-31 21:14:50 -0600 | [diff] [blame] | 1075 | driver->CopyPixels = xmesa_CopyPixels; |
| 1076 | if (xmvisual->undithered_pf == PF_8R8G8B && |
| 1077 | xmvisual->dithered_pf == PF_8R8G8B && |
| 1078 | xmvisual->BitsPerPixel == 32) { |
| 1079 | driver->DrawPixels = xmesa_DrawPixels_8R8G8B; |
| 1080 | } |
| 1081 | else if (xmvisual->undithered_pf == PF_5R6G5B) { |
| 1082 | driver->DrawPixels = xmesa_DrawPixels_5R6G5B; |
| 1083 | } |
Brian Paul | 4fdc96d | 2009-09-03 21:19:23 -0600 | [diff] [blame] | 1084 | } |
Brian Paul | 03a4f97 | 2010-11-24 12:01:02 -0700 | [diff] [blame] | 1085 | |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1086 | #if ENABLE_EXT_texure_compression_s3tc |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 1087 | driver->ChooseTextureFormat = choose_tex_format; |
Brian Paul | be2de8b | 2004-11-25 23:25:33 +0000 | [diff] [blame] | 1088 | #else |
| 1089 | (void) choose_tex_format; |
Daniel Borca | 3c9faa4 | 2004-10-12 07:32:11 +0000 | [diff] [blame] | 1090 | #endif |
Brian Paul | 4fb9950 | 2005-09-02 13:42:49 +0000 | [diff] [blame] | 1091 | |
| 1092 | #if ENABLE_EXT_timer_query |
| 1093 | driver->NewQueryObject = xmesa_new_query_object; |
| 1094 | driver->BeginQuery = xmesa_begin_query; |
| 1095 | driver->EndQuery = xmesa_end_query; |
| 1096 | #endif |
Brian Paul | 693f81b | 2000-09-07 15:40:30 +0000 | [diff] [blame] | 1097 | } |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1098 | |
| 1099 | |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1100 | #define XMESA_NEW_POINT (_NEW_POINT | \ |
| 1101 | _NEW_RENDERMODE | \ |
| 1102 | _SWRAST_NEW_RASTERMASK) |
| 1103 | |
| 1104 | #define XMESA_NEW_LINE (_NEW_LINE | \ |
| 1105 | _NEW_TEXTURE | \ |
| 1106 | _NEW_LIGHT | \ |
| 1107 | _NEW_DEPTH | \ |
| 1108 | _NEW_RENDERMODE | \ |
| 1109 | _SWRAST_NEW_RASTERMASK) |
| 1110 | |
| 1111 | #define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \ |
| 1112 | _NEW_TEXTURE | \ |
| 1113 | _NEW_LIGHT | \ |
| 1114 | _NEW_DEPTH | \ |
| 1115 | _NEW_RENDERMODE | \ |
| 1116 | _SWRAST_NEW_RASTERMASK) |
| 1117 | |
| 1118 | |
Brian Paul | 3a5bb17 | 2006-01-26 01:32:47 +0000 | [diff] [blame] | 1119 | /** |
| 1120 | * Extend the software rasterizer with our line/point/triangle |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1121 | * functions. |
Brian Paul | 3a5bb17 | 2006-01-26 01:32:47 +0000 | [diff] [blame] | 1122 | * Called during context creation only. |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1123 | */ |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 1124 | void xmesa_register_swrast_functions( struct gl_context *ctx ) |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1125 | { |
| 1126 | SWcontext *swrast = SWRAST_CONTEXT( ctx ); |
| 1127 | |
| 1128 | swrast->choose_point = xmesa_choose_point; |
| 1129 | swrast->choose_line = xmesa_choose_line; |
| 1130 | swrast->choose_triangle = xmesa_choose_triangle; |
| 1131 | |
Brian Paul | 3a5bb17 | 2006-01-26 01:32:47 +0000 | [diff] [blame] | 1132 | /* XXX these lines have no net effect. Remove??? */ |
| 1133 | swrast->InvalidatePointMask |= XMESA_NEW_POINT; |
| 1134 | swrast->InvalidateLineMask |= XMESA_NEW_LINE; |
| 1135 | swrast->InvalidateTriangleMask |= XMESA_NEW_TRIANGLE; |
Brian Paul | 097d2a0 | 2001-09-12 03:32:29 +0000 | [diff] [blame] | 1136 | } |