diff options
author | Keith Whitwell <[email protected]> | 2009-08-21 17:13:11 +0100 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2009-08-21 18:14:19 +0100 |
commit | 4fc7d0345a18042a79686940fb7cc4e698cc9192 (patch) | |
tree | b039e7d5e5e673a8677926050df0648c17bfd0fc /src/gallium/drivers/softpipe/sp_state_sampler.c | |
parent | b1cc196e6d18494348c2974aad5d85d1b8281ce0 (diff) |
softpipe: rework texture sampling code
Split into component pieces, stitch together at runtime using function
pointers. Make it possible to utilize the existing fastpaths as image-level
filters for generic mip-filtering routines.
Remove special case for rectangle filtering, as it can now be handled by
the 2d path.
As most of the mesa demo texturing was already covered by fast paths, its
harder to find examples of speedups, but tunnel gets a boost as mip-nearest
filtering is now able to access the img_2d_linear_wrap_POT functions
for sampling within a mipmap level.
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_state_sampler.c')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_sampler.c | 104 |
1 files changed, 103 insertions, 1 deletions
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index aa2f3f2ccd6..714e6380487 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -38,15 +38,32 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "sp_tex_sample.h" #include "draw/draw_context.h" +struct sp_sampler { + struct pipe_sampler_state base; + struct sp_sampler_varient *varients; + struct sp_sampler_varient *current; +}; + +static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler ) +{ + return (struct sp_sampler *)sampler; +} + void * softpipe_create_sampler_state(struct pipe_context *pipe, const struct pipe_sampler_state *sampler) { - return mem_dup(sampler, sizeof(*sampler)); + struct sp_sampler *sp_sampler = CALLOC_STRUCT(sp_sampler); + + sp_sampler->base = *sampler; + sp_sampler->varients = NULL; + + return (void *)sp_sampler; } @@ -106,10 +123,95 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, } + +static struct sp_sampler_varient * +get_sampler_varient( struct sp_sampler *sampler, + struct pipe_texture *texture, + unsigned processor ) +{ + struct softpipe_texture *sp_texture = softpipe_texture(texture); + struct sp_sampler_varient *v = NULL; + union sp_sampler_key key; + + key.bits.target = sp_texture->base.target; + key.bits.is_pot = sp_texture->pot; + key.bits.processor = processor; + key.bits.pad = 0; + + if (sampler->current && + key.value == sampler->current->key.value) { + v = sampler->current; + } + + if (v == NULL) { + for (v = sampler->varients; v; v = v->next) + if (v->key.value == key.value) + break; + + if (v == NULL) { + v = sp_create_sampler_varient( &sampler->base, key ); + v->next = sampler->varients; + sampler->varients = v; + } + } + + sampler->current = v; + return v; +} + + + + +void +softpipe_reset_sampler_varients(struct softpipe_context *softpipe) +{ + int i; + + /* It's a bit hard to build these samplers ahead of time -- don't + * really know which samplers are going to be used for vertex and + * fragment programs. + */ + for (i = 0; i <= softpipe->vs->max_sampler; i++) { + if (softpipe->sampler[i]) { + softpipe->tgsi.vert_samplers_list[i] = + get_sampler_varient( sp_sampler(softpipe->sampler[i]), + softpipe->texture[i], + TGSI_PROCESSOR_VERTEX ); + + sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], + softpipe->tex_cache[i], + softpipe->texture[i] ); + } + } + + for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { + if (softpipe->sampler[i]) { + softpipe->tgsi.frag_samplers_list[i] = + get_sampler_varient( sp_sampler(softpipe->sampler[i]), + softpipe->texture[i], + TGSI_PROCESSOR_FRAGMENT ); + + sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], + softpipe->tex_cache[i], + softpipe->texture[i] ); + } + } +} + + + void softpipe_delete_sampler_state(struct pipe_context *pipe, void *sampler) { + struct sp_sampler *sp_sampler = (struct sp_sampler *)sampler; + struct sp_sampler_varient *v, *tmp; + + for (v = sp_sampler->varients; v; v = tmp) { + tmp = v->next; + sp_sampler_varient_destroy(v); + } + FREE( sampler ); } |