+static unsigned
+get_texture_format_swizzle(const struct st_texture_object *stObj,
+ unsigned glsl_version)
+{
+ GLenum baseFormat = _mesa_texture_base_format(&stObj->base);
+ unsigned tex_swizzle;
+
+ if (baseFormat != GL_NONE) {
+ tex_swizzle = compute_texture_format_swizzle(baseFormat,
+ stObj->base.DepthMode,
+ stObj->pt->format,
+ glsl_version);
+ }
+ else {
+ tex_swizzle = SWIZZLE_XYZW;
+ }
+
+ /* Combine the texture format swizzle with user's swizzle */
+ return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
+}
+
+
+/**
+ * Return TRUE if the texture's sampler view swizzle is not equal to
+ * the texture's swizzle.
+ *
+ * \param stObj the st texture object,
+ */
+static boolean
+check_sampler_swizzle(const struct st_texture_object *stObj,
+ struct pipe_sampler_view *sv, unsigned glsl_version)
+{
+ unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version);
+
+ return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
+ (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
+ (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
+ (sv->swizzle_a != GET_SWZ(swizzle, 3)));
+}
+
+
+static unsigned last_level(struct st_texture_object *stObj)
+{
+ unsigned ret = MIN2(stObj->base.MinLevel + stObj->base._MaxLevel,
+ stObj->pt->last_level);
+ if (stObj->base.Immutable)
+ ret = MIN2(ret, stObj->base.MinLevel + stObj->base.NumLevels - 1);
+ return ret;
+}
+
+static unsigned last_layer(struct st_texture_object *stObj)
+{
+ if (stObj->base.Immutable && stObj->pt->array_size > 1)
+ return MIN2(stObj->base.MinLayer + stObj->base.NumLayers - 1,
+ stObj->pt->array_size - 1);
+ return stObj->pt->array_size - 1;
+}
+
+static struct pipe_sampler_view *
+st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
+ struct st_texture_object *stObj,
+ enum pipe_format format,
+ unsigned glsl_version)
+{
+ struct pipe_sampler_view templ;
+ unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version);
+
+ u_sampler_view_default_template(&templ,
+ stObj->pt,
+ format);
+
+ if (stObj->pt->target == PIPE_BUFFER) {
+ unsigned base, size;
+ unsigned f, n;
+ const struct util_format_description *desc
+ = util_format_description(templ.format);
+
+ base = stObj->base.BufferOffset;
+ if (base >= stObj->pt->width0)
+ return NULL;
+ size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
+
+ f = ((base * 8) / desc->block.bits) * desc->block.width;
+ n = ((size * 8) / desc->block.bits) * desc->block.width;
+ if (!n)
+ return NULL;
+ templ.u.buf.first_element = f;
+ templ.u.buf.last_element = f + (n - 1);
+ } else {
+ templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
+ templ.u.tex.last_level = last_level(stObj);
+ assert(templ.u.tex.first_level <= templ.u.tex.last_level);
+ templ.u.tex.first_layer = stObj->base.MinLayer;
+ templ.u.tex.last_layer = last_layer(stObj);
+ assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
+ templ.target = gl_target_to_pipe(stObj->base.Target);
+ }
+
+ if (swizzle != SWIZZLE_NOOP) {
+ templ.swizzle_r = GET_SWZ(swizzle, 0);
+ templ.swizzle_g = GET_SWZ(swizzle, 1);
+ templ.swizzle_b = GET_SWZ(swizzle, 2);
+ templ.swizzle_a = GET_SWZ(swizzle, 3);
+ }
+
+ return pipe->create_sampler_view(pipe, stObj->pt, &templ);
+}