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:
parent
b3cc74aa44
commit
c0bf732208
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue