Procházet zdrojové kódy

gallium: use cso state handling for pipe_vertex_element state

tags/mesa-7.9-rc1
Roland Scheidegger před 16 roky
rodič
revize
51d139f038

+ 21
- 0
src/gallium/auxiliary/cso_cache/cso_cache.c Zobrazit soubor

@@ -43,6 +43,7 @@ struct cso_cache {
struct cso_hash *vs_hash;
struct cso_hash *rasterizer_hash;
struct cso_hash *sampler_hash;
struct cso_hash *velements_hash;
int max_size;

cso_sanitize_callback sanitize_cb;
@@ -108,6 +109,9 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
case CSO_VELEMENTS:
hash = sc->velements_hash;
break;
}

return hash;
@@ -161,6 +165,13 @@ static void delete_vs_state(void *state, void *data)
FREE(state);
}

static void delete_velements(void *state, void *data)
{
struct cso_velements *cso = (struct cso_velements *)state;
if (cso->delete_state)
cso->delete_state(cso->context, cso->data);
FREE(state);
}

static INLINE void delete_cso(void *state, enum cso_cache_type type)
{
@@ -183,6 +194,9 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
case CSO_VERTEX_SHADER:
delete_vs_state(state, 0);
break;
case CSO_VELEMENTS:
delete_velements(state, 0);
break;
default:
assert(0);
FREE(state);
@@ -294,6 +308,7 @@ struct cso_cache *cso_cache_create(void)
sc->rasterizer_hash = cso_hash_create();
sc->fs_hash = cso_hash_create();
sc->vs_hash = cso_hash_create();
sc->velements_hash = cso_hash_create();
sc->sanitize_cb = sanitize_cb;
sc->sanitize_data = 0;

@@ -325,6 +340,9 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
case CSO_VELEMENTS:
hash = sc->velements_hash;
break;
}

iter = cso_hash_first_node(hash);
@@ -351,6 +369,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0);
cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0);
cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0);
cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0);

cso_hash_delete(sc->blend_hash);
cso_hash_delete(sc->sampler_hash);
@@ -358,6 +377,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_hash_delete(sc->rasterizer_hash);
cso_hash_delete(sc->fs_hash);
cso_hash_delete(sc->vs_hash);
cso_hash_delete(sc->velements_hash);
FREE(sc);
}

@@ -372,6 +392,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
sanitize_hash(sc, sc->velements_hash, CSO_VELEMENTS, sc->max_size);
}

int cso_maximum_cache_size(const struct cso_cache *sc)

+ 10
- 1
src/gallium/auxiliary/cso_cache/cso_cache.h Zobrazit soubor

@@ -53,6 +53,7 @@
* - rasterizer (old setup)
* - sampler
* - vertex shader
* - vertex elements
*
* Things that are not constant state objects include:
* - blend_color
@@ -90,7 +91,8 @@ enum cso_cache_type {
CSO_DEPTH_STENCIL_ALPHA,
CSO_RASTERIZER,
CSO_FRAGMENT_SHADER,
CSO_VERTEX_SHADER
CSO_VERTEX_SHADER,
CSO_VELEMENTS
};

typedef void (*cso_state_callback)(void *ctx, void *obj);
@@ -144,6 +146,13 @@ struct cso_sampler {
struct pipe_context *context;
};

struct cso_velements {
struct pipe_vertex_element state[PIPE_MAX_ATTRIBS];
void *data;
cso_state_callback delete_state;
struct pipe_context *context;
};

unsigned cso_construct_key(void *item, int item_size);

struct cso_cache *cso_cache_create(void);

+ 74
- 0
src/gallium/auxiliary/cso_cache/cso_context.c Zobrazit soubor

@@ -89,6 +89,7 @@ struct cso_context {
void *rasterizer, *rasterizer_saved;
void *fragment_shader, *fragment_shader_saved, *geometry_shader;
void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
void *velements, *velements_saved;

struct pipe_framebuffer_state fb, fb_saved;
struct pipe_viewport_state vp, vp_saved;
@@ -171,6 +172,20 @@ static boolean delete_vs_state(struct cso_context *ctx, void *state)
return FALSE;
}

static boolean delete_vertex_elements(struct cso_context *ctx,
void *state)
{
struct cso_velements *cso = (struct cso_velements *)state;

if (ctx->velements == cso->data)
return FALSE;

if (cso->delete_state)
cso->delete_state(cso->context, cso->data);
FREE(state);
return TRUE;
}


static INLINE boolean delete_cso(struct cso_context *ctx,
void *state, enum cso_cache_type type)
@@ -194,6 +209,9 @@ static INLINE boolean delete_cso(struct cso_context *ctx,
case CSO_VERTEX_SHADER:
return delete_vs_state(ctx, state);
break;
case CSO_VELEMENTS:
return delete_vertex_elements(ctx, state);
break;
default:
assert(0);
FREE(state);
@@ -1126,3 +1144,59 @@ void cso_restore_geometry_shader(struct cso_context *ctx)
}
ctx->geometry_shader_saved = NULL;
}

enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count,
const struct pipe_vertex_element *states)
{
unsigned key_size, hash_key;
struct cso_hash_iter iter;
void *handle;

key_size = sizeof(struct pipe_vertex_element) * count;
hash_key = cso_construct_key((void*)states, key_size);
iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)states, key_size);

if (cso_hash_iter_is_null(iter)) {
struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;

memcpy(&cso->state, states, key_size);
cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state[0]);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state;
cso->context = ctx->pipe;

iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
if (cso_hash_iter_is_null(iter)) {
FREE(cso);
return PIPE_ERROR_OUT_OF_MEMORY;
}

handle = cso->data;
}
else {
handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
}

if (ctx->velements != handle) {
ctx->velements = handle;
ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
}
return PIPE_OK;
}

void cso_save_vertex_elements(struct cso_context *ctx)
{
assert(!ctx->velements);
ctx->velements_saved = ctx->velements;
}

void cso_restore_vertex_elements(struct cso_context *ctx)
{
if (ctx->velements != ctx->velements_saved) {
ctx->velements = ctx->velements_saved;
ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
}
ctx->velements_saved = NULL;
}

+ 6
- 1
src/gallium/auxiliary/cso_cache/cso_context.h Zobrazit soubor

@@ -122,6 +122,12 @@ void
cso_restore_vertex_sampler_textures(struct cso_context *cso);


enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count,
const struct pipe_vertex_element *states);
void cso_save_vertex_elements(struct cso_context *ctx);
void cso_restore_vertex_elements(struct cso_context *ctx);


/* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't
@@ -157,7 +163,6 @@ void cso_save_geometry_shader(struct cso_context *cso);
void cso_restore_geometry_shader(struct cso_context *cso);



enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb);
void cso_save_framebuffer(struct cso_context *cso);

+ 6
- 3
src/gallium/include/pipe/p_context.h Zobrazit soubor

@@ -177,6 +177,12 @@ struct pipe_context {
void (*bind_gs_state)(struct pipe_context *, void *);
void (*delete_gs_state)(struct pipe_context *, void *);

void * (*create_vertex_elements_state)(struct pipe_context *,
unsigned num_elements,
const struct pipe_vertex_element *);
void (*bind_vertex_elements_state)(struct pipe_context *, void *);
void (*delete_vertex_elements_state)(struct pipe_context *, void *);

/*@}*/

/**
@@ -220,9 +226,6 @@ struct pipe_context {
unsigned num_buffers,
const struct pipe_vertex_buffer * );

void (*set_vertex_elements)( struct pipe_context *,
unsigned num_elements,
const struct pipe_vertex_element * );
/*@}*/



Načítá se…
Zrušit
Uložit