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_stage * | sp_quad_depth_test_stage (struct softpipe_context *softpipe) |
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.
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 }