Ejemplo n.º 1
0
static void
update_textures(struct st_context *st,
                unsigned shader_stage,
                const struct gl_program *prog,
                unsigned max_units,
                struct pipe_sampler_view **sampler_views,
                unsigned *num_textures)
{
    const GLuint old_max = *num_textures;
    GLbitfield samplers_used = prog->SamplersUsed;
    GLuint unit, new_count;

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

    *num_textures = 0;

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

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

            retval = update_single_texture(st, &sampler_view, texUnit);
            if (retval == GL_FALSE)
                continue;

            *num_textures = unit + 1;
        }
        else if (samplers_used == 0 && unit >= old_max) {
            /* if we've reset all the old views and we have no more new ones */
            break;
        }

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

    /* Ex: if old_max = 3 and *num_textures = 1, we need to pass an
     * array of views={X, NULL, NULL} to unref the old texture views
     * at positions [1] and [2].
     */
    new_count = MAX2(*num_textures, old_max);
    assert(new_count <= max_units);

    cso_set_sampler_views(st->cso_context,
                          shader_stage,
                          new_count,
                          sampler_views);
}
Ejemplo n.º 2
0
static void
update_textures(struct st_context *st,
                gl_shader_stage mesa_shader,
                const struct gl_program *prog,
                unsigned max_units,
                struct pipe_sampler_view **sampler_views,
                unsigned *num_textures)
{
    const GLuint old_max = *num_textures;
    GLbitfield samplers_used = prog->SamplersUsed;
    GLuint unit;
    struct gl_shader_program *shader =
            st->ctx->_Shader->CurrentProgram[mesa_shader];
    unsigned glsl_version = shader ? shader->Version : 0;
    unsigned shader_stage = st_shader_stage_to_ptarget(mesa_shader);

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

    *num_textures = 0;

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

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

            retval = update_single_texture(st, &sampler_view, texUnit,
                                           glsl_version);
            if (retval == GL_FALSE)
                continue;

            *num_textures = unit + 1;
        }
        else if (samplers_used == 0 && unit >= old_max) {
            /* if we've reset all the old views and we have no more new ones */
            break;
        }

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

    cso_set_sampler_views(st->cso_context,
                          shader_stage,
                          *num_textures,
                          sampler_views);
}
Ejemplo n.º 3
0
static void
update_vertex_textures(struct st_context *st)
{
   const struct gl_context *ctx = st->ctx;
   struct gl_vertex_program *vprog = ctx->VertexProgram._Current;
   GLuint su;

   if (!vprog->Base.SamplersUsed && st->state.num_vertex_textures == 0)
      return;

   st->state.num_vertex_textures = 0;

   /* loop over sampler units (aka tex image units) */
   for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) {
      struct pipe_sampler_view *sampler_view = NULL;
      if (vprog->Base.SamplersUsed & (1 << su)) {
         GLboolean retval;
         GLuint texUnit;

         texUnit = vprog->Base.SamplerUnits[su];

         retval = update_single_texture(st, &sampler_view, texUnit);
         if (retval == GL_FALSE)
            continue;

         st->state.num_vertex_textures = su + 1;
      }
      pipe_sampler_view_reference(&st->state.sampler_vertex_views[su],
                                  sampler_view);
   }

   if (ctx->Const.MaxVertexTextureImageUnits > 0) {
      GLuint numUnits = MIN2(st->state.num_vertex_textures,
                             ctx->Const.MaxVertexTextureImageUnits);
      cso_set_vertex_sampler_views(st->cso_context,
                                   numUnits,
                                   st->state.sampler_vertex_views);
   }
}
Ejemplo n.º 4
0
static void
update_fragment_textures(struct st_context *st)
{
   const struct gl_context *ctx = st->ctx;
   struct gl_fragment_program *fprog = ctx->FragmentProgram._Current;
   GLuint su;
   int old_max = st->state.num_textures;
   GLbitfield samplers_used = fprog->Base.SamplersUsed;

   st->state.num_textures = 0;

   /* loop over sampler units (aka tex image units) */
   for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++, samplers_used >>= 1) {
      struct pipe_sampler_view *sampler_view = NULL;

      if (samplers_used & 1) {
         GLboolean retval;
         GLuint texUnit;

         texUnit = fprog->Base.SamplerUnits[su];

         retval = update_single_texture(st, &sampler_view, texUnit);
         if (retval == GL_FALSE)
            continue;

         st->state.num_textures = su + 1;
      } else if (samplers_used == 0 && su >= old_max) {
         /* if we've reset all the old views and we have no more new ones */
         break;
      }

      pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view);
   }

   cso_set_fragment_sampler_views(st->cso_context,
                                  st->state.num_textures,
                                  st->state.sampler_views);
}
Ejemplo n.º 5
0
static void
update_textures(struct st_context *st,
                gl_shader_stage mesa_shader,
                const struct gl_program *prog,
                unsigned max_units,
                struct pipe_sampler_view **sampler_views,
                unsigned *num_textures)
{
   const GLuint old_max = *num_textures;
   GLbitfield samplers_used = prog->SamplersUsed;
   GLbitfield free_slots = ~prog->SamplersUsed;
   GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
   GLuint unit;
   enum pipe_shader_type shader_stage = st_shader_stage_to_ptarget(mesa_shader);

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

   *num_textures = 0;

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

      if (samplers_used & 1) {
         /* prog->sh.data is NULL if it's ARB_fragment_program */
         unsigned glsl_version = prog->sh.data ? prog->sh.data->Version : 0;
         const GLuint texUnit = prog->SamplerUnits[unit];
         GLboolean retval;

         retval = update_single_texture(st, &sampler_view, texUnit,
                                        glsl_version);
         if (retval == GL_FALSE)
            continue;

         *num_textures = unit + 1;
      }
      else if (samplers_used == 0 && unit >= old_max) {
         /* if we've reset all the old views and we have no more new ones */
         break;
      }

      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);
}