brw_wm_sampler_state.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
00003  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
00004  develop this 3D driver.
00005 
00006  Permission is hereby granted, free of charge, to any person obtaining
00007  a copy of this software and associated documentation files (the
00008  "Software"), to deal in the Software without restriction, including
00009  without limitation the rights to use, copy, modify, merge, publish,
00010  distribute, sublicense, and/or sell copies of the Software, and to
00011  permit persons to whom the Software is furnished to do so, subject to
00012  the following conditions:
00013 
00014  The above copyright notice and this permission notice (including the
00015  next paragraph) shall be included in all copies or substantial
00016  portions of the Software.
00017 
00018  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
00022  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026  **********************************************************************/
00027  /*
00028   * Authors:
00029   *   Keith Whitwell <keith@tungstengraphics.com>
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 /* Samplers aren't strictly wm state from the hardware's perspective,
00051  * but that is the only situation in which we use them in this driver.
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 /* The brw (and related graphics cores) do not support GL_CLAMP.  The
00080  * Intel drivers for "other operating systems" implement GL_CLAMP as
00081  * GL_CLAMP_TO_EDGE, so the same is done here.
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; /* conform likes it this way */
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    /* Set Anisotropy:
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    /* Fulsim complains if I don't do this.  Hardware doesn't mind:
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    /* Set shadow function:
00196     */
00197    if (pipe_sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
00198       /* Shadowing is "enabled" by emitting a particular sampler
00199        * message (sample_c).  So need to recompile WM program when
00200        * shadow comparison is enabled on each/any texture unit.
00201        */
00202       sampler->ss0.shadow_function = intel_translate_shadow_compare_func(pipe_sampler->compare_func);
00203    }
00204 
00205    /* Set LOD bias:
00206     */
00207    sampler->ss0.lod_bias = S_FIXED(CLAMP(pipe_sampler->lod_bias, -16, 15), 6);
00208 
00209    sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
00210    sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
00211 
00212    /* Set BaseMipLevel, MaxLOD, MinLOD:
00213     *
00214     * XXX: I don't think that using firstLevel, lastLevel works,
00215     * because we always setup the surface state as if firstLevel ==
00216     * level zero.  Probably have to subtract firstLevel from each of
00217     * these:
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 /* All samplers must be uploaded in a single contiguous array, which
00230  * complicates various things.  However, this is still too confusing -
00231  * FIXME: simplify all the different new texture state flags.
00232  */
00233 static void upload_wm_samplers(struct brw_context *brw)
00234 {
00235    unsigned unit;
00236    unsigned sampler_count = 0;
00237 
00238    /* BRW_NEW_SAMPLER */
00239    for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers;
00240         unit++) {
00241       /* determine unit enable/disable by looking for a bound texture */
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 

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4