Exemple #1
0
static GLboolean
update_single_texture(struct st_context *st,
                      struct pipe_sampler_view **sampler_view,
                      GLuint texUnit)
{
    struct pipe_context *pipe = st->pipe;
    struct gl_context *ctx = st->ctx;
    const struct gl_sampler_object *samp;
    struct gl_texture_object *texObj;
    struct st_texture_object *stObj;
    enum pipe_format view_format;
    GLboolean retval;

    samp = _mesa_get_samplerobj(ctx, texUnit);

    texObj = ctx->Texture.Unit[texUnit]._Current;

    if (!texObj) {
        texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
        samp = &texObj->Sampler;
    }
    stObj = st_texture_object(texObj);

    retval = st_finalize_texture(ctx, st->pipe, texObj);
    if (!retval) {
        /* out of mem */
        return GL_FALSE;
    }

    /* Determine the format of the texture sampler view */
    if (texObj->Target == GL_TEXTURE_BUFFER) {
        view_format =
            st_mesa_format_to_pipe_format(stObj->base._BufferObjectFormat);
    }
    else {
        view_format = stObj->pt->format;

        /* If sRGB decoding is off, use the linear format */
        if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) {
            view_format = util_format_linear(view_format);
        }
    }

    /* if sampler view has changed dereference it */
    if (stObj->sampler_view) {
        if (check_sampler_swizzle(stObj->sampler_view,
                                  stObj->base._Swizzle,
                                  stObj->base.DepthMode) ||
                (view_format != stObj->sampler_view->format) ||
                stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
            pipe_sampler_view_reference(&stObj->sampler_view, NULL);
        }
    }

    *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe,
                    samp,
                    view_format);
    return GL_TRUE;
}
Exemple #2
0
static struct gl_texture_object *
update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
                              int s)
{
    gl_texture_index target_index;
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_sampler_object *sampler;
    int unit;

    if (!(prog->SamplersUsed & (1 << s)))
        return NULL;

    unit = prog->SamplerUnits[s];
    texUnit = &ctx->Texture.Unit[unit];

    /* Note: If more than one bit was set in TexturesUsed[unit], then we should
     * have had the draw call rejected already.  From the GL 4.4 specification,
     * section 7.10 ("Samplers"):
     *
     *     "It is not allowed to have variables of different sampler types
     *      pointing to the same texture image unit within a program
     *      object. This situation can only be detected at the next rendering
     *      command issued which triggers shader invocations, and an
     *      INVALID_OPERATION error will then be generated."
     */
    target_index = ffs(prog->TexturesUsed[unit]) - 1;
    texObj = texUnit->CurrentTex[target_index];

    sampler = texUnit->Sampler ?
              texUnit->Sampler : &texObj->Sampler;

    if (likely(texObj)) {
        if (_mesa_is_texture_complete(texObj, sampler))
            return texObj;

        _mesa_test_texobj_completeness(ctx, texObj);
        if (_mesa_is_texture_complete(texObj, sampler))
            return texObj;
    }

    /* If we've reached this point, we didn't find a complete texture of the
     * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
     * ("Texture Access"):
     *
     *     "If a sampler is used in a shader and the sampler’s associated
     *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
     *      will be returned for a non-shadow sampler and 0 for a shadow
     *      sampler."
     *
     * Mesa implements this by creating a hidden texture object with a pixel of
     * that value.
     */
    texObj = _mesa_get_fallback_texture(ctx, target_index);
    assert(texObj);

    return texObj;
}
Exemple #3
0
static GLboolean
update_single_texture(struct st_context *st,
                      struct pipe_sampler_view **sampler_view,
                      GLuint texUnit, unsigned glsl_version)
{
    struct gl_context *ctx = st->ctx;
    const struct gl_sampler_object *samp;
    struct gl_texture_object *texObj;
    struct st_texture_object *stObj;
    enum pipe_format view_format;
    GLboolean retval;

    samp = _mesa_get_samplerobj(ctx, texUnit);

    texObj = ctx->Texture.Unit[texUnit]._Current;

    if (!texObj) {
        texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
        samp = &texObj->Sampler;
    }
    stObj = st_texture_object(texObj);

    retval = st_finalize_texture(ctx, st->pipe, texObj);
    if (!retval) {
        /* out of mem */
        return GL_FALSE;
    }

    /* Determine the format of the texture sampler view */
    if (texObj->Target == GL_TEXTURE_BUFFER) {
        view_format =
            st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat);
    }
    else {
        view_format =
            stObj->surface_based ? stObj->surface_format : stObj->pt->format;

        /* If sRGB decoding is off, use the linear format */
        if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) {
            view_format = util_format_linear(view_format);
        }
    }

    *sampler_view =
        st_get_texture_sampler_view_from_stobj(st, stObj, view_format,
                glsl_version);
    return GL_TRUE;
}
static GLboolean
update_single_texture(struct st_context *st,
                      struct pipe_sampler_view **sampler_view,
		      GLuint texUnit, unsigned glsl_version)
{
   struct gl_context *ctx = st->ctx;
   const struct gl_sampler_object *samp;
   struct gl_texture_object *texObj;
   struct st_texture_object *stObj;
   GLboolean retval;

   samp = _mesa_get_samplerobj(ctx, texUnit);

   texObj = ctx->Texture.Unit[texUnit]._Current;

   if (!texObj) {
      texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
      samp = &texObj->Sampler;
   }
   stObj = st_texture_object(texObj);

   retval = st_finalize_texture(ctx, st->pipe, texObj);
   if (!retval) {
      /* out of mem */
      return GL_FALSE;
   }

   /* Check a few pieces of state outside the texture object to see if we
    * need to force revalidation.
    */
   if (stObj->prev_glsl_version != glsl_version ||
       stObj->prev_sRGBDecode != samp->sRGBDecode) {

      st_texture_release_all_sampler_views(st, stObj);

      stObj->prev_glsl_version = glsl_version;
      stObj->prev_sRGBDecode = samp->sRGBDecode;
   }

   if (texObj->TargetIndex == TEXTURE_EXTERNAL_INDEX &&
       stObj->pt->screen->resource_changed)
         stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt);

   *sampler_view =
      st_get_texture_sampler_view_from_stobj(st, stObj, samp, glsl_version);
   return GL_TRUE;
}
Exemple #5
0
static void
fix_missing_textures_for_atifs(struct gl_context *ctx,
                               struct gl_program *prog,
                               BITSET_WORD *enabled_texture_units)
{
   GLbitfield mask = prog->SamplersUsed;

   while (mask) {
      const int s = u_bit_scan(&mask);
      const int unit = prog->SamplerUnits[s];
      const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1;

      if (!ctx->Texture.Unit[unit]._Current) {
         struct gl_texture_object *texObj =
            _mesa_get_fallback_texture(ctx, target_index);
         _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
         BITSET_SET(enabled_texture_units, unit);
         ctx->Texture._MaxEnabledTexImageUnit =
            MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
      }
   }
}
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;
}
Exemple #7
0
/**
 * \note This routine refers to derived texture matrix values to
 * compute the ENABLE_TEXMAT flags, but is only called on
 * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
 * flags are updated by _mesa_update_texture_matrices, above.
 *
 * \param ctx GL context.
 */
static void
update_texture_state( GLcontext *ctx )
{
   GLuint unit;
   struct gl_fragment_program *fprog = NULL;
   struct gl_vertex_program *vprog = NULL;
   GLbitfield enabledFragUnits = 0x0;

   if (ctx->Shader.CurrentProgram &&
       ctx->Shader.CurrentProgram->LinkStatus) {
      fprog = ctx->Shader.CurrentProgram->FragmentProgram;
      vprog = ctx->Shader.CurrentProgram->VertexProgram;
   }
   else {
      if (ctx->FragmentProgram._Enabled) {
         fprog = ctx->FragmentProgram.Current;
      }
      if (ctx->VertexProgram._Enabled) {
         /* XXX enable this if/when non-shader vertex programs get
          * texture fetches:
         vprog = ctx->VertexProgram.Current;
         */
      }
   }

   /* TODO: only set this if there are actual changes */
   ctx->NewState |= _NEW_TEXTURE;

   ctx->Texture._EnabledUnits = 0x0;
   ctx->Texture._GenFlags = 0x0;
   ctx->Texture._TexMatEnabled = 0x0;
   ctx->Texture._TexGenEnabled = 0x0;

   /*
    * Update texture unit state.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      GLbitfield enabledVertTargets = 0x0;
      GLbitfield enabledFragTargets = 0x0;
      GLbitfield enabledTargets = 0x0;
      GLuint texIndex;

      /* Get the bitmask of texture target enables.
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
       * which texture targets are enabled (fixed function) or referenced
       * by a fragment shader/program.  When multiple flags are set, we'll
       * settle on the one with highest priority (see below).
       */
      if (vprog) {
         enabledVertTargets |= vprog->Base.TexturesUsed[unit];
      }

      if (fprog) {
         enabledFragTargets |= fprog->Base.TexturesUsed[unit];
      }
      else {
         /* fixed-function fragment program */
         enabledFragTargets |= texUnit->Enabled;
      }

      enabledTargets = enabledVertTargets | enabledFragTargets;

      texUnit->_ReallyEnabled = 0x0;

      if (enabledTargets == 0x0) {
         /* neither vertex nor fragment processing uses this unit */
         continue;
      }

      /* Look for the highest priority texture target that's enabled (or used
       * by the vert/frag shaders) and "complete".  That's the one we'll use
       * for texturing.  If we're using vert/frag program we're guaranteed
       * that bitcount(enabledBits) <= 1.
       * Note that the TEXTURE_x_INDEX values are in high to low priority.
       */
      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
         if (enabledTargets & (1 << texIndex)) {
            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
            if (!texObj->_Complete) {
               _mesa_test_texobj_completeness(ctx, texObj);
            }
            if (texObj->_Complete) {
               texUnit->_ReallyEnabled = 1 << texIndex;
               _mesa_reference_texobj(&texUnit->_Current, texObj);
               break;
            }
         }
      }

      if (!texUnit->_ReallyEnabled) {
         if (fprog) {
            /* If we get here it means the shader is expecting a texture
             * object, but there isn't one (or it's incomplete).  Use the
             * fallback texture.
             */
            struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx);
            texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX;
            _mesa_reference_texobj(&texUnit->_Current, texObj);
         }
         else {
            /* fixed-function: texture unit is really disabled */
            continue;
         }
      }

      /* if we get here, we know this texture unit is enabled */

      ctx->Texture._EnabledUnits |= (1 << unit);

      if (enabledFragTargets)
         enabledFragUnits |= (1 << unit);

      update_tex_combine(ctx, texUnit);
   }


   /* Determine which texture coordinate sets are actually needed */
   if (fprog) {
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
      ctx->Texture._EnabledCoordUnits
         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
   }
   else {
Exemple #8
0
/**
 * \note This routine refers to derived texture matrix values to
 * compute the ENABLE_TEXMAT flags, but is only called on
 * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
 * flags are updated by _mesa_update_texture_matrices, above.
 *
 * \param ctx GL context.
 */
static void
update_texture_state( struct gl_context *ctx )
{
   GLuint unit;
   struct gl_program *fprog = NULL;
   struct gl_program *vprog = NULL;
   struct gl_program *gprog = NULL;
   GLbitfield enabledFragUnits = 0x0;

   if (ctx->Shader.CurrentVertexProgram &&
       ctx->Shader.CurrentVertexProgram->LinkStatus) {
      vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
   }

   if (ctx->Shader.CurrentGeometryProgram &&
       ctx->Shader.CurrentGeometryProgram->LinkStatus) {
      gprog = ctx->Shader.CurrentGeometryProgram->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
   }

   if (ctx->Shader.CurrentFragmentProgram &&
       ctx->Shader.CurrentFragmentProgram->LinkStatus) {
      fprog = ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
   }
   else if (ctx->FragmentProgram._Enabled) {
      fprog = &ctx->FragmentProgram.Current->Base;
   }

   /* TODO: only set this if there are actual changes */
   ctx->NewState |= _NEW_TEXTURE;

   ctx->Texture._EnabledUnits = 0x0;
   ctx->Texture._GenFlags = 0x0;
   ctx->Texture._TexMatEnabled = 0x0;
   ctx->Texture._TexGenEnabled = 0x0;

   /*
    * Update texture unit state.
    */
   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      GLbitfield enabledVertTargets = 0x0;
      GLbitfield enabledFragTargets = 0x0;
      GLbitfield enabledGeomTargets = 0x0;
      GLbitfield enabledTargets = 0x0;
      GLuint texIndex;

      /* Get the bitmask of texture target enables.
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
       * which texture targets are enabled (fixed function) or referenced
       * by a fragment program/program.  When multiple flags are set, we'll
       * settle on the one with highest priority (see below).
       */
      if (vprog) {
         enabledVertTargets |= vprog->TexturesUsed[unit];
      }

      if (gprog) {
         enabledGeomTargets |= gprog->TexturesUsed[unit];
      }

      if (fprog) {
         enabledFragTargets |= fprog->TexturesUsed[unit];
      }
      else {
         /* fixed-function fragment program */
         enabledFragTargets |= texUnit->Enabled;
      }

      enabledTargets = enabledVertTargets | enabledFragTargets |
                       enabledGeomTargets;

      texUnit->_ReallyEnabled = 0x0;

      if (enabledTargets == 0x0) {
         /* neither vertex nor fragment processing uses this unit */
         continue;
      }

      /* Look for the highest priority texture target that's enabled (or used
       * by the vert/frag shaders) and "complete".  That's the one we'll use
       * for texturing.
       *
       * Note that the TEXTURE_x_INDEX values are in high to low priority.
       */
      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
         if (enabledTargets & (1 << texIndex)) {
            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
            struct gl_sampler_object *sampler = texUnit->Sampler ?
               texUnit->Sampler : &texObj->Sampler;

            if (!_mesa_is_texture_complete(texObj, sampler)) {
               _mesa_test_texobj_completeness(ctx, texObj);
            }
            if (_mesa_is_texture_complete(texObj, sampler)) {
               texUnit->_ReallyEnabled = 1 << texIndex;
               _mesa_reference_texobj(&texUnit->_Current, texObj);
               break;
            }
         }
      }

      if (!texUnit->_ReallyEnabled) {
         if (fprog) {
            /* If we get here it means the shader is expecting a texture
             * object, but there isn't one (or it's incomplete).  Use the
             * fallback texture.
             */
            struct gl_texture_object *texObj;
            gl_texture_index texTarget;

            texTarget = (gl_texture_index) (ffs(enabledTargets) - 1);
            texObj = _mesa_get_fallback_texture(ctx, texTarget);
            
            assert(texObj);
            if (!texObj) {
               /* invalid fallback texture: don't enable the texture unit */
               continue;
            }

            _mesa_reference_texobj(&texUnit->_Current, texObj);
            texUnit->_ReallyEnabled = 1 << texTarget;
         }
         else {
            /* fixed-function: texture unit is really disabled */
            continue;
         }
      }

      /* if we get here, we know this texture unit is enabled */

      ctx->Texture._EnabledUnits |= (1 << unit);

      if (enabledFragTargets)
         enabledFragUnits |= (1 << unit);

      if (!fprog)
         update_tex_combine(ctx, texUnit);
   }


   /* Determine which texture coordinate sets are actually needed */
   if (fprog) {
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
      ctx->Texture._EnabledCoordUnits
         = (fprog->InputsRead >> VARYING_SLOT_TEX0) & coordMask;
   }
   else {
static void
convert_sampler(struct st_context *st,
                struct pipe_sampler_state *sampler,
                GLuint texUnit)
{
    struct gl_texture_object *texobj;
    struct gl_context *ctx = st->ctx;
    struct gl_sampler_object *msamp;

    texobj = ctx->Texture.Unit[texUnit]._Current;
    if (!texobj) {
        texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
    }

    msamp = _mesa_get_samplerobj(ctx, texUnit);

    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 = CLAMP(msamp->MinLod,
                             0.0f,
                             (GLfloat) texobj->MaxLevel - texobj->BaseLevel);
    sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel,
                            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);
    }

    if (msamp->BorderColor.ui[0] ||
            msamp->BorderColor.ui[1] ||
            msamp->BorderColor.ui[2] ||
            msamp->BorderColor.ui[3]) {
        struct st_texture_object *stobj = st_texture_object(texobj);
        struct gl_texture_image *teximg;
        GLboolean is_integer = GL_FALSE;
        union pipe_color_union border_color;

        teximg = texobj->Image[0][texobj->BaseLevel];

        if (teximg) {
            is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat);
        }

        if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view) {
            const unsigned char swz[4] =
            {
                stobj->sampler_view->swizzle_r,
                stobj->sampler_view->swizzle_g,
                stobj->sampler_view->swizzle_b,
                stobj->sampler_view->swizzle_a,
            };

            st_translate_color(&msamp->BorderColor,
                               &border_color,
                               teximg ? teximg->_BaseFormat : GL_RGBA, is_integer);

            util_format_apply_color_swizzle(&sampler->border_color,
                                            &border_color, swz, is_integer);
        } else {
            st_translate_color(&msamp->BorderColor,
                               &sampler->border_color,
                               teximg ? teximg->_BaseFormat : GL_RGBA, is_integer);
        }
    }

    sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
                               0 : (GLuint) msamp->MaxAnisotropy);

    /* only care about ARB_shadow, not SGI shadow */
    if (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;
}
Exemple #10
0
static GLboolean
update_single_texture(struct st_context *st,
                      struct pipe_sampler_view **sampler_view,
		      GLuint texUnit)
{
   struct pipe_context *pipe = st->pipe;
   struct gl_context *ctx = st->ctx;
   const struct gl_sampler_object *samp;
   struct gl_texture_object *texObj;
   struct st_texture_object *stObj;
   enum pipe_format st_view_format;
   GLboolean retval;

   samp = _mesa_get_samplerobj(ctx, texUnit);

   texObj = ctx->Texture.Unit[texUnit]._Current;

   if (!texObj) {
      texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
      samp = &texObj->Sampler;
   }
   stObj = st_texture_object(texObj);

   retval = st_finalize_texture(ctx, st->pipe, texObj);
   if (!retval) {
      /* out of mem */
      return GL_FALSE;
   }

   /* Determine the format of the texture sampler view */
   st_view_format = stObj->pt->format;
   {
      const struct st_texture_image *firstImage =
	 st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
      const gl_format texFormat = firstImage->base.TexFormat;
      enum pipe_format firstImageFormat =
	 st_mesa_format_to_pipe_format(texFormat);

      if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) &&
	  (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) {
         /* Don't do sRGB->RGB conversion.  Interpret the texture data as
          * linear values.
          */
	 const gl_format linearFormat =
	    _mesa_get_srgb_format_linear(texFormat);
	 firstImageFormat = st_mesa_format_to_pipe_format(linearFormat);
      }

      if (firstImageFormat != stObj->pt->format)
	 st_view_format = firstImageFormat;
   }

   /* if sampler view has changed dereference it */
   if (stObj->sampler_view) {
      if (check_sampler_swizzle(stObj->sampler_view,
				stObj->base._Swizzle,
				samp->DepthMode) ||
	  (st_view_format != stObj->sampler_view->format) ||
	  stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
	 pipe_sampler_view_reference(&stObj->sampler_view, NULL);
      }
   }

   *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe,
							  samp,
							  st_view_format);
   return GL_TRUE;
}