diff options
30 files changed, 337 insertions, 384 deletions
diff --git a/src/mesa/cso_cache/cso_cache.c b/src/mesa/cso_cache/cso_cache.c index 61da5905754..a4730394f87 100644 --- a/src/mesa/cso_cache/cso_cache.c +++ b/src/mesa/cso_cache/cso_cache.c @@ -76,6 +76,8 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_ hash = sc->blend_hash; case CSO_SAMPLER: hash = sc->sampler_hash; + case CSO_DEPTH_STENCIL: + hash = sc->depth_stencil_hash; } return hash; @@ -88,6 +90,8 @@ static int _cso_size_for_type(enum cso_cache_type type) return sizeof(struct pipe_blend_state); case CSO_SAMPLER: return sizeof(struct pipe_sampler_state); + case CSO_DEPTH_STENCIL: + return sizeof(struct pipe_depth_stencil_state); } return 0; } @@ -138,6 +142,7 @@ struct cso_cache *cso_cache_create(void) sc->blend_hash = cso_hash_create(); sc->sampler_hash = cso_hash_create(); + sc->depth_stencil_hash = cso_hash_create(); return sc; } @@ -147,6 +152,7 @@ void cso_cache_delete(struct cso_cache *sc) assert(sc); cso_hash_delete(sc->blend_hash); cso_hash_delete(sc->sampler_hash); + cso_hash_delete(sc->depth_stencil_hash); free(sc); } diff --git a/src/mesa/cso_cache/cso_cache.h b/src/mesa/cso_cache/cso_cache.h index 05a4cfcbdda..c340cf7f674 100644 --- a/src/mesa/cso_cache/cso_cache.h +++ b/src/mesa/cso_cache/cso_cache.h @@ -42,11 +42,13 @@ struct cso_hash; struct cso_cache { struct cso_hash *blend_hash; struct cso_hash *sampler_hash; + struct cso_hash *depth_stencil_hash; }; enum cso_cache_type { CSO_BLEND, - CSO_SAMPLER + CSO_SAMPLER, + CSO_DEPTH_STENCIL }; unsigned cso_construct_key(void *item, int item_size); diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index fa336193a8d..63ec7239abf 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -36,25 +36,24 @@ -#define FO_NEW_VIEWPORT 0x1 -#define FO_NEW_SETUP 0x2 -#define FO_NEW_FRAGMENT_SHADER 0x4 -#define FO_NEW_BLEND 0x8 -#define FO_NEW_CLIP 0x10 -#define FO_NEW_SCISSOR 0x20 -#define FO_NEW_STIPPLE 0x40 -#define FO_NEW_FRAMEBUFFER 0x80 -#define FO_NEW_ALPHA_TEST 0x100 -#define FO_NEW_DEPTH_TEST 0x200 -#define FO_NEW_SAMPLER 0x400 -#define FO_NEW_TEXTURE 0x800 -#define FO_NEW_STENCIL 0x1000 -#define FO_NEW_VERTEX 0x2000 -#define FO_NEW_VERTEX_SHADER 0x4000 -#define FO_NEW_BLEND_COLOR 0x8000 -#define FO_NEW_CLEAR_COLOR 0x10000 -#define FO_NEW_VERTEX_BUFFER 0x20000 -#define FO_NEW_VERTEX_ELEMENT 0x40000 +#define FO_NEW_VIEWPORT 0x1 +#define FO_NEW_SETUP 0x2 +#define FO_NEW_FRAGMENT_SHADER 0x4 +#define FO_NEW_BLEND 0x8 +#define FO_NEW_CLIP 0x10 +#define FO_NEW_SCISSOR 0x20 +#define FO_NEW_STIPPLE 0x40 +#define FO_NEW_FRAMEBUFFER 0x80 +#define FO_NEW_ALPHA_TEST 0x100 +#define FO_NEW_DEPTH_STENCIL 0x200 +#define FO_NEW_SAMPLER 0x400 +#define FO_NEW_TEXTURE 0x800 +#define FO_NEW_VERTEX 0x2000 +#define FO_NEW_VERTEX_SHADER 0x4000 +#define FO_NEW_BLEND_COLOR 0x8000 +#define FO_NEW_CLEAR_COLOR 0x10000 +#define FO_NEW_VERTEX_BUFFER 0x20000 +#define FO_NEW_VERTEX_ELEMENT 0x40000 @@ -69,19 +68,18 @@ struct failover_context { */ const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_state *depth_stencil; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; - struct pipe_depth_state depth_test; struct pipe_framebuffer_state framebuffer; struct pipe_shader_state fragment_shader; struct pipe_shader_state vertex_shader; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_setup_state setup; - struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index f3a99e41989..43b9757b319 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -103,14 +103,14 @@ failover_set_clear_color_state( struct pipe_context *pipe, } static void -failover_set_depth_test_state(struct pipe_context *pipe, - const struct pipe_depth_state *depth) +failover_bind_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) { struct failover_context *failover = failover_context(pipe); - failover->depth_test = *depth; - failover->dirty |= FO_NEW_DEPTH_TEST; - failover->hw->set_depth_state( failover->hw, depth ); + failover->depth_stencil = depth_stencil; + failover->dirty |= FO_NEW_DEPTH_STENCIL; + failover->hw->bind_depth_stencil_state( failover->hw, depth_stencil ); } static void @@ -184,18 +184,6 @@ failover_set_scissor_state( struct pipe_context *pipe, } static void -failover_set_stencil_state(struct pipe_context *pipe, - const struct pipe_stencil_state *stencil) -{ - struct failover_context *failover = failover_context(pipe); - - failover->stencil = *stencil; - failover->dirty |= FO_NEW_STENCIL; - failover->hw->set_stencil_state( failover->hw, stencil ); -} - - -static void failover_bind_sampler_state(struct pipe_context *pipe, unsigned unit, const struct pipe_sampler_state *sampler) @@ -268,19 +256,18 @@ failover_init_state_functions( struct failover_context *failover ) { failover->pipe.bind_blend_state = failover_bind_blend_state; failover->pipe.bind_sampler_state = failover_bind_sampler_state; + failover->pipe.bind_depth_stencil_state = failover_bind_depth_stencil_state; failover->pipe.set_alpha_test_state = failover_set_alpha_test_state; failover->pipe.set_blend_color = failover_set_blend_color; failover->pipe.set_clip_state = failover_set_clip_state; failover->pipe.set_clear_color_state = failover_set_clear_color_state; - failover->pipe.set_depth_state = failover_set_depth_test_state; failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_fs_state = failover_set_fs_state; failover->pipe.set_vs_state = failover_set_vs_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; failover->pipe.set_setup_state = failover_set_setup_state; - failover->pipe.set_stencil_state = failover_set_stencil_state; failover->pipe.set_texture_state = failover_set_texture_state; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; diff --git a/src/mesa/pipe/failover/fo_state_emit.c b/src/mesa/pipe/failover/fo_state_emit.c index 9d462678c5d..3a1865d7668 100644 --- a/src/mesa/pipe/failover/fo_state_emit.c +++ b/src/mesa/pipe/failover/fo_state_emit.c @@ -70,8 +70,8 @@ failover_state_emit( struct failover_context *failover ) if (failover->dirty & FO_NEW_CLEAR_COLOR) failover->sw->set_clear_color_state( failover->sw, &failover->clear_color ); - if (failover->dirty & FO_NEW_DEPTH_TEST) - failover->sw->set_depth_state( failover->sw, &failover->depth_test ); + if (failover->dirty & FO_NEW_DEPTH_STENCIL) + failover->sw->bind_depth_stencil_state( failover->sw, failover->depth_stencil ); if (failover->dirty & FO_NEW_FRAMEBUFFER) failover->sw->set_framebuffer_state( failover->sw, &failover->framebuffer ); @@ -91,9 +91,6 @@ failover_state_emit( struct failover_context *failover ) if (failover->dirty & FO_NEW_SCISSOR) failover->sw->set_scissor_state( failover->sw, &failover->scissor ); - if (failover->dirty & FO_NEW_STENCIL) - failover->sw->set_stencil_state( failover->sw, &failover->stencil ); - if (failover->dirty & FO_NEW_VIEWPORT) failover->sw->set_viewport_state( failover->sw, &failover->viewport ); diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index 51baa281ec5..518f780449b 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -125,19 +125,18 @@ struct i915_context */ const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_state *depth_stencil; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; - struct pipe_depth_state depth_test; struct pipe_framebuffer_state framebuffer; struct pipe_shader_state fs; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_setup_state setup; - struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; @@ -163,16 +162,15 @@ struct i915_context #define I915_NEW_SETUP 0x2 #define I915_NEW_FS 0x4 #define I915_NEW_BLEND 0x8 -#define I915_NEW_CLIP 0x10 -#define I915_NEW_SCISSOR 0x20 -#define I915_NEW_STIPPLE 0x40 -#define I915_NEW_FRAMEBUFFER 0x80 -#define I915_NEW_ALPHA_TEST 0x100 -#define I915_NEW_DEPTH_TEST 0x200 -#define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 -#define I915_NEW_STENCIL 0x1000 -#define I915_NEW_CONSTANTS 0x2000 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 /* Driver's internally generated state flags: diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 10060b45a4f..5ac2e27d1a6 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -107,38 +107,44 @@ static void i915_delete_sampler_state(struct pipe_context *pipe, /** XXX move someday? Or consolidate all these simple state setters * into one file. */ -static void i915_set_depth_test_state(struct pipe_context *pipe, - const struct pipe_depth_state *depth) -{ - struct i915_context *i915 = i915_context(pipe); - i915->depth_test = *depth; +static const struct pipe_depth_stencil_state * +i915_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) +{ + struct pipe_depth_stencil_state *new_ds = + malloc(sizeof(struct pipe_depth_stencil_state)); + memcpy(new_ds, depth_stencil, sizeof(struct pipe_depth_stencil_state)); - i915->dirty |= I915_NEW_DEPTH_TEST; + return new_ds; } -static void i915_set_alpha_test_state(struct pipe_context *pipe, - const struct pipe_alpha_test_state *alpha) +static void i915_bind_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) { struct i915_context *i915 = i915_context(pipe); - i915->alpha_test = *alpha; + i915->depth_stencil = depth_stencil; - i915->dirty |= I915_NEW_ALPHA_TEST; + i915->dirty |= I915_NEW_DEPTH_STENCIL; } -static void i915_set_stencil_state(struct pipe_context *pipe, - const struct pipe_stencil_state *stencil) +static void i915_delete_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) +{ + free((struct pipe_depth_stencil_state *)depth_stencil); +} + +static void i915_set_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *alpha) { struct i915_context *i915 = i915_context(pipe); - i915->stencil = *stencil; + i915->alpha_test = *alpha; - i915->dirty |= I915_NEW_STENCIL; + i915->dirty |= I915_NEW_ALPHA_TEST; } - - static void i915_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { @@ -328,19 +334,21 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.bind_sampler_state = i915_bind_sampler_state; i915->pipe.delete_sampler_state = i915_delete_sampler_state; + i915->pipe.create_depth_stencil_state = i915_create_depth_stencil_state; + i915->pipe.bind_depth_stencil_state = i915_bind_depth_stencil_state; + i915->pipe.delete_depth_stencil_state = i915_delete_depth_stencil_state; + i915->pipe.set_alpha_test_state = i915_set_alpha_test_state; i915->pipe.set_blend_color = i915_set_blend_color; i915->pipe.set_clip_state = i915_set_clip_state; i915->pipe.set_clear_color_state = i915_set_clear_color_state; i915->pipe.set_constant_buffer = i915_set_constant_buffer; - i915->pipe.set_depth_state = i915_set_depth_test_state; i915->pipe.set_framebuffer_state = i915_set_framebuffer_state; i915->pipe.set_fs_state = i915_set_fs_state; i915->pipe.set_vs_state = i915_set_vs_state; i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; i915->pipe.set_scissor_state = i915_set_scissor_state; i915->pipe.set_setup_state = i915_set_setup_state; - i915->pipe.set_stencil_state = i915_set_stencil_state; i915->pipe.set_texture_state = i915_set_texture_state; i915->pipe.set_viewport_state = i915_set_viewport_state; i915->pipe.set_vertex_buffer = i915_set_vertex_buffer; diff --git a/src/mesa/pipe/i915simple/i915_state_dynamic.c b/src/mesa/pipe/i915simple/i915_state_dynamic.c index 49a30fac115..9140eee7c29 100644 --- a/src/mesa/pipe/i915simple/i915_state_dynamic.c +++ b/src/mesa/pipe/i915simple/i915_state_dynamic.c @@ -68,8 +68,8 @@ static void upload_MODES4( struct i915_context *i915 ) /* I915_NEW_STENCIL */ { - int testmask = i915->stencil.value_mask[0] & 0xff; - int writemask = i915->stencil.write_mask[0] & 0xff; + int testmask = i915->depth_stencil->stencil.value_mask[0] & 0xff; + int writemask = i915->depth_stencil->stencil.write_mask[0] & 0xff; modes4 |= (_3DSTATE_MODES_4_CMD | ENABLE_STENCIL_TEST_MASK | @@ -94,7 +94,7 @@ static void upload_MODES4( struct i915_context *i915 ) } const struct i915_tracked_state i915_upload_MODES4 = { - .dirty = I915_NEW_BLEND | I915_NEW_STENCIL, + .dirty = I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL, .update = upload_MODES4 }; @@ -112,14 +112,14 @@ static void upload_BFO( struct i915_context *i915 ) /* _NEW_STENCIL */ - if (i915->stencil.back_enabled) { - int test = i915_translate_compare_func(i915->stencil.back_func); - int fop = i915_translate_stencil_op(i915->stencil.back_fail_op); - int dfop = i915_translate_stencil_op(i915->stencil.back_zfail_op); - int dpop = i915_translate_stencil_op(i915->stencil.back_zpass_op); - int ref = i915->stencil.ref_value[1] & 0xff; - int tmask = i915->stencil.value_mask[1] & 0xff; - int wmask = i915->stencil.write_mask[1] & 0xff; + if (i915->depth_stencil->stencil.back_enabled) { + int test = i915_translate_compare_func(i915->depth_stencil->stencil.back_func); + int fop = i915_translate_stencil_op(i915->depth_stencil->stencil.back_fail_op); + int dfop = i915_translate_stencil_op(i915->depth_stencil->stencil.back_zfail_op); + int dpop = i915_translate_stencil_op(i915->depth_stencil->stencil.back_zpass_op); + int ref = i915->depth_stencil->stencil.ref_value[1] & 0xff; + int tmask = i915->depth_stencil->stencil.value_mask[1] & 0xff; + int wmask = i915->depth_stencil->stencil.write_mask[1] & 0xff; bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_FUNCS | @@ -157,7 +157,7 @@ static void upload_BFO( struct i915_context *i915 ) } const struct i915_tracked_state i915_upload_BFO = { - .dirty = I915_NEW_STENCIL, + .dirty = I915_NEW_DEPTH_STENCIL, .update = upload_BFO }; diff --git a/src/mesa/pipe/i915simple/i915_state_immediate.c b/src/mesa/pipe/i915simple/i915_state_immediate.c index aaca534f5ad..484913d308c 100644 --- a/src/mesa/pipe/i915simple/i915_state_immediate.c +++ b/src/mesa/pipe/i915simple/i915_state_immediate.c @@ -128,12 +128,12 @@ static void upload_S5( struct i915_context *i915 ) unsigned LIS5 = 0; /* I915_NEW_STENCIL */ - if (i915->stencil.front_enabled) { - int test = i915_translate_compare_func(i915->stencil.front_func); - int fop = i915_translate_stencil_op(i915->stencil.front_fail_op); - int dfop = i915_translate_stencil_op(i915->stencil.front_zfail_op); - int dpop = i915_translate_stencil_op(i915->stencil.front_zpass_op); - int ref = i915->stencil.ref_value[0] & 0xff; + if (i915->depth_stencil->stencil.front_enabled) { + int test = i915_translate_compare_func(i915->depth_stencil->stencil.front_func); + int fop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_fail_op); + int dfop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_zfail_op); + int dpop = i915_translate_stencil_op(i915->depth_stencil->stencil.front_zpass_op); + int ref = i915->depth_stencil->stencil.ref_value[0] & 0xff; LIS5 |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE | @@ -179,7 +179,7 @@ static void upload_S5( struct i915_context *i915 ) } const struct i915_tracked_state i915_upload_S5 = { - .dirty = (I915_NEW_STENCIL | I915_NEW_BLEND | I915_NEW_SETUP), + .dirty = (I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_SETUP), .update = upload_S5 }; @@ -219,13 +219,13 @@ static void upload_S6( struct i915_context *i915 ) /* I915_NEW_DEPTH */ - if (i915->depth_test.enabled) { - int func = i915_translate_compare_func(i915->depth_test.func); + if (i915->depth_stencil->depth.enabled) { + int func = i915_translate_compare_func(i915->depth_stencil->depth.func); LIS6 |= (S6_DEPTH_TEST_ENABLE | (func << S6_DEPTH_TEST_FUNC_SHIFT)); - if (i915->depth_test.writemask) + if (i915->depth_stencil->depth.writemask) LIS6 |= S6_DEPTH_WRITE_ENABLE; } @@ -236,7 +236,7 @@ static void upload_S6( struct i915_context *i915 ) } const struct i915_tracked_state i915_upload_S6 = { - .dirty = I915_NEW_ALPHA_TEST | I915_NEW_BLEND | I915_NEW_DEPTH_TEST, + .dirty = I915_NEW_ALPHA_TEST | I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL, .update = upload_S6 }; diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 0913e490967..488f0025311 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -101,6 +101,14 @@ struct pipe_context { void (*delete_sampler_state)(struct pipe_context *, const struct pipe_sampler_state *); + const struct pipe_depth_stencil_state * (*create_depth_stencil_state)( + struct pipe_context *, + const struct pipe_depth_stencil_state *); + void (*bind_depth_stencil_state)(struct pipe_context *, + const struct pipe_depth_stencil_state *); + void (*delete_depth_stencil_state)(struct pipe_context *, + const struct pipe_depth_stencil_state *); + void (*set_alpha_test_state)( struct pipe_context *, const struct pipe_alpha_test_state * ); @@ -116,9 +124,6 @@ struct pipe_context { void (*set_constant_buffer)( struct pipe_context *, uint shader, uint index, const struct pipe_constant_buffer *buf ); - - void (*set_depth_state)( struct pipe_context *, - const struct pipe_depth_state * ); void (*set_feedback_state)( struct pipe_context *, const struct pipe_feedback_state *); @@ -141,9 +146,6 @@ struct pipe_context { void (*set_scissor_state)( struct pipe_context *, const struct pipe_scissor_state * ); - void (*set_stencil_state)( struct pipe_context *, - const struct pipe_stencil_state * ); - void (*set_texture_state)( struct pipe_context *, unsigned unit, struct pipe_mipmap_tree * ); diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index b994d17ea9e..30e559b5948 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -146,13 +146,31 @@ struct pipe_shader_state { void *executable; }; -struct pipe_depth_state +struct pipe_depth_stencil_state { - unsigned enabled:1; /**< depth test enabled? */ - unsigned writemask:1; /**< allow depth buffer writes? */ - unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ - unsigned occlusion_count:1; /**< XXX move this elsewhere? */ - float clear; /**< Clear value in [0,1] (XXX correct place?) */ + struct { + unsigned enabled:1; /**< depth test enabled? */ + unsigned writemask:1; /**< allow depth buffer writes? */ + unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ + unsigned occlusion_count:1; /**< XXX move this elsewhere? */ + float clear; /**< Clear value in [0,1] (XXX correct place?) */ + } depth; + struct { + unsigned front_enabled:1; + unsigned front_func:3; /**< PIPE_FUNC_x */ + unsigned front_fail_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned front_zpass_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned front_zfail_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned back_enabled:1; + unsigned back_func:3; /**< PIPE_FUNC_x */ + unsigned back_fail_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned back_zpass_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned back_zfail_op:3; /**< PIPE_STENCIL_OP_x */ + ubyte ref_value[2]; /**< [0] = front, [1] = back */ + ubyte value_mask[2]; + ubyte write_mask[2]; + ubyte clear_value; + } stencil; }; struct pipe_alpha_test_state { @@ -188,24 +206,6 @@ struct pipe_clear_color_state float color[4]; }; -struct pipe_stencil_state { - unsigned front_enabled:1; - unsigned front_func:3; /**< PIPE_FUNC_x */ - unsigned front_fail_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned front_zpass_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned front_zfail_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned back_enabled:1; - unsigned back_func:3; /**< PIPE_FUNC_x */ - unsigned back_fail_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned back_zpass_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned back_zfail_op:3; /**< PIPE_STENCIL_OP_x */ - ubyte ref_value[2]; /**< [0] = front, [1] = back */ - ubyte value_mask[2]; - ubyte write_mask[2]; - ubyte clear_value; -}; - - struct pipe_framebuffer_state { /** multiple colorbuffers for multiple render targets */ diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index bab7985e8d1..9a8b55bb0e3 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -256,13 +256,15 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + softpipe->pipe.create_depth_stencil_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_state = softpipe_delete_depth_stencil_state; softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; - softpipe->pipe.set_depth_state = softpipe_set_depth_test_state; softpipe->pipe.set_feedback_state = softpipe_set_feedback_state; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_fs_state = softpipe_set_fs_state; @@ -270,7 +272,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; 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; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 5cee1a3cf93..4cbb0f891ed 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -50,18 +50,17 @@ struct draw_stage; #define SP_NEW_SETUP 0x2 #define SP_NEW_FS 0x4 #define SP_NEW_BLEND 0x8 -#define SP_NEW_CLIP 0x10 -#define SP_NEW_SCISSOR 0x20 -#define SP_NEW_STIPPLE 0x40 -#define SP_NEW_FRAMEBUFFER 0x80 -#define SP_NEW_ALPHA_TEST 0x100 -#define SP_NEW_DEPTH_TEST 0x200 -#define SP_NEW_SAMPLER 0x400 -#define SP_NEW_TEXTURE 0x800 -#define SP_NEW_STENCIL 0x1000 -#define SP_NEW_VERTEX 0x2000 -#define SP_NEW_VS 0x4000 -#define SP_NEW_CONSTANTS 0x8000 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_ALPHA_TEST 0x100 +#define SP_NEW_DEPTH_STENCIL 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_CONSTANTS 0x4000 struct softpipe_context { @@ -73,13 +72,13 @@ struct softpipe_context { */ const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_state *depth_stencil; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; struct pipe_constant_buffer constants[2]; - struct pipe_depth_state depth_test; struct pipe_feedback_state feedback; struct pipe_framebuffer_state framebuffer; struct pipe_shader_state fs; @@ -87,7 +86,6 @@ struct softpipe_context { struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_setup_state setup; - struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index 2fcbea1f22e..1f45776d477 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -31,7 +31,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->quad.first = sp->quad.bufloop; } - if (sp->depth_test.occlusion_count) { + if (sp->depth_stencil->depth.occlusion_count) { sp->quad.occlusion->next = sp->quad.first; sp->quad.first = sp->quad.occlusion; } @@ -43,12 +43,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->quad.first = sp->quad.coverage; } - if ( sp->stencil.front_enabled - || sp->stencil.front_enabled) { + if ( sp->depth_stencil->stencil.front_enabled + || sp->depth_stencil->stencil.back_enabled) { sp->quad.stencil_test->next = sp->quad.first; sp->quad.first = sp->quad.stencil_test; } - else if (sp->depth_test.enabled && + else if (sp->depth_stencil->depth.enabled && sp->framebuffer.zbuf) { sp->quad.depth_test->next = sp->quad.first; sp->quad.first = sp->quad.depth_test; diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index 5d46e70393d..ff1d84a02dd 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -77,7 +77,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) /* get zquad from zbuffer */ sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz); - switch (softpipe->depth_test.func) { + switch (softpipe->depth_stencil->depth.func) { case PIPE_FUNC_NEVER: /* zmask = 0 */ break; @@ -129,7 +129,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) quad->mask &= zmask; - if (softpipe->depth_test.writemask) { + if (softpipe->depth_stencil->depth.writemask) { /* This is also efficient with sse / spe instructions: */ diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index cb0b6d8a77f..46ad08aaa14 100755 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -179,7 +179,7 @@ static void shade_begin(struct quad_stage *qs) unsigned i, entry; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - qss->samplers[i].state = &softpipe->sampler[i]; + qss->samplers[i].state = softpipe->sampler[i]; qss->samplers[i].texture = softpipe->texture[i]; qss->samplers[i].get_samples = sp_get_samples; qss->samplers[i].pipe = &softpipe->pipe; diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c index 47b3b4f0893..56cc6907b2f 100644 --- a/src/mesa/pipe/softpipe/sp_quad_stencil.c +++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c @@ -207,23 +207,23 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) /* choose front or back face function, operator, etc */ /* XXX we could do these initializations once per primitive */ - if (softpipe->stencil.back_enabled && quad->facing) { - func = softpipe->stencil.back_func; - failOp = softpipe->stencil.back_fail_op; - zFailOp = softpipe->stencil.back_zfail_op; - zPassOp = softpipe->stencil.back_zpass_op; - ref = softpipe->stencil.ref_value[1]; - wrtMask = softpipe->stencil.write_mask[1]; - valMask = softpipe->stencil.value_mask[1]; + if (softpipe->depth_stencil->stencil.back_enabled && quad->facing) { + func = softpipe->depth_stencil->stencil.back_func; + failOp = softpipe->depth_stencil->stencil.back_fail_op; + zFailOp = softpipe->depth_stencil->stencil.back_zfail_op; + zPassOp = softpipe->depth_stencil->stencil.back_zpass_op; + ref = softpipe->depth_stencil->stencil.ref_value[1]; + wrtMask = softpipe->depth_stencil->stencil.write_mask[1]; + valMask = softpipe->depth_stencil->stencil.value_mask[1]; } else { - func = softpipe->stencil.front_func; - failOp = softpipe->stencil.front_fail_op; - zFailOp = softpipe->stencil.front_zfail_op; - zPassOp = softpipe->stencil.front_zpass_op; - ref = softpipe->stencil.ref_value[0]; - wrtMask = softpipe->stencil.write_mask[0]; - valMask = softpipe->stencil.value_mask[0]; + func = softpipe->depth_stencil->stencil.front_func; + failOp = softpipe->depth_stencil->stencil.front_fail_op; + zFailOp = softpipe->depth_stencil->stencil.front_zfail_op; + zPassOp = softpipe->depth_stencil->stencil.front_zpass_op; + ref = softpipe->depth_stencil->stencil.ref_value[0]; + wrtMask = softpipe->depth_stencil->stencil.write_mask[0]; + valMask = softpipe->depth_stencil->stencil.value_mask[0]; } assert(s_surf); /* shouldn't get here if there's no stencil buffer */ @@ -244,7 +244,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) if (quad->mask) { /* now the pixels that passed the stencil test are depth tested */ - if (softpipe->depth_test.enabled) { + if (softpipe->depth_stencil->depth.enabled) { const unsigned origMask = quad->mask; sp_depth_test_quad(qs, quad); /* quad->mask is updated */ diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index c8c93709dbc..caec3b4519a 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -50,6 +50,15 @@ void softpipe_bind_sampler_state(struct pipe_context *, void softpipe_delete_sampler_state(struct pipe_context *, const struct pipe_sampler_state *); + +const struct pipe_depth_stencil_state * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_state *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_state *); + void softpipe_set_framebuffer_state( struct pipe_context *, const struct pipe_framebuffer_state * ); @@ -69,9 +78,6 @@ void softpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, const struct pipe_constant_buffer *buf); -void softpipe_set_depth_test_state( struct pipe_context *, - const struct pipe_depth_state * ); - void softpipe_set_feedback_state( struct pipe_context *, const struct pipe_feedback_state * ); @@ -90,9 +96,6 @@ void softpipe_set_scissor_state( struct pipe_context *, void softpipe_set_setup_state( struct pipe_context *, const struct pipe_setup_state * ); -void softpipe_set_stencil_state( struct pipe_context *, - const struct pipe_stencil_state * ); - void softpipe_set_texture_state( struct pipe_context *, unsigned unit, struct pipe_mipmap_tree * ); diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c index 34da613f9dd..83f456ded55 100644 --- a/src/mesa/pipe/softpipe/sp_state_blend.c +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -71,16 +71,6 @@ void softpipe_set_blend_color( struct pipe_context *pipe, /** 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 |= SP_NEW_DEPTH_TEST; -} void softpipe_set_alpha_test_state(struct pipe_context *pipe, @@ -93,14 +83,30 @@ softpipe_set_alpha_test_state(struct pipe_context *pipe, softpipe->dirty |= SP_NEW_ALPHA_TEST; } +const struct pipe_depth_stencil_state * +softpipe_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) +{ + struct pipe_depth_stencil_state *new_ds = malloc(sizeof(struct pipe_depth_stencil_state)); + memcpy(new_ds, depth_stencil, sizeof(struct pipe_depth_stencil_state)); + + return new_ds; +} + void -softpipe_set_stencil_state(struct pipe_context *pipe, - const struct pipe_stencil_state *stencil) +softpipe_bind_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth_stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->stencil = *stencil; + softpipe->depth_stencil = depth_stencil; - softpipe->dirty |= SP_NEW_STENCIL; + softpipe->dirty |= SP_NEW_DEPTH_STENCIL; } +void +softpipe_delete_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_state *depth) +{ + free((struct pipe_depth_stencil_state*)depth); +} diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index e08ed50a70e..47743e185c2 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -55,7 +55,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) /* Need Z if depth test is enabled or the fragment program uses the * fragment position (XYZW). */ - if (softpipe->depth_test.enabled || + if (softpipe->depth_stencil->depth.enabled || (inputsRead & (1 << TGSI_ATTRIB_POS))) softpipe->need_z = TRUE; else @@ -186,15 +186,14 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) calculate_vertex_layout( softpipe ); if (softpipe->dirty & (SP_NEW_SCISSOR | - SP_NEW_STENCIL | + SP_NEW_DEPTH_STENCIL | SP_NEW_FRAMEBUFFER)) compute_cliprect(softpipe); if (softpipe->dirty & (SP_NEW_BLEND | - SP_NEW_DEPTH_TEST | + SP_NEW_DEPTH_STENCIL | SP_NEW_ALPHA_TEST | SP_NEW_FRAMEBUFFER | - SP_NEW_STENCIL | SP_NEW_SETUP | SP_NEW_FS)) sp_build_quad_pipeline(softpipe); diff --git a/src/mesa/sources b/src/mesa/sources index 90fa5c65bfb..22b592df09f 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -204,7 +204,6 @@ STATETRACKER_SOURCES = \ state_tracker/st_atom_sampler.c \ state_tracker/st_atom_scissor.c \ state_tracker/st_atom_setup.c \ - state_tracker/st_atom_stencil.c \ state_tracker/st_atom_stipple.c \ state_tracker/st_atom_texture.c \ state_tracker/st_atom_viewport.c \ diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 66ab5d7c3a7..99d0bcb90bb 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -46,7 +46,7 @@ static const struct st_tracked_state *atoms[] = { &st_update_framebuffer, &st_update_clear_color, - &st_update_depth, + &st_update_depth_stencil, &st_update_clip, &st_update_tnl, @@ -58,7 +58,6 @@ static const struct st_tracked_state *atoms[] = &st_update_viewport, &st_update_scissor, &st_update_blend, - &st_update_stencil, &st_update_sampler, &st_update_texture, &st_update_vs_constants, diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index 447430bfef1..0e362b1fbf1 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -47,7 +47,7 @@ void st_validate_state( struct st_context *st ); const struct st_tracked_state st_update_framebuffer; const struct st_tracked_state st_update_clip; const struct st_tracked_state st_update_clear_color; -const struct st_tracked_state st_update_depth; +const struct st_tracked_state st_update_depth_stencil; const struct st_tracked_state st_update_tnl; const struct st_tracked_state st_update_fs; const struct st_tracked_state st_update_vs; @@ -56,7 +56,6 @@ const struct st_tracked_state st_update_polygon_stipple; const struct st_tracked_state st_update_viewport; const struct st_tracked_state st_update_scissor; const struct st_tracked_state st_update_blend; -const struct st_tracked_state st_update_stencil; const struct st_tracked_state st_update_sampler; const struct st_tracked_state st_update_texture; const struct st_tracked_state st_update_fs_constants; diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c index df05c79e365..406773213d3 100644 --- a/src/mesa/state_tracker/st_atom_depth.c +++ b/src/mesa/state_tracker/st_atom_depth.c @@ -29,16 +29,68 @@ * Authors: * Keith Whitwell <[email protected]> * Brian Paul + * Zack Rusin */ #include "st_context.h" +#include "st_cache.h" #include "st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" /** + * Convert GLenum stencil func tokens to pipe tokens. + */ +static GLuint +gl_stencil_func_to_sp(GLenum func) +{ + /* Same values, just biased */ + assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); + assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); + assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); + assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); + assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); + assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); + assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); + assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); + assert(func >= GL_NEVER); + assert(func <= GL_ALWAYS); + return func - GL_NEVER; +} + + +/** + * Convert GLenum stencil op tokens to pipe tokens. + */ +static GLuint +gl_stencil_op_to_sp(GLenum func) +{ + switch (func) { + case GL_KEEP: + return PIPE_STENCIL_OP_KEEP; + case GL_ZERO: + return PIPE_STENCIL_OP_ZERO; + case GL_REPLACE: + return PIPE_STENCIL_OP_REPLACE; + case GL_INCR: + return PIPE_STENCIL_OP_INCR; + case GL_DECR: + return PIPE_STENCIL_OP_DECR; + case GL_INCR_WRAP: + return PIPE_STENCIL_OP_INCR_WRAP; + case GL_DECR_WRAP: + return PIPE_STENCIL_OP_DECR_WRAP; + case GL_INVERT: + return PIPE_STENCIL_OP_INVERT; + default: + assert("invalid GL token in gl_stencil_op_to_sp()" == NULL); + return 0; + } +} + +/** * Convert GLenum depth func tokens to pipe tokens. */ static GLuint @@ -59,35 +111,59 @@ gl_depth_func_to_sp(GLenum func) } -static void -update_depth( struct st_context *st ) +static void +update_depth_stencil(struct st_context *st) { - struct pipe_depth_state depth; + struct pipe_depth_stencil_state depth_stencil; - memset(&depth, 0, sizeof(depth)); + memset(&depth_stencil, 0, sizeof(depth_stencil)); - depth.enabled = st->ctx->Depth.Test; - depth.writemask = st->ctx->Depth.Mask; - depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func); - depth.clear = st->ctx->Depth.Clear; + depth_stencil.depth.enabled = st->ctx->Depth.Test; + depth_stencil.depth.writemask = st->ctx->Depth.Mask; + depth_stencil.depth.func = gl_depth_func_to_sp(st->ctx->Depth.Func); + depth_stencil.depth.clear = st->ctx->Depth.Clear; if (st->ctx->Query.CurrentOcclusionObject && st->ctx->Query.CurrentOcclusionObject->Active) - depth.occlusion_count = 1; + depth_stencil.depth.occlusion_count = 1; + + if (st->ctx->Stencil.Enabled) { + depth_stencil.stencil.front_enabled = 1; + depth_stencil.stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]); + depth_stencil.stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]); + depth_stencil.stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]); + depth_stencil.stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]); + depth_stencil.stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff; + depth_stencil.stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff; + depth_stencil.stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff; + if (st->ctx->Stencil.TestTwoSide) { + depth_stencil.stencil.back_enabled = 1; + depth_stencil.stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]); + depth_stencil.stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]); + depth_stencil.stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]); + depth_stencil.stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]); + depth_stencil.stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff; + depth_stencil.stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff; + depth_stencil.stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff; + } + depth_stencil.stencil.clear_value = st->ctx->Stencil.Clear & 0xff; + } - if (memcmp(&depth, &st->state.depth, sizeof(depth)) != 0) { + struct pipe_depth_stencil_state *cached_state = + st_cached_depth_stencil_state(st, &depth_stencil); + if (st->state.depth_stencil != cached_state) { /* state has changed */ - st->state.depth = depth; /* struct copy */ - st->pipe->set_depth_state(st->pipe, &depth); /* set new state */ + st->state.depth_stencil = cached_state; + st->pipe->bind_depth_stencil_state(st->pipe, cached_state); /* set new state */ } } -const struct st_tracked_state st_update_depth = { - .name = "st_update_depth", +const struct st_tracked_state st_update_depth_stencil = { + .name = "st_update_depth_stencil", .dirty = { - .mesa = (_NEW_DEPTH), + .mesa = (_NEW_DEPTH|_NEW_STENCIL), .st = 0, }, - .update = update_depth + .update = update_depth_stencil }; diff --git a/src/mesa/state_tracker/st_atom_stencil.c b/src/mesa/state_tracker/st_atom_stencil.c deleted file mode 100644 index b8aec0b3b65..00000000000 --- a/src/mesa/state_tracker/st_atom_stencil.c +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell <[email protected]> - * Brian Paul - */ - - -#include "st_context.h" -#include "st_atom.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" - - -/** - * Convert GLenum stencil func tokens to pipe tokens. - */ -static GLuint -gl_stencil_func_to_sp(GLenum func) -{ - /* Same values, just biased */ - assert(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); - assert(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); - assert(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); - assert(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); - assert(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); - assert(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); - assert(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); - assert(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); - assert(func >= GL_NEVER); - assert(func <= GL_ALWAYS); - return func - GL_NEVER; -} - - -/** - * Convert GLenum stencil op tokens to pipe tokens. - */ -static GLuint -gl_stencil_op_to_sp(GLenum func) -{ - switch (func) { - case GL_KEEP: - return PIPE_STENCIL_OP_KEEP; - case GL_ZERO: - return PIPE_STENCIL_OP_ZERO; - case GL_REPLACE: - return PIPE_STENCIL_OP_REPLACE; - case GL_INCR: - return PIPE_STENCIL_OP_INCR; - case GL_DECR: - return PIPE_STENCIL_OP_DECR; - case GL_INCR_WRAP: - return PIPE_STENCIL_OP_INCR_WRAP; - case GL_DECR_WRAP: - return PIPE_STENCIL_OP_DECR_WRAP; - case GL_INVERT: - return PIPE_STENCIL_OP_INVERT; - default: - assert("invalid GL token in gl_stencil_op_to_sp()" == NULL); - return 0; - } -} - - -static void -update_stencil( struct st_context *st ) -{ - struct pipe_stencil_state stencil; - - memset(&stencil, 0, sizeof(stencil)); - - if (st->ctx->Stencil.Enabled) { - stencil.front_enabled = 1; - stencil.front_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[0]); - stencil.front_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[0]); - stencil.front_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[0]); - stencil.front_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[0]); - stencil.ref_value[0] = st->ctx->Stencil.Ref[0] & 0xff; - stencil.value_mask[0] = st->ctx->Stencil.ValueMask[0] & 0xff; - stencil.write_mask[0] = st->ctx->Stencil.WriteMask[0] & 0xff; - if (st->ctx->Stencil.TestTwoSide) { - stencil.back_enabled = 1; - stencil.back_func = gl_stencil_func_to_sp(st->ctx->Stencil.Function[1]); - stencil.back_fail_op = gl_stencil_op_to_sp(st->ctx->Stencil.FailFunc[1]); - stencil.back_zfail_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZFailFunc[1]); - stencil.back_zpass_op = gl_stencil_op_to_sp(st->ctx->Stencil.ZPassFunc[1]); - stencil.ref_value[1] = st->ctx->Stencil.Ref[1] & 0xff; - stencil.value_mask[1] = st->ctx->Stencil.ValueMask[1] & 0xff; - stencil.write_mask[1] = st->ctx->Stencil.WriteMask[1] & 0xff; - } - stencil.clear_value = st->ctx->Stencil.Clear & 0xff; - } - - if (memcmp(&stencil, &st->state.stencil, sizeof(stencil)) != 0) { - /* state has changed */ - st->state.stencil = stencil; /* struct copy */ - st->pipe->set_stencil_state(st->pipe, &stencil); /* set new state */ - } -} - - -const struct st_tracked_state st_update_stencil = { - .name = "st_update_stencil", - .dirty = { - .mesa = (_NEW_STENCIL), - .st = 0, - }, - .update = update_stencil -}; - - - - - diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c index 99fb45f00a6..64c03be99db 100644 --- a/src/mesa/state_tracker/st_cache.c +++ b/src/mesa/state_tracker/st_cache.c @@ -76,3 +76,20 @@ struct pipe_sampler_state * st_cached_sampler_state( } return (struct pipe_sampler_state*)(cso_hash_iter_data(iter)); } + +struct pipe_depth_stencil_state * st_cached_depth_stencil_state( + struct st_context *st, + const struct pipe_depth_stencil_state *depth_stencil) +{ + unsigned hash_key = cso_construct_key((void*)depth_stencil, sizeof(struct pipe_depth_stencil_state)); + struct cso_hash_iter iter = cso_find_state_template(st->cache, + hash_key, CSO_DEPTH_STENCIL, + (void*)depth_stencil); + if (cso_hash_iter_is_null(iter)) { + const struct pipe_depth_stencil_state *created_state = st->pipe->create_depth_stencil_state( + st->pipe, depth_stencil); + iter = cso_insert_state(st->cache, hash_key, CSO_DEPTH_STENCIL, + (void*)created_state); + } + return (struct pipe_depth_stencil_state*)(cso_hash_iter_data(iter)); +} diff --git a/src/mesa/state_tracker/st_cache.h b/src/mesa/state_tracker/st_cache.h index 927585141c6..78cb2e774e1 100644 --- a/src/mesa/state_tracker/st_cache.h +++ b/src/mesa/state_tracker/st_cache.h @@ -45,5 +45,8 @@ struct pipe_sampler_state * st_cached_sampler_state( struct st_context *st, const struct pipe_sampler_state *sampler); +struct pipe_depth_stencil_state *st_cached_depth_stencil_state( + struct st_context *st, + const struct pipe_depth_stencil_state *sampler); #endif diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 55e03f644eb..e9aabd15b58 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -283,6 +283,7 @@ clear_with_quad(GLcontext *ctx, /* blend state: RGBA masking */ { struct pipe_blend_state blend; + const struct pipe_blend_state *state; memset(&blend, 0, sizeof(blend)); if (color) { if (ctx->Color.ColorMask[0]) @@ -296,20 +297,34 @@ clear_with_quad(GLcontext *ctx, if (st->ctx->Color.DitherFlag) blend.dither = 1; } - const struct pipe_blend_state *state = st_cached_blend_state(st, &blend); + state = st_cached_blend_state(st, &blend); pipe->bind_blend_state(pipe, state); } - /* depth state: always pass */ + /* depth_stencil state: always pass/set to ref value */ { - struct pipe_depth_state depth_test; - memset(&depth_test, 0, sizeof(depth_test)); + struct pipe_depth_stencil_state depth_stencil; + struct pipe_depth_stencil_state *cached; + memset(&depth_stencil, 0, sizeof(depth_stencil)); if (depth) { - depth_test.enabled = 1; - depth_test.writemask = 1; - depth_test.func = PIPE_FUNC_ALWAYS; + depth_stencil.depth.enabled = 1; + depth_stencil.depth.writemask = 1; + depth_stencil.depth.func = PIPE_FUNC_ALWAYS; } - pipe->set_depth_state(pipe, &depth_test); + + if (stencil) { + depth_stencil.stencil.front_enabled = 1; + depth_stencil.stencil.front_func = PIPE_FUNC_ALWAYS; + depth_stencil.stencil.front_fail_op = PIPE_STENCIL_OP_REPLACE; + depth_stencil.stencil.front_zpass_op = PIPE_STENCIL_OP_REPLACE; + depth_stencil.stencil.front_zfail_op = PIPE_STENCIL_OP_REPLACE; + depth_stencil.stencil.ref_value[0] = ctx->Stencil.Clear; + depth_stencil.stencil.value_mask[0] = 0xff; + depth_stencil.stencil.write_mask[0] = ctx->Stencil.WriteMask[0] & 0xff; + } + cached = + st_cached_depth_stencil_state(ctx->st, &depth_stencil); + pipe->bind_depth_stencil_state(pipe, cached); } /* setup state: nothing */ @@ -326,23 +341,6 @@ clear_with_quad(GLcontext *ctx, pipe->set_setup_state(pipe, &setup); } - /* stencil state: always set to ref value */ - { - struct pipe_stencil_state stencil_test; - memset(&stencil_test, 0, sizeof(stencil_test)); - if (stencil) { - stencil_test.front_enabled = 1; - stencil_test.front_func = PIPE_FUNC_ALWAYS; - stencil_test.front_fail_op = PIPE_STENCIL_OP_REPLACE; - stencil_test.front_zpass_op = PIPE_STENCIL_OP_REPLACE; - stencil_test.front_zfail_op = PIPE_STENCIL_OP_REPLACE; - stencil_test.ref_value[0] = ctx->Stencil.Clear; - stencil_test.value_mask[0] = 0xff; - stencil_test.write_mask[0] = ctx->Stencil.WriteMask[0] & 0xff; - } - pipe->set_stencil_state(pipe, &stencil_test); - } - /* fragment shader state: color pass-through program */ { static struct st_fragment_program *stfp = NULL; @@ -393,11 +391,10 @@ clear_with_quad(GLcontext *ctx, /* Restore pipe state */ pipe->set_alpha_test_state(pipe, &st->state.alpha_test); pipe->bind_blend_state(pipe, st->state.blend); - pipe->set_depth_state(pipe, &st->state.depth); + pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil); pipe->set_fs_state(pipe, &st->state.fs); pipe->set_vs_state(pipe, &st->state.vs); pipe->set_setup_state(pipe, &st->state.setup); - pipe->set_stencil_state(pipe, &st->state.stencil); pipe->set_viewport_state(pipe, &ctx->st->state.viewport); /* OR: st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 31a37e5cd4c..a0012e3a8c3 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -478,7 +478,7 @@ any_fragment_ops(const struct st_context *st) if (st->state.alpha_test.enabled || st->state.blend->blend_enable || st->state.blend->logicop_enable || - st->state.depth.enabled) + st->state.depth_stencil->depth.enabled) /* XXX more checks */ return GL_TRUE; else diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 13526ff9e7c..7c887d0b559 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -76,13 +76,13 @@ struct st_context struct { const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_state *depth_stencil; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; struct pipe_constant_buffer constants[2]; - struct pipe_depth_state depth; struct pipe_feedback_state feedback; struct pipe_framebuffer_state framebuffer; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; @@ -91,7 +91,6 @@ struct st_context struct pipe_setup_state setup; struct pipe_shader_state fs; struct pipe_shader_state vs; - struct pipe_stencil_state stencil; struct pipe_viewport_state viewport; } state; |