struct cso_hash *vs_hash;
};
+struct cso_blend {
+ struct pipe_blend_state state;
+ void *data;
+};
+
enum cso_cache_type {
CSO_BLEND,
CSO_SAMPLER,
#define FO_HW 0
#define FO_SW 1
+struct fo_state {
+ void *sw_state;
+ void *hw_state;
+};
struct failover_context {
struct pipe_context pipe; /**< base class */
/* The most recent drawing state as set by the driver:
*/
- const struct pipe_blend_state *blend;
+ const struct fo_state *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct pipe_depth_stencil_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;
}
-static void
+static void *
+failover_create_blend_state( struct pipe_context *pipe,
+ const struct pipe_blend_state *blend )
+{
+ struct fo_state *state = malloc(sizeof(struct fo_state));
+ struct failover_context *failover = failover_context(pipe);
+
+ state->sw_state = failover->sw->create_blend_state(pipe, blend);
+ state->hw_state = failover->hw->create_blend_state(pipe, blend);
+
+ return state;
+}
+
+static void
failover_bind_blend_state( struct pipe_context *pipe,
- const struct pipe_blend_state *blend )
+ void *blend )
{
struct failover_context *failover = failover_context(pipe);
- failover->blend = blend;
+ failover->blend = (struct fo_state *)blend;
failover->dirty |= FO_NEW_BLEND;
failover->hw->bind_blend_state( failover->hw, blend );
}
+static void
+failover_delete_blend_state( struct pipe_context *pipe,
+ void *blend )
+{
+ struct fo_state *state = (struct fo_state*)blend;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->delete_blend_state(pipe, state->sw_state);
+ failover->hw->delete_blend_state(pipe, state->hw_state);
+ state->sw_state = 0;
+ state->hw_state = 0;
+ free(state);
+}
static void
failover_set_blend_color( struct pipe_context *pipe,
void
failover_init_state_functions( struct failover_context *failover )
{
+ failover->pipe.create_blend_state = failover_create_blend_state;
failover->pipe.bind_blend_state = failover_bind_blend_state;
+ failover->pipe.delete_blend_state = failover_delete_blend_state;
failover->pipe.bind_sampler_state = failover_bind_sampler_state;
failover->pipe.bind_depth_stencil_state = failover_bind_depth_stencil_state;
failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state;
failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test );
if (failover->dirty & FO_NEW_BLEND)
- failover->sw->bind_blend_state( failover->sw, failover->blend );
+ failover->sw->bind_blend_state( failover->sw,
+ failover->blend->sw_state );
if (failover->dirty & FO_NEW_BLEND_COLOR)
failover->sw->set_blend_color( failover->sw, &failover->blend_color );
/* None of this state is actually used for anything yet.
*/
-static const struct pipe_blend_state *
+static void *
i915_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
}
static void i915_bind_blend_state( struct pipe_context *pipe,
- const struct pipe_blend_state *blend )
+ void *blend )
{
struct i915_context *i915 = i915_context(pipe);
- i915->blend = blend;
+ i915->blend = (struct pipe_blend_state *)blend;
i915->dirty |= I915_NEW_BLEND;
}
static void i915_delete_blend_state( struct pipe_context *pipe,
- const struct pipe_blend_state *blend )
+ void *blend )
{
- free((void*)blend);
+ free(blend);
}
static void i915_set_blend_color( struct pipe_context *pipe,
/*
* State functions
*/
- const struct pipe_blend_state * (*create_blend_state)(struct pipe_context *,
- const struct pipe_blend_state *);
- void (*bind_blend_state)(struct pipe_context *,
- const struct pipe_blend_state *);
- void (*delete_blend_state)(struct pipe_context *,
- const struct pipe_blend_state *);
+ 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 *);
const struct pipe_sampler_state * (*create_sampler_state)(
struct pipe_context *,
#include "pipe/p_state.h"
-const struct pipe_blend_state *
+void *
softpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);
void softpipe_bind_blend_state(struct pipe_context *,
- const struct pipe_blend_state *);
+ void *);
void softpipe_delete_blend_state(struct pipe_context *,
- const struct pipe_blend_state *);
+ void *);
const struct pipe_sampler_state *
softpipe_create_sampler_state(struct pipe_context *,
#include "sp_context.h"
#include "sp_state.h"
-const struct pipe_blend_state *
+void *
softpipe_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
}
void softpipe_bind_blend_state( struct pipe_context *pipe,
- const struct pipe_blend_state *blend )
+ void *blend )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->blend = blend;
+ softpipe->blend = (const struct pipe_blend_state *)blend;
softpipe->dirty |= SP_NEW_BLEND;
}
void softpipe_delete_blend_state(struct pipe_context *pipe,
- const struct pipe_blend_state *blend )
+ void *blend )
{
- free((struct pipe_blend_state *)blend);
+ free(blend);
}
if (st->ctx->Color.DitherFlag)
blend.dither = 1;
- struct pipe_blend_state *real_blend =
+ const struct cso_blend *cso =
st_cached_blend_state(st, &blend);
- if (st->state.blend != real_blend) {
+ if (st->state.blend != cso) {
/* state has changed */
- st->state.blend = real_blend;
+ st->state.blend = cso;
/* bind new state */
- st->pipe->bind_blend_state(st->pipe, real_blend);
+ st->pipe->bind_blend_state(st->pipe, cso->data);
}
if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
* in the cache or it will create a new state state from the given
* template, will insert it in the cache and return it.
*/
-struct pipe_blend_state * st_cached_blend_state(
- struct st_context *st,
- const struct pipe_blend_state *blend)
+const struct cso_blend * st_cached_blend_state(struct st_context *st,
+ const struct pipe_blend_state *templ)
{
- unsigned hash_key = cso_construct_key((void*)blend, sizeof(struct pipe_blend_state));
+ unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state));
struct cso_hash_iter iter = cso_find_state_template(st->cache,
hash_key, CSO_BLEND,
- (void*)blend);
+ (void*)templ);
if (cso_hash_iter_is_null(iter)) {
- const struct pipe_blend_state *created_state = st->pipe->create_blend_state(
- st->pipe, blend);
- iter = cso_insert_state(st->cache, hash_key, CSO_BLEND,
- (void*)created_state);
+ struct cso_blend *cso = malloc(sizeof(struct cso_blend));
+ memcpy(&cso->state, templ, sizeof(struct pipe_blend_state));
+ cso->data = st->pipe->create_blend_state(st->pipe, templ);
+ if (!cso->data)
+ cso->data = &cso->state;
+ iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, cso);
}
- return (struct pipe_blend_state*)(cso_hash_iter_data(iter));
+ return ((struct cso_blend *)cso_hash_iter_data(iter));
}
struct pipe_sampler_state * st_cached_sampler_state(
#ifndef ST_CACHE_H
#define ST_CACHE_H
+#include "pipe/cso_cache/cso_cache.h"
+
struct pipe_blend_state;
struct pipe_sampler_state;
struct st_context;
-struct pipe_blend_state * st_cached_blend_state(
- struct st_context *st,
- const struct pipe_blend_state *blend);
+const struct cso_blend *
+st_cached_blend_state(struct st_context *st,
+ const struct pipe_blend_state *blend);
-struct pipe_sampler_state * st_cached_sampler_state(
- struct st_context *st,
- const struct pipe_sampler_state *sampler);
+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,
/* blend state: RGBA masking */
{
struct pipe_blend_state blend;
- const struct pipe_blend_state *state;
+ const struct cso_blend *cso;
memset(&blend, 0, sizeof(blend));
if (color) {
if (ctx->Color.ColorMask[0])
if (st->ctx->Color.DitherFlag)
blend.dither = 1;
}
- state = st_cached_blend_state(st, &blend);
- pipe->bind_blend_state(pipe, state);
+ cso = st_cached_blend_state(st, &blend);
+ pipe->bind_blend_state(pipe, cso->data);
}
/* depth_stencil state: always pass/set to ref value */
/* Restore pipe state */
pipe->set_alpha_test_state(pipe, &st->state.alpha_test);
- pipe->bind_blend_state(pipe, st->state.blend);
+ pipe->bind_blend_state(pipe, st->state.blend->data);
pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil);
pipe->bind_fs_state(pipe, st->state.fs);
pipe->bind_vs_state(pipe, st->state.vs);
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.blend->state.blend_enable ||
+ st->state.blend->state.logicop_enable ||
st->state.depth_stencil->depth.enabled)
/* XXX more checks */
return GL_TRUE;
struct draw_context;
struct draw_stage;
struct cso_cache;
+struct cso_blend;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
#define ST_NEW_FRAGMENT_PROGRAM 0x2
* though, we just shove random objects across the interface.
*/
struct {
- const struct pipe_blend_state *blend;
+ const struct cso_blend *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct pipe_depth_stencil_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;