Exemplo n.º 1
0
/**
 * Check if we should call svga_propagate_surface on the surface.
 */
boolean
svga_surface_needs_propagation(const struct pipe_surface *surf)
{
   const struct svga_surface *s = svga_surface_const(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   return s->dirty && s->handle != tex->handle;
}
Exemplo n.º 2
0
static void
svga_surface_destroy(struct pipe_context *pipe,
                     struct pipe_surface *surf)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *t = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);
   enum pipe_error ret = PIPE_OK;

   /* Destroy the backed view surface if it exists */
   if (s->backed) {
      svga_surface_destroy(pipe, &s->backed->base);
      s->backed = NULL;
   }

   if (s->handle != t->handle) {
      SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
      svga_screen_surface_destroy(ss, &s->key, &s->handle);
   }

   if (s->view_id != SVGA3D_INVALID_ID) {
      unsigned try;

      assert(svga_have_vgpu10(svga));
      for (try = 0; try < 2; try++) {
         if (util_format_is_depth_or_stencil(s->base.format)) {
            ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
         }
         else {
            ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
         }
         if (ret == PIPE_OK)
            break;
         svga_context_flush(svga, NULL);
      }
      assert(ret == PIPE_OK);
      util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
   }

   pipe_resource_reference(&surf->texture, NULL);
   FREE(surf);

   svga->hud.num_surface_views--;
}


static void 
svga_mark_surface_dirty(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   if (!s->dirty) {
      s->dirty = TRUE;

      if (s->handle == tex->handle) {
         /* hmm so 3d textures always have all their slices marked ? */
         svga_define_texture_level(tex, surf->u.tex.first_layer,
                                   surf->u.tex.level);
      }
      else {
         /* this will happen later in svga_propagate_surface */
      }
   }

   /* Increment the view_age and texture age for this surface's mipmap
    * level so that any sampler views into the texture are re-validated too.
    */
   svga_age_texture_view(tex, surf->u.tex.level);
}


void
svga_mark_surfaces_dirty(struct svga_context *svga)
{
   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
   unsigned i;

   for (i = 0; i < svgascreen->max_color_buffers; i++) {
      if (svga->curr.framebuffer.cbufs[i])
         svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
   }
   if (svga->curr.framebuffer.zsbuf)
      svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
}


/**
 * Progagate any changes from surfaces to texture.
 * pipe is optional context to inline the blit command in.
 */
void
svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);
   unsigned zslice, layer;
   unsigned nlayers = 1;
   unsigned i;

   if (!s->dirty)
      return;

   if (surf->texture->target == PIPE_TEXTURE_CUBE) {
      zslice = 0;
      layer = surf->u.tex.first_layer;
   }
   else if (surf->texture->target == PIPE_TEXTURE_1D_ARRAY ||
            surf->texture->target == PIPE_TEXTURE_2D_ARRAY) {
      zslice = 0;
      layer = surf->u.tex.first_layer;
      nlayers = surf->u.tex.last_layer - surf->u.tex.first_layer + 1;
   }
   else {
      zslice = surf->u.tex.first_layer;
      layer = 0;
   }

   s->dirty = FALSE;
   ss->texture_timestamp++;
   svga_age_texture_view(tex, surf->u.tex.level);

   if (s->handle != tex->handle) {
      SVGA_DBG(DEBUG_VIEWS,
               "svga: Surface propagate: tex %p, level %u, from %p\n",
               tex, surf->u.tex.level, surf);
      for (i = 0; i < nlayers; i++) {
         svga_texture_copy_handle(svga,
                                  s->handle, 0, 0, 0, s->real_level, s->real_layer + i,
                                  tex->handle, 0, 0, zslice, surf->u.tex.level, layer + i,
                                  u_minify(tex->b.b.width0, surf->u.tex.level),
                                  u_minify(tex->b.b.height0, surf->u.tex.level), 1);
         svga_define_texture_level(tex, layer + i, surf->u.tex.level);
      }
   }
}


/**
 * Check if we should call svga_propagate_surface on the surface.
 */
boolean
svga_surface_needs_propagation(const struct pipe_surface *surf)
{
   const struct svga_surface *s = svga_surface_const(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   return s->dirty && s->handle != tex->handle;
}


static void
svga_get_sample_position(struct pipe_context *context,
                         unsigned sample_count, unsigned sample_index,
                         float *pos_out)
{
   /* We can't actually query the device to learn the sample positions.
    * These were grabbed from nvidia's driver.
    */
   static const float pos1[1][2] = {
      { 0.5, 0.5 }
   };
   static const float pos4[4][2] = {
      { 0.375000, 0.125000 },
      { 0.875000, 0.375000 },
      { 0.125000, 0.625000 },
      { 0.625000, 0.875000 }
   };
   static const float pos8[8][2] = {
      { 0.562500, 0.312500 },
      { 0.437500, 0.687500 },
      { 0.812500, 0.562500 },
      { 0.312500, 0.187500 },
      { 0.187500, 0.812500 },
      { 0.062500, 0.437500 },
      { 0.687500, 0.937500 },
      { 0.937500, 0.062500 }
   };
   static const float pos16[16][2] = {
      { 0.187500, 0.062500 },
      { 0.437500, 0.187500 },
      { 0.062500, 0.312500 },
      { 0.312500, 0.437500 },
      { 0.687500, 0.062500 },
      { 0.937500, 0.187500 },
      { 0.562500, 0.312500 },
      { 0.812500, 0.437500 },
      { 0.187500, 0.562500 },
      { 0.437500, 0.687500 },
      { 0.062500, 0.812500 },
      { 0.312500, 0.937500 },
      { 0.687500, 0.562500 },
      { 0.937500, 0.687500 },
      { 0.562500, 0.812500 },
      { 0.812500, 0.937500 }
   };
   const float (*positions)[2];

   switch (sample_count) {
   case 4:
      positions = pos4;
      break;
   case 8:
      positions = pos8;
      break;
   case 16:
      positions = pos16;
      break;
   default:
      positions = pos1;
   }

   pos_out[0] = positions[sample_index][0];
   pos_out[1] = positions[sample_index][1];
}


void
svga_init_surface_functions(struct svga_context *svga)
{
   svga->pipe.create_surface = svga_create_surface;
   svga->pipe.surface_destroy = svga_surface_destroy;
   svga->pipe.get_sample_position = svga_get_sample_position;
}