sp_quad_depth_test.c File Reference

Include dependency graph for sp_quad_depth_test.c:

Go to the source code of this file.

Functions

void sp_depth_test_quad (struct quad_stage *qs, struct quad_header *quad)
 Quad depth testing.
static void depth_test_quad (struct quad_stage *qs, struct quad_header *quad)
static void depth_test_begin (struct quad_stage *qs)
static void depth_test_destroy (struct quad_stage *qs)
struct quad_stagesp_quad_depth_test_stage (struct softpipe_context *softpipe)


Function Documentation

static void depth_test_begin ( struct quad_stage qs  )  [static]

Definition at line 268 of file sp_quad_depth_test.c.

References quad_stage::begin, and quad_stage::next.

00269 {
00270    qs->next->begin(qs->next);
00271 }

static void depth_test_destroy ( struct quad_stage qs  )  [static]

Definition at line 274 of file sp_quad_depth_test.c.

References FREE.

00275 {
00276    FREE( qs );
00277 }

static void depth_test_quad ( struct quad_stage qs,
struct quad_header quad 
) [static]

Definition at line 259 of file sp_quad_depth_test.c.

References quad_header::inout, quad_header_inout::mask, quad_stage::next, quad_stage::run, and sp_depth_test_quad().

00260 {
00261    sp_depth_test_quad(qs, quad);
00262 
00263    if (quad->inout.mask)
00264       qs->next->run(qs->next, quad);
00265 }

void sp_depth_test_quad ( struct quad_stage qs,
struct quad_header quad 
)

Quad depth testing.

Do depth testing for a quad. Not static since it's used by the stencil code.

< Z values fetched from depth buffer

< Z values from the quad

Definition at line 53 of file sp_quad_depth_test.c.

References assert, softpipe_cached_tile::data, pipe_depth_stencil_alpha_state::depth, quad_header_output::depth, softpipe_cached_tile::depth16, softpipe_cached_tile::depth32, softpipe_context::depth_stencil, pipe_surface::format, softpipe_context::framebuffer, pipe_depth_state::func, quad_header::inout, quad_header::input, quad_header_inout::mask, MASK_ALL, quad_header::output, PIPE_FORMAT_S8Z24_UNORM, PIPE_FORMAT_X8Z24_UNORM, PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24S8_UNORM, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z32_UNORM, PIPE_FUNC_ALWAYS, PIPE_FUNC_EQUAL, PIPE_FUNC_GEQUAL, PIPE_FUNC_GREATER, PIPE_FUNC_LEQUAL, PIPE_FUNC_LESS, PIPE_FUNC_NEVER, PIPE_FUNC_NOTEQUAL, QUAD_SIZE, quad_stage::softpipe, sp_get_cached_tile(), TILE_SIZE, pipe_depth_state::writemask, softpipe_cached_tile::x, quad_header_input::x0, softpipe_cached_tile::y, quad_header_input::y0, pipe_framebuffer_state::zsbuf, and softpipe_context::zsbuf_cache.

00054 {
00055    struct softpipe_context *softpipe = qs->softpipe;
00056    struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
00057    const enum pipe_format format = ps->format;
00058    unsigned bzzzz[QUAD_SIZE];  
00059    unsigned qzzzz[QUAD_SIZE];  
00060    unsigned zmask = 0;
00061    unsigned j;
00062    struct softpipe_cached_tile *tile
00063       = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->input.x0, quad->input.y0);
00064 
00065    assert(ps); /* shouldn't get here if there's no zbuffer */
00066 
00067    /*
00068     * Convert quad's float depth values to int depth values (qzzzz).
00069     * If the Z buffer stores integer values, we _have_ to do the depth
00070     * compares with integers (not floats).  Otherwise, the float->int->float
00071     * conversion of Z values (which isn't an identity function) will cause
00072     * Z-fighting errors.
00073     *
00074     * Also, get the zbuffer values (bzzzz) from the cached tile.
00075     */
00076    switch (format) {
00077    case PIPE_FORMAT_Z16_UNORM:
00078       {
00079          float scale = 65535.0;
00080 
00081          for (j = 0; j < QUAD_SIZE; j++) {
00082             qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
00083          }
00084 
00085          for (j = 0; j < QUAD_SIZE; j++) {
00086             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00087             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00088             bzzzz[j] = tile->data.depth16[y][x];
00089          }
00090       }
00091       break;
00092    case PIPE_FORMAT_Z32_UNORM:
00093       {
00094          double scale = (double) (uint) ~0UL;
00095 
00096          for (j = 0; j < QUAD_SIZE; j++) {
00097             qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
00098          }
00099 
00100          for (j = 0; j < QUAD_SIZE; j++) {
00101             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00102             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00103             bzzzz[j] = tile->data.depth32[y][x];
00104          }
00105       }
00106       break;
00107    case PIPE_FORMAT_X8Z24_UNORM:
00108       /* fall-through */
00109    case PIPE_FORMAT_S8Z24_UNORM:
00110       {
00111          float scale = (float) ((1 << 24) - 1);
00112 
00113          for (j = 0; j < QUAD_SIZE; j++) {
00114             qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
00115          }
00116 
00117          for (j = 0; j < QUAD_SIZE; j++) {
00118             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00119             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00120             bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
00121          }
00122       }
00123       break;
00124    case PIPE_FORMAT_Z24X8_UNORM:
00125       /* fall-through */
00126    case PIPE_FORMAT_Z24S8_UNORM:
00127       {
00128          float scale = (float) ((1 << 24) - 1);
00129 
00130          for (j = 0; j < QUAD_SIZE; j++) {
00131             qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
00132          }
00133 
00134          for (j = 0; j < QUAD_SIZE; j++) {
00135             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00136             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00137             bzzzz[j] = tile->data.depth32[y][x] >> 8;
00138          }
00139       }
00140       break;
00141    default:
00142       assert(0);
00143    }
00144 
00145    switch (softpipe->depth_stencil->depth.func) {
00146    case PIPE_FUNC_NEVER:
00147       /* zmask = 0 */
00148       break;
00149    case PIPE_FUNC_LESS:
00150       /* Note this is pretty much a single sse or cell instruction.  
00151        * Like this:  quad->mask &= (quad->outputs.depth < zzzz);
00152        */
00153       for (j = 0; j < QUAD_SIZE; j++) {
00154          if (qzzzz[j] < bzzzz[j]) 
00155             zmask |= 1 << j;
00156       }
00157       break;
00158    case PIPE_FUNC_EQUAL:
00159       for (j = 0; j < QUAD_SIZE; j++) {
00160          if (qzzzz[j] == bzzzz[j]) 
00161             zmask |= 1 << j;
00162       }
00163       break;
00164    case PIPE_FUNC_LEQUAL:
00165       for (j = 0; j < QUAD_SIZE; j++) {
00166          if (qzzzz[j] <= bzzzz[j]) 
00167             zmask |= (1 << j);
00168       }
00169       break;
00170    case PIPE_FUNC_GREATER:
00171       for (j = 0; j < QUAD_SIZE; j++) {
00172          if (qzzzz[j] > bzzzz[j]) 
00173             zmask |= (1 << j);
00174       }
00175       break;
00176    case PIPE_FUNC_NOTEQUAL:
00177       for (j = 0; j < QUAD_SIZE; j++) {
00178          if (qzzzz[j] != bzzzz[j]) 
00179             zmask |= (1 << j);
00180       }
00181       break;
00182    case PIPE_FUNC_GEQUAL:
00183       for (j = 0; j < QUAD_SIZE; j++) {
00184          if (qzzzz[j] >= bzzzz[j]) 
00185             zmask |= (1 << j);
00186       }
00187       break;
00188    case PIPE_FUNC_ALWAYS:
00189       zmask = MASK_ALL;
00190       break;
00191    default:
00192       assert(0);
00193    }
00194 
00195    quad->inout.mask &= zmask;
00196 
00197    if (softpipe->depth_stencil->depth.writemask) {
00198       
00199       /* This is also efficient with sse / spe instructions: 
00200        */
00201       for (j = 0; j < QUAD_SIZE; j++) {
00202          if (quad->inout.mask & (1 << j)) {
00203             bzzzz[j] = qzzzz[j];
00204          }
00205       }
00206 
00207       /* put updated Z values back into cached tile */
00208       switch (format) {
00209       case PIPE_FORMAT_Z16_UNORM:
00210          for (j = 0; j < QUAD_SIZE; j++) {
00211             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00212             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00213             tile->data.depth16[y][x] = (ushort) bzzzz[j];
00214          }
00215          break;
00216       case PIPE_FORMAT_X8Z24_UNORM:
00217          /* fall-through */
00218          /* (yes, this falls through to a different case than above) */
00219       case PIPE_FORMAT_Z32_UNORM:
00220          for (j = 0; j < QUAD_SIZE; j++) {
00221             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00222             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00223             tile->data.depth32[y][x] = bzzzz[j];
00224          }
00225          break;
00226       case PIPE_FORMAT_S8Z24_UNORM:
00227          for (j = 0; j < QUAD_SIZE; j++) {
00228             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00229             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00230             uint s8z24 = tile->data.depth32[y][x];
00231             s8z24 = (s8z24 & 0xff000000) | bzzzz[j];
00232             tile->data.depth32[y][x] = s8z24;
00233          }
00234          break;
00235       case PIPE_FORMAT_Z24S8_UNORM:
00236          for (j = 0; j < QUAD_SIZE; j++) {
00237             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00238             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00239             uint z24s8 = tile->data.depth32[y][x];
00240             z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8);
00241             tile->data.depth32[y][x] = z24s8;
00242          }
00243          break;
00244       case PIPE_FORMAT_Z24X8_UNORM:
00245          for (j = 0; j < QUAD_SIZE; j++) {
00246             int x = quad->input.x0 % TILE_SIZE + (j & 1);
00247             int y = quad->input.y0 % TILE_SIZE + (j >> 1);
00248             tile->data.depth32[y][x] = bzzzz[j] << 8;
00249          }
00250          break;
00251       default:
00252          assert(0);
00253       }
00254    }
00255 }

struct quad_stage* sp_quad_depth_test_stage ( struct softpipe_context softpipe  )  [read]

Definition at line 280 of file sp_quad_depth_test.c.

References quad_stage::begin, CALLOC_STRUCT, depth_test_begin(), depth_test_destroy(), depth_test_quad(), quad_stage::destroy, quad_stage::run, and quad_stage::softpipe.

00281 {
00282    struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
00283 
00284    stage->softpipe = softpipe;
00285    stage->begin = depth_test_begin;
00286    stage->run = depth_test_quad;
00287    stage->destroy = depth_test_destroy;
00288 
00289    return stage;
00290 }


Generated on Tue Sep 29 06:25:40 2009 for Gallium3D by  doxygen 1.5.4