case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
+ case CSO_ALPHA_TEST:
+ hash = sc->alpha_hash;
+ break;
}
return hash;
return sizeof(struct pipe_shader_state);
case CSO_VERTEX_SHADER:
return sizeof(struct pipe_shader_state);
+ case CSO_ALPHA_TEST:
+ return sizeof(struct pipe_alpha_test_state);
}
return 0;
}
sc->rasterizer_hash = cso_hash_create();
sc->fs_hash = cso_hash_create();
sc->vs_hash = cso_hash_create();
+ sc->alpha_hash = cso_hash_create();
return sc;
}
cso_hash_delete(sc->rasterizer_hash);
cso_hash_delete(sc->fs_hash);
cso_hash_delete(sc->vs_hash);
+ cso_hash_delete(sc->alpha_hash);
free(sc);
}
struct cso_hash;
struct cso_cache {
+ struct cso_hash *alpha_hash;
struct cso_hash *blend_hash;
- struct cso_hash *sampler_hash;
struct cso_hash *depth_stencil_hash;
- struct cso_hash *rasterizer_hash;
struct cso_hash *fs_hash;
struct cso_hash *vs_hash;
+ struct cso_hash *rasterizer_hash;
+ struct cso_hash *sampler_hash;
};
struct cso_blend {
void *data;
};
+struct cso_alpha_test {
+ struct pipe_alpha_test_state state;
+ void *data;
+};
+
enum cso_cache_type {
CSO_BLEND,
CSO_SAMPLER,
CSO_DEPTH_STENCIL,
CSO_RASTERIZER,
CSO_FRAGMENT_SHADER,
- CSO_VERTEX_SHADER
+ CSO_VERTEX_SHADER,
+ CSO_ALPHA_TEST
};
unsigned cso_construct_key(void *item, int item_size);
void *sw_state;
void *hw_state;
};
-struct failover_context {
+struct failover_context {
struct pipe_context pipe; /**< base class */
/* The most recent drawing state as set by the driver:
*/
+ const struct fo_state *alpha_test;
const struct fo_state *blend;
const struct fo_state *sampler[PIPE_MAX_SAMPLERS];
const struct fo_state *depth_stencil;
const struct fo_state *fragment_shader;
const struct fo_state *vertex_shader;
- 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;
* lower overheads.
*/
+static void *
+failover_create_alpha_test_state(struct pipe_context *pipe,
+ const struct pipe_alpha_test_state *templ)
+{
+ struct fo_state *state = malloc(sizeof(struct fo_state));
+ struct failover_context *failover = failover_context(pipe);
+
+ state->sw_state = failover->sw->create_alpha_test_state(pipe, templ);
+ state->hw_state = failover->hw->create_alpha_test_state(pipe, templ);
+
+ return state;
+}
+
static void
-failover_set_alpha_test_state(struct pipe_context *pipe,
- const struct pipe_alpha_test_state *alpha)
+failover_bind_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
{
struct failover_context *failover = failover_context(pipe);
+ struct fo_state *state = (struct fo_state *)alpha;
- failover->alpha_test = *alpha;
+ failover->alpha_test = state;
failover->dirty |= FO_NEW_ALPHA_TEST;
- failover->hw->set_alpha_test_state( failover->hw, alpha );
+ failover->hw->bind_alpha_test_state(failover->hw,
+ state->hw_state);
+}
+
+static void
+failover_delete_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
+{
+ struct fo_state *state = (struct fo_state*)alpha;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->delete_alpha_test_state(pipe, state->sw_state);
+ failover->hw->delete_alpha_test_state(pipe, state->hw_state);
+ state->sw_state = 0;
+ state->hw_state = 0;
+ free(state);
}
free(state);
}
-static void
+static void
failover_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
{
void
failover_init_state_functions( struct failover_context *failover )
{
+ failover->pipe.create_alpha_test_state = failover_create_alpha_test_state;
+ failover->pipe.bind_alpha_test_state = failover_bind_alpha_test_state;
+ failover->pipe.delete_alpha_test_state = failover_delete_alpha_test_state;
failover->pipe.create_blend_state = failover_create_blend_state;
- failover->pipe.bind_blend_state = failover_bind_blend_state;
+ failover->pipe.bind_blend_state = failover_bind_blend_state;
failover->pipe.delete_blend_state = failover_delete_blend_state;
failover->pipe.create_sampler_state = failover_create_sampler_state;
failover->pipe.bind_sampler_state = failover_bind_sampler_state;
failover->pipe.bind_vs_state = failover_bind_vs_state;
failover->pipe.delete_vs_state = failover_delete_vs_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;
unsigned i;
if (failover->dirty & FO_NEW_ALPHA_TEST)
- failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test );
+ failover->sw->bind_alpha_test_state( failover->sw,
+ failover->alpha_test->sw_state );
if (failover->dirty & FO_NEW_BLEND)
failover->sw->bind_blend_state( failover->sw,
/* The most recent drawing state as set by the driver:
*/
+ const struct pipe_alpha_test_state *alpha_test;
const struct i915_blend_state *blend;
const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct i915_depth_stencil_state *depth_stencil;
const struct i915_rasterizer_state *rasterizer;
const struct pipe_shader_state *fs;
- 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;
free(depth_stencil);
}
-static void i915_set_alpha_test_state(struct pipe_context *pipe,
- const struct pipe_alpha_test_state *alpha)
+
+static void *
+i915_create_alpha_test_state(struct pipe_context *pipe,
+ const struct pipe_alpha_test_state *alpha)
+{
+ return 0;
+}
+
+static void i915_bind_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
{
struct i915_context *i915 = i915_context(pipe);
- i915->alpha_test = *alpha;
+ i915->alpha_test = (const struct pipe_alpha_test_state*)alpha;
i915->dirty |= I915_NEW_ALPHA_TEST;
}
+static void i915_delete_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
+{
+}
+
static void i915_set_scissor_state( struct pipe_context *pipe,
const struct pipe_scissor_state *scissor )
{
void
i915_init_state_functions( struct i915_context *i915 )
{
+ i915->pipe.create_alpha_test_state = i915_create_alpha_test_state;
+ i915->pipe.bind_alpha_test_state = i915_bind_alpha_test_state;
+ i915->pipe.delete_alpha_test_state = i915_delete_alpha_test_state;
+
i915->pipe.create_blend_state = i915_create_blend_state;
i915->pipe.bind_blend_state = i915_bind_blend_state;
i915->pipe.delete_blend_state = i915_delete_blend_state;
i915->pipe.bind_vs_state = i915_bind_vs_state;
i915->pipe.delete_vs_state = i915_delete_shader_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_NEW_ALPHA_TEST
*/
- if (i915->alpha_test.enabled) {
- int test = i915_translate_compare_func(i915->alpha_test.func);
- ubyte refByte = float_to_ubyte(i915->alpha_test.ref);
+ if (i915->alpha_test->enabled) {
+ int test = i915_translate_compare_func(i915->alpha_test->func);
+ ubyte refByte = float_to_ubyte(i915->alpha_test->ref);
LIS6 |= (S6_ALPHA_TEST_ENABLE |
/*
* State functions
*/
+ void * (*create_alpha_test_state)(struct pipe_context *,
+ const struct pipe_alpha_test_state *);
+ void (*bind_alpha_test_state)(struct pipe_context *, void *);
+ void (*delete_alpha_test_state)(struct pipe_context *, void *);
+
void * (*create_blend_state)(struct pipe_context *,
const struct pipe_blend_state *);
- void (*bind_blend_state)(struct pipe_context *, void *);
- void (*delete_blend_state)(struct pipe_context *, void *);
+ void (*bind_blend_state)(struct pipe_context *, void *);
+ void (*delete_blend_state)(struct pipe_context *, void *);
void * (*create_sampler_state)(struct pipe_context *,
const struct pipe_sampler_state *);
- void (*bind_sampler_state)(struct pipe_context *, unsigned unit,
- void *);
- void (*delete_sampler_state)(struct pipe_context *, void *);
+ void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *);
+ void (*delete_sampler_state)(struct pipe_context *, void *);
- void *(*create_rasterizer_state)(struct pipe_context *,
- const struct pipe_rasterizer_state *);
- void (*bind_rasterizer_state)(struct pipe_context *, void *);
- void (*delete_rasterizer_state)(struct pipe_context *, void *);
+ void * (*create_rasterizer_state)(struct pipe_context *,
+ const struct pipe_rasterizer_state *);
+ void (*bind_rasterizer_state)(struct pipe_context *, void *);
+ void (*delete_rasterizer_state)(struct pipe_context *, void *);
void * (*create_depth_stencil_state)(struct pipe_context *,
const struct pipe_depth_stencil_state *);
- void (*bind_depth_stencil_state)(struct pipe_context *, void *);
- void (*delete_depth_stencil_state)(struct pipe_context *, void *);
+ void (*bind_depth_stencil_state)(struct pipe_context *, void *);
+ void (*delete_depth_stencil_state)(struct pipe_context *, void *);
void * (*create_fs_state)(struct pipe_context *,
const struct pipe_shader_state *);
void (*bind_vs_state)(struct pipe_context *, void *);
void (*delete_vs_state)(struct pipe_context *, void *);
- void (*set_alpha_test_state)( struct pipe_context *,
- const struct pipe_alpha_test_state * );
-
+ /* The following look more properties than states.
+ * maybe combine a few of them into states or pass them
+ * in the bind calls to the state */
void (*set_blend_color)( struct pipe_context *,
const struct pipe_blend_color * );
softpipe->pipe.get_param = softpipe_get_param;
/* state setters */
+ softpipe->pipe.create_alpha_test_state = softpipe_create_alpha_test_state;
+ softpipe->pipe.bind_alpha_test_state = softpipe_bind_alpha_test_state;
+ softpipe->pipe.delete_alpha_test_state = softpipe_delete_alpha_test_state;
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
softpipe->pipe.delete_vs_state = softpipe_delete_shader_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;
/* The most recent drawing state as set by the driver:
*/
+ const struct pipe_alpha_test_state *alpha_test;
const struct pipe_blend_state *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct pipe_depth_stencil_state *depth_stencil;
const struct pipe_shader_state *fs;
const struct pipe_shader_state *vs;
- 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;
sp->quad.first = sp->quad.depth_test;
}
- if (sp->alpha_test.enabled) {
+ if (sp->alpha_test->enabled) {
sp->quad.alpha_test->next = sp->quad.first;
sp->quad.first = sp->quad.alpha_test;
}
alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- const float ref = softpipe->alpha_test.ref;
+ const float ref = softpipe->alpha_test->ref;
unsigned passMask = 0x0, j;
- switch (softpipe->alpha_test.func) {
+ switch (softpipe->alpha_test->func) {
case PIPE_FUNC_NEVER:
quad->mask = 0x0;
break;
#include "pipe/p_state.h"
+
+void *
+softpipe_create_alpha_test_state(struct pipe_context *,
+ const struct pipe_alpha_test_state *);
+void
+softpipe_bind_alpha_test_state(struct pipe_context *, void *);
+void
+softpipe_delete_alpha_test_state(struct pipe_context *, void *);
+
void *
softpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);
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_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color );
* into one file.
*/
+void *
+softpipe_create_alpha_test_state(struct pipe_context *pipe,
+ const struct pipe_alpha_test_state *alpha)
+{
+ return 0;
+}
+
void
-softpipe_set_alpha_test_state(struct pipe_context *pipe,
- const struct pipe_alpha_test_state *alpha)
+softpipe_bind_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->alpha_test = *alpha;
+ softpipe->alpha_test = (const struct pipe_alpha_test_state *)alpha;
softpipe->dirty |= SP_NEW_ALPHA_TEST;
}
+void
+softpipe_delete_alpha_test_state(struct pipe_context *pipe,
+ void *alpha)
+{
+ /* do nothing */
+}
+
void *
softpipe_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_state *depth_stencil)
&st_update_texture,
&st_update_vs_constants,
&st_update_fs_constants,
+ &st_update_alpha_test
};
const struct st_tracked_state st_update_texture;
const struct st_tracked_state st_update_fs_constants;
const struct st_tracked_state st_update_vs_constants;
+const struct st_tracked_state st_update_alpha_test;
#endif
#include "st_context.h"
+#include "st_cache.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
update_alpha_test( struct st_context *st )
{
struct pipe_alpha_test_state alpha;
+ const struct cso_alpha_test *cso;
memset(&alpha, 0, sizeof(alpha));
alpha.func = gl_alpha_func_to_sp(st->ctx->Color.AlphaFunc);
alpha.ref = st->ctx->Color.AlphaRef;
}
-
- if (memcmp(&alpha, &st->state.alpha_test, sizeof(alpha)) != 0) {
+ cso = st_cached_alpha_test_state(st, &alpha);
+ if (st->state.alpha_test != cso) {
/* state has changed */
- st->state.alpha_test = alpha; /* struct copy */
- st->pipe->set_alpha_test_state(st->pipe, &alpha); /* set new state */
+ st->state.alpha_test = cso;
+ st->pipe->bind_alpha_test_state(st->pipe, cso->data); /* bind new state */
}
}
},
.update = update_alpha_test
};
-
-
-
-
-
}
return (struct cso_vertex_shader*)(cso_hash_iter_data(iter));
}
+
+const struct cso_alpha_test *
+st_cached_alpha_test_state(struct st_context *st,
+ const struct pipe_alpha_test_state *templ)
+{
+ unsigned hash_key = cso_construct_key((void*)templ,
+ sizeof(struct pipe_alpha_test_state));
+ struct cso_hash_iter iter = cso_find_state_template(st->cache,
+ hash_key, CSO_ALPHA_TEST,
+ (void*)templ);
+ if (cso_hash_iter_is_null(iter)) {
+ struct cso_alpha_test *cso = malloc(sizeof(struct cso_alpha_test));
+ memcpy(&cso->state, templ, sizeof(struct pipe_alpha_test_state));
+ cso->data = st->pipe->create_alpha_test_state(st->pipe, &cso->state);
+ if (!cso->data)
+ cso->data = &cso->state;
+ iter = cso_insert_state(st->cache, hash_key, CSO_ALPHA_TEST, cso);
+ }
+ return ((struct cso_alpha_test *)cso_hash_iter_data(iter));
+}
struct pipe_sampler_state;
struct st_context;
+const struct cso_alpha_test *
+st_cached_alpha_test_state(struct st_context *st,
+ const struct pipe_alpha_test_state *alpha);
+
const struct cso_blend *
st_cached_blend_state(struct st_context *st,
const struct pipe_blend_state *blend);
/* alpha state: disabled */
{
struct pipe_alpha_test_state alpha_test;
+ const struct cso_alpha_test *cso;
memset(&alpha_test, 0, sizeof(alpha_test));
- pipe->set_alpha_test_state(pipe, &alpha_test);
+ cso = st_cached_alpha_test_state(st, &alpha_test);
+ pipe->bind_alpha_test_state(pipe, cso->data);
}
/* blend state: RGBA masking */
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
/* Restore pipe state */
- pipe->set_alpha_test_state(pipe, &st->state.alpha_test);
+ pipe->bind_alpha_test_state(pipe, st->state.alpha_test->data);
pipe->bind_blend_state(pipe, st->state.blend->data);
pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil->data);
pipe->bind_fs_state(pipe, st->state.fs->data);
static GLboolean
any_fragment_ops(const struct st_context *st)
{
- if (st->state.alpha_test.enabled ||
+ if (st->state.alpha_test->state.enabled ||
st->state.blend->state.blend_enable ||
st->state.blend->state.logicop_enable ||
st->state.depth_stencil->state.depth.enabled)
* though, we just shove random objects across the interface.
*/
struct {
- const struct cso_blend *blend;
- const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS];
- const struct cso_depth_stencil *depth_stencil;
- const struct cso_rasterizer *rasterizer;
+ const struct cso_alpha_test *alpha_test;
+ const struct cso_blend *blend;
+ const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS];
+ const struct cso_depth_stencil *depth_stencil;
+ const struct cso_rasterizer *rasterizer;
const struct cso_fragment_shader *fs;
const struct cso_vertex_shader *vs;
- 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;