try to fix the deleting of the bound cso during cleanup of the hash
This commit is contained in:
parent
dadb11f5d9
commit
026e31a068
|
@ -43,6 +43,9 @@ struct cso_cache {
|
||||||
struct cso_hash *rasterizer_hash;
|
struct cso_hash *rasterizer_hash;
|
||||||
struct cso_hash *sampler_hash;
|
struct cso_hash *sampler_hash;
|
||||||
int max_size;
|
int max_size;
|
||||||
|
|
||||||
|
cso_sanitize_callback sanitize_cb;
|
||||||
|
void *sanitize_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -205,8 +208,19 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
|
|
||||||
|
static INLINE void sanitize_hash(struct cso_cache *sc,
|
||||||
|
struct cso_hash *hash,
|
||||||
|
enum cso_cache_type type,
|
||||||
int max_size)
|
int max_size)
|
||||||
|
{
|
||||||
|
if (sc->sanitize_cb)
|
||||||
|
sc->sanitize_cb(hash, type, max_size, sc->sanitize_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE void sanitize_cb(struct cso_hash *hash, enum cso_cache_type type,
|
||||||
|
int max_size, void *user_data)
|
||||||
{
|
{
|
||||||
/* if we're approach the maximum size, remove fourth of the entries
|
/* if we're approach the maximum size, remove fourth of the entries
|
||||||
* otherwise every subsequent call will go through the same */
|
* otherwise every subsequent call will go through the same */
|
||||||
|
@ -231,7 +245,7 @@ cso_insert_state(struct cso_cache *sc,
|
||||||
void *state)
|
void *state)
|
||||||
{
|
{
|
||||||
struct cso_hash *hash = _cso_hash_for_type(sc, type);
|
struct cso_hash *hash = _cso_hash_for_type(sc, type);
|
||||||
sanitize_hash(hash, type, sc->max_size);
|
sanitize_hash(sc, hash, type, sc->max_size);
|
||||||
|
|
||||||
return cso_hash_insert(hash, hash_key, state);
|
return cso_hash_insert(hash, hash_key, state);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +314,8 @@ struct cso_cache *cso_cache_create(void)
|
||||||
sc->rasterizer_hash = cso_hash_create();
|
sc->rasterizer_hash = cso_hash_create();
|
||||||
sc->fs_hash = cso_hash_create();
|
sc->fs_hash = cso_hash_create();
|
||||||
sc->vs_hash = cso_hash_create();
|
sc->vs_hash = cso_hash_create();
|
||||||
|
sc->sanitize_cb = sanitize_cb;
|
||||||
|
sc->sanitize_data = 0;
|
||||||
|
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
@ -365,13 +381,13 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
|
||||||
{
|
{
|
||||||
sc->max_size = number;
|
sc->max_size = number;
|
||||||
|
|
||||||
sanitize_hash(sc->blend_hash, CSO_BLEND, sc->max_size);
|
sanitize_hash(sc, sc->blend_hash, CSO_BLEND, sc->max_size);
|
||||||
sanitize_hash(sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA,
|
sanitize_hash(sc, sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA,
|
||||||
sc->max_size);
|
sc->max_size);
|
||||||
sanitize_hash(sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size);
|
sanitize_hash(sc, sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size);
|
||||||
sanitize_hash(sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
|
sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
|
||||||
sanitize_hash(sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
|
sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
|
||||||
sanitize_hash(sc->sampler_hash, CSO_SAMPLER, sc->max_size);
|
sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cso_maximum_cache_size(const struct cso_cache *sc)
|
int cso_maximum_cache_size(const struct cso_cache *sc)
|
||||||
|
@ -379,3 +395,11 @@ int cso_maximum_cache_size(const struct cso_cache *sc)
|
||||||
return sc->max_size;
|
return sc->max_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cso_cache_set_sanitize_callback(struct cso_cache *sc,
|
||||||
|
cso_sanitize_callback cb,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
sc->sanitize_cb = cb;
|
||||||
|
sc->sanitize_data = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,22 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum cso_cache_type {
|
||||||
|
CSO_BLEND,
|
||||||
|
CSO_SAMPLER,
|
||||||
|
CSO_DEPTH_STENCIL_ALPHA,
|
||||||
|
CSO_RASTERIZER,
|
||||||
|
CSO_FRAGMENT_SHADER,
|
||||||
|
CSO_VERTEX_SHADER
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*cso_state_callback)(void *ctx, void *obj);
|
typedef void (*cso_state_callback)(void *ctx, void *obj);
|
||||||
|
|
||||||
|
typedef void (*cso_sanitize_callback)(struct cso_hash *hash,
|
||||||
|
enum cso_cache_type type,
|
||||||
|
int max_size,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
struct cso_cache;
|
struct cso_cache;
|
||||||
|
|
||||||
struct cso_blend {
|
struct cso_blend {
|
||||||
|
@ -130,21 +144,15 @@ struct cso_sampler {
|
||||||
struct pipe_context *context;
|
struct pipe_context *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum cso_cache_type {
|
|
||||||
CSO_BLEND,
|
|
||||||
CSO_SAMPLER,
|
|
||||||
CSO_DEPTH_STENCIL_ALPHA,
|
|
||||||
CSO_RASTERIZER,
|
|
||||||
CSO_FRAGMENT_SHADER,
|
|
||||||
CSO_VERTEX_SHADER
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned cso_construct_key(void *item, int item_size);
|
unsigned cso_construct_key(void *item, int item_size);
|
||||||
|
|
||||||
struct cso_cache *cso_cache_create(void);
|
struct cso_cache *cso_cache_create(void);
|
||||||
void cso_cache_delete(struct cso_cache *sc);
|
void cso_cache_delete(struct cso_cache *sc);
|
||||||
|
|
||||||
|
void cso_cache_set_sanitize_callback(struct cso_cache *sc,
|
||||||
|
cso_sanitize_callback cb,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
struct cso_hash_iter cso_insert_state(struct cso_cache *sc,
|
struct cso_hash_iter cso_insert_state(struct cso_cache *sc,
|
||||||
unsigned hash_key, enum cso_cache_type type,
|
unsigned hash_key, enum cso_cache_type type,
|
||||||
void *state);
|
void *state);
|
||||||
|
|
|
@ -80,6 +80,131 @@ struct cso_context {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static boolean delete_blend_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_blend *cso = (struct cso_blend *)state;
|
||||||
|
|
||||||
|
if (ctx->blend == state)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state;
|
||||||
|
|
||||||
|
if (ctx->depth_stencil == cso->data)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean delete_sampler_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_sampler *cso = (struct cso_sampler *)state;
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean delete_rasterizer_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_rasterizer *cso = (struct cso_rasterizer *)state;
|
||||||
|
|
||||||
|
if (ctx->rasterizer == cso->data)
|
||||||
|
return FALSE;
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean delete_fs_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state;
|
||||||
|
if (ctx->fragment_shader == cso->data)
|
||||||
|
return FALSE;
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean delete_vs_state(struct cso_context *ctx, void *state)
|
||||||
|
{
|
||||||
|
struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state;
|
||||||
|
if (ctx->vertex_shader == cso->data)
|
||||||
|
return TRUE;
|
||||||
|
if (cso->delete_state)
|
||||||
|
cso->delete_state(cso->context, cso->data);
|
||||||
|
FREE(state);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE boolean delete_cso(struct cso_context *ctx,
|
||||||
|
void *state, enum cso_cache_type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case CSO_BLEND:
|
||||||
|
return delete_blend_state(ctx, state);
|
||||||
|
break;
|
||||||
|
case CSO_SAMPLER:
|
||||||
|
return delete_sampler_state(ctx, state);
|
||||||
|
break;
|
||||||
|
case CSO_DEPTH_STENCIL_ALPHA:
|
||||||
|
return delete_depth_stencil_state(ctx, state);
|
||||||
|
break;
|
||||||
|
case CSO_RASTERIZER:
|
||||||
|
return delete_rasterizer_state(ctx, state);
|
||||||
|
break;
|
||||||
|
case CSO_FRAGMENT_SHADER:
|
||||||
|
return delete_fs_state(ctx, state);
|
||||||
|
break;
|
||||||
|
case CSO_VERTEX_SHADER:
|
||||||
|
return delete_vs_state(ctx, state);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
FREE(state);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
|
||||||
|
int max_size, void *user_data)
|
||||||
|
{
|
||||||
|
struct cso_context *ctx = (struct cso_context *)user_data;
|
||||||
|
/* if we're approach the maximum size, remove fourth of the entries
|
||||||
|
* otherwise every subsequent call will go through the same */
|
||||||
|
int hash_size = cso_hash_size(hash);
|
||||||
|
int max_entries = (max_size > hash_size) ? max_size : hash_size;
|
||||||
|
int to_remove = (max_size < max_entries) * max_entries/4;
|
||||||
|
struct cso_hash_iter iter = cso_hash_first_node(hash);
|
||||||
|
if (hash_size > max_size)
|
||||||
|
to_remove += hash_size - max_size;
|
||||||
|
while (to_remove) {
|
||||||
|
/*remove elements until we're good */
|
||||||
|
/*fixme: currently we pick the nodes to remove at random*/
|
||||||
|
void *cso = cso_hash_iter_data(iter);
|
||||||
|
if (delete_cso(ctx, cso, type)) {
|
||||||
|
iter = cso_hash_erase(hash, iter);
|
||||||
|
--to_remove;
|
||||||
|
} else
|
||||||
|
iter = cso_hash_iter_next(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cso_context *cso_create_context( struct pipe_context *pipe )
|
struct cso_context *cso_create_context( struct pipe_context *pipe )
|
||||||
{
|
{
|
||||||
struct cso_context *ctx = CALLOC_STRUCT(cso_context);
|
struct cso_context *ctx = CALLOC_STRUCT(cso_context);
|
||||||
|
@ -89,6 +214,9 @@ struct cso_context *cso_create_context( struct pipe_context *pipe )
|
||||||
ctx->cache = cso_cache_create();
|
ctx->cache = cso_cache_create();
|
||||||
if (ctx->cache == NULL)
|
if (ctx->cache == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
cso_cache_set_sanitize_callback(ctx->cache,
|
||||||
|
sanitize_hash,
|
||||||
|
ctx);
|
||||||
|
|
||||||
ctx->pipe = pipe;
|
ctx->pipe = pipe;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue