i915_state_sampler.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * 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, sub license, 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 portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 #include "pipe/p_context.h"
00029 #include "pipe/p_state.h"
00030 #include "util/u_memory.h"
00031 
00032 #include "i915_state_inlines.h"
00033 #include "i915_context.h"
00034 #include "i915_reg.h"
00035 #include "i915_state.h"
00036 
00037 
00038 /*
00039  * A note about min_lod & max_lod.
00040  *
00041  * There is a circular dependancy between the sampler state
00042  * and the map state to be submitted to hw.
00043  *
00044  * Two condition must be meet:
00045  * min_lod =< max_lod == true
00046  * max_lod =< last_level == true
00047  *
00048  *
00049  * This is all fine and dandy if it where for the fact that max_lod
00050  * is set on the map state instead of the sampler state. That is
00051  * the max_lod we submit on map is:
00052  * max_lod = MIN2(last_level, max_lod);
00053  *
00054  * So we need to update the map state when we change samplers and
00055  * we need to be change the sampler state when map state is changed.
00056  * The first part is done by calling i915_update_texture in
00057  * i915_update_samplers and the second part is done else where in
00058  * code tracking the state changes.
00059  */
00060 
00061 static void
00062 i915_update_texture(struct i915_context *i915,
00063                     uint unit,
00064                     const struct i915_texture *tex,
00065                     const struct i915_sampler_state *sampler,
00066                     uint state[6]);
00075 static void update_sampler(struct i915_context *i915,
00076                            uint unit,
00077                            const struct i915_sampler_state *sampler,
00078                            const struct i915_texture *tex,
00079                            unsigned state[3] )
00080 {
00081    const struct pipe_texture *pt = &tex->base;
00082    unsigned minlod, lastlod;
00083 
00084    /* Need to do this after updating the maps, which call the
00085     * intel_finalize_mipmap_tree and hence can update firstLevel:
00086     */
00087    state[0] = sampler->state[0];
00088    state[1] = sampler->state[1];
00089    state[2] = sampler->state[2];
00090 
00091    if (pt->format == PIPE_FORMAT_YCBCR ||
00092        pt->format == PIPE_FORMAT_YCBCR_REV)
00093       state[0] |= SS2_COLORSPACE_CONVERSION;
00094 
00095    /* 3D textures don't seem to respect the border color.
00096     * Fallback if there's ever a danger that they might refer to
00097     * it.  
00098     * 
00099     * Effectively this means fallback on 3D clamp or
00100     * clamp_to_border.
00101     *
00102     * XXX: Check if this is true on i945.  
00103     * XXX: Check if this bug got fixed in release silicon.
00104     */
00105 #if 0
00106    {
00107       const unsigned ws = sampler->templ->wrap_s;
00108       const unsigned wt = sampler->templ->wrap_t;
00109       const unsigned wr = sampler->templ->wrap_r;
00110       if (pt->target == PIPE_TEXTURE_3D &&
00111           (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
00112            sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
00113           (ws == PIPE_TEX_WRAP_CLAMP ||
00114            wt == PIPE_TEX_WRAP_CLAMP ||
00115            wr == PIPE_TEX_WRAP_CLAMP ||
00116            ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
00117            wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || 
00118            wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) {
00119          if (i915->strict_conformance) {
00120             assert(0);
00121             /*      sampler->fallback = true; */
00122             /* TODO */
00123          }
00124       }
00125    }
00126 #endif
00127 
00128    /* See note at the top of file */
00129    minlod = sampler->minlod;
00130    lastlod = pt->last_level << 4;
00131 
00132    if (lastlod < minlod) {
00133       minlod = lastlod;
00134    }
00135 
00136    state[1] |= (sampler->minlod << SS3_MIN_LOD_SHIFT);
00137    state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
00138 }
00139 
00140 
00141 void i915_update_samplers( struct i915_context *i915 )
00142 {
00143    uint unit;
00144 
00145    i915->current.sampler_enable_nr = 0;
00146    i915->current.sampler_enable_flags = 0x0;
00147 
00148    for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
00149         unit++) {
00150       /* determine unit enable/disable by looking for a bound texture */
00151       /* could also examine the fragment program? */
00152       if (i915->texture[unit]) {
00153          update_sampler( i915,
00154                          unit,
00155                          i915->sampler[unit],       /* sampler state */
00156                          i915->texture[unit],        /* texture */
00157                          i915->current.sampler[unit] /* the result */
00158                          );
00159          i915_update_texture( i915,
00160                               unit,
00161                               i915->texture[unit],          /* texture */
00162                               i915->sampler[unit],          /* sampler state */
00163                               i915->current.texbuffer[unit] );
00164 
00165          i915->current.sampler_enable_nr++;
00166          i915->current.sampler_enable_flags |= (1 << unit);
00167       }
00168    }
00169 
00170    i915->hardware_dirty |= I915_HW_SAMPLER | I915_HW_MAP;
00171 }
00172 
00173 
00174 static uint
00175 translate_texture_format(enum pipe_format pipeFormat)
00176 {
00177    switch (pipeFormat) {
00178    case PIPE_FORMAT_L8_UNORM:
00179       return MAPSURF_8BIT | MT_8BIT_L8;
00180    case PIPE_FORMAT_I8_UNORM:
00181       return MAPSURF_8BIT | MT_8BIT_I8;
00182    case PIPE_FORMAT_A8_UNORM:
00183       return MAPSURF_8BIT | MT_8BIT_A8;
00184    case PIPE_FORMAT_A8L8_UNORM:
00185       return MAPSURF_16BIT | MT_16BIT_AY88;
00186    case PIPE_FORMAT_R5G6B5_UNORM:
00187       return MAPSURF_16BIT | MT_16BIT_RGB565;
00188    case PIPE_FORMAT_A1R5G5B5_UNORM:
00189       return MAPSURF_16BIT | MT_16BIT_ARGB1555;
00190    case PIPE_FORMAT_A4R4G4B4_UNORM:
00191       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
00192    case PIPE_FORMAT_A8R8G8B8_UNORM:
00193       return MAPSURF_32BIT | MT_32BIT_ARGB8888;
00194    case PIPE_FORMAT_YCBCR_REV:
00195       return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
00196    case PIPE_FORMAT_YCBCR:
00197       return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
00198 #if 0
00199    case PIPE_FORMAT_RGB_FXT1:
00200    case PIPE_FORMAT_RGBA_FXT1:
00201       return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
00202 #endif
00203    case PIPE_FORMAT_Z16_UNORM:
00204       return (MAPSURF_16BIT | MT_16BIT_L16);
00205 #if 0
00206    case PIPE_FORMAT_RGBA_DXT1:
00207    case PIPE_FORMAT_RGB_DXT1:
00208       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
00209    case PIPE_FORMAT_RGBA_DXT3:
00210       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
00211    case PIPE_FORMAT_RGBA_DXT5:
00212       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
00213 #endif
00214    case PIPE_FORMAT_S8Z24_UNORM:
00215       return (MAPSURF_32BIT | MT_32BIT_xI824);
00216    default:
00217       debug_printf("i915: translate_texture_format() bad image format %x\n",
00218               pipeFormat);
00219       assert(0);
00220       return 0;
00221    }
00222 }
00223 
00224 
00225 static void
00226 i915_update_texture(struct i915_context *i915,
00227                     uint unit,
00228                     const struct i915_texture *tex,
00229                     const struct i915_sampler_state *sampler,
00230                     uint state[6])
00231 {
00232    const struct pipe_texture *pt = &tex->base;
00233    uint format, pitch;
00234    const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
00235    const uint num_levels = pt->last_level;
00236    unsigned max_lod = num_levels * 4;
00237    unsigned tiled = MS3_USE_FENCE_REGS;
00238 
00239    assert(tex);
00240    assert(width);
00241    assert(height);
00242    assert(depth);
00243 
00244    format = translate_texture_format(pt->format);
00245    pitch = tex->stride;
00246 
00247    assert(format);
00248    assert(pitch);
00249 
00250    if (tex->tiled) {
00251       assert(!((pitch - 1) & pitch));
00252       tiled = MS3_TILED_SURFACE;
00253    }
00254 
00255    /* MS3 state */
00256    state[0] =
00257       (((height - 1) << MS3_HEIGHT_SHIFT)
00258        | ((width - 1) << MS3_WIDTH_SHIFT)
00259        | format
00260        | tiled);
00261 
00262    /*
00263     * XXX When min_filter != mag_filter and there's just one mipmap level,
00264     * set max_lod = 1 to make sure i915 chooses between min/mag filtering.
00265     */
00266 
00267    /* See note at the top of file */
00268    if (max_lod > (sampler->maxlod >> 2))
00269       max_lod = sampler->maxlod >> 2;
00270 
00271    /* MS4 state */
00272    state[1] =
00273       ((((pitch / 4) - 1) << MS4_PITCH_SHIFT)
00274        | MS4_CUBE_FACE_ENA_MASK
00275        | ((max_lod) << MS4_MAX_LOD_SHIFT)
00276        | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
00277 }
00278 
00279 
00280 void
00281 i915_update_textures(struct i915_context *i915)
00282 {
00283    uint unit;
00284 
00285    for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
00286         unit++) {
00287       /* determine unit enable/disable by looking for a bound texture */
00288       /* could also examine the fragment program? */
00289       if (i915->texture[unit]) {
00290          i915_update_texture( i915,
00291                               unit,
00292                               i915->texture[unit],          /* texture */
00293                               i915->sampler[unit],          /* sampler state */
00294                               i915->current.texbuffer[unit] );
00295       }
00296    }
00297 
00298    i915->hardware_dirty |= I915_HW_MAP;
00299 }

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