Redo the cso cache to map driver data in a lot more pleasing way.

Drivers can now create whatever they want from the state template. We
use cso_state object to store the template (necessary during lookups),
and the driver data. Convert blend state to the new semantics.
This commit is contained in:
Zack Rusin 2007-09-19 12:35:29 -04:00
parent b3cc74aa44
commit c0bf732208
14 changed files with 91 additions and 51 deletions

View File

@ -48,6 +48,11 @@ struct cso_cache {
struct cso_hash *vs_hash;
};
struct cso_blend {
struct pipe_blend_state state;
void *data;
};
enum cso_cache_type {
CSO_BLEND,
CSO_SAMPLER,

View File

@ -60,13 +60,17 @@
#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;

View File

@ -57,17 +57,43 @@ failover_set_alpha_test_state(struct pipe_context *pipe,
}
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,
@ -253,7 +279,9 @@ failover_set_vertex_element(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;

View File

@ -59,7 +59,8 @@ failover_state_emit( struct failover_context *failover )
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 );

View File

@ -38,7 +38,7 @@
/* 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)
{
@ -49,20 +49,20 @@ i915_create_blend_state(struct pipe_context *pipe,
}
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,

View File

@ -85,12 +85,10 @@ struct pipe_context {
/*
* 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 *,

View File

@ -33,13 +33,13 @@
#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 *,

View File

@ -30,7 +30,7 @@
#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)
{
@ -41,19 +41,19 @@ softpipe_create_blend_state(struct pipe_context *pipe,
}
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);
}

View File

@ -211,14 +211,14 @@ update_blend( struct st_context *st )
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) {

View File

@ -43,21 +43,22 @@
* 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(

View File

@ -33,17 +33,19 @@
#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,

View File

@ -298,7 +298,7 @@ clear_with_quad(GLcontext *ctx,
/* 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])
@ -312,8 +312,8 @@ clear_with_quad(GLcontext *ctx,
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 */
@ -411,7 +411,7 @@ 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->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);

View File

@ -493,8 +493,8 @@ static GLboolean
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;

View File

@ -40,6 +40,7 @@ struct st_fragment_program;
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
@ -74,7 +75,7 @@ struct st_context
* 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;