Пример #1
0
/**
 * Update the gallium driver's sampler state for fragment, vertex or
 * geometry shader stage.
 */
static void
update_shader_samplers(struct st_context *st,
                       unsigned shader_stage,
                       const struct gl_program *prog,
                       unsigned max_units,
                       struct pipe_sampler_state *samplers,
                       unsigned *num_samplers)
{
    GLuint unit;
    GLbitfield samplers_used;
    const GLuint old_max = *num_samplers;

    samplers_used = prog->SamplersUsed;

    if (*num_samplers == 0 && samplers_used == 0x0)
        return;

    *num_samplers = 0;

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

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

            convert_sampler(st, sampler, texUnit);

            *num_samplers = unit + 1;

            cso_single_sampler(st->cso_context, shader_stage, unit, sampler);
        }
        else if (samplers_used != 0 || unit < old_max) {
            cso_single_sampler(st->cso_context, shader_stage, unit, NULL);
        }
        else {
            /* if we've reset all the old samplers and we have no more new ones */
            break;
        }
    }

    cso_single_sampler_done(st->cso_context, shader_stage);
}
Пример #2
0
/**
 * Update the gallium driver's sampler state for fragment, vertex or
 * geometry shader stage.
 */
static void
update_shader_samplers(struct st_context *st,
                       enum pipe_shader_type shader_stage,
                       const struct gl_program *prog,
                       unsigned max_units,
                       struct pipe_sampler_state *samplers,
                       unsigned *num_samplers)
{
   GLbitfield samplers_used = prog->SamplersUsed;
   GLbitfield free_slots = ~prog->SamplersUsed;
   GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
   GLuint unit;
   const GLuint old_max = *num_samplers;
   const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS];

   if (*num_samplers == 0 && samplers_used == 0x0)
      return;

   *num_samplers = 0;

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

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

         convert_sampler(st, sampler, texUnit);
         states[unit] = sampler;
         *num_samplers = unit + 1;
      }
      else if (samplers_used != 0 || unit < old_max) {
         states[unit] = NULL;
      }
      else {
         /* if we've reset all the old samplers and we have no more new ones */
         break;
      }
   }

   /* For any external samplers with multiplaner YUV, stuff the additional
    * sampler states we need at the end.
    *
    * Just re-use the existing sampler-state from the primary slot.
    */
   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_state *sampler = samplers + unit;

      if (!stObj)
         continue;

      switch (st_get_view_format(stObj)) {
      case PIPE_FORMAT_NV12:
         /* we need one additional sampler: */
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         break;
      case PIPE_FORMAT_IYUV:
         /* we need two additional samplers: */
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         break;
      default:
         break;
      }

      *num_samplers = MAX2(*num_samplers, extra + 1);
   }

   cso_set_samplers(st->cso_context, shader_stage, *num_samplers, states);
}