Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbuffers.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00033 #include "glheader.h" 00034 #include "buffers.h" 00035 #include "colormac.h" 00036 #include "context.h" 00037 #include "enums.h" 00038 #include "fbobject.h" 00039 #include "state.h" 00040 00041 00042 #define BAD_MASK ~0u 00043 00044 00054 static GLbitfield 00055 supported_buffer_bitmask(const GLcontext *ctx, const struct gl_framebuffer *fb) 00056 { 00057 GLbitfield mask = 0x0; 00058 00059 if (fb->Name > 0) { 00060 /* A user-created renderbuffer */ 00061 GLuint i; 00062 ASSERT(ctx->Extensions.EXT_framebuffer_object); 00063 for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { 00064 mask |= (BUFFER_BIT_COLOR0 << i); 00065 } 00066 } 00067 else { 00068 /* A window system framebuffer */ 00069 GLint i; 00070 mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ 00071 if (fb->Visual.stereoMode) { 00072 mask |= BUFFER_BIT_FRONT_RIGHT; 00073 if (fb->Visual.doubleBufferMode) { 00074 mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 00075 } 00076 } 00077 else if (fb->Visual.doubleBufferMode) { 00078 mask |= BUFFER_BIT_BACK_LEFT; 00079 } 00080 00081 for (i = 0; i < fb->Visual.numAuxBuffers; i++) { 00082 mask |= (BUFFER_BIT_AUX0 << i); 00083 } 00084 } 00085 00086 return mask; 00087 } 00088 00089 00095 static GLbitfield 00096 draw_buffer_enum_to_bitmask(GLenum buffer) 00097 { 00098 switch (buffer) { 00099 case GL_NONE: 00100 return 0; 00101 case GL_FRONT: 00102 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; 00103 case GL_BACK: 00104 return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 00105 case GL_RIGHT: 00106 return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 00107 case GL_FRONT_RIGHT: 00108 return BUFFER_BIT_FRONT_RIGHT; 00109 case GL_BACK_RIGHT: 00110 return BUFFER_BIT_BACK_RIGHT; 00111 case GL_BACK_LEFT: 00112 return BUFFER_BIT_BACK_LEFT; 00113 case GL_FRONT_AND_BACK: 00114 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT 00115 | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 00116 case GL_LEFT: 00117 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; 00118 case GL_FRONT_LEFT: 00119 return BUFFER_BIT_FRONT_LEFT; 00120 case GL_AUX0: 00121 return BUFFER_BIT_AUX0; 00122 case GL_AUX1: 00123 return BUFFER_BIT_AUX1; 00124 case GL_AUX2: 00125 return BUFFER_BIT_AUX2; 00126 case GL_AUX3: 00127 return BUFFER_BIT_AUX3; 00128 case GL_COLOR_ATTACHMENT0_EXT: 00129 return BUFFER_BIT_COLOR0; 00130 case GL_COLOR_ATTACHMENT1_EXT: 00131 return BUFFER_BIT_COLOR1; 00132 case GL_COLOR_ATTACHMENT2_EXT: 00133 return BUFFER_BIT_COLOR2; 00134 case GL_COLOR_ATTACHMENT3_EXT: 00135 return BUFFER_BIT_COLOR3; 00136 case GL_COLOR_ATTACHMENT4_EXT: 00137 return BUFFER_BIT_COLOR4; 00138 case GL_COLOR_ATTACHMENT5_EXT: 00139 return BUFFER_BIT_COLOR5; 00140 case GL_COLOR_ATTACHMENT6_EXT: 00141 return BUFFER_BIT_COLOR6; 00142 case GL_COLOR_ATTACHMENT7_EXT: 00143 return BUFFER_BIT_COLOR7; 00144 default: 00145 /* error */ 00146 return BAD_MASK; 00147 } 00148 } 00149 00150 00157 static GLint 00158 read_buffer_enum_to_index(GLenum buffer) 00159 { 00160 switch (buffer) { 00161 case GL_FRONT: 00162 return BUFFER_FRONT_LEFT; 00163 case GL_BACK: 00164 return BUFFER_BACK_LEFT; 00165 case GL_RIGHT: 00166 return BUFFER_FRONT_RIGHT; 00167 case GL_FRONT_RIGHT: 00168 return BUFFER_FRONT_RIGHT; 00169 case GL_BACK_RIGHT: 00170 return BUFFER_BACK_RIGHT; 00171 case GL_BACK_LEFT: 00172 return BUFFER_BACK_LEFT; 00173 case GL_LEFT: 00174 return BUFFER_FRONT_LEFT; 00175 case GL_FRONT_LEFT: 00176 return BUFFER_FRONT_LEFT; 00177 case GL_AUX0: 00178 return BUFFER_AUX0; 00179 case GL_AUX1: 00180 return BUFFER_AUX1; 00181 case GL_AUX2: 00182 return BUFFER_AUX2; 00183 case GL_AUX3: 00184 return BUFFER_AUX3; 00185 case GL_COLOR_ATTACHMENT0_EXT: 00186 return BUFFER_COLOR0; 00187 case GL_COLOR_ATTACHMENT1_EXT: 00188 return BUFFER_COLOR1; 00189 case GL_COLOR_ATTACHMENT2_EXT: 00190 return BUFFER_COLOR2; 00191 case GL_COLOR_ATTACHMENT3_EXT: 00192 return BUFFER_COLOR3; 00193 case GL_COLOR_ATTACHMENT4_EXT: 00194 return BUFFER_COLOR4; 00195 case GL_COLOR_ATTACHMENT5_EXT: 00196 return BUFFER_COLOR5; 00197 case GL_COLOR_ATTACHMENT6_EXT: 00198 return BUFFER_COLOR6; 00199 case GL_COLOR_ATTACHMENT7_EXT: 00200 return BUFFER_COLOR7; 00201 default: 00202 /* error */ 00203 return -1; 00204 } 00205 } 00206 00207 00230 void GLAPIENTRY 00231 _mesa_DrawBuffer(GLenum buffer) 00232 { 00233 GLbitfield destMask; 00234 GET_CURRENT_CONTEXT(ctx); 00235 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ 00236 00237 if (MESA_VERBOSE & VERBOSE_API) { 00238 _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 00239 } 00240 00241 if (buffer == GL_NONE) { 00242 destMask = 0x0; 00243 } 00244 else { 00245 const GLbitfield supportedMask 00246 = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 00247 destMask = draw_buffer_enum_to_bitmask(buffer); 00248 if (destMask == BAD_MASK) { 00249 /* totally bogus buffer */ 00250 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer=0x%x)", buffer); 00251 return; 00252 } 00253 destMask &= supportedMask; 00254 if (destMask == 0x0) { 00255 /* none of the named color buffers exist! */ 00256 _mesa_error(ctx, GL_INVALID_OPERATION, 00257 "glDrawBuffer(buffer=0x%x)", buffer); 00258 return; 00259 } 00260 } 00261 00262 /* if we get here, there's no error so set new state */ 00263 _mesa_drawbuffers(ctx, 1, &buffer, &destMask); 00264 00265 /* 00266 * Call device driver function. 00267 */ 00268 if (ctx->Driver.DrawBuffers) 00269 ctx->Driver.DrawBuffers(ctx, 1, &buffer); 00270 else if (ctx->Driver.DrawBuffer) 00271 ctx->Driver.DrawBuffer(ctx, buffer); 00272 } 00273 00274 00284 void GLAPIENTRY 00285 _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) 00286 { 00287 GLint output; 00288 GLbitfield usedBufferMask, supportedMask; 00289 GLbitfield destMask[MAX_DRAW_BUFFERS]; 00290 GET_CURRENT_CONTEXT(ctx); 00291 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 00292 00293 if (!ctx->Extensions.ARB_draw_buffers) { 00294 _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB"); 00295 return; 00296 } 00297 if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { 00298 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); 00299 return; 00300 } 00301 00302 supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 00303 usedBufferMask = 0x0; 00304 00305 /* complicated error checking... */ 00306 for (output = 0; output < n; output++) { 00307 if (buffers[output] == GL_NONE) { 00308 destMask[output] = 0x0; 00309 } 00310 else { 00311 destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]); 00312 if (destMask[output] == BAD_MASK 00313 || _mesa_bitcount(destMask[output]) > 1) { 00314 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); 00315 return; 00316 } 00317 destMask[output] &= supportedMask; 00318 if (destMask[output] == 0) { 00319 _mesa_error(ctx, GL_INVALID_OPERATION, 00320 "glDrawBuffersARB(unsupported buffer)"); 00321 return; 00322 } 00323 if (destMask[output] & usedBufferMask) { 00324 /* can't specify a dest buffer more than once! */ 00325 _mesa_error(ctx, GL_INVALID_OPERATION, 00326 "glDrawBuffersARB(duplicated buffer)"); 00327 return; 00328 } 00329 00330 /* update bitmask */ 00331 usedBufferMask |= destMask[output]; 00332 } 00333 } 00334 00335 /* OK, if we get here, there were no errors so set the new state */ 00336 _mesa_drawbuffers(ctx, n, buffers, destMask); 00337 00338 /* 00339 * Call device driver function. 00340 */ 00341 if (ctx->Driver.DrawBuffers) 00342 ctx->Driver.DrawBuffers(ctx, n, buffers); 00343 else if (ctx->Driver.DrawBuffer) 00344 ctx->Driver.DrawBuffer(ctx, buffers[0]); 00345 } 00346 00347 00362 void 00363 _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, 00364 const GLbitfield *destMask) 00365 { 00366 struct gl_framebuffer *fb = ctx->DrawBuffer; 00367 GLbitfield mask[MAX_DRAW_BUFFERS]; 00368 00369 if (!destMask) { 00370 /* compute destMask values now */ 00371 const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); 00372 GLuint output; 00373 for (output = 0; output < n; output++) { 00374 mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); 00375 ASSERT(mask[output] != BAD_MASK); 00376 mask[output] &= supportedMask; 00377 } 00378 destMask = mask; 00379 } 00380 00381 if (n == 1) { 00382 GLuint buf, count = 0; 00383 /* init to -1 to help catch errors */ 00384 fb->_ColorDrawBufferIndexes[0] = -1; 00385 for (buf = 0; buf < BUFFER_COUNT; buf++) { 00386 if (destMask[0] & (1 << buf)) { 00387 fb->_ColorDrawBufferIndexes[count] = buf; 00388 count++; 00389 } 00390 } 00391 fb->ColorDrawBuffer[0] = buffers[0]; 00392 fb->_NumColorDrawBuffers = count; 00393 } 00394 else { 00395 GLuint buf, count = 0; 00396 for (buf = 0; buf < n; buf++ ) { 00397 if (destMask[buf]) { 00398 fb->_ColorDrawBufferIndexes[buf] = _mesa_ffs(destMask[buf]) - 1; 00399 fb->ColorDrawBuffer[buf] = buffers[buf]; 00400 count = buf + 1; 00401 } 00402 else { 00403 fb->_ColorDrawBufferIndexes[buf] = -1; 00404 } 00405 } 00406 /* set remaining outputs to -1 (GL_NONE) */ 00407 while (buf < ctx->Const.MaxDrawBuffers) { 00408 fb->_ColorDrawBufferIndexes[buf] = -1; 00409 fb->ColorDrawBuffer[buf] = GL_NONE; 00410 buf++; 00411 } 00412 fb->_NumColorDrawBuffers = count; 00413 } 00414 00415 if (fb->Name == 0) { 00416 /* also set context drawbuffer state */ 00417 GLuint buf; 00418 for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 00419 ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; 00420 } 00421 } 00422 00423 ctx->NewState |= _NEW_COLOR; 00424 } 00425 00426 00434 void 00435 _mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex) 00436 { 00437 struct gl_framebuffer *fb = ctx->ReadBuffer; 00438 00439 if (fb->Name == 0) { 00440 /* Only update the per-context READ_BUFFER state if we're bound to 00441 * a window-system framebuffer. 00442 */ 00443 ctx->Pixel.ReadBuffer = buffer; 00444 } 00445 00446 fb->ColorReadBuffer = buffer; 00447 fb->_ColorReadBufferIndex = bufferIndex; 00448 00449 ctx->NewState |= _NEW_PIXEL; 00450 } 00451 00452 00453 00458 void GLAPIENTRY 00459 _mesa_ReadBuffer(GLenum buffer) 00460 { 00461 struct gl_framebuffer *fb; 00462 GLbitfield supportedMask; 00463 GLint srcBuffer; 00464 GET_CURRENT_CONTEXT(ctx); 00465 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 00466 00467 if (MESA_VERBOSE & VERBOSE_API) 00468 _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 00469 00470 fb = ctx->ReadBuffer; 00471 00472 if (MESA_VERBOSE & VERBOSE_API) 00473 _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 00474 00475 if (fb->Name > 0 && buffer == GL_NONE) { 00476 /* This is legal for user-created framebuffer objects */ 00477 srcBuffer = -1; 00478 } 00479 else { 00480 /* general case / window-system framebuffer */ 00481 srcBuffer = read_buffer_enum_to_index(buffer); 00482 if (srcBuffer == -1) { 00483 _mesa_error(ctx, GL_INVALID_ENUM, 00484 "glReadBuffer(buffer=0x%x)", buffer); 00485 return; 00486 } 00487 supportedMask = supported_buffer_bitmask(ctx, fb); 00488 if (((1 << srcBuffer) & supportedMask) == 0) { 00489 _mesa_error(ctx, GL_INVALID_OPERATION, 00490 "glReadBuffer(buffer=0x%x)", buffer); 00491 return; 00492 } 00493 } 00494 00495 /* OK, all error checking has been completed now */ 00496 00497 _mesa_readbuffer(ctx, buffer, srcBuffer); 00498 00499 /* 00500 * Call device driver function. 00501 */ 00502 if (ctx->Driver.ReadBuffer) 00503 (*ctx->Driver.ReadBuffer)(ctx, buffer); 00504 } Generated on Sat May 26 2012 04:18:57 for ReactOS by
1.7.6.1
|