Example #1
0
/**
 * Create a texture handle from a texture unit.
 */
static GLuint64
st_create_texture_handle_from_unit(struct st_context *st,
                                   struct gl_program *prog, GLuint texUnit)
{
   struct pipe_context *pipe = st->pipe;
   struct pipe_sampler_view *view;
   struct pipe_sampler_state sampler = {0};

   st_update_single_texture(st, &view, texUnit, prog->sh.data->Version >= 130);
   if (!view)
      return 0;

   if (view->target != PIPE_BUFFER)
      st_convert_sampler_from_unit(st, &sampler, texUnit);

   assert(st->ctx->Texture.Unit[texUnit]._Current);

   return pipe->create_texture_handle(pipe, view, &sampler);
}
static void
update_textures(struct st_context *st,
                enum pipe_shader_type shader_stage,
                const struct gl_program *prog,
                struct pipe_sampler_view **sampler_views,
                unsigned *out_num_textures)
{
   const GLuint old_max = *out_num_textures;
   GLbitfield samplers_used = prog->SamplersUsed;
   GLbitfield texel_fetch_samplers = prog->info.textures_used_by_txf;
   GLbitfield free_slots = ~prog->SamplersUsed;
   GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
   GLuint unit;

   if (samplers_used == 0x0 && old_max == 0)
      return;

   unsigned num_textures = 0;

   /* prog->sh.data is NULL if it's ARB_fragment_program */
   bool glsl130 = (prog->sh.data ? prog->sh.data->Version : 0) >= 130;

   /* loop over sampler units (aka tex image units) */
   for (unit = 0; samplers_used || unit < old_max;
        unit++, samplers_used >>= 1, texel_fetch_samplers >>= 1) {
      struct pipe_sampler_view *sampler_view = NULL;

      if (samplers_used & 1) {
         const GLuint texUnit = prog->SamplerUnits[unit];

         /* The EXT_texture_sRGB_decode extension says:
          *
          *    "The conversion of sRGB color space components to linear color
          *     space is always performed if the texel lookup function is one
          *     of the texelFetch builtin functions.
          *
          *     Otherwise, if the texel lookup function is one of the texture
          *     builtin functions or one of the texture gather functions, the
          *     conversion of sRGB color space components to linear color space
          *     is controlled by the TEXTURE_SRGB_DECODE_EXT parameter.
          *
          *     If the TEXTURE_SRGB_DECODE_EXT parameter is DECODE_EXT, the
          *     conversion of sRGB color space components to linear color space
          *     is performed.
          *
          *     If the TEXTURE_SRGB_DECODE_EXT parameter is SKIP_DECODE_EXT,
          *     the value is returned without decoding. However, if the texture
          *     is also [statically] accessed with a texelFetch function, then
          *     the result of texture builtin functions and/or texture gather
          *     functions may be returned with decoding or without decoding."
          *
          * Note: the "statically" will be added to the language per
          *       https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14934
          *
          * So we simply ignore the setting entirely for samplers that are
          * (statically) accessed with a texelFetch function.
          */
         st_update_single_texture(st, &sampler_view, texUnit, glsl130,
                                  texel_fetch_samplers & 1);
         num_textures = unit + 1;
      }

      pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view);
   }

   /* For any external samplers with multiplaner YUV, stuff the additional
    * sampler views we need at the end.
    *
    * Trying to cache the sampler view in the stObj looks painful, so just
    * re-create the sampler view for the extra planes each time.  Main use
    * case is video playback (ie. fps games wouldn't be using this) so I
    * guess no point to try to optimize this feature.
    */
   while (unlikely(external_samplers_used)) {
      GLuint unit = u_bit_scan(&external_samplers_used);
      GLuint extra = 0;
      struct st_texture_object *stObj =
            st_get_texture_object(st->ctx, prog, unit);
      struct pipe_sampler_view tmpl;

      if (!stObj)
         continue;

      /* use original view as template: */
      tmpl = *sampler_views[unit];

      switch (st_get_view_format(stObj)) {
      case PIPE_FORMAT_NV12:
         /* we need one additional R8G8 view: */
         tmpl.format = PIPE_FORMAT_RG88_UNORM;
         tmpl.swizzle_g = PIPE_SWIZZLE_Y;   /* tmpl from Y plane is R8 */
         extra = u_bit_scan(&free_slots);
         sampler_views[extra] =
               st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl);
         break;
      case PIPE_FORMAT_IYUV:
         /* we need two additional R8 views: */
         tmpl.format = PIPE_FORMAT_R8_UNORM;
         extra = u_bit_scan(&free_slots);
         sampler_views[extra] =
               st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl);
         extra = u_bit_scan(&free_slots);
         sampler_views[extra] =
               st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl);
         break;
      default:
         break;
      }

      num_textures = MAX2(num_textures, extra + 1);
   }

   cso_set_sampler_views(st->cso_context,
                         shader_stage,
                         num_textures,
                         sampler_views);
   *out_num_textures = num_textures;
}