From 742e32a40bf5ef1bd90b23aa0f7d451b7b7f0ba3 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 20 Sep 2007 12:34:31 -0400 Subject: [PATCH] Cache the i915 sampler state. --- src/mesa/pipe/i915simple/i915_context.h | 7 +- src/mesa/pipe/i915simple/i915_state.c | 129 ++++++++++++- src/mesa/pipe/i915simple/i915_state_sampler.c | 171 +++--------------- 3 files changed, 156 insertions(+), 151 deletions(-) diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index c582b069d79..f1e10f34332 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -141,6 +141,11 @@ struct i915_rasterizer_state { union { float f; unsigned u; } ds[2]; }; +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + struct i915_context { struct pipe_context pipe; @@ -150,7 +155,7 @@ struct i915_context /* The most recent drawing state as set by the driver: */ const struct i915_blend_state *blend; - const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct i915_depth_stencil_state *depth_stencil; const struct i915_rasterizer_state *rasterizer; const struct pipe_shader_state *fs; diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index c7086c17f5a..525f8ce13a2 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -38,9 +38,79 @@ #include "i915_state.h" #include "i915_state_inlines.h" -/* None of this state is actually used for anything yet. + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. */ +static unsigned +translate_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + return TEXCOORDMODE_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; +// case PIPE_TEX_WRAP_MIRRORED_REPEAT: +// return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} +static unsigned translate_img_filter( unsigned filter ) +{ + switch (filter) { + case PIPE_TEX_FILTER_NEAREST: + return FILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + return FILTER_LINEAR; + default: + assert(0); + return FILTER_NEAREST; + } +} + +static unsigned translate_mip_filter( unsigned filter ) +{ + switch (filter) { + case PIPE_TEX_MIPFILTER_NONE: + return MIPFILTER_NONE; + case PIPE_TEX_MIPFILTER_NEAREST: + return MIPFILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + return MIPFILTER_LINEAR; + default: + assert(0); + return MIPFILTER_NONE; + } +} + +static unsigned translate_compare_func(unsigned func) +{ + switch (func) { + case PIPE_FUNC_NEVER: + case PIPE_FUNC_LESS: + case PIPE_FUNC_EQUAL: + case PIPE_FUNC_LEQUAL: + case PIPE_FUNC_GREATER: + case PIPE_FUNC_NOTEQUAL: + case PIPE_FUNC_GEQUAL: + case PIPE_FUNC_ALWAYS: + return 0; + default: + assert(0); + return 0; + } +} + + +/* None of this state is actually used for anything yet. + */ static void * i915_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) @@ -147,7 +217,59 @@ static void * i915_create_sampler_state(struct pipe_context *pipe, const struct pipe_sampler_state *sampler) { - return 0; + struct i915_sampler_state *cso = calloc(1, sizeof(struct i915_sampler_state)); + cso->templ = sampler; + + const unsigned ws = sampler->wrap_s; + const unsigned wt = sampler->wrap_t; + const unsigned wr = sampler->wrap_r; + unsigned minFilt, magFilt; + unsigned mipFilt; + + mipFilt = translate_mip_filter(sampler->min_mip_filter); + if (sampler->max_anisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + minFilt = translate_img_filter( sampler->min_img_filter ); + magFilt = translate_img_filter( sampler->mag_img_filter ); + } + + { + int b = sampler->lod_bias * 16.0; + b = CLAMP(b, -256, 255); + cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + } + + /* Shadow: + */ + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) + { + cso->state[0] |= (SS2_SHADOW_ENABLE | + translate_compare_func(sampler->compare_func)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + + cso->state[1] |= + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); + + { + ubyte r = float_to_ubyte(sampler->border_color[0]); + ubyte g = float_to_ubyte(sampler->border_color[1]); + ubyte b = float_to_ubyte(sampler->border_color[2]); + ubyte a = float_to_ubyte(sampler->border_color[3]); + cso->state[2] = I915PACKCOLOR8888(r, g, b, a); + } + return cso; } static void i915_bind_sampler_state(struct pipe_context *pipe, @@ -156,7 +278,7 @@ static void i915_bind_sampler_state(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); assert(unit < PIPE_MAX_SAMPLERS); - i915->sampler[unit] = (const struct pipe_sampler_state *)sampler; + i915->sampler[unit] = (const struct i915_sampler_state*)sampler; i915->dirty |= I915_NEW_SAMPLER; } @@ -164,6 +286,7 @@ static void i915_bind_sampler_state(struct pipe_context *pipe, static void i915_delete_sampler_state(struct pipe_context *pipe, void *sampler) { + free(sampler); } diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 419a156136c..ebfd29fadb3 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -42,81 +42,6 @@ #include "i915_state.h" //#include "i915_cache.h" - - - - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static unsigned -translate_wrap_mode(unsigned wrap) -{ - switch (wrap) { - case PIPE_TEX_WRAP_REPEAT: - return TEXCOORDMODE_WRAP; - case PIPE_TEX_WRAP_CLAMP: - return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - return TEXCOORDMODE_CLAMP_EDGE; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return TEXCOORDMODE_CLAMP_BORDER; -// case PIPE_TEX_WRAP_MIRRORED_REPEAT: -// return TEXCOORDMODE_MIRROR; - default: - return TEXCOORDMODE_WRAP; - } -} - -static unsigned translate_img_filter( unsigned filter ) -{ - switch (filter) { - case PIPE_TEX_FILTER_NEAREST: - return FILTER_NEAREST; - case PIPE_TEX_FILTER_LINEAR: - return FILTER_LINEAR; - default: - assert(0); - return FILTER_NEAREST; - } -} - -static unsigned translate_mip_filter( unsigned filter ) -{ - switch (filter) { - case PIPE_TEX_MIPFILTER_NONE: - return MIPFILTER_NONE; - case PIPE_TEX_MIPFILTER_NEAREST: - return MIPFILTER_NEAREST; - case PIPE_TEX_FILTER_LINEAR: - return MIPFILTER_LINEAR; - default: - assert(0); - return MIPFILTER_NONE; - } -} - -static unsigned translate_compare_func(unsigned func) -{ - switch (func) { - case PIPE_FUNC_NEVER: - case PIPE_FUNC_LESS: - case PIPE_FUNC_EQUAL: - case PIPE_FUNC_LEQUAL: - case PIPE_FUNC_GREATER: - case PIPE_FUNC_NOTEQUAL: - case PIPE_FUNC_GEQUAL: - case PIPE_FUNC_ALWAYS: - return 0; - default: - assert(0); - return 0; - } -} - - static uint bitcount(uint k) { @@ -153,60 +78,21 @@ is_power_of_two_texture(const struct pipe_mipmap_tree *mt) */ static void update_sampler(struct i915_context *i915, uint unit, - const struct pipe_sampler_state *sampler, + const struct i915_sampler_state *sampler, const struct pipe_mipmap_tree *mt, unsigned state[3] ) { - const unsigned ws = sampler->wrap_s; - const unsigned wt = sampler->wrap_t; - const unsigned wr = sampler->wrap_r; - /* Need to do this after updating the maps, which call the * intel_finalize_mipmap_tree and hence can update firstLevel: */ - unsigned minFilt, magFilt; - unsigned mipFilt; - - state[0] = state[1] = state[2] = 0; - - mipFilt = translate_mip_filter( sampler->min_mip_filter ); - - if (sampler->max_anisotropy > 1.0) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - minFilt = translate_img_filter( sampler->min_img_filter ); - magFilt = translate_img_filter( sampler->mag_img_filter ); - } - - { - int b = sampler->lod_bias * 16.0; - b = CLAMP(b, -256, 255); - state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); - } + state[0] = sampler->state[0]; + state[1] = sampler->state[1]; + state[2] = sampler->state[2]; if (mt->format == PIPE_FORMAT_YCBCR || mt->format == PIPE_FORMAT_YCBCR_REV) state[0] |= SS2_COLORSPACE_CONVERSION; - - /* Shadow: - */ - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) - { - state[0] |= (SS2_SHADOW_ENABLE | - translate_compare_func(sampler->compare_func)); - - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; - } - - state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | - (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT)); - - /* 3D textures don't seem to respect the border color. * Fallback if there's ever a danger that they might refer to * it. @@ -217,45 +103,36 @@ static void update_sampler(struct i915_context *i915, * XXX: Check if this is true on i945. * XXX: Check if this bug got fixed in release silicon. */ - if (mt->target == PIPE_TEXTURE_3D && - (sampler->min_img_filter != PIPE_TEX_FILTER_NEAREST || - sampler->mag_img_filter != PIPE_TEX_FILTER_NEAREST) && - (ws == PIPE_TEX_WRAP_CLAMP || - wt == PIPE_TEX_WRAP_CLAMP || - wr == PIPE_TEX_WRAP_CLAMP || - ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER || - wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || - wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) { #if 0 - if (i915->strict_conformance) { - assert(0); - /* sampler->fallback = true; */ - /* TODO */ + { + const unsigned ws = sampler->templ->wrap_s; + const unsigned wt = sampler->templ->wrap_t; + const unsigned wr = sampler->templ->wrap_r; + if (mt->target == PIPE_TEXTURE_3D && + (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST || + sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) && + (ws == PIPE_TEX_WRAP_CLAMP || + wt == PIPE_TEX_WRAP_CLAMP || + wr == PIPE_TEX_WRAP_CLAMP || + ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER || + wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || + wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) { + if (i915->strict_conformance) { + assert(0); + /* sampler->fallback = true; */ + /* TODO */ + } } -#endif } +#endif - state[1] = - ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); if (is_power_of_two_texture(mt)) { state[1] |= SS3_NORMALIZED_COORDS; } - - { - ubyte r = float_to_ubyte(sampler->border_color[0]); - ubyte g = float_to_ubyte(sampler->border_color[1]); - ubyte b = float_to_ubyte(sampler->border_color[2]); - ubyte a = float_to_ubyte(sampler->border_color[3]); - state[2] = I915PACKCOLOR8888(r, g, b, a); - } } - - void i915_update_samplers( struct i915_context *i915 ) { uint unit; -- 2.30.2