Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_depth.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.2.1 00004 * 00005 * Copyright (C) 1999-2008 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 00026 #include "main/glheader.h" 00027 #include "main/context.h" 00028 #include "main/macros.h" 00029 #include "main/imports.h" 00030 #include "main/fbobject.h" 00031 00032 #include "s_depth.h" 00033 #include "s_context.h" 00034 #include "s_span.h" 00035 00036 00043 static GLuint 00044 depth_test_span16( GLcontext *ctx, GLuint n, 00045 GLushort zbuffer[], const GLuint z[], GLubyte mask[] ) 00046 { 00047 GLuint passed = 0; 00048 00049 /* switch cases ordered from most frequent to less frequent */ 00050 switch (ctx->Depth.Func) { 00051 case GL_LESS: 00052 if (ctx->Depth.Mask) { 00053 /* Update Z buffer */ 00054 GLuint i; 00055 for (i=0; i<n; i++) { 00056 if (mask[i]) { 00057 if (z[i] < zbuffer[i]) { 00058 /* pass */ 00059 zbuffer[i] = z[i]; 00060 passed++; 00061 } 00062 else { 00063 /* fail */ 00064 mask[i] = 0; 00065 } 00066 } 00067 } 00068 } 00069 else { 00070 /* Don't update Z buffer */ 00071 GLuint i; 00072 for (i=0; i<n; i++) { 00073 if (mask[i]) { 00074 if (z[i] < zbuffer[i]) { 00075 /* pass */ 00076 passed++; 00077 } 00078 else { 00079 mask[i] = 0; 00080 } 00081 } 00082 } 00083 } 00084 break; 00085 case GL_LEQUAL: 00086 if (ctx->Depth.Mask) { 00087 /* Update Z buffer */ 00088 GLuint i; 00089 for (i=0;i<n;i++) { 00090 if (mask[i]) { 00091 if (z[i] <= zbuffer[i]) { 00092 zbuffer[i] = z[i]; 00093 passed++; 00094 } 00095 else { 00096 mask[i] = 0; 00097 } 00098 } 00099 } 00100 } 00101 else { 00102 /* Don't update Z buffer */ 00103 GLuint i; 00104 for (i=0;i<n;i++) { 00105 if (mask[i]) { 00106 if (z[i] <= zbuffer[i]) { 00107 /* pass */ 00108 passed++; 00109 } 00110 else { 00111 mask[i] = 0; 00112 } 00113 } 00114 } 00115 } 00116 break; 00117 case GL_GEQUAL: 00118 if (ctx->Depth.Mask) { 00119 /* Update Z buffer */ 00120 GLuint i; 00121 for (i=0;i<n;i++) { 00122 if (mask[i]) { 00123 if (z[i] >= zbuffer[i]) { 00124 zbuffer[i] = z[i]; 00125 passed++; 00126 } 00127 else { 00128 mask[i] = 0; 00129 } 00130 } 00131 } 00132 } 00133 else { 00134 /* Don't update Z buffer */ 00135 GLuint i; 00136 for (i=0;i<n;i++) { 00137 if (mask[i]) { 00138 if (z[i] >= zbuffer[i]) { 00139 /* pass */ 00140 passed++; 00141 } 00142 else { 00143 mask[i] = 0; 00144 } 00145 } 00146 } 00147 } 00148 break; 00149 case GL_GREATER: 00150 if (ctx->Depth.Mask) { 00151 /* Update Z buffer */ 00152 GLuint i; 00153 for (i=0;i<n;i++) { 00154 if (mask[i]) { 00155 if (z[i] > zbuffer[i]) { 00156 zbuffer[i] = z[i]; 00157 passed++; 00158 } 00159 else { 00160 mask[i] = 0; 00161 } 00162 } 00163 } 00164 } 00165 else { 00166 /* Don't update Z buffer */ 00167 GLuint i; 00168 for (i=0;i<n;i++) { 00169 if (mask[i]) { 00170 if (z[i] > zbuffer[i]) { 00171 /* pass */ 00172 passed++; 00173 } 00174 else { 00175 mask[i] = 0; 00176 } 00177 } 00178 } 00179 } 00180 break; 00181 case GL_NOTEQUAL: 00182 if (ctx->Depth.Mask) { 00183 /* Update Z buffer */ 00184 GLuint i; 00185 for (i=0;i<n;i++) { 00186 if (mask[i]) { 00187 if (z[i] != zbuffer[i]) { 00188 zbuffer[i] = z[i]; 00189 passed++; 00190 } 00191 else { 00192 mask[i] = 0; 00193 } 00194 } 00195 } 00196 } 00197 else { 00198 /* Don't update Z buffer */ 00199 GLuint i; 00200 for (i=0;i<n;i++) { 00201 if (mask[i]) { 00202 if (z[i] != zbuffer[i]) { 00203 /* pass */ 00204 passed++; 00205 } 00206 else { 00207 mask[i] = 0; 00208 } 00209 } 00210 } 00211 } 00212 break; 00213 case GL_EQUAL: 00214 if (ctx->Depth.Mask) { 00215 /* Update Z buffer */ 00216 GLuint i; 00217 for (i=0;i<n;i++) { 00218 if (mask[i]) { 00219 if (z[i] == zbuffer[i]) { 00220 zbuffer[i] = z[i]; 00221 passed++; 00222 } 00223 else { 00224 mask[i] = 0; 00225 } 00226 } 00227 } 00228 } 00229 else { 00230 /* Don't update Z buffer */ 00231 GLuint i; 00232 for (i=0;i<n;i++) { 00233 if (mask[i]) { 00234 if (z[i] == zbuffer[i]) { 00235 /* pass */ 00236 passed++; 00237 } 00238 else { 00239 mask[i] = 0; 00240 } 00241 } 00242 } 00243 } 00244 break; 00245 case GL_ALWAYS: 00246 if (ctx->Depth.Mask) { 00247 /* Update Z buffer */ 00248 GLuint i; 00249 for (i=0;i<n;i++) { 00250 if (mask[i]) { 00251 zbuffer[i] = z[i]; 00252 passed++; 00253 } 00254 } 00255 } 00256 else { 00257 /* Don't update Z buffer or mask */ 00258 passed = n; 00259 } 00260 break; 00261 case GL_NEVER: 00262 _mesa_bzero(mask, n * sizeof(GLubyte)); 00263 break; 00264 default: 00265 _mesa_problem(ctx, "Bad depth func in depth_test_span16"); 00266 } 00267 00268 return passed; 00269 } 00270 00271 00272 static GLuint 00273 depth_test_span32( GLcontext *ctx, GLuint n, 00274 GLuint zbuffer[], const GLuint z[], GLubyte mask[] ) 00275 { 00276 GLuint passed = 0; 00277 00278 /* switch cases ordered from most frequent to less frequent */ 00279 switch (ctx->Depth.Func) { 00280 case GL_LESS: 00281 if (ctx->Depth.Mask) { 00282 /* Update Z buffer */ 00283 GLuint i; 00284 for (i=0; i<n; i++) { 00285 if (mask[i]) { 00286 if (z[i] < zbuffer[i]) { 00287 /* pass */ 00288 zbuffer[i] = z[i]; 00289 passed++; 00290 } 00291 else { 00292 /* fail */ 00293 mask[i] = 0; 00294 } 00295 } 00296 } 00297 } 00298 else { 00299 /* Don't update Z buffer */ 00300 GLuint i; 00301 for (i=0; i<n; i++) { 00302 if (mask[i]) { 00303 if (z[i] < zbuffer[i]) { 00304 /* pass */ 00305 passed++; 00306 } 00307 else { 00308 mask[i] = 0; 00309 } 00310 } 00311 } 00312 } 00313 break; 00314 case GL_LEQUAL: 00315 if (ctx->Depth.Mask) { 00316 /* Update Z buffer */ 00317 GLuint i; 00318 for (i=0;i<n;i++) { 00319 if (mask[i]) { 00320 if (z[i] <= zbuffer[i]) { 00321 zbuffer[i] = z[i]; 00322 passed++; 00323 } 00324 else { 00325 mask[i] = 0; 00326 } 00327 } 00328 } 00329 } 00330 else { 00331 /* Don't update Z buffer */ 00332 GLuint i; 00333 for (i=0;i<n;i++) { 00334 if (mask[i]) { 00335 if (z[i] <= zbuffer[i]) { 00336 /* pass */ 00337 passed++; 00338 } 00339 else { 00340 mask[i] = 0; 00341 } 00342 } 00343 } 00344 } 00345 break; 00346 case GL_GEQUAL: 00347 if (ctx->Depth.Mask) { 00348 /* Update Z buffer */ 00349 GLuint i; 00350 for (i=0;i<n;i++) { 00351 if (mask[i]) { 00352 if (z[i] >= zbuffer[i]) { 00353 zbuffer[i] = z[i]; 00354 passed++; 00355 } 00356 else { 00357 mask[i] = 0; 00358 } 00359 } 00360 } 00361 } 00362 else { 00363 /* Don't update Z buffer */ 00364 GLuint i; 00365 for (i=0;i<n;i++) { 00366 if (mask[i]) { 00367 if (z[i] >= zbuffer[i]) { 00368 /* pass */ 00369 passed++; 00370 } 00371 else { 00372 mask[i] = 0; 00373 } 00374 } 00375 } 00376 } 00377 break; 00378 case GL_GREATER: 00379 if (ctx->Depth.Mask) { 00380 /* Update Z buffer */ 00381 GLuint i; 00382 for (i=0;i<n;i++) { 00383 if (mask[i]) { 00384 if (z[i] > zbuffer[i]) { 00385 zbuffer[i] = z[i]; 00386 passed++; 00387 } 00388 else { 00389 mask[i] = 0; 00390 } 00391 } 00392 } 00393 } 00394 else { 00395 /* Don't update Z buffer */ 00396 GLuint i; 00397 for (i=0;i<n;i++) { 00398 if (mask[i]) { 00399 if (z[i] > zbuffer[i]) { 00400 /* pass */ 00401 passed++; 00402 } 00403 else { 00404 mask[i] = 0; 00405 } 00406 } 00407 } 00408 } 00409 break; 00410 case GL_NOTEQUAL: 00411 if (ctx->Depth.Mask) { 00412 /* Update Z buffer */ 00413 GLuint i; 00414 for (i=0;i<n;i++) { 00415 if (mask[i]) { 00416 if (z[i] != zbuffer[i]) { 00417 zbuffer[i] = z[i]; 00418 passed++; 00419 } 00420 else { 00421 mask[i] = 0; 00422 } 00423 } 00424 } 00425 } 00426 else { 00427 /* Don't update Z buffer */ 00428 GLuint i; 00429 for (i=0;i<n;i++) { 00430 if (mask[i]) { 00431 if (z[i] != zbuffer[i]) { 00432 /* pass */ 00433 passed++; 00434 } 00435 else { 00436 mask[i] = 0; 00437 } 00438 } 00439 } 00440 } 00441 break; 00442 case GL_EQUAL: 00443 if (ctx->Depth.Mask) { 00444 /* Update Z buffer */ 00445 GLuint i; 00446 for (i=0;i<n;i++) { 00447 if (mask[i]) { 00448 if (z[i] == zbuffer[i]) { 00449 zbuffer[i] = z[i]; 00450 passed++; 00451 } 00452 else { 00453 mask[i] = 0; 00454 } 00455 } 00456 } 00457 } 00458 else { 00459 /* Don't update Z buffer */ 00460 GLuint i; 00461 for (i=0;i<n;i++) { 00462 if (mask[i]) { 00463 if (z[i] == zbuffer[i]) { 00464 /* pass */ 00465 passed++; 00466 } 00467 else { 00468 mask[i] = 0; 00469 } 00470 } 00471 } 00472 } 00473 break; 00474 case GL_ALWAYS: 00475 if (ctx->Depth.Mask) { 00476 /* Update Z buffer */ 00477 GLuint i; 00478 for (i=0;i<n;i++) { 00479 if (mask[i]) { 00480 zbuffer[i] = z[i]; 00481 passed++; 00482 } 00483 } 00484 } 00485 else { 00486 /* Don't update Z buffer or mask */ 00487 passed = n; 00488 } 00489 break; 00490 case GL_NEVER: 00491 _mesa_bzero(mask, n * sizeof(GLubyte)); 00492 break; 00493 default: 00494 _mesa_problem(ctx, "Bad depth func in depth_test_span32"); 00495 } 00496 00497 return passed; 00498 } 00499 00500 00501 00502 /* 00503 * Apply depth test to span of fragments. 00504 */ 00505 static GLuint 00506 depth_test_span( GLcontext *ctx, SWspan *span) 00507 { 00508 struct gl_framebuffer *fb = ctx->DrawBuffer; 00509 struct gl_renderbuffer *rb = fb->_DepthBuffer; 00510 const GLint x = span->x; 00511 const GLint y = span->y; 00512 const GLuint count = span->end; 00513 const GLuint *zValues = span->array->z; 00514 GLubyte *mask = span->array->mask; 00515 GLuint passed; 00516 00517 ASSERT((span->arrayMask & SPAN_XY) == 0); 00518 ASSERT(span->arrayMask & SPAN_Z); 00519 00520 if (rb->GetPointer(ctx, rb, 0, 0)) { 00521 /* Directly access buffer */ 00522 if (rb->DataType == GL_UNSIGNED_SHORT) { 00523 GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y); 00524 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask); 00525 } 00526 else { 00527 GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y); 00528 ASSERT(rb->DataType == GL_UNSIGNED_INT); 00529 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask); 00530 } 00531 } 00532 else { 00533 /* read depth values from buffer, test, write back */ 00534 if (rb->DataType == GL_UNSIGNED_SHORT) { 00535 GLushort zbuffer[MAX_WIDTH]; 00536 rb->GetRow(ctx, rb, count, x, y, zbuffer); 00537 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask); 00538 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask); 00539 } 00540 else { 00541 GLuint zbuffer[MAX_WIDTH]; 00542 ASSERT(rb->DataType == GL_UNSIGNED_INT); 00543 rb->GetRow(ctx, rb, count, x, y, zbuffer); 00544 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask); 00545 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask); 00546 } 00547 } 00548 00549 if (passed < count) { 00550 span->writeAll = GL_FALSE; 00551 } 00552 return passed; 00553 } 00554 00555 00556 00557 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X)) 00558 00559 00560 /* 00561 * Do depth testing for an array of fragments at assorted locations. 00562 */ 00563 static void 00564 direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride, 00565 GLuint n, const GLint x[], const GLint y[], 00566 const GLuint z[], GLubyte mask[] ) 00567 { 00568 /* switch cases ordered from most frequent to less frequent */ 00569 switch (ctx->Depth.Func) { 00570 case GL_LESS: 00571 if (ctx->Depth.Mask) { 00572 /* Update Z buffer */ 00573 GLuint i; 00574 for (i=0; i<n; i++) { 00575 if (mask[i]) { 00576 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00577 if (z[i] < *zptr) { 00578 /* pass */ 00579 *zptr = z[i]; 00580 } 00581 else { 00582 /* fail */ 00583 mask[i] = 0; 00584 } 00585 } 00586 } 00587 } 00588 else { 00589 /* Don't update Z buffer */ 00590 GLuint i; 00591 for (i=0; i<n; i++) { 00592 if (mask[i]) { 00593 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00594 if (z[i] < *zptr) { 00595 /* pass */ 00596 } 00597 else { 00598 /* fail */ 00599 mask[i] = 0; 00600 } 00601 } 00602 } 00603 } 00604 break; 00605 case GL_LEQUAL: 00606 if (ctx->Depth.Mask) { 00607 /* Update Z buffer */ 00608 GLuint i; 00609 for (i=0; i<n; i++) { 00610 if (mask[i]) { 00611 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00612 if (z[i] <= *zptr) { 00613 /* pass */ 00614 *zptr = z[i]; 00615 } 00616 else { 00617 /* fail */ 00618 mask[i] = 0; 00619 } 00620 } 00621 } 00622 } 00623 else { 00624 /* Don't update Z buffer */ 00625 GLuint i; 00626 for (i=0; i<n; i++) { 00627 if (mask[i]) { 00628 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00629 if (z[i] <= *zptr) { 00630 /* pass */ 00631 } 00632 else { 00633 /* fail */ 00634 mask[i] = 0; 00635 } 00636 } 00637 } 00638 } 00639 break; 00640 case GL_GEQUAL: 00641 if (ctx->Depth.Mask) { 00642 /* Update Z buffer */ 00643 GLuint i; 00644 for (i=0; i<n; i++) { 00645 if (mask[i]) { 00646 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00647 if (z[i] >= *zptr) { 00648 /* pass */ 00649 *zptr = z[i]; 00650 } 00651 else { 00652 /* fail */ 00653 mask[i] = 0; 00654 } 00655 } 00656 } 00657 } 00658 else { 00659 /* Don't update Z buffer */ 00660 GLuint i; 00661 for (i=0; i<n; i++) { 00662 if (mask[i]) { 00663 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00664 if (z[i] >= *zptr) { 00665 /* pass */ 00666 } 00667 else { 00668 /* fail */ 00669 mask[i] = 0; 00670 } 00671 } 00672 } 00673 } 00674 break; 00675 case GL_GREATER: 00676 if (ctx->Depth.Mask) { 00677 /* Update Z buffer */ 00678 GLuint i; 00679 for (i=0; i<n; i++) { 00680 if (mask[i]) { 00681 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00682 if (z[i] > *zptr) { 00683 /* pass */ 00684 *zptr = z[i]; 00685 } 00686 else { 00687 /* fail */ 00688 mask[i] = 0; 00689 } 00690 } 00691 } 00692 } 00693 else { 00694 /* Don't update Z buffer */ 00695 GLuint i; 00696 for (i=0; i<n; i++) { 00697 if (mask[i]) { 00698 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00699 if (z[i] > *zptr) { 00700 /* pass */ 00701 } 00702 else { 00703 /* fail */ 00704 mask[i] = 0; 00705 } 00706 } 00707 } 00708 } 00709 break; 00710 case GL_NOTEQUAL: 00711 if (ctx->Depth.Mask) { 00712 /* Update Z buffer */ 00713 GLuint i; 00714 for (i=0; i<n; i++) { 00715 if (mask[i]) { 00716 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00717 if (z[i] != *zptr) { 00718 /* pass */ 00719 *zptr = z[i]; 00720 } 00721 else { 00722 /* fail */ 00723 mask[i] = 0; 00724 } 00725 } 00726 } 00727 } 00728 else { 00729 /* Don't update Z buffer */ 00730 GLuint i; 00731 for (i=0; i<n; i++) { 00732 if (mask[i]) { 00733 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00734 if (z[i] != *zptr) { 00735 /* pass */ 00736 } 00737 else { 00738 /* fail */ 00739 mask[i] = 0; 00740 } 00741 } 00742 } 00743 } 00744 break; 00745 case GL_EQUAL: 00746 if (ctx->Depth.Mask) { 00747 /* Update Z buffer */ 00748 GLuint i; 00749 for (i=0; i<n; i++) { 00750 if (mask[i]) { 00751 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00752 if (z[i] == *zptr) { 00753 /* pass */ 00754 *zptr = z[i]; 00755 } 00756 else { 00757 /* fail */ 00758 mask[i] = 0; 00759 } 00760 } 00761 } 00762 } 00763 else { 00764 /* Don't update Z buffer */ 00765 GLuint i; 00766 for (i=0; i<n; i++) { 00767 if (mask[i]) { 00768 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00769 if (z[i] == *zptr) { 00770 /* pass */ 00771 } 00772 else { 00773 /* fail */ 00774 mask[i] = 0; 00775 } 00776 } 00777 } 00778 } 00779 break; 00780 case GL_ALWAYS: 00781 if (ctx->Depth.Mask) { 00782 /* Update Z buffer */ 00783 GLuint i; 00784 for (i=0; i<n; i++) { 00785 if (mask[i]) { 00786 GLushort *zptr = Z_ADDRESS(x[i], y[i]); 00787 *zptr = z[i]; 00788 } 00789 } 00790 } 00791 else { 00792 /* Don't update Z buffer or mask */ 00793 } 00794 break; 00795 case GL_NEVER: 00796 /* depth test never passes */ 00797 _mesa_bzero(mask, n * sizeof(GLubyte)); 00798 break; 00799 default: 00800 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels"); 00801 } 00802 } 00803 00804 00805 00806 /* 00807 * Do depth testing for an array of fragments with direct access to zbuffer. 00808 */ 00809 static void 00810 direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride, 00811 GLuint n, const GLint x[], const GLint y[], 00812 const GLuint z[], GLubyte mask[] ) 00813 { 00814 /* switch cases ordered from most frequent to less frequent */ 00815 switch (ctx->Depth.Func) { 00816 case GL_LESS: 00817 if (ctx->Depth.Mask) { 00818 /* Update Z buffer */ 00819 GLuint i; 00820 for (i=0; i<n; i++) { 00821 if (mask[i]) { 00822 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00823 if (z[i] < *zptr) { 00824 /* pass */ 00825 *zptr = z[i]; 00826 } 00827 else { 00828 /* fail */ 00829 mask[i] = 0; 00830 } 00831 } 00832 } 00833 } 00834 else { 00835 /* Don't update Z buffer */ 00836 GLuint i; 00837 for (i=0; i<n; i++) { 00838 if (mask[i]) { 00839 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00840 if (z[i] < *zptr) { 00841 /* pass */ 00842 } 00843 else { 00844 /* fail */ 00845 mask[i] = 0; 00846 } 00847 } 00848 } 00849 } 00850 break; 00851 case GL_LEQUAL: 00852 if (ctx->Depth.Mask) { 00853 /* Update Z buffer */ 00854 GLuint i; 00855 for (i=0; i<n; i++) { 00856 if (mask[i]) { 00857 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00858 if (z[i] <= *zptr) { 00859 /* pass */ 00860 *zptr = z[i]; 00861 } 00862 else { 00863 /* fail */ 00864 mask[i] = 0; 00865 } 00866 } 00867 } 00868 } 00869 else { 00870 /* Don't update Z buffer */ 00871 GLuint i; 00872 for (i=0; i<n; i++) { 00873 if (mask[i]) { 00874 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00875 if (z[i] <= *zptr) { 00876 /* pass */ 00877 } 00878 else { 00879 /* fail */ 00880 mask[i] = 0; 00881 } 00882 } 00883 } 00884 } 00885 break; 00886 case GL_GEQUAL: 00887 if (ctx->Depth.Mask) { 00888 /* Update Z buffer */ 00889 GLuint i; 00890 for (i=0; i<n; i++) { 00891 if (mask[i]) { 00892 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00893 if (z[i] >= *zptr) { 00894 /* pass */ 00895 *zptr = z[i]; 00896 } 00897 else { 00898 /* fail */ 00899 mask[i] = 0; 00900 } 00901 } 00902 } 00903 } 00904 else { 00905 /* Don't update Z buffer */ 00906 GLuint i; 00907 for (i=0; i<n; i++) { 00908 if (mask[i]) { 00909 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00910 if (z[i] >= *zptr) { 00911 /* pass */ 00912 } 00913 else { 00914 /* fail */ 00915 mask[i] = 0; 00916 } 00917 } 00918 } 00919 } 00920 break; 00921 case GL_GREATER: 00922 if (ctx->Depth.Mask) { 00923 /* Update Z buffer */ 00924 GLuint i; 00925 for (i=0; i<n; i++) { 00926 if (mask[i]) { 00927 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00928 if (z[i] > *zptr) { 00929 /* pass */ 00930 *zptr = z[i]; 00931 } 00932 else { 00933 /* fail */ 00934 mask[i] = 0; 00935 } 00936 } 00937 } 00938 } 00939 else { 00940 /* Don't update Z buffer */ 00941 GLuint i; 00942 for (i=0; i<n; i++) { 00943 if (mask[i]) { 00944 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00945 if (z[i] > *zptr) { 00946 /* pass */ 00947 } 00948 else { 00949 /* fail */ 00950 mask[i] = 0; 00951 } 00952 } 00953 } 00954 } 00955 break; 00956 case GL_NOTEQUAL: 00957 if (ctx->Depth.Mask) { 00958 /* Update Z buffer */ 00959 GLuint i; 00960 for (i=0; i<n; i++) { 00961 if (mask[i]) { 00962 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00963 if (z[i] != *zptr) { 00964 /* pass */ 00965 *zptr = z[i]; 00966 } 00967 else { 00968 /* fail */ 00969 mask[i] = 0; 00970 } 00971 } 00972 } 00973 } 00974 else { 00975 /* Don't update Z buffer */ 00976 GLuint i; 00977 for (i=0; i<n; i++) { 00978 if (mask[i]) { 00979 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00980 if (z[i] != *zptr) { 00981 /* pass */ 00982 } 00983 else { 00984 /* fail */ 00985 mask[i] = 0; 00986 } 00987 } 00988 } 00989 } 00990 break; 00991 case GL_EQUAL: 00992 if (ctx->Depth.Mask) { 00993 /* Update Z buffer */ 00994 GLuint i; 00995 for (i=0; i<n; i++) { 00996 if (mask[i]) { 00997 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 00998 if (z[i] == *zptr) { 00999 /* pass */ 01000 *zptr = z[i]; 01001 } 01002 else { 01003 /* fail */ 01004 mask[i] = 0; 01005 } 01006 } 01007 } 01008 } 01009 else { 01010 /* Don't update Z buffer */ 01011 GLuint i; 01012 for (i=0; i<n; i++) { 01013 if (mask[i]) { 01014 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 01015 if (z[i] == *zptr) { 01016 /* pass */ 01017 } 01018 else { 01019 /* fail */ 01020 mask[i] = 0; 01021 } 01022 } 01023 } 01024 } 01025 break; 01026 case GL_ALWAYS: 01027 if (ctx->Depth.Mask) { 01028 /* Update Z buffer */ 01029 GLuint i; 01030 for (i=0; i<n; i++) { 01031 if (mask[i]) { 01032 GLuint *zptr = Z_ADDRESS(x[i], y[i]); 01033 *zptr = z[i]; 01034 } 01035 } 01036 } 01037 else { 01038 /* Don't update Z buffer or mask */ 01039 } 01040 break; 01041 case GL_NEVER: 01042 /* depth test never passes */ 01043 _mesa_bzero(mask, n * sizeof(GLubyte)); 01044 break; 01045 default: 01046 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels"); 01047 } 01048 } 01049 01050 01051 01052 01053 static GLuint 01054 depth_test_pixels( GLcontext *ctx, SWspan *span ) 01055 { 01056 struct gl_framebuffer *fb = ctx->DrawBuffer; 01057 struct gl_renderbuffer *rb = fb->_DepthBuffer; 01058 const GLuint count = span->end; 01059 const GLint *x = span->array->x; 01060 const GLint *y = span->array->y; 01061 const GLuint *z = span->array->z; 01062 GLubyte *mask = span->array->mask; 01063 01064 if (rb->GetPointer(ctx, rb, 0, 0)) { 01065 /* Directly access values */ 01066 if (rb->DataType == GL_UNSIGNED_SHORT) { 01067 GLushort *zStart = (GLushort *) rb->Data; 01068 GLuint stride = rb->Width; 01069 direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask); 01070 } 01071 else { 01072 GLuint *zStart = (GLuint *) rb->Data; 01073 GLuint stride = rb->Width; 01074 ASSERT(rb->DataType == GL_UNSIGNED_INT); 01075 direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask); 01076 } 01077 } 01078 else { 01079 /* read depth values from buffer, test, write back */ 01080 if (rb->DataType == GL_UNSIGNED_SHORT) { 01081 GLushort zbuffer[MAX_WIDTH]; 01082 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort)); 01083 depth_test_span16(ctx, count, zbuffer, z, mask); 01084 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask); 01085 } 01086 else { 01087 GLuint zbuffer[MAX_WIDTH]; 01088 ASSERT(rb->DataType == GL_UNSIGNED_INT); 01089 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint)); 01090 depth_test_span32(ctx, count, zbuffer, z, mask); 01091 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask); 01092 } 01093 } 01094 01095 return count; /* not really correct, but OK */ 01096 } 01097 01098 01103 GLuint 01104 _swrast_depth_test_span( GLcontext *ctx, SWspan *span) 01105 { 01106 if (span->arrayMask & SPAN_XY) 01107 return depth_test_pixels(ctx, span); 01108 else 01109 return depth_test_span(ctx, span); 01110 } 01111 01112 01120 GLboolean 01121 _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span ) 01122 { 01123 struct gl_framebuffer *fb = ctx->DrawBuffer; 01124 struct gl_renderbuffer *rb = fb->_DepthBuffer; 01125 GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F); 01126 GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F); 01127 GLubyte *mask = span->array->mask; 01128 const GLuint count = span->end; 01129 GLuint i; 01130 GLboolean anyPass = GL_FALSE; 01131 01132 if (rb->DataType == GL_UNSIGNED_SHORT) { 01133 /* get 16-bit values */ 01134 GLushort zbuffer16[MAX_WIDTH], *zbuffer; 01135 if (span->arrayMask & SPAN_XY) { 01136 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y, 01137 zbuffer16, sizeof(GLushort)); 01138 zbuffer = zbuffer16; 01139 } 01140 else { 01141 zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y); 01142 if (!zbuffer) { 01143 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16); 01144 zbuffer = zbuffer16; 01145 } 01146 } 01147 assert(zbuffer); 01148 01149 /* Now do the tests */ 01150 for (i = 0; i < count; i++) { 01151 if (mask[i]) { 01152 if (zbuffer[i] < zMin || zbuffer[i] > zMax) 01153 mask[i] = GL_FALSE; 01154 else 01155 anyPass = GL_TRUE; 01156 } 01157 } 01158 } 01159 else { 01160 /* get 32-bit values */ 01161 GLuint zbuffer32[MAX_WIDTH], *zbuffer; 01162 ASSERT(rb->DataType == GL_UNSIGNED_INT); 01163 if (span->arrayMask & SPAN_XY) { 01164 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y, 01165 zbuffer32, sizeof(GLuint)); 01166 zbuffer = zbuffer32; 01167 } 01168 else { 01169 zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y); 01170 if (!zbuffer) { 01171 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32); 01172 zbuffer = zbuffer32; 01173 } 01174 } 01175 assert(zbuffer); 01176 01177 /* Now do the tests */ 01178 for (i = 0; i < count; i++) { 01179 if (mask[i]) { 01180 if (zbuffer[i] < zMin || zbuffer[i] > zMax) 01181 mask[i] = GL_FALSE; 01182 else 01183 anyPass = GL_TRUE; 01184 } 01185 } 01186 } 01187 01188 return anyPass; 01189 } 01190 01191 01192 01193 /**********************************************************************/ 01194 /***** Read Depth Buffer *****/ 01195 /**********************************************************************/ 01196 01197 01205 void 01206 _swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb, 01207 GLint n, GLint x, GLint y, GLfloat depth[] ) 01208 { 01209 const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF; 01210 01211 if (!rb) { 01212 /* really only doing this to prevent FP exceptions later */ 01213 _mesa_bzero(depth, n * sizeof(GLfloat)); 01214 } 01215 01216 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); 01217 01218 if (y < 0 || y >= (GLint) rb->Height || 01219 x + n <= 0 || x >= (GLint) rb->Width) { 01220 /* span is completely outside framebuffer */ 01221 _mesa_bzero(depth, n * sizeof(GLfloat)); 01222 return; 01223 } 01224 01225 if (x < 0) { 01226 GLint dx = -x; 01227 GLint i; 01228 for (i = 0; i < dx; i++) 01229 depth[i] = 0.0; 01230 x = 0; 01231 n -= dx; 01232 depth += dx; 01233 } 01234 if (x + n > (GLint) rb->Width) { 01235 GLint dx = x + n - (GLint) rb->Width; 01236 GLint i; 01237 for (i = 0; i < dx; i++) 01238 depth[n - i - 1] = 0.0; 01239 n -= dx; 01240 } 01241 if (n <= 0) { 01242 return; 01243 } 01244 01245 if (rb->DataType == GL_UNSIGNED_INT) { 01246 GLuint temp[MAX_WIDTH]; 01247 GLint i; 01248 rb->GetRow(ctx, rb, n, x, y, temp); 01249 for (i = 0; i < n; i++) { 01250 depth[i] = temp[i] * scale; 01251 } 01252 } 01253 else if (rb->DataType == GL_UNSIGNED_SHORT) { 01254 GLushort temp[MAX_WIDTH]; 01255 GLint i; 01256 rb->GetRow(ctx, rb, n, x, y, temp); 01257 for (i = 0; i < n; i++) { 01258 depth[i] = temp[i] * scale; 01259 } 01260 } 01261 else { 01262 _mesa_problem(ctx, "Invalid depth renderbuffer data type"); 01263 } 01264 } 01265 01266 01270 void 01271 _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb, 01272 GLint n, GLint x, GLint y, GLuint depth[] ) 01273 { 01274 if (!rb) { 01275 /* really only doing this to prevent FP exceptions later */ 01276 _mesa_bzero(depth, n * sizeof(GLfloat)); 01277 } 01278 01279 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT); 01280 01281 if (y < 0 || y >= (GLint) rb->Height || 01282 x + n <= 0 || x >= (GLint) rb->Width) { 01283 /* span is completely outside framebuffer */ 01284 _mesa_bzero(depth, n * sizeof(GLfloat)); 01285 return; 01286 } 01287 01288 if (x < 0) { 01289 GLint dx = -x; 01290 GLint i; 01291 for (i = 0; i < dx; i++) 01292 depth[i] = 0; 01293 x = 0; 01294 n -= dx; 01295 depth += dx; 01296 } 01297 if (x + n > (GLint) rb->Width) { 01298 GLint dx = x + n - (GLint) rb->Width; 01299 GLint i; 01300 for (i = 0; i < dx; i++) 01301 depth[n - i - 1] = 0; 01302 n -= dx; 01303 } 01304 if (n <= 0) { 01305 return; 01306 } 01307 01308 if (rb->DataType == GL_UNSIGNED_INT) { 01309 rb->GetRow(ctx, rb, n, x, y, depth); 01310 if (rb->DepthBits < 32) { 01311 GLuint shift = 32 - rb->DepthBits; 01312 GLint i; 01313 for (i = 0; i < n; i++) { 01314 GLuint z = depth[i]; 01315 depth[i] = z << shift; /* XXX lsb bits? */ 01316 } 01317 } 01318 } 01319 else if (rb->DataType == GL_UNSIGNED_SHORT) { 01320 GLushort temp[MAX_WIDTH]; 01321 GLint i; 01322 rb->GetRow(ctx, rb, n, x, y, temp); 01323 if (rb->DepthBits == 16) { 01324 for (i = 0; i < n; i++) { 01325 GLuint z = temp[i]; 01326 depth[i] = (z << 16) | z; 01327 } 01328 } 01329 else { 01330 GLuint shift = 16 - rb->DepthBits; 01331 for (i = 0; i < n; i++) { 01332 GLuint z = temp[i]; 01333 depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */ 01334 } 01335 } 01336 } 01337 else { 01338 _mesa_problem(ctx, "Invalid depth renderbuffer data type"); 01339 } 01340 } 01341 01342 01343 01347 void 01348 _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) 01349 { 01350 GLuint clearValue; 01351 GLint x, y, width, height; 01352 01353 if (!rb || !ctx->Depth.Mask) { 01354 /* no depth buffer, or writing to it is disabled */ 01355 return; 01356 } 01357 01358 /* compute integer clearing value */ 01359 if (ctx->Depth.Clear == 1.0) { 01360 clearValue = ctx->DrawBuffer->_DepthMax; 01361 } 01362 else { 01363 clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF); 01364 } 01365 01366 assert(rb->_BaseFormat == GL_DEPTH_COMPONENT); 01367 01368 /* compute region to clear */ 01369 x = ctx->DrawBuffer->_Xmin; 01370 y = ctx->DrawBuffer->_Ymin; 01371 width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 01372 height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 01373 01374 if (rb->GetPointer(ctx, rb, 0, 0)) { 01375 /* Direct buffer access is possible. Either this is just malloc'd 01376 * memory, or perhaps the driver mmap'd the zbuffer memory. 01377 */ 01378 if (rb->DataType == GL_UNSIGNED_SHORT) { 01379 if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) && 01380 ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width == 01381 (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) { 01382 /* optimized case */ 01383 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y); 01384 GLuint len = width * height * sizeof(GLushort); 01385 _mesa_memset(dst, (clearValue & 0xff), len); 01386 } 01387 else { 01388 /* general case */ 01389 GLint i, j; 01390 for (i = 0; i < height; i++) { 01391 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i); 01392 for (j = 0; j < width; j++) { 01393 dst[j] = clearValue; 01394 } 01395 } 01396 } 01397 } 01398 else { 01399 GLint i, j; 01400 ASSERT(rb->DataType == GL_UNSIGNED_INT); 01401 for (i = 0; i < height; i++) { 01402 GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i); 01403 for (j = 0; j < width; j++) { 01404 dst[j] = clearValue; 01405 } 01406 } 01407 } 01408 } 01409 else { 01410 /* Direct access not possible. Use PutRow to write new values. */ 01411 if (rb->DataType == GL_UNSIGNED_SHORT) { 01412 GLushort clearVal16 = (GLushort) (clearValue & 0xffff); 01413 GLint i; 01414 for (i = 0; i < height; i++) { 01415 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL); 01416 } 01417 } 01418 else if (rb->DataType == GL_UNSIGNED_INT) { 01419 GLint i; 01420 ASSERT(sizeof(clearValue) == sizeof(GLuint)); 01421 for (i = 0; i < height; i++) { 01422 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL); 01423 } 01424 } 01425 else { 01426 _mesa_problem(ctx, "bad depth renderbuffer DataType"); 01427 } 01428 } 01429 } Generated on Sun May 27 2012 04:20:42 for ReactOS by
1.7.6.1
|