cso: Add support for separate vertex sampler state.

This commit is contained in:
Michal Krol 2009-12-01 08:35:43 +01:00
parent 15d1b406af
commit fd4aa4f323
2 changed files with 192 additions and 4 deletions

View file

@ -50,20 +50,35 @@ struct cso_context {
struct {
void *samplers[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
unsigned nr_vertex_samplers;
} hw;
void *samplers[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
unsigned nr_vertex_samplers;
unsigned nr_samplers_saved;
void *samplers_saved[PIPE_MAX_SAMPLERS];
unsigned nr_vertex_samplers_saved;
void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
uint nr_textures;
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
uint nr_vertex_textures;
uint nr_textures_saved;
struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
uint nr_vertex_textures_saved;
struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS];
/** Current and saved state.
* The saved state is used as a 1-deep stack.
*/
@ -244,7 +259,8 @@ void cso_release_all( struct cso_context *ctx )
if (ctx->pipe) {
ctx->pipe->bind_blend_state( ctx->pipe, NULL );
ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
ctx->pipe->bind_sampler_states( ctx->pipe, 0, NULL );
ctx->pipe->bind_fragment_sampler_states( ctx->pipe, 0, NULL );
ctx->pipe->bind_vertex_sampler_states(ctx->pipe, 0, NULL);
ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
ctx->pipe->bind_fs_state( ctx->pipe, NULL );
ctx->pipe->bind_vs_state( ctx->pipe, NULL );
@ -255,6 +271,11 @@ void cso_release_all( struct cso_context *ctx )
pipe_texture_reference(&ctx->textures_saved[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
pipe_texture_reference(&ctx->vertex_textures[i], NULL);
pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL);
}
free_framebuffer_state(&ctx->fb);
free_framebuffer_state(&ctx->fb_saved);
@ -378,6 +399,46 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx,
return PIPE_OK;
}
enum pipe_error
cso_single_vertex_sampler(struct cso_context *ctx,
unsigned idx,
const struct pipe_sampler_state *templ)
{
void *handle = NULL;
if (templ != NULL) {
unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state));
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key, CSO_SAMPLER,
(void*)templ);
if (cso_hash_iter_is_null(iter)) {
struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
cso->context = ctx->pipe;
iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
if (cso_hash_iter_is_null(iter)) {
FREE(cso);
return PIPE_ERROR_OUT_OF_MEMORY;
}
handle = cso->data;
}
else {
handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
}
}
ctx->vertex_samplers[idx] = handle;
return PIPE_OK;
}
void cso_single_sampler_done( struct cso_context *ctx )
{
unsigned i;
@ -398,7 +459,36 @@ void cso_single_sampler_done( struct cso_context *ctx )
memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *));
ctx->hw.nr_samplers = ctx->nr_samplers;
ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers);
ctx->pipe->bind_fragment_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers);
}
}
void
cso_single_vertex_sampler_done(struct cso_context *ctx)
{
unsigned i;
/* find highest non-null sampler */
for (i = PIPE_MAX_VERTEX_SAMPLERS; i > 0; i--) {
if (ctx->vertex_samplers[i - 1] != NULL)
break;
}
ctx->nr_vertex_samplers = i;
if (ctx->hw.nr_vertex_samplers != ctx->nr_vertex_samplers ||
memcmp(ctx->hw.vertex_samplers,
ctx->vertex_samplers,
ctx->nr_vertex_samplers * sizeof(void *)) != 0)
{
memcpy(ctx->hw.vertex_samplers,
ctx->vertex_samplers,
ctx->nr_vertex_samplers * sizeof(void *));
ctx->hw.nr_vertex_samplers = ctx->nr_vertex_samplers;
ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
ctx->nr_vertex_samplers,
ctx->vertex_samplers);
}
}
@ -447,6 +537,21 @@ void cso_restore_samplers(struct cso_context *ctx)
cso_single_sampler_done( ctx );
}
void
cso_save_vertex_samplers(struct cso_context *ctx)
{
ctx->nr_vertex_samplers_saved = ctx->nr_vertex_samplers;
memcpy(ctx->vertex_samplers_saved, ctx->vertex_samplers, sizeof(ctx->vertex_samplers));
}
void
cso_restore_vertex_samplers(struct cso_context *ctx)
{
ctx->nr_vertex_samplers = ctx->nr_vertex_samplers_saved;
memcpy(ctx->vertex_samplers, ctx->vertex_samplers_saved, sizeof(ctx->vertex_samplers));
cso_single_vertex_sampler_done(ctx);
}
enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
uint count,
@ -461,7 +566,7 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
for ( ; i < PIPE_MAX_SAMPLERS; i++)
pipe_texture_reference(&ctx->textures[i], NULL);
ctx->pipe->set_sampler_textures(ctx->pipe, count, textures);
ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures);
return PIPE_OK;
}
@ -491,13 +596,71 @@ void cso_restore_sampler_textures( struct cso_context *ctx )
for ( ; i < PIPE_MAX_SAMPLERS; i++)
pipe_texture_reference(&ctx->textures[i], NULL);
ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
ctx->nr_textures_saved = 0;
}
enum pipe_error
cso_set_vertex_sampler_textures(struct cso_context *ctx,
uint count,
struct pipe_texture **textures)
{
uint i;
ctx->nr_vertex_textures = count;
for (i = 0; i < count; i++) {
pipe_texture_reference(&ctx->vertex_textures[i], textures[i]);
}
for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
pipe_texture_reference(&ctx->vertex_textures[i], NULL);
}
ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures);
return PIPE_OK;
}
void
cso_save_vertex_sampler_textures(struct cso_context *ctx)
{
uint i;
ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures;
for (i = 0; i < ctx->nr_vertex_textures; i++) {
assert(!ctx->vertex_textures_saved[i]);
pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]);
}
}
void
cso_restore_vertex_sampler_textures(struct cso_context *ctx)
{
uint i;
ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved;
for (i = 0; i < ctx->nr_vertex_textures; i++) {
pipe_texture_reference(&ctx->vertex_textures[i], NULL);
ctx->vertex_textures[i] = ctx->vertex_textures_saved[i];
ctx->vertex_textures_saved[i] = NULL;
}
for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
pipe_texture_reference(&ctx->vertex_textures[i], NULL);
}
ctx->pipe->set_vertex_sampler_textures(ctx->pipe,
ctx->nr_vertex_textures,
ctx->vertex_textures);
ctx->nr_vertex_textures_saved = 0;
}
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{

View file

@ -84,6 +84,20 @@ enum pipe_error cso_single_sampler( struct cso_context *cso,
void cso_single_sampler_done( struct cso_context *cso );
void
cso_save_vertex_samplers(struct cso_context *cso);
void
cso_restore_vertex_samplers(struct cso_context *cso);
enum pipe_error
cso_single_vertex_sampler(struct cso_context *cso,
unsigned nr,
const struct pipe_sampler_state *states);
void
cso_single_vertex_sampler_done(struct cso_context *cso);
enum pipe_error cso_set_sampler_textures( struct cso_context *cso,
@ -94,6 +108,17 @@ void cso_restore_sampler_textures( struct cso_context *cso );
enum pipe_error
cso_set_vertex_sampler_textures(struct cso_context *cso,
uint count,
struct pipe_texture **textures);
void
cso_save_vertex_sampler_textures(struct cso_context *cso);
void
cso_restore_sampler_textures(struct cso_context *cso);
/* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't
* (eg mesa's internall-generated texenv programs), it will be up to