diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 154 |
2 files changed, 101 insertions, 59 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a5ef058e8ca..fd18fcdc210 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -582,12 +582,6 @@ struct brw_context */ GLuint input_size_masks[4]; - - /** - * Array of sampler state uploaded at sampler_bo of BRW_SAMPLER - * cache - */ - struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; /** Array of surface default colors (texture border color) */ dri_bo *sdc_bo[BRW_MAX_TEX_UNIT]; diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index d410b1e804f..0f59584c6e3 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -91,16 +91,31 @@ static dri_bo *upload_default_color( struct brw_context *brw, } -/* +struct wm_sampler_key { + int sampler_count; + + struct wm_sampler_entry { + GLenum wrap_r, wrap_s, wrap_t; + float maxlod, minlod; + float lod_bias; + float max_aniso; + GLenum minfilter, magfilter; + GLenum comparemode; + dri_bo *sdc_bo; + } sampler[BRW_MAX_TEX_UNIT]; +}; + +/** + * Sets the sampler state for a single unit based off of the sampler key + * entry. */ -static void brw_update_sampler_state( struct gl_texture_unit *texUnit, - struct gl_texture_object *texObj, - dri_bo *sdc_bo, - struct brw_sampler_state *sampler) -{ +static void brw_update_sampler_state(struct wm_sampler_entry *key, + dri_bo *sdc_bo, + struct brw_sampler_state *sampler) +{ _mesa_memset(sampler, 0, sizeof(*sampler)); - switch (texObj->MinFilter) { + switch (key->minfilter) { case GL_NEAREST: sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; @@ -131,17 +146,17 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, /* Set Anisotropy: */ - if ( texObj->MaxAnisotropy > 1.0 ) { + if (key->max_aniso > 1.0) { sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; - if (texObj->MaxAnisotropy > 2.0) { - sampler->ss3.max_aniso = MAX2((texObj->MaxAnisotropy - 2) / 2, + if (key->max_aniso > 2.0) { + sampler->ss3.max_aniso = MAX2((key->max_aniso - 2) / 2, BRW_ANISORATIO_16); } } else { - switch (texObj->MagFilter) { + switch (key->magfilter) { case GL_NEAREST: sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; break; @@ -153,9 +168,9 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, } } - sampler->ss1.r_wrap_mode = translate_wrap_mode(texObj->WrapR); - sampler->ss1.s_wrap_mode = translate_wrap_mode(texObj->WrapS); - sampler->ss1.t_wrap_mode = translate_wrap_mode(texObj->WrapT); + sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r); + sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s); + sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t); /* Fulsim complains if I don't do this. Hardware doesn't mind: */ @@ -169,17 +184,18 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, /* Set shadow function: */ - if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { + if (key->comparemode == GL_COMPARE_R_TO_TEXTURE_ARB) { /* Shadowing is "enabled" by emitting a particular sampler * message (sample_c). So need to recompile WM program when * shadow comparison is enabled on each/any texture unit. */ - sampler->ss0.shadow_function = intel_translate_shadow_compare_func(texObj->CompareFunc); + sampler->ss0.shadow_function = + intel_translate_shadow_compare_func(key->comparemode); } /* Set LOD bias: */ - sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + texObj->LodBias, -16, 15), 6); + sampler->ss0.lod_bias = S_FIXED(CLAMP(key->lod_bias, -16, 15), 6); sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ @@ -193,61 +209,93 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, */ sampler->ss0.base_level = U_FIXED(0, 1); - sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(texObj->MaxLod, 0), 13), 6); - sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(texObj->MinLod, 0), 13), 6); + sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(key->maxlod, 0), 13), 6); + sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(key->minlod, 0), 13), 6); sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */ } - - -/* All samplers must be uploaded in a single contiguous array, which - * complicates various things. However, this is still too confusing - - * FIXME: simplify all the different new texture state flags. - */ -static void upload_wm_samplers( struct brw_context *brw ) +/** Sets up the cache key for sampler state for all texture units */ +static void +brw_wm_sampler_populate_key(struct brw_context *brw, + struct wm_sampler_key *key) { - GLuint unit; - GLuint sampler_count = 0; - dri_bo *reloc_bufs[BRW_MAX_TEX_UNIT]; + int unit; + + memset(key, 0, sizeof(*key)); - /* _NEW_TEXTURE */ for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { - if (brw->attribs.Texture->Unit[unit]._ReallyEnabled) { + if (brw->attribs.Texture->Unit[unit]._ReallyEnabled) { + struct wm_sampler_entry *entry = &key->sampler[unit]; struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[unit]; struct gl_texture_object *texObj = texUnit->_Current; - dri_bo_unreference(brw->wm.sdc_bo[unit]); - brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor); + entry->wrap_r = texObj->WrapR; + entry->wrap_s = texObj->WrapS; + entry->wrap_t = texObj->WrapT; - brw_update_sampler_state(texUnit, - texObj, - brw->wm.sdc_bo[unit], - &brw->wm.sampler[unit]); + entry->maxlod = texObj->MaxLod; + entry->minlod = texObj->MinLod; + entry->lod_bias = texUnit->LodBias + texObj->LodBias; + entry->max_aniso = texObj->MaxAnisotropy; + entry->minfilter = texObj->MinFilter; + entry->magfilter = texObj->MagFilter; + entry->comparemode = texObj->CompareMode; - sampler_count = unit + 1; - } else { dri_bo_unreference(brw->wm.sdc_bo[unit]); - brw->wm.sdc_bo[unit] = NULL; + brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor); + + key->sampler_count = unit + 1; } - reloc_bufs[unit] = brw->wm.sdc_bo[unit]; } - - if (brw->wm.sampler_count != sampler_count) { - brw->wm.sampler_count = sampler_count; +} + +/* All samplers must be uploaded in a single contiguous array, which + * complicates various things. However, this is still too confusing - + * FIXME: simplify all the different new texture state flags. + */ +static void upload_wm_samplers( struct brw_context *brw ) +{ + struct wm_sampler_key key; + int i; + + brw_wm_sampler_populate_key(brw, &key); + + if (brw->wm.sampler_count != key.sampler_count) { + brw->wm.sampler_count = key.sampler_count; brw->state.dirty.cache |= CACHE_NEW_SAMPLER; } dri_bo_unreference(brw->wm.sampler_bo); - if (brw->wm.sampler_count) { - brw->wm.sampler_bo = - brw_cache_data_sz(&brw->cache, BRW_SAMPLER, - brw->wm.sampler, - sizeof(struct brw_sampler_state) * - brw->wm.sampler_count, - reloc_bufs, BRW_MAX_TEX_UNIT); - } else { - brw->wm.sampler_bo = NULL; + brw->wm.sampler_bo = NULL; + if (brw->wm.sampler_count == 0) + return; + + brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + NULL); + + /* If we didnt find it in the cache, compute the state and put it in the + * cache. + */ + if (brw->wm.sampler_bo == NULL) { + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + memset(sampler, 0, sizeof(sampler)); + for (i = 0; i < key.sampler_count; i++) { + if (brw->wm.sdc_bo[i] == NULL) + continue; + + brw_update_sampler_state(&key.sampler[i], brw->wm.sdc_bo[i], + &sampler[i]); + } + + brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + &sampler, sizeof(sampler), + NULL, NULL); } } |