summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_atom.c3
-rw-r--r--src/mesa/state_tracker/st_atom.h3
-rw-r--r--src/mesa/state_tracker/st_atom_depth.c108
-rw-r--r--src/mesa/state_tracker/st_atom_stencil.c141
-rw-r--r--src/mesa/state_tracker/st_cache.c17
-rw-r--r--src/mesa/state_tracker/st_cache.h3
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c51
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c2
-rw-r--r--src/mesa/state_tracker/st_context.h3
9 files changed, 140 insertions, 191 deletions
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;