ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.