Begin hooking up stenciling.

This commit is contained in:
Brian
2007-07-10 16:37:18 -06:00
parent 227c95737b
commit e6eca5c37e
8 changed files with 175 additions and 16 deletions

View File

@@ -65,20 +65,21 @@ struct pipe_context *softpipe_create( void )
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
softpipe->pipe.destroy = softpipe_destroy;
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
softpipe->pipe.set_blend_state = softpipe_set_blend_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_blend_state = softpipe_set_blend_state;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
softpipe->pipe.set_depth_state = softpipe_set_depth_test_state;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_setup_state = softpipe_set_setup_state;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_fs_state = softpipe_set_fs_state;
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
softpipe->pipe.set_sampler_state = softpipe_set_sampler_state;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
softpipe->pipe.set_setup_state = softpipe_set_setup_state;
softpipe->pipe.set_stencil_state = softpipe_set_stencil_state;
softpipe->pipe.set_texture_state = softpipe_set_texture_state;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.draw_vb = softpipe_draw_vb;
softpipe->pipe.clear = softpipe_clear;

View File

@@ -63,6 +63,7 @@ enum interp_mode {
#define SP_NEW_DEPTH_TEST 0x200
#define SP_NEW_SAMPLER 0x400
#define SP_NEW_TEXTURE 0x800
#define SP_NEW_STENCIL 0x1000
struct softpipe_context {
@@ -82,6 +83,7 @@ struct softpipe_context {
struct pipe_scissor_state scissor;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct pipe_setup_state setup;
struct pipe_stencil_state stencil;
struct pipe_texture_object *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
GLuint dirty;
@@ -117,6 +119,7 @@ struct softpipe_context {
struct {
struct quad_stage *shade;
struct quad_stage *alpha_test;
struct quad_stage *stencil_test;
struct quad_stage *depth_test;
struct quad_stage *blend;
struct quad_stage *output;

View File

@@ -16,7 +16,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
sp->quad.first = sp->quad.blend;
}
if (sp->depth_test.enabled) {
if ( sp->stencil.front_enabled
|| sp->stencil.front_enabled) {
sp->quad.stencil_test->next = sp->quad.first;
sp->quad.first = sp->quad.stencil_test;
}
else if (sp->depth_test.enabled) {
sp->quad.depth_test->next = sp->quad.first;
sp->quad.first = sp->quad.depth_test;
}

View File

@@ -48,6 +48,7 @@ struct quad_stage {
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );

View File

@@ -0,0 +1,134 @@
/**
* \brief Quad stencil testing
*/
#include "main/glheader.h"
#include "main/imports.h"
#include "sp_context.h"
#include "sp_headers.h"
#include "sp_surface.h"
#include "sp_quad.h"
#include "pipe/p_defines.h"
static void
stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
GLuint bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
GLuint qzzzz[QUAD_SIZE]; /**< Z values from the quad */
GLuint zmask = 0;
GLuint j;
GLfloat scale;
assert(sps); /* shouldn't get here if there's no zbuffer */
/*
* To increase efficiency, we should probably have multiple versions
* of this function that are specifically for Z16, Z32 and FP Z buffers.
* Try to effectively do that with codegen...
*/
if (sps->surface.format == PIPE_FORMAT_U_Z16)
scale = 65535.0;
else
assert(0); /* XXX fix this someday */
/*
* Convert quad's float depth values to int depth values.
* If the Z buffer stores integer values, we _have_ to do the depth
* compares with integers (not floats). Otherwise, the float->int->float
* conversion of Z values (which isn't an identity function) will cause
* Z-fighting errors.
*/
for (j = 0; j < QUAD_SIZE; j++) {
qzzzz[j] = (GLuint) (quad->outputs.depth[j] * scale);
}
/* get zquad from zbuffer */
sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz);
switch (softpipe->depth_test.func) {
case PIPE_FUNC_NEVER:
/* zmask = 0 */
break;
case PIPE_FUNC_LESS:
/* Note this is pretty much a single sse or cell instruction.
* Like this: quad->mask &= (quad->outputs.depth < zzzz);
*/
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] < bzzzz[j])
zmask |= 1 << j;
}
break;
case PIPE_FUNC_EQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] == bzzzz[j])
zmask |= 1 << j;
}
break;
case PIPE_FUNC_LEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] <= bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_GREATER:
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] > bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_NOTEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] != bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_GEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
if (qzzzz[j] >= bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_ALWAYS:
zmask = MASK_ALL;
break;
default:
abort();
}
quad->mask &= zmask;
if (softpipe->depth_test.writemask) {
/* This is also efficient with sse / spe instructions:
*/
for (j = 0; j < QUAD_SIZE; j++) {
if (quad->mask & (1 << j)) {
bzzzz[j] = qzzzz[j];
}
}
/* write updated zquad to zbuffer */
sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz);
}
if (quad->mask)
qs->next->run(qs->next, quad);
}
struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe )
{
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
stage->softpipe = softpipe;
stage->run = stencil_test_quad;
return stage;
}

View File

@@ -56,8 +56,14 @@ void softpipe_set_clip_state( struct pipe_context *,
void softpipe_set_depth_test_state( struct pipe_context *,
const struct pipe_depth_state * );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void softpipe_set_fs_state( struct pipe_context *,
const struct pipe_fs_state * );
void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
void softpipe_set_setup_state( struct pipe_context *,
const struct pipe_setup_state * );
@@ -66,18 +72,15 @@ void softpipe_set_sampler_state( struct pipe_context *,
GLuint unit,
const struct pipe_sampler_state * );
void softpipe_set_stencil_state( struct pipe_context *,
const struct pipe_stencil_state * );
void softpipe_set_texture_state( struct pipe_context *,
GLuint unit,
struct pipe_texture_object * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
void softpipe_set_fs_state( struct pipe_context *,
const struct pipe_fs_state * );
void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void softpipe_update_derived( struct softpipe_context *softpipe );

View File

@@ -80,3 +80,14 @@ softpipe_set_alpha_test_state(struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_ALPHA_TEST;
}
void
softpipe_set_stencil_state(struct pipe_context *pipe,
const struct pipe_stencil_state *stencil)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
softpipe->stencil = *stencil;
softpipe->dirty |= SP_NEW_STENCIL;
}

View File

@@ -163,6 +163,7 @@ SOFTPIPE_SOURCES = \
pipe/softpipe/sp_quad_depth_test.c \
pipe/softpipe/sp_quad_fs.c \
pipe/softpipe/sp_quad_output.c \
pipe/softpipe/sp_quad_stencil.c \
pipe/softpipe/sp_state_blend.c \
pipe/softpipe/sp_state_clip.c \
pipe/softpipe/sp_state_derived.c \