Switch the sample to be an immutable state object.
switch(type) {
case CSO_BLEND:
hash = sc->blend_hash;
+ case CSO_SAMPLER:
+ hash = sc->sampler_hash;
}
return hash;
switch(type) {
case CSO_BLEND:
return sizeof(struct pipe_blend_state);
+ case CSO_SAMPLER:
+ return sizeof(struct pipe_sampler_state);
}
return 0;
}
struct cso_cache *sc = malloc(sizeof(struct cso_cache));
sc->blend_hash = cso_hash_create();
+ sc->sampler_hash = cso_hash_create();
return sc;
}
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);
}
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);
/* 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;
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];
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<<unit);
- failover->hw->set_sampler_state( failover->hw, unit, sampler );
+ failover->hw->bind_sampler_state( failover->hw, unit, sampler );
}
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;
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;
if (failover->dirty & FO_NEW_SAMPLER) {
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
if (failover->dirty_sampler & (1<<i)) {
- failover->sw->set_sampler_state( failover->sw, i,
- &failover->sampler[i] );
+ failover->sw->bind_sampler_state( failover->sw, i,
+ failover->sampler[i] );
}
}
}
/* 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;
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];
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));
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,
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.
}
-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)
/* 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,
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;
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;
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 */
);
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 * );
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 * );
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;
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;
/* 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;
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];
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 * );
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 * );
+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,
#include "st_context.h"
+#include "st_cache.h"
#include "st_atom.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
/* 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);
}
}
}
}
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));
+}
#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
#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"
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 */
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);
* 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;
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;