Esempio n. 1
0
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);
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}