st_atom_sampler.c revision 8f6d9e12be0be086ca2aab0b56dff8d2181addd9
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Keith Whitwell <keith@tungstengraphics.com> 31 * Brian Paul 32 */ 33 34 35#include "main/macros.h" 36 37#include "st_context.h" 38#include "st_cb_texture.h" 39#include "st_atom.h" 40#include "st_program.h" 41#include "pipe/p_context.h" 42#include "pipe/p_defines.h" 43 44#include "cso_cache/cso_context.h" 45 46 47/** 48 * Convert GLenum texcoord wrap tokens to pipe tokens. 49 */ 50static GLuint 51gl_wrap_to_sp(GLenum wrap) 52{ 53 switch (wrap) { 54 case GL_REPEAT: 55 return PIPE_TEX_WRAP_REPEAT; 56 case GL_CLAMP: 57 return PIPE_TEX_WRAP_CLAMP; 58 case GL_CLAMP_TO_EDGE: 59 return PIPE_TEX_WRAP_CLAMP_TO_EDGE; 60 case GL_CLAMP_TO_BORDER: 61 return PIPE_TEX_WRAP_CLAMP_TO_BORDER; 62 case GL_MIRRORED_REPEAT: 63 return PIPE_TEX_WRAP_MIRROR_REPEAT; 64 case GL_MIRROR_CLAMP_EXT: 65 return PIPE_TEX_WRAP_MIRROR_CLAMP; 66 case GL_MIRROR_CLAMP_TO_EDGE_EXT: 67 return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; 68 case GL_MIRROR_CLAMP_TO_BORDER_EXT: 69 return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER; 70 default: 71 assert(0); 72 return 0; 73 } 74} 75 76 77static GLuint 78gl_filter_to_mip_filter(GLenum filter) 79{ 80 switch (filter) { 81 case GL_NEAREST: 82 case GL_LINEAR: 83 return PIPE_TEX_MIPFILTER_NONE; 84 85 case GL_NEAREST_MIPMAP_NEAREST: 86 case GL_LINEAR_MIPMAP_NEAREST: 87 return PIPE_TEX_MIPFILTER_NEAREST; 88 89 case GL_NEAREST_MIPMAP_LINEAR: 90 case GL_LINEAR_MIPMAP_LINEAR: 91 return PIPE_TEX_MIPFILTER_LINEAR; 92 93 default: 94 assert(0); 95 return PIPE_TEX_MIPFILTER_NONE; 96 } 97} 98 99 100static GLuint 101gl_filter_to_img_filter(GLenum filter) 102{ 103 switch (filter) { 104 case GL_NEAREST: 105 case GL_NEAREST_MIPMAP_NEAREST: 106 case GL_NEAREST_MIPMAP_LINEAR: 107 return PIPE_TEX_FILTER_NEAREST; 108 109 case GL_LINEAR: 110 case GL_LINEAR_MIPMAP_NEAREST: 111 case GL_LINEAR_MIPMAP_LINEAR: 112 return PIPE_TEX_FILTER_LINEAR; 113 114 default: 115 assert(0); 116 return PIPE_TEX_FILTER_NEAREST; 117 } 118} 119 120 121static void 122update_samplers(struct st_context *st) 123{ 124 const struct st_fragment_program *fs = st->fp; 125 GLuint su; 126 127 st->state.num_samplers = 0; 128 129 /*printf("%s samplers used = 0x%x\n", __FUNCTION__, fs->Base.Base.SamplersUsed);*/ 130 131 /* loop over sampler units (aka tex image units) */ 132 for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { 133 struct pipe_sampler_state *sampler = st->state.samplers + su; 134 135 memset(sampler, 0, sizeof(*sampler)); 136 137 if (fs->Base.Base.SamplersUsed & (1 << su)) { 138 GLuint texUnit = fs->Base.Base.SamplerUnits[su]; 139 const struct gl_texture_object *texobj 140 = st->ctx->Texture.Unit[texUnit]._Current; 141 142 if (!texobj) { 143 texobj = st_get_default_texture(st); 144 } 145 146 sampler->wrap_s = gl_wrap_to_sp(texobj->WrapS); 147 sampler->wrap_t = gl_wrap_to_sp(texobj->WrapT); 148 sampler->wrap_r = gl_wrap_to_sp(texobj->WrapR); 149 150 sampler->min_img_filter = gl_filter_to_img_filter(texobj->MinFilter); 151 sampler->min_mip_filter = gl_filter_to_mip_filter(texobj->MinFilter); 152 sampler->mag_img_filter = gl_filter_to_img_filter(texobj->MagFilter); 153 154 if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) 155 sampler->normalized_coords = 1; 156 157 sampler->lod_bias = st->ctx->Texture.Unit[su].LodBias; 158 sampler->min_lod = MAX2(0.0f, texobj->MinLod); 159 sampler->max_lod = MIN2(texobj->MaxLevel - texobj->BaseLevel, 160 texobj->MaxLod); 161 if (sampler->max_lod < sampler->min_lod) { 162 /* The GL spec doesn't seem to specify what to do in this case. 163 * Swap the values. 164 */ 165 float tmp = sampler->max_lod; 166 sampler->max_lod = sampler->min_lod; 167 sampler->min_lod = tmp; 168 assert(sampler->min_lod <= sampler->max_lod); 169 } 170 171 sampler->border_color[0] = texobj->BorderColor[RCOMP]; 172 sampler->border_color[1] = texobj->BorderColor[GCOMP]; 173 sampler->border_color[2] = texobj->BorderColor[BCOMP]; 174 sampler->border_color[3] = texobj->BorderColor[ACOMP]; 175 176 sampler->max_anisotropy = texobj->MaxAnisotropy; 177 if (sampler->max_anisotropy > 1.0) { 178 sampler->min_img_filter = PIPE_TEX_FILTER_ANISO; 179 sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO; 180 } 181 182 /* only care about ARB_shadow, not SGI shadow */ 183 if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) { 184 sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; 185 sampler->compare_func 186 = st_compare_func_to_pipe(texobj->CompareFunc); 187 } 188 189 st->state.num_samplers = su + 1; 190 191 /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ 192 cso_single_sampler(st->cso_context, su, sampler); 193 } 194 else { 195 /*printf("%s su=%u null\n", __FUNCTION__, su);*/ 196 cso_single_sampler(st->cso_context, su, NULL); 197 } 198 } 199 200 cso_single_sampler_done(st->cso_context); 201} 202 203 204const struct st_tracked_state st_update_sampler = { 205 "st_update_sampler", /* name */ 206 { /* dirty */ 207 _NEW_TEXTURE, /* mesa */ 208 0, /* st */ 209 }, 210 update_samplers /* update */ 211}; 212