st_atom_sampler.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 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  /*
00029   * Authors:
00030   *   Keith Whitwell <keith@tungstengraphics.com>
00031   *   Brian Paul
00032   */
00033  
00034 
00035 #include "main/macros.h"
00036 
00037 #include "st_context.h"
00038 #include "st_cb_texture.h"
00039 #include "st_atom.h"
00040 #include "st_program.h"
00041 #include "pipe/p_context.h"
00042 #include "pipe/p_defines.h"
00043 
00044 #include "cso_cache/cso_context.h"
00045 
00046 
00050 static GLuint
00051 gl_wrap_to_sp(GLenum wrap)
00052 {
00053    switch (wrap) {
00054    case GL_REPEAT:
00055       return PIPE_TEX_WRAP_REPEAT;
00056    case GL_CLAMP:
00057       return PIPE_TEX_WRAP_CLAMP;
00058    case GL_CLAMP_TO_EDGE:
00059       return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00060    case GL_CLAMP_TO_BORDER:
00061       return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
00062    case GL_MIRRORED_REPEAT:
00063       return PIPE_TEX_WRAP_MIRROR_REPEAT;
00064    case GL_MIRROR_CLAMP_EXT:
00065       return PIPE_TEX_WRAP_MIRROR_CLAMP;
00066    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
00067       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
00068    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
00069       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
00070    default:
00071       assert(0);
00072       return 0;
00073    }
00074 }
00075 
00076 
00077 static GLuint
00078 gl_filter_to_mip_filter(GLenum filter)
00079 {
00080    switch (filter) {
00081    case GL_NEAREST:
00082    case GL_LINEAR:
00083       return PIPE_TEX_MIPFILTER_NONE;
00084 
00085    case GL_NEAREST_MIPMAP_NEAREST:
00086    case GL_LINEAR_MIPMAP_NEAREST:
00087       return PIPE_TEX_MIPFILTER_NEAREST;
00088 
00089    case GL_NEAREST_MIPMAP_LINEAR:
00090    case GL_LINEAR_MIPMAP_LINEAR:
00091       return PIPE_TEX_MIPFILTER_LINEAR;
00092 
00093    default:
00094       assert(0);
00095       return PIPE_TEX_MIPFILTER_NONE;
00096    }
00097 }
00098 
00099 
00100 static GLuint
00101 gl_filter_to_img_filter(GLenum filter)
00102 {
00103    switch (filter) {
00104    case GL_NEAREST:
00105    case GL_NEAREST_MIPMAP_NEAREST:
00106    case GL_NEAREST_MIPMAP_LINEAR:
00107       return PIPE_TEX_FILTER_NEAREST;
00108 
00109    case GL_LINEAR:
00110    case GL_LINEAR_MIPMAP_NEAREST:
00111    case GL_LINEAR_MIPMAP_LINEAR:
00112       return PIPE_TEX_FILTER_LINEAR;
00113 
00114    default:
00115       assert(0);
00116       return PIPE_TEX_FILTER_NEAREST;
00117    }
00118 }
00119 
00120 
00121 static void 
00122 update_samplers(struct st_context *st)
00123 {
00124    const struct st_fragment_program *fs = st->fp;
00125    GLuint su;
00126 
00127    st->state.num_samplers = 0;
00128 
00129    /*printf("%s samplers used = 0x%x\n", __FUNCTION__, fs->Base.Base.SamplersUsed);*/
00130 
00131    /* loop over sampler units (aka tex image units) */
00132    for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
00133       struct pipe_sampler_state *sampler = st->state.samplers + su;
00134 
00135       memset(sampler, 0, sizeof(*sampler));
00136 
00137       if (fs->Base.Base.SamplersUsed & (1 << su)) {
00138          GLuint texUnit = fs->Base.Base.SamplerUnits[su];
00139          const struct gl_texture_object *texobj
00140             = st->ctx->Texture.Unit[texUnit]._Current;
00141 
00142          if (!texobj) {
00143             texobj = st_get_default_texture(st);
00144          }
00145 
00146          sampler->wrap_s = gl_wrap_to_sp(texobj->WrapS);
00147          sampler->wrap_t = gl_wrap_to_sp(texobj->WrapT);
00148          sampler->wrap_r = gl_wrap_to_sp(texobj->WrapR);
00149 
00150          sampler->min_img_filter = gl_filter_to_img_filter(texobj->MinFilter);
00151          sampler->min_mip_filter = gl_filter_to_mip_filter(texobj->MinFilter);
00152          sampler->mag_img_filter = gl_filter_to_img_filter(texobj->MagFilter);
00153 
00154          if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
00155             sampler->normalized_coords = 1;
00156 
00157          sampler->lod_bias = st->ctx->Texture.Unit[su].LodBias;
00158          sampler->min_lod = MAX2(0.0f, texobj->MinLod);
00159          sampler->max_lod = MIN2(texobj->MaxLevel - texobj->BaseLevel,
00160                                  texobj->MaxLod);
00161          if (sampler->max_lod < sampler->min_lod) {
00162             /* The GL spec doesn't seem to specify what to do in this case.
00163              * Swap the values.
00164              */
00165             float tmp = sampler->max_lod;
00166             sampler->max_lod = sampler->min_lod;
00167             sampler->min_lod = tmp;
00168             assert(sampler->min_lod <= sampler->max_lod);
00169          }
00170 
00171          sampler->border_color[0] = texobj->BorderColor[RCOMP];
00172          sampler->border_color[1] = texobj->BorderColor[GCOMP];
00173          sampler->border_color[2] = texobj->BorderColor[BCOMP];
00174          sampler->border_color[3] = texobj->BorderColor[ACOMP];
00175 
00176          sampler->max_anisotropy = texobj->MaxAnisotropy;
00177          if (sampler->max_anisotropy > 1.0) {
00178             sampler->min_img_filter = PIPE_TEX_FILTER_ANISO;
00179             sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO;
00180          }
00181 
00182          /* only care about ARB_shadow, not SGI shadow */
00183          if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
00184             sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
00185             sampler->compare_func
00186                = st_compare_func_to_pipe(texobj->CompareFunc);
00187          }
00188 
00189          st->state.num_samplers = su + 1;
00190 
00191          /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
00192          cso_single_sampler(st->cso_context, su, sampler);
00193       }
00194       else {
00195          /*printf("%s su=%u null\n", __FUNCTION__, su);*/
00196          cso_single_sampler(st->cso_context, su, NULL);
00197       }
00198    }
00199 
00200    cso_single_sampler_done(st->cso_context);
00201 }
00202 
00203 
00204 const struct st_tracked_state st_update_sampler = {
00205    "st_update_sampler",                                 /* name */
00206    {                                                    /* dirty */
00207       _NEW_TEXTURE,                                     /* mesa */
00208       0,                                                /* st */
00209    },
00210    update_samplers                                      /* update */
00211 };

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