static unsigned get_texture_format_swizzle(const struct st_context *st, const struct st_texture_object *stObj, unsigned glsl_version) { GLenum baseFormat = _mesa_texture_base_format(&stObj->base); unsigned tex_swizzle; if (baseFormat != GL_NONE) { GLenum depth_mode = stObj->base.DepthMode; /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures * with depth component data specified with a sized internal format. */ if (_mesa_is_gles3(st->ctx) && util_format_is_depth_or_stencil(stObj->pt->format)) { const struct gl_texture_image *firstImage = _mesa_base_tex_image(&stObj->base); if (firstImage->InternalFormat != GL_DEPTH_COMPONENT && firstImage->InternalFormat != GL_DEPTH_STENCIL && firstImage->InternalFormat != GL_STENCIL_INDEX) depth_mode = GL_RED; } tex_swizzle = compute_texture_format_swizzle(baseFormat, depth_mode, 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); }
/** * Determine the format for the texture sampler view. */ static enum pipe_format get_sampler_view_format(struct st_context *st, const struct st_texture_object *stObj, const struct gl_sampler_object *samp) { enum pipe_format format; if (stObj->base.Target == GL_TEXTURE_BUFFER) { format = st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat); } else { format = stObj->surface_based ? stObj->surface_format : stObj->pt->format; if (util_format_is_depth_and_stencil(format)) { if (stObj->base.StencilSampling) { format = util_format_stencil_only(format); } else { GLenum baseFormat = _mesa_texture_base_format(&stObj->base); if (baseFormat == GL_STENCIL_INDEX) { format = util_format_stencil_only(format); } } } else { /* If sRGB decoding is off, use the linear format */ if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) { format = util_format_linear(format); } /* Use R8_UNORM for video formats */ switch (format) { case PIPE_FORMAT_NV12: case PIPE_FORMAT_IYUV: format = PIPE_FORMAT_R8_UNORM; break; default: break; } } } return format; }
static unsigned get_texture_format_swizzle(const struct st_texture_object *stObj) { 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); } else { tex_swizzle = SWIZZLE_XYZW; } /* Combine the texture format swizzle with user's swizzle */ return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle); }
static void convert_sampler(struct st_context *st, struct pipe_sampler_state *sampler, GLuint texUnit) { const struct gl_texture_object *texobj; struct gl_context *ctx = st->ctx; const struct gl_sampler_object *msamp; GLenum texBaseFormat; texobj = ctx->Texture.Unit[texUnit]._Current; if (!texobj) { texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX); msamp = &texobj->Sampler; } else { msamp = _mesa_get_samplerobj(ctx, texUnit); } texBaseFormat = _mesa_texture_base_format(texobj); memset(sampler, 0, sizeof(*sampler)); sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) sampler->normalized_coords = 1; sampler->lod_bias = ctx->Texture.Unit[texUnit].LodBias + msamp->LodBias; sampler->min_lod = MAX2(msamp->MinLod, 0.0f); sampler->max_lod = msamp->MaxLod; if (sampler->max_lod < sampler->min_lod) { /* The GL spec doesn't seem to specify what to do in this case. * Swap the values. */ float tmp = sampler->max_lod; sampler->max_lod = sampler->min_lod; sampler->min_lod = tmp; assert(sampler->min_lod <= sampler->max_lod); } /* For non-black borders... */ if (msamp->BorderColor.ui[0] || msamp->BorderColor.ui[1] || msamp->BorderColor.ui[2] || msamp->BorderColor.ui[3]) { const struct st_texture_object *stobj = st_texture_object_const(texobj); const GLboolean is_integer = texobj->_IsIntegerFormat; const struct pipe_sampler_view *sv = NULL; union pipe_color_union border_color; GLuint i; /* Just search for the first used view. We can do this because the swizzle is per-texture, not per context. */ /* XXX: clean that up to not use the sampler view at all */ for (i = 0; i < stobj->num_sampler_views; ++i) { if (stobj->sampler_views[i]) { sv = stobj->sampler_views[i]; break; } } if (st->apply_texture_swizzle_to_border_color && sv) { const unsigned char swz[4] = { sv->swizzle_r, sv->swizzle_g, sv->swizzle_b, sv->swizzle_a, }; st_translate_color(&msamp->BorderColor, &border_color, texBaseFormat, is_integer); util_format_apply_color_swizzle(&sampler->border_color, &border_color, swz, is_integer); } else { st_translate_color(&msamp->BorderColor, &sampler->border_color, texBaseFormat, is_integer); } } sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? 0 : (GLuint) msamp->MaxAnisotropy); /* If sampling a depth texture and using shadow comparison */ if ((texBaseFormat == GL_DEPTH_COMPONENT || texBaseFormat == GL_DEPTH_STENCIL) && msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc); } sampler->seamless_cube_map = ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; }