00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "brw_context.h"
00034 #include "brw_state.h"
00035 #include "brw_defines.h"
00036
00037 #include "util/u_math.h"
00038 #include "util/u_memory.h"
00039
00040
00041 #define COMPAREFUNC_ALWAYS 0
00042 #define COMPAREFUNC_NEVER 0x1
00043 #define COMPAREFUNC_LESS 0x2
00044 #define COMPAREFUNC_EQUAL 0x3
00045 #define COMPAREFUNC_LEQUAL 0x4
00046 #define COMPAREFUNC_GREATER 0x5
00047 #define COMPAREFUNC_NOTEQUAL 0x6
00048 #define COMPAREFUNC_GEQUAL 0x7
00049
00050
00051
00052
00053
00054 static int intel_translate_shadow_compare_func(unsigned func)
00055 {
00056 switch(func) {
00057 case PIPE_FUNC_NEVER:
00058 return COMPAREFUNC_ALWAYS;
00059 case PIPE_FUNC_LESS:
00060 return COMPAREFUNC_LEQUAL;
00061 case PIPE_FUNC_LEQUAL:
00062 return COMPAREFUNC_LESS;
00063 case PIPE_FUNC_GREATER:
00064 return COMPAREFUNC_GEQUAL;
00065 case PIPE_FUNC_GEQUAL:
00066 return COMPAREFUNC_GREATER;
00067 case PIPE_FUNC_NOTEQUAL:
00068 return COMPAREFUNC_EQUAL;
00069 case PIPE_FUNC_EQUAL:
00070 return COMPAREFUNC_NOTEQUAL;
00071 case PIPE_FUNC_ALWAYS:
00072 return COMPAREFUNC_NEVER;
00073 }
00074
00075 debug_printf("Unknown value in %s: %x\n", __FUNCTION__, func);
00076 return COMPAREFUNC_NEVER;
00077 }
00078
00079
00080
00081
00082
00083 static unsigned translate_wrap_mode( int wrap )
00084 {
00085 switch( wrap ) {
00086 case PIPE_TEX_WRAP_REPEAT:
00087 return BRW_TEXCOORDMODE_WRAP;
00088 case PIPE_TEX_WRAP_CLAMP:
00089 return BRW_TEXCOORDMODE_CLAMP;
00090 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
00091 return BRW_TEXCOORDMODE_CLAMP;
00092 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
00093 return BRW_TEXCOORDMODE_CLAMP_BORDER;
00094 case PIPE_TEX_WRAP_MIRROR_REPEAT:
00095 return BRW_TEXCOORDMODE_MIRROR;
00096 default:
00097 return BRW_TEXCOORDMODE_WRAP;
00098 }
00099 }
00100
00101
00102 static unsigned U_FIXED(float value, unsigned frac_bits)
00103 {
00104 value *= (1<<frac_bits);
00105 return value < 0 ? 0 : value;
00106 }
00107
00108 static int S_FIXED(float value, unsigned frac_bits)
00109 {
00110 return value * (1<<frac_bits);
00111 }
00112
00113
00114 static unsigned upload_default_color( struct brw_context *brw,
00115 const float *color )
00116 {
00117 struct brw_sampler_default_color sdc;
00118
00119 COPY_4V(sdc.color, color);
00120
00121 return brw_cache_data( &brw->cache[BRW_SAMPLER_DEFAULT_COLOR], &sdc );
00122 }
00123
00124
00125
00126
00127 static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_sampler,
00128 unsigned sdc_gs_offset,
00129 struct brw_sampler_state *sampler)
00130 {
00131 memset(sampler, 0, sizeof(*sampler));
00132
00133 switch (pipe_sampler->min_mip_filter) {
00134 case PIPE_TEX_FILTER_NEAREST:
00135 sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
00136 break;
00137 case PIPE_TEX_FILTER_LINEAR:
00138 sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
00139 break;
00140 case PIPE_TEX_FILTER_ANISO:
00141 sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
00142 break;
00143 default:
00144 break;
00145 }
00146
00147 switch (pipe_sampler->min_mip_filter) {
00148 case PIPE_TEX_MIPFILTER_NEAREST:
00149 sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
00150 break;
00151 case PIPE_TEX_MIPFILTER_LINEAR:
00152 sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
00153 break;
00154 case PIPE_TEX_MIPFILTER_NONE:
00155 sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
00156 break;
00157 default:
00158 break;
00159 }
00160
00161
00162 switch (pipe_sampler->mag_img_filter) {
00163 case PIPE_TEX_FILTER_NEAREST:
00164 sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
00165 break;
00166 case PIPE_TEX_FILTER_LINEAR:
00167 sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
00168 break;
00169 case PIPE_TEX_FILTER_ANISO:
00170 sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
00171 break;
00172 default:
00173 break;
00174 }
00175
00176 if (pipe_sampler->max_anisotropy > 2.0) {
00177 sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2,
00178 BRW_ANISORATIO_16);
00179 }
00180
00181 sampler->ss1.s_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_s);
00182 sampler->ss1.r_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_r);
00183 sampler->ss1.t_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_t);
00184
00185
00186
00187 #if 0
00188 if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) {
00189 sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
00190 sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
00191 sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
00192 }
00193 #endif
00194
00195
00196
00197 if (pipe_sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
00198
00199
00200
00201
00202 sampler->ss0.shadow_function = intel_translate_shadow_compare_func(pipe_sampler->compare_func);
00203 }
00204
00205
00206
00207 sampler->ss0.lod_bias = S_FIXED(CLAMP(pipe_sampler->lod_bias, -16, 15), 6);
00208
00209 sampler->ss0.lod_preclamp = 1;
00210 sampler->ss0.default_color_mode = 0;
00211
00212
00213
00214
00215
00216
00217
00218
00219 sampler->ss0.base_level = U_FIXED(0, 1);
00220
00221 sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(pipe_sampler->max_lod, 0), 13), 6);
00222 sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(pipe_sampler->min_lod, 0), 13), 6);
00223
00224 sampler->ss2.default_color_pointer = sdc_gs_offset >> 5;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 static void upload_wm_samplers(struct brw_context *brw)
00234 {
00235 unsigned unit;
00236 unsigned sampler_count = 0;
00237
00238
00239 for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers;
00240 unit++) {
00241
00242 if (brw->attribs.Texture[unit]) {
00243 const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit];
00244 unsigned sdc_gs_offset = upload_default_color(brw, sampler->border_color);
00245
00246 brw_update_sampler_state(sampler,
00247 sdc_gs_offset,
00248 &brw->wm.sampler[unit]);
00249
00250 sampler_count = unit + 1;
00251 }
00252 }
00253
00254 if (brw->wm.sampler_count != sampler_count) {
00255 brw->wm.sampler_count = sampler_count;
00256 brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
00257 }
00258
00259 brw->wm.sampler_gs_offset = 0;
00260
00261 if (brw->wm.sampler_count)
00262 brw->wm.sampler_gs_offset =
00263 brw_cache_data_sz(&brw->cache[BRW_SAMPLER],
00264 brw->wm.sampler,
00265 sizeof(struct brw_sampler_state) * brw->wm.sampler_count);
00266 }
00267
00268 const struct brw_tracked_state brw_wm_samplers = {
00269 .dirty = {
00270 .brw = BRW_NEW_SAMPLER,
00271 .cache = 0
00272 },
00273 .update = upload_wm_samplers
00274 };
00275