Exemplo n.º 1
0
static int
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   unsigned i;
   unsigned count = MAX2( svga->curr.num_textures,
                          svga->state.hw_draw.num_views );
   unsigned min_lod;
   unsigned max_lod;


   struct {
      struct {
         unsigned unit;
         struct svga_hw_view_state *view;
      } bind[PIPE_MAX_SAMPLERS];

      unsigned bind_count;
   } queue;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      const struct svga_sampler_state *s = svga->curr.sampler[i];
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];

      /* get min max lod */
      if (svga->curr.texture[i]) {
         min_lod = MAX2(s->view_min_lod, 0);
         max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
      } else {
         min_lod = 0;
         max_lod = 0;
      }

      if (view->texture != svga->curr.texture[i] ||
          view->min_lod != min_lod ||
          view->max_lod != max_lod) {

         svga_sampler_view_reference(&view->v, NULL);
         pipe_texture_reference( &view->texture, svga->curr.texture[i] );

         view->dirty = TRUE;
         view->min_lod = min_lod;
         view->max_lod = max_lod;

         if (svga->curr.texture[i])
            view->v = svga_get_tex_sampler_view(&svga->pipe, 
                                                svga->curr.texture[i], 
                                                min_lod,
                                                max_lod);
      }

      if (view->dirty) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      } 
      else if (view->v) {
         svga_validate_sampler_view(svga, view->v);
      }
   }

   svga->state.hw_draw.num_views = svga->curr.num_textures;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (queue.bind[i].view->v) {
            svga->swc->surface_relocation(svga->swc,
                                          &ts[i].value,
                                          queue.bind[i].view->v->handle,
                                          PIPE_BUFFER_USAGE_GPU_READ);
         }
         else {
            ts[i].value = SVGA3D_INVALID_ID;
         }
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   return 0;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}
Exemplo n.º 2
0
static int
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   boolean reemit = svga->rebind.texture_samplers;
   unsigned i;
   unsigned count = MAX2( svga->curr.num_sampler_views,
                          svga->state.hw_draw.num_views );
   unsigned min_lod;
   unsigned max_lod;

   struct bind_queue queue;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      const struct svga_sampler_state *s = svga->curr.sampler[i];
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
      struct pipe_resource *texture = NULL;

      /* get min max lod */
      if (svga->curr.sampler_views[i]) {
         min_lod = MAX2(s->view_min_lod, 0);
         max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level);
         texture = svga->curr.sampler_views[i]->texture;
      } else {
         min_lod = 0;
         max_lod = 0;
      }

      if (view->texture != texture ||
          view->min_lod != min_lod ||
          view->max_lod != max_lod) {

         svga_sampler_view_reference(&view->v, NULL);
         pipe_resource_reference( &view->texture, texture );

         view->dirty = TRUE;
         view->min_lod = min_lod;
         view->max_lod = max_lod;

         if (texture)
            view->v = svga_get_tex_sampler_view(&svga->pipe, 
                                                texture, 
                                                min_lod,
                                                max_lod);
      }

      /*
       * We need to reemit non-null texture bindings, even when they are not
       * dirty, to ensure that the resources are paged in.
       */

      if (view->dirty ||
          (reemit && view->v)) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      } 
      if (!view->dirty && view->v) {
         svga_validate_sampler_view(svga, view->v);
      }
   }

   svga->state.hw_draw.num_views = svga->curr.num_sampler_views;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         struct svga_winsys_surface *handle;

         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (queue.bind[i].view->v) {
            handle = queue.bind[i].view->v->handle;
         }
         else {
            handle = NULL;
         }
         svga->swc->surface_relocation(svga->swc,
                                       &ts[i].value,
                                       handle,
                                       SVGA_RELOC_READ);
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   svga->rebind.texture_samplers = FALSE;

   return 0;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}