Esempio n. 1
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);
}
Esempio n. 2
0
/**
 * Make all bindless images bound to image units resident in the context.
 */
void
st_make_bound_images_resident(struct st_context *st,
                              struct gl_program *prog)
{
   enum pipe_shader_type shader = st_shader_stage_to_ptarget(prog->info.stage);
   struct st_bound_handles *bound_handles = &st->bound_image_handles[shader];
   struct pipe_context *pipe = st->pipe;
   GLuint64 handle;
   int i;

   /* Remove previous bound image handles for this stage. */
   st_destroy_bound_image_handles_per_stage(st, shader);

   if (likely(!prog->sh.HasBoundBindlessImage))
      return;

   for (i = 0; i < prog->sh.NumBindlessImages; i++) {
      struct gl_bindless_image *image = &prog->sh.BindlessImages[i];

      if (!image->bound)
         continue;

      /* Request a new image handle from the driver and make it resident. */
      handle = st_create_image_handle_from_unit(st, prog, image->unit);
      if (!handle)
         continue;

      pipe->make_image_handle_resident(st->pipe, handle, GL_READ_WRITE, true);

      /* Overwrite the image unit value by the resident handle before uploading
       * the constant buffer.
       */
      *(uint64_t *)image->data = handle;

      /* Store the handle in the context. */
      bound_handles->handles = (uint64_t *)
         realloc(bound_handles->handles,
                 (bound_handles->num_handles + 1) * sizeof(uint64_t));
      bound_handles->handles[bound_handles->num_handles] = handle;
      bound_handles->num_handles++;
   }
}
Esempio n. 3
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);
}
Esempio n. 4
0
/**
 * Pass the given program parameters to the graphics pipe as a
 * constant buffer.
 * \param shader_type  either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
 */
void st_upload_constants( struct st_context *st,
                          struct gl_program_parameter_list *params,
                          gl_shader_stage stage)
{
   enum pipe_shader_type shader_type = st_shader_stage_to_ptarget(stage);

   assert(shader_type == PIPE_SHADER_VERTEX ||
          shader_type == PIPE_SHADER_FRAGMENT ||
          shader_type == PIPE_SHADER_GEOMETRY ||
          shader_type == PIPE_SHADER_TESS_CTRL ||
          shader_type == PIPE_SHADER_TESS_EVAL ||
          shader_type == PIPE_SHADER_COMPUTE);

   /* update the ATI constants before rendering */
   if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) {
      struct ati_fragment_shader *ati_fs = st->fp->ati_fs;
      unsigned c;

      for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) {
         if (ati_fs->LocalConstDef & (1 << c))
            memcpy(params->ParameterValues[c],
                   ati_fs->Constants[c], sizeof(GLfloat) * 4);
         else
            memcpy(params->ParameterValues[c],
                   st->ctx->ATIFragmentShader.GlobalConstants[c], sizeof(GLfloat) * 4);
      }
   }

   /* update constants */
   if (params && params->NumParameters) {
      struct pipe_constant_buffer cb;
      const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;

      /* Update the constants which come from fixed-function state, such as
       * transformation matrices, fog factors, etc.  The rest of the values in
       * the parameters list are explicitly set by the user with glUniform,
       * glProgramParameter(), etc.
       */
      if (params->StateFlags)
         _mesa_load_state_parameters(st->ctx, params);

      _mesa_shader_write_subroutine_indices(st->ctx, stage);

      /* We always need to get a new buffer, to keep the drivers simple and
       * avoid gratuitous rendering synchronization.
       * Let's use a user buffer to avoid an unnecessary copy.
       */
      if (st->constbuf_uploader) {
         cb.buffer = NULL;
         cb.user_buffer = NULL;
         u_upload_data(st->constbuf_uploader, 0, paramBytes,
                       st->ctx->Const.UniformBufferOffsetAlignment,
                       params->ParameterValues, &cb.buffer_offset, &cb.buffer);
         u_upload_unmap(st->constbuf_uploader);
      } else {
         cb.buffer = NULL;
         cb.user_buffer = params->ParameterValues;
         cb.buffer_offset = 0;
      }
      cb.buffer_size = paramBytes;

      if (ST_DEBUG & DEBUG_CONSTANTS) {
         debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
                      __func__, shader_type, params->NumParameters,
                      params->StateFlags);
         _mesa_print_parameter_list(params);
      }

      cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
      pipe_resource_reference(&cb.buffer, NULL);

      st->state.constants[shader_type].ptr = params->ParameterValues;
      st->state.constants[shader_type].size = paramBytes;
   }
   else if (st->state.constants[shader_type].ptr) {
      /* Unbind. */
      st->state.constants[shader_type].ptr = NULL;
      st->state.constants[shader_type].size = 0;
      cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL);
   }
}