diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_sampler_state.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 178 |
1 files changed, 125 insertions, 53 deletions
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 93d4cfc3a5..e1db31ec08 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -34,7 +34,7 @@ #include "brw_state.h" #include "brw_defines.h" -#include "macros.h" +#include "main/macros.h" @@ -54,7 +54,7 @@ static GLuint translate_wrap_mode( GLenum wrap ) case GL_REPEAT: return BRW_TEXCOORDMODE_WRAP; case GL_CLAMP: - return BRW_TEXCOORDMODE_CLAMP_BORDER; /* conform likes it this way */ + return BRW_TEXCOORDMODE_CLAMP; case GL_CLAMP_TO_EDGE: return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */ case GL_CLAMP_TO_BORDER: @@ -79,27 +79,43 @@ static GLint S_FIXED(GLfloat value, GLuint frac_bits) } -static GLuint upload_default_color( struct brw_context *brw, - const GLfloat *color ) +static dri_bo *upload_default_color( struct brw_context *brw, + const GLfloat *color ) { struct brw_sampler_default_color sdc; COPY_4V(sdc.color, color); - return brw_cache_data( &brw->cache[BRW_SAMPLER_DEFAULT_COLOR], &sdc ); + return brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc, + NULL, 0 ); } -/* +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, comparefunc; + 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, - GLuint sdc_gs_offset, - 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; @@ -130,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; @@ -152,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: */ @@ -168,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_compare_func(texObj->CompareFunc); + sampler->ss0.shadow_function = + intel_translate_shadow_compare_func(key->comparefunc); } /* Set LOD bias: */ - sampler->ss0.lod_bias = S_FIXED(texUnit->LodBias + texObj->LodBias, 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 */ @@ -192,54 +209,109 @@ 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(MAX2(texObj->MaxLod, 0), 6); - sampler->ss1.min_lod = U_FIXED(MAX2(texObj->MinLod, 0), 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_gs_offset >> 5; + 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; + 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; - GLuint sdc_gs_offset = 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, - sdc_gs_offset, - &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; + entry->comparefunc = texObj->CompareFunc; - sampler_count = unit + 1; + dri_bo_unreference(brw->wm.sdc_bo[unit]); + brw->wm.sdc_bo[unit] = upload_default_color(brw, texObj->BorderColor); + + key->sampler_count = unit + 1; } } - - 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; } - brw->wm.sampler_gs_offset = 0; + dri_bo_unreference(brw->wm.sampler_bo); + brw->wm.sampler_bo = NULL; + if (brw->wm.sampler_count == 0) + return; - if (brw->wm.sampler_count) - brw->wm.sampler_gs_offset = - brw_cache_data_sz(&brw->cache[BRW_SAMPLER], - brw->wm.sampler, - sizeof(struct brw_sampler_state) * brw->wm.sampler_count); -} + 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); + + /* Emit SDC relocations */ + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + if (!brw->attribs.Texture->Unit[i]._ReallyEnabled) + continue; + + dri_bo_emit_reloc(brw->wm.sampler_bo, + I915_GEM_DOMAIN_INSTRUCTION, 0, + 0, + i * sizeof(struct brw_sampler_state) + + offsetof(struct brw_sampler_state, ss2), + brw->wm.sdc_bo[i]); + } + } +} const struct brw_tracked_state brw_wm_samplers = { .dirty = { @@ -247,7 +319,7 @@ const struct brw_tracked_state brw_wm_samplers = { .brw = 0, .cache = 0 }, - .update = upload_wm_samplers + .prepare = upload_wm_samplers, }; |