diff options
author | Kenneth Graunke <[email protected]> | 2011-04-28 22:46:15 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2011-05-17 23:33:01 -0700 |
commit | 3f44043da37bcd0c481ceddf4f878ddb3419b763 (patch) | |
tree | 74bb450da46e746b2499f718139f35b256894bba /src/mesa/drivers/dri/i965/gen7_sampler_state.c | |
parent | 3984372104ec6ac5986dedb07b8ca99d53dede18 (diff) |
i965: Fix SAMPLER_STATE on Ivybridge.
Most of this code copied from brw_wm_sampler_state.c.
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/gen7_sampler_state.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/gen7_sampler_state.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen7_sampler_state.c b/src/mesa/drivers/dri/i965/gen7_sampler_state.c new file mode 100644 index 00000000000..75d898e5ad7 --- /dev/null +++ b/src/mesa/drivers/dri/i965/gen7_sampler_state.c @@ -0,0 +1,199 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "intel_batchbuffer.h" + +#include "main/macros.h" +#include "main/samplerobj.h" + +/** + * Sets the sampler state for a single unit. + */ +static void +gen7_update_sampler_state(struct brw_context *brw, int unit, + struct gen7_sampler_state *sampler) +{ + struct intel_context *intel = &brw->intel; + struct gl_context *ctx = &intel->ctx; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *texObj = texUnit->_Current; + struct gl_sampler_object *gl_sampler = _mesa_get_samplerobj(ctx, unit); + + switch (gl_sampler->MinFilter) { + case GL_NEAREST: + sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; + sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; + break; + case GL_LINEAR: + sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; + sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; + sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; + sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; + sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; + sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR; + break; + default: + break; + } + + /* Set Anisotropy: */ + if (gl_sampler->MaxAnisotropy > 1.0) { + sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; + sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; + + if (gl_sampler->MaxAnisotropy > 2.0) { + sampler->ss3.max_aniso = MIN2((gl_sampler->MaxAnisotropy - 2) / 2, + BRW_ANISORATIO_16); + } + } + else { + switch (gl_sampler->MagFilter) { + case GL_NEAREST: + sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; + break; + case GL_LINEAR: + sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + break; + default: + break; + } + } + + sampler->ss3.r_wrap_mode = translate_wrap_mode(gl_sampler->WrapR); + sampler->ss3.s_wrap_mode = translate_wrap_mode(gl_sampler->WrapS); + sampler->ss3.t_wrap_mode = translate_wrap_mode(gl_sampler->WrapT); + + /* Cube-maps on 965 and later must use the same wrap mode for all 3 + * coordinate dimensions. Futher, only CUBE and CLAMP are valid. + */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + if (ctx->Texture.CubeMapSeamless && + (gl_sampler->MinFilter != GL_NEAREST || + gl_sampler->MagFilter != GL_NEAREST)) { + sampler->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CUBE; + sampler->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CUBE; + sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CUBE; + } else { + sampler->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + sampler->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + } + } else if (texObj->Target == GL_TEXTURE_1D) { + /* There's a bug in 1D texture sampling - it actually pays + * attention to the wrap_t value, though it should not. + * Override the wrap_t value here to GL_REPEAT to keep + * any nonexistent border pixels from floating in. + */ + sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; + } + + /* Set shadow function: */ + if (gl_sampler->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->ss1.shadow_function = + intel_translate_shadow_compare_func(gl_sampler->CompareFunc); + } + + /* Set LOD bias: */ + sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + + gl_sampler->LodBias, -16, 15), 6); + + sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ + sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ + + /* Set BaseMipLevel, MaxLOD, MinLOD: + * + * XXX: I don't think that using firstLevel, lastLevel works, + * because we always setup the surface state as if firstLevel == + * level zero. Probably have to subtract firstLevel from each of + * these: + */ + sampler->ss0.base_level = U_FIXED(0, 1); + + sampler->ss1.max_lod = U_FIXED(CLAMP(gl_sampler->MaxLod, 0, 13), 6); + sampler->ss1.min_lod = U_FIXED(CLAMP(gl_sampler->MinLod, 0, 13), 6); + + upload_default_color(brw, gl_sampler, unit); + + sampler->ss2.default_color_pointer = brw->wm.sdc_offset[unit] >> 5; +} + + +/* 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 +gen7_prepare_samplers(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->intel.ctx; + struct gen7_sampler_state *samplers; + int i; + + brw->wm.sampler_count = 0; + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + brw->wm.sampler_count = i + 1; + } + + if (brw->wm.sampler_count == 0) + return; + + samplers = brw_state_batch(brw, brw->wm.sampler_count * sizeof(*samplers), + 32, &brw->wm.sampler_offset); + memset(samplers, 0, brw->wm.sampler_count * sizeof(*samplers)); + + for (i = 0; i < brw->wm.sampler_count; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + gen7_update_sampler_state(brw, i, &samplers[i]); + } + + brw->state.dirty.cache |= CACHE_NEW_SAMPLER; +} + +const struct brw_tracked_state gen7_samplers = { + .dirty = { + .mesa = _NEW_TEXTURE, + .brw = BRW_NEW_BATCH, + .cache = 0 + }, + .prepare = gen7_prepare_samplers, +}; |