return (struct pipe_surface *) xrb->pSurface;
}
+
+struct pipe_surface *
+xmesa_get_z_surface(GLcontext *ctx, GLuint i)
+{
+ return NULL;
+}
+
+
+struct pipe_surface *
+xmesa_get_stencil_surface(GLcontext *ctx, GLuint i)
+{
+ return NULL;
+}
+
#endif
-
+#if 0
GLboolean xmesa_get_cbuf_details( GLcontext *ctx,
void **ptr,
GLuint *cpp,
*format = 0;
return GL_FALSE;
}
-
+#endif
/**
#define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */
#endif
-
+#if 0
GLboolean xmesa_get_cbuf_details( GLcontext *ctx,
void **ptr,
GLuint *cpp,
GLint *stride,
GLuint *format );
-
+#endif
struct pipe_surface;
struct pipe_surface *
xmesa_get_color_surface(GLcontext *ctx, GLuint buf);
+struct pipe_surface *
+xmesa_get_z_surface(GLcontext *ctx, GLuint i);
+
+struct pipe_surface *
+xmesa_get_stencil_surface(GLcontext *ctx, GLuint i);
+
+
#endif
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_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_point_state = softpipe_set_point_state;
softpipe->pipe.set_viewport = softpipe_set_viewport;
softpipe->pipe.set_setup_state = softpipe_set_setup_state;
softpipe->prim.cull = prim_cull( softpipe );
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
+ softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
softpipe->quad.output = sp_quad_output_stage(softpipe);
struct pipe_alpha_test_state alpha_test;
struct pipe_clip_state clip;
struct pipe_clear_color_state clear_color;
+ struct pipe_depth_state depth_test;
struct pipe_point_state point;
struct pipe_scissor_rect scissor;
struct pipe_poly_stipple poly_stipple;
void
sp_build_quad_pipeline(struct softpipe_context *sp)
{
+ /* build up the pipeline in reverse order... */
sp->quad.first = sp->quad.output;
sp->quad.first = sp->quad.blend;
}
+ if (sp->depth_test.enabled) {
+ sp->quad.depth_test->next = sp->quad.first;
+ sp->quad.first = sp->quad.depth_test;
+ }
+
/* XXX always enable shader? */
if (1) {
sp->quad.shade->next = sp->quad.first;
#include "sp_headers.h"
#include "sp_surface.h"
#include "sp_quad.h"
-
+#include "pipe/p_defines.h"
static void
depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
-#if 0
struct softpipe_context *softpipe = qs->softpipe;
- GLfloat dest[4][QUAD_SIZE], result[4][QUAD_SIZE];
- GLuint i;
-
- /* XXX we're also looping in output_quad() !?! */
-
- for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
- struct softpipe_surface *sps
- = softpipe_surface(softpipe->framebuffer.cbufs[i]);
-
- sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest);
+ GLuint j;
+ struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
+ GLfloat zzzz[QUAD_SIZE]; /**< Z for four pixels in quad */
- /* XXX do blend here */
+#if 0
+ assert(sps); /* shouldn't get here if there's no zbuffer */
+#else
+ if (!sps)
+ return;
+#endif
+ /* XXX get zquad from zbuffer */
+ sps->read_quad_z(sps, quad->x0, quad->y0, zzzz);
+
+ switch (softpipe->depth_test.func) {
+ case PIPE_FUNC_NEVER:
+ quad->mask = 0x0;
+ break;
+ case PIPE_FUNC_LESS:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->mask & (1 << j)) {
+ if (quad->outputs.depth[j] >= zzzz[j]) {
+ /* fail */
+ quad->mask &= (1 << j);
+ }
+ else if (softpipe->depth_test.writemask) {
+ /* pass, and update Z buffer */
+ zzzz[j] = quad->outputs.depth[j];
+ }
+ }
+ }
+ break;
+ case PIPE_FUNC_EQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->mask & (1 << j)) {
+ if (quad->outputs.depth[j] != zzzz[j]) {
+ /* fail */
+ quad->mask &= (1 << j);
+ }
+ else if (softpipe->depth_test.writemask) {
+ /* pass, and update Z buffer */
+ zzzz[j] = quad->outputs.depth[j];
+ }
+ }
+ }
+ break;
+ case PIPE_FUNC_LEQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->mask & (1 << j)) {
+ if (quad->outputs.depth[j] > zzzz[j]) {
+ /* fail */
+ quad->mask &= (1 << j);
+ }
+ else if (softpipe->depth_test.writemask) {
+ /* pass, and update Z buffer */
+ zzzz[j] = quad->outputs.depth[j];
+ }
+ }
+ }
+ break;
+ /* XXX fill in remaining cases */
+ default:
+ abort();
}
-#endif
+
+ /* XXX write updated zquad to zbuffer */
+ sps->write_quad_z(sps, quad->x0, quad->y0, zzzz);
qs->next->run(qs->next, quad);
}
void softpipe_set_framebuffer_state( struct pipe_context *,
const struct pipe_framebuffer_state * );
+void softpipe_set_alpha_test_state( struct pipe_context *,
+ const struct pipe_alpha_test_state * );
+
void softpipe_set_blend_state( struct pipe_context *,
const struct pipe_blend_state * );
void softpipe_set_clip_state( struct pipe_context *,
const struct pipe_clip_state * );
+void softpipe_set_depth_test_state( struct pipe_context *,
+ const struct pipe_depth_state * );
+
void softpipe_set_viewport( struct pipe_context *,
const struct pipe_viewport * );
softpipe->dirty |= G_NEW_BLEND;
}
+
+/** XXX move someday? Or consolidate all these simple state setters
+ * into one file.
+ */
+void
+softpipe_set_depth_test_state(struct pipe_context *pipe,
+ const struct pipe_depth_state *depth)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+
+ softpipe->depth_test = *depth;
+
+ softpipe->dirty |= G_NEW_DEPTH_TEST;
+}
+
+void
+softpipe_set_alpha_test_state(struct pipe_context *pipe,
+ const struct pipe_alpha_test_state *alpha)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+
+ softpipe->alpha_test = *alpha;
+
+ softpipe->dirty |= G_NEW_ALPHA_TEST;
+}
+
if (softpipe->dirty & (G_NEW_SETUP | G_NEW_FS))
calculate_vertex_layout( softpipe );
- if (softpipe->dirty & (G_NEW_BLEND | G_NEW_FS))
+ if (softpipe->dirty & (G_NEW_BLEND | G_NEW_DEPTH_TEST | G_NEW_ALPHA_TEST | G_NEW_FS))
sp_build_quad_pipeline(softpipe);
softpipe->dirty = 0;
void (*write_mono_row_ub)( struct softpipe_surface *,
GLuint count, GLint x, GLint y,
GLubyte rgba[NUM_CHANNELS] );
+
+ void (*read_quad_z)(struct softpipe_surface *,
+ GLint x, GLint y, GLfloat zzzz[QUAD_SIZE]);
+ void (*write_quad_z)(struct softpipe_surface *,
+ GLint x, GLint y, const GLfloat zzzz[QUAD_SIZE]);
};
{
&st_update_framebuffer,
&st_update_clear_color,
+ &st_update_depth,
&st_update_clip,
&st_update_fs,
&st_update_point,
extern struct pipe_surface *
xmesa_get_color_surface(GLcontext *ctx, GLuint i);
+extern struct pipe_surface *
+xmesa_get_z_surface(GLcontext *ctx, GLuint i);
+
+extern struct pipe_surface *
+xmesa_get_stencil_surface(GLcontext *ctx, GLuint i);
+
/**
* Update framebuffer state (color, depth, stencil, etc. buffers)
framebuffer.cbufs[i] = xmesa_get_color_surface(st->ctx, i);
}
+ if (st->ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) {
+ framebuffer.zbuf = xmesa_get_z_surface(st->ctx, i);
+ }
+
+ if (st->ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) {
+ framebuffer.sbuf = xmesa_get_stencil_surface(st->ctx, i);
+ }
+
if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) {
st->state.framebuffer = framebuffer;
st->pipe->set_framebuffer_state( st->pipe, &framebuffer );