From: Zack Rusin Date: Mon, 17 Sep 2007 13:47:41 +0000 (-0400) Subject: Make sampler an immutable state object. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f117327a3f246713abfd4dc4320d4a1a7f1b811a;p=mesa.git Make sampler an immutable state object. Switch the sample to be an immutable state object. --- diff --git a/src/mesa/cso_cache/cso_cache.c b/src/mesa/cso_cache/cso_cache.c index 784d1f970f4..61da5905754 100644 --- a/src/mesa/cso_cache/cso_cache.c +++ b/src/mesa/cso_cache/cso_cache.c @@ -74,6 +74,8 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_ switch(type) { case CSO_BLEND: hash = sc->blend_hash; + case CSO_SAMPLER: + hash = sc->sampler_hash; } return hash; @@ -84,6 +86,8 @@ static int _cso_size_for_type(enum cso_cache_type type) switch(type) { case CSO_BLEND: return sizeof(struct pipe_blend_state); + case CSO_SAMPLER: + return sizeof(struct pipe_sampler_state); } return 0; } @@ -133,6 +137,7 @@ struct cso_cache *cso_cache_create(void) struct cso_cache *sc = malloc(sizeof(struct cso_cache)); sc->blend_hash = cso_hash_create(); + sc->sampler_hash = cso_hash_create(); return sc; } @@ -140,8 +145,8 @@ struct cso_cache *cso_cache_create(void) void cso_cache_delete(struct cso_cache *sc) { assert(sc); - assert(sc->blend_hash); cso_hash_delete(sc->blend_hash); + cso_hash_delete(sc->sampler_hash); free(sc); } diff --git a/src/mesa/cso_cache/cso_cache.h b/src/mesa/cso_cache/cso_cache.h index c022b98d436..05a4cfcbdda 100644 --- a/src/mesa/cso_cache/cso_cache.h +++ b/src/mesa/cso_cache/cso_cache.h @@ -41,10 +41,12 @@ struct cso_hash; struct cso_cache { struct cso_hash *blend_hash; + struct cso_hash *sampler_hash; }; enum cso_cache_type { CSO_BLEND, + CSO_SAMPLER }; unsigned cso_construct_key(void *item, int item_size); diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index b065aa832a4..fa336193a8d 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -68,6 +68,7 @@ struct failover_context { /* The most recent drawing state as set by the driver: */ const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; @@ -79,7 +80,6 @@ struct failover_context { struct pipe_shader_state vertex_shader; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct pipe_setup_state setup; struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index 2357d7ef5ce..f3a99e41989 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -196,16 +196,16 @@ failover_set_stencil_state(struct pipe_context *pipe, static void -failover_set_sampler_state(struct pipe_context *pipe, +failover_bind_sampler_state(struct pipe_context *pipe, unsigned unit, const struct pipe_sampler_state *sampler) { struct failover_context *failover = failover_context(pipe); - failover->sampler[unit] = *sampler; + failover->sampler[unit] = sampler; failover->dirty |= FO_NEW_SAMPLER; failover->dirty_sampler |= (1<hw->set_sampler_state( failover->hw, unit, sampler ); + failover->hw->bind_sampler_state( failover->hw, unit, sampler ); } @@ -267,6 +267,7 @@ void failover_init_state_functions( struct failover_context *failover ) { failover->pipe.bind_blend_state = failover_bind_blend_state; + failover->pipe.bind_sampler_state = failover_bind_sampler_state; failover->pipe.set_alpha_test_state = failover_set_alpha_test_state; failover->pipe.set_blend_color = failover_set_blend_color; @@ -277,7 +278,6 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_fs_state = failover_set_fs_state; failover->pipe.set_vs_state = failover_set_vs_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; - failover->pipe.set_sampler_state = failover_set_sampler_state; failover->pipe.set_scissor_state = failover_set_scissor_state; failover->pipe.set_setup_state = failover_set_setup_state; failover->pipe.set_stencil_state = failover_set_stencil_state; diff --git a/src/mesa/pipe/failover/fo_state_emit.c b/src/mesa/pipe/failover/fo_state_emit.c index 77413d100b3..9d462678c5d 100644 --- a/src/mesa/pipe/failover/fo_state_emit.c +++ b/src/mesa/pipe/failover/fo_state_emit.c @@ -100,8 +100,8 @@ failover_state_emit( struct failover_context *failover ) if (failover->dirty & FO_NEW_SAMPLER) { for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { if (failover->dirty_sampler & (1<sw->set_sampler_state( failover->sw, i, - &failover->sampler[i] ); + failover->sw->bind_sampler_state( failover->sw, i, + failover->sampler[i] ); } } } diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index 215c5294fa6..51baa281ec5 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -123,7 +123,8 @@ struct i915_context /* The most recent drawing state as set by the driver: */ - const struct pipe_blend_state *blend; + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; @@ -135,7 +136,6 @@ struct i915_context struct pipe_shader_state fs; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct pipe_setup_state setup; struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 478988fd4a9..10060b45a4f 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -42,8 +42,6 @@ static const struct pipe_blend_state * i915_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) { - /*struct i915_context *i915 = i915_context(pipe);*/ - struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state)); memcpy(new_blend, blend, sizeof(struct pipe_blend_state)); @@ -62,10 +60,9 @@ static void i915_bind_blend_state( struct pipe_context *pipe, static void i915_delete_blend_state( struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + const struct pipe_blend_state *blend ) { - /*struct i915_context *i915 = i915_context(pipe);*/ - free(blend); + free((void*)blend); } static void i915_set_blend_color( struct pipe_context *pipe, @@ -78,6 +75,34 @@ static void i915_set_blend_color( struct pipe_context *pipe, i915->dirty |= I915_NEW_BLEND; } +static const struct pipe_sampler_state * +i915_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + struct pipe_sampler_state *new_sampler = malloc(sizeof(struct pipe_sampler_state)); + memcpy(new_sampler, sampler, sizeof(struct pipe_sampler_state)); + + return new_sampler; +} + +static void i915_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, + const struct pipe_sampler_state *sampler) +{ + struct i915_context *i915 = i915_context(pipe); + + assert(unit < PIPE_MAX_SAMPLERS); + i915->sampler[unit] = sampler; + + i915->dirty |= I915_NEW_SAMPLER; +} + +static void i915_delete_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + free((struct pipe_sampler_state*)sampler); +} + /** XXX move someday? Or consolidate all these simple state setters * into one file. @@ -189,19 +214,6 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } -static void i915_set_sampler_state(struct pipe_context *pipe, - unsigned unit, - const struct pipe_sampler_state *sampler) -{ - struct i915_context *i915 = i915_context(pipe); - - assert(unit < PIPE_MAX_SAMPLERS); - i915->sampler[unit] = *sampler; - - i915->dirty |= I915_NEW_SAMPLER; -} - - static void i915_set_texture_state(struct pipe_context *pipe, unsigned unit, struct pipe_mipmap_tree *texture) @@ -293,7 +305,6 @@ static void i915_set_vertex_buffer( struct pipe_context *pipe, /* pass-through to draw module */ draw_set_vertex_buffer(i915->draw, index, buffer); } - static void i915_set_vertex_element( struct pipe_context *pipe, unsigned index, @@ -313,6 +324,10 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.bind_blend_state = i915_bind_blend_state; i915->pipe.delete_blend_state = i915_delete_blend_state; + i915->pipe.create_sampler_state = i915_create_sampler_state; + i915->pipe.bind_sampler_state = i915_bind_sampler_state; + i915->pipe.delete_sampler_state = i915_delete_sampler_state; + i915->pipe.set_alpha_test_state = i915_set_alpha_test_state; i915->pipe.set_blend_color = i915_set_blend_color; i915->pipe.set_clip_state = i915_set_clip_state; @@ -323,7 +338,6 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_fs_state = i915_set_fs_state; i915->pipe.set_vs_state = i915_set_vs_state; i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; - i915->pipe.set_sampler_state = i915_set_sampler_state; i915->pipe.set_scissor_state = i915_set_scissor_state; i915->pipe.set_setup_state = i915_set_setup_state; i915->pipe.set_stencil_state = i915_set_stencil_state; diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 7a595d10229..419a156136c 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -269,7 +269,7 @@ void i915_update_samplers( struct i915_context *i915 ) if (i915->texture[unit]) { update_sampler( i915, unit, - i915->sampler + unit, /* sampler state */ + i915->sampler[unit], /* sampler state */ i915->texture[unit], /* mipmap tree */ i915->current.sampler[unit] /* the result */ ); diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index b9af69fc050..0913e490967 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -92,6 +92,15 @@ struct pipe_context { void (*delete_blend_state)(struct pipe_context *, const struct pipe_blend_state *); + const struct pipe_sampler_state * (*create_sampler_state)( + struct pipe_context *, + const struct pipe_sampler_state *); + void (*bind_sampler_state)(struct pipe_context *, + unsigned unit, + const struct pipe_sampler_state *); + void (*delete_sampler_state)(struct pipe_context *, + const struct pipe_sampler_state *); + void (*set_alpha_test_state)( struct pipe_context *, const struct pipe_alpha_test_state * ); @@ -135,10 +144,6 @@ struct pipe_context { void (*set_stencil_state)( struct pipe_context *, const struct pipe_stencil_state * ); - void (*set_sampler_state)( struct pipe_context *, - unsigned unit, - const struct pipe_sampler_state * ); - void (*set_texture_state)( struct pipe_context *, unsigned unit, struct pipe_mipmap_tree * ); diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index b9c7013e9e1..bab7985e8d1 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -253,6 +253,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.create_blend_state = softpipe_create_blend_state; softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; @@ -265,7 +268,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.set_fs_state = softpipe_set_fs_state; softpipe->pipe.set_vs_state = softpipe_set_vs_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; - softpipe->pipe.set_sampler_state = softpipe_set_sampler_state; softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; softpipe->pipe.set_setup_state = softpipe_set_setup_state; softpipe->pipe.set_stencil_state = softpipe_set_stencil_state; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 7fecf2974ac..5cee1a3cf93 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -71,7 +71,8 @@ struct softpipe_context { /* The most recent drawing state as set by the driver: */ - const struct pipe_blend_state *blend; + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; @@ -85,7 +86,6 @@ struct softpipe_context { struct pipe_shader_state vs; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct pipe_setup_state setup; struct pipe_stencil_state stencil; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index e2b1a2a1641..c8c93709dbc 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -41,6 +41,15 @@ void softpipe_bind_blend_state(struct pipe_context *, void softpipe_delete_blend_state(struct pipe_context *, const struct pipe_blend_state *); +const struct pipe_sampler_state * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_state(struct pipe_context *, + unsigned, + const struct pipe_sampler_state *); +void softpipe_delete_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); + void softpipe_set_framebuffer_state( struct pipe_context *, const struct pipe_framebuffer_state * ); @@ -81,10 +90,6 @@ void softpipe_set_scissor_state( struct pipe_context *, void softpipe_set_setup_state( struct pipe_context *, const struct pipe_setup_state * ); -void softpipe_set_sampler_state( struct pipe_context *, - unsigned unit, - const struct pipe_sampler_state * ); - void softpipe_set_stencil_state( struct pipe_context *, const struct pipe_stencil_state * ); diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 2e3d0c3d65d..09898eb5790 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -34,20 +34,38 @@ +const struct pipe_sampler_state * +softpipe_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + struct pipe_sampler_state *new_sampler = malloc(sizeof(struct pipe_sampler_state)); + memcpy(new_sampler, sampler, sizeof(struct pipe_sampler_state)); + + return new_sampler; +} + void -softpipe_set_sampler_state(struct pipe_context *pipe, - unsigned unit, - const struct pipe_sampler_state *sampler) +softpipe_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, + const struct pipe_sampler_state *sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); assert(unit < PIPE_MAX_SAMPLERS); - softpipe->sampler[unit] = *sampler; + softpipe->sampler[unit] = sampler; softpipe->dirty |= SP_NEW_SAMPLER; } +void +softpipe_delete_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + free((struct pipe_sampler_state*)sampler); +} + + void softpipe_set_texture_state(struct pipe_context *pipe, unsigned unit, diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index d65565f991d..9a728e2d791 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -33,6 +33,7 @@ #include "st_context.h" +#include "st_cache.h" #include "st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -142,10 +143,13 @@ update_samplers(struct st_context *st) /* XXX more sampler state here */ } - if (memcmp(&sampler, &st->state.sampler[u], sizeof(sampler)) != 0) { + const struct pipe_sampler_state *cached_sampler = + st_cached_sampler_state(st, &sampler); + + if (cached_sampler == st->state.sampler[u]) { /* state has changed */ - st->state.sampler[u] = sampler; - st->pipe->set_sampler_state(st->pipe, u, &sampler); + st->state.sampler[u] = cached_sampler; + st->pipe->bind_sampler_state(st->pipe, u, cached_sampler); } } } diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c index 0205b1cab32..99fb45f00a6 100644 --- a/src/mesa/state_tracker/st_cache.c +++ b/src/mesa/state_tracker/st_cache.c @@ -59,3 +59,20 @@ struct pipe_blend_state * st_cached_blend_state( } return (struct pipe_blend_state*)(cso_hash_iter_data(iter)); } + +struct pipe_sampler_state * st_cached_sampler_state( + struct st_context *st, + const struct pipe_sampler_state *sampler) +{ + unsigned hash_key = cso_construct_key((void*)sampler, sizeof(struct pipe_sampler_state)); + struct cso_hash_iter iter = cso_find_state_template(st->cache, + hash_key, CSO_SAMPLER, + (void*)sampler); + if (cso_hash_iter_is_null(iter)) { + const struct pipe_sampler_state *created_state = st->pipe->create_sampler_state( + st->pipe, sampler); + iter = cso_insert_state(st->cache, hash_key, CSO_SAMPLER, + (void*)created_state); + } + return (struct pipe_sampler_state*)(cso_hash_iter_data(iter)); +} diff --git a/src/mesa/state_tracker/st_cache.h b/src/mesa/state_tracker/st_cache.h index 29b1d00dca1..927585141c6 100644 --- a/src/mesa/state_tracker/st_cache.h +++ b/src/mesa/state_tracker/st_cache.h @@ -34,10 +34,16 @@ #define ST_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); +struct pipe_sampler_state * st_cached_sampler_state( + struct st_context *st, + const struct pipe_sampler_state *sampler); + + #endif diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c2d231cdb5d..31a37e5cd4c 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -34,6 +34,7 @@ #include "st_context.h" #include "st_atom.h" +#include "st_cache.h" #include "st_draw.h" #include "st_program.h" #include "st_cb_drawpixels.h" @@ -359,7 +360,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - pipe->set_sampler_state(pipe, unit, &sampler); + const struct pipe_sampler_state *state = st_cached_sampler_state(ctx->st, &sampler); + pipe->bind_sampler_state(pipe, unit, state); } /* viewport state: viewport matching window dims */ @@ -402,7 +404,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->set_fs_state(pipe, &ctx->st->state.fs); pipe->set_vs_state(pipe, &ctx->st->state.vs); pipe->set_texture_state(pipe, unit, ctx->st->state.texture[unit]); - pipe->set_sampler_state(pipe, unit, &ctx->st->state.sampler[unit]); + pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]); pipe->set_viewport_state(pipe, &ctx->st->state.viewport); free_mipmap_tree(pipe, mt); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index bd2efdb960b..13526ff9e7c 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -74,7 +74,8 @@ struct st_context * though, we just shove random objects across the interface. */ struct { - const struct pipe_blend_state *blend; + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; @@ -86,7 +87,6 @@ struct st_context struct pipe_framebuffer_state framebuffer; struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_poly_stipple poly_stipple; - struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; struct pipe_setup_state setup; struct pipe_shader_state fs;