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
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
00130
00131
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
00163
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
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
00192 cso_single_sampler(st->cso_context, su, sampler);
00193 }
00194 else {
00195
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",
00206 {
00207 _NEW_TEXTURE,
00208 0,
00209 },
00210 update_samplers
00211 };