enum pipe_error
svga_buffer_create_host_surface(struct svga_screen *ss,
                                struct svga_buffer *sbuf)
{
   assert(!sbuf->user);

   if (!sbuf->handle) {
      sbuf->key.flags = 0;

      sbuf->key.format = SVGA3D_BUFFER;
      if (sbuf->bind_flags & PIPE_BIND_VERTEX_BUFFER) {
         sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
         sbuf->key.flags |= SVGA3D_SURFACE_BIND_VERTEX_BUFFER;
      }
      if (sbuf->bind_flags & PIPE_BIND_INDEX_BUFFER) {
         sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
         sbuf->key.flags |= SVGA3D_SURFACE_BIND_INDEX_BUFFER;
      }
      if (sbuf->bind_flags & PIPE_BIND_CONSTANT_BUFFER)
         sbuf->key.flags |= SVGA3D_SURFACE_BIND_CONSTANT_BUFFER;

      if (sbuf->bind_flags & PIPE_BIND_STREAM_OUTPUT)
         sbuf->key.flags |= SVGA3D_SURFACE_BIND_STREAM_OUTPUT;

      if (sbuf->bind_flags & PIPE_BIND_SAMPLER_VIEW)
         sbuf->key.flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE;

      sbuf->key.size.width = sbuf->b.b.width0;
      sbuf->key.size.height = 1;
      sbuf->key.size.depth = 1;

      sbuf->key.numFaces = 1;
      sbuf->key.numMipLevels = 1;
      sbuf->key.cachable = 1;
      sbuf->key.arraySize = 1;

      SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->b.b.width0);

      sbuf->handle = svga_screen_surface_create(ss, sbuf->b.b.bind,
                                                sbuf->b.b.usage, &sbuf->key);
      if (!sbuf->handle)
         return PIPE_ERROR_OUT_OF_MEMORY;

      /* Always set the discard flag on the first time the buffer is written
       * as svga_screen_surface_create might have passed a recycled host
       * buffer.
       */
      sbuf->dma.flags.discard = TRUE;

      SVGA_DBG(DEBUG_DMA, "   --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->b.b.width0);
   }

   return PIPE_OK;
}
static INLINE enum pipe_error
svga_buffer_create_host_surface(struct svga_screen *ss,
                                struct svga_buffer *sbuf)
{
   if(!sbuf->handle) {
      sbuf->key.flags = 0;
      
      sbuf->key.format = SVGA3D_BUFFER;
      if(sbuf->base.usage & PIPE_BUFFER_USAGE_VERTEX)
         sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
      if(sbuf->base.usage & PIPE_BUFFER_USAGE_INDEX)
         sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
      
      sbuf->key.size.width = sbuf->base.size;
      sbuf->key.size.height = 1;
      sbuf->key.size.depth = 1;
      
      sbuf->key.numFaces = 1;
      sbuf->key.numMipLevels = 1;
      sbuf->key.cachable = 1;
      
      SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size);

      sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
      if(!sbuf->handle)
         return PIPE_ERROR_OUT_OF_MEMORY;
   
      /* Always set the discard flag on the first time the buffer is written
       * as svga_screen_surface_create might have passed a recycled host
       * buffer.
       */
      sbuf->dma.flags.discard = TRUE;

      SVGA_DBG(DEBUG_DMA, "   --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
   }
   
   return PIPE_OK;
}   
struct svga_winsys_surface *
svga_texture_view_surface(struct pipe_context *pipe,
                          struct svga_texture *tex,
                          SVGA3dSurfaceFormat format,
                          unsigned start_mip,
                          unsigned num_mip,
                          int face_pick,
                          int zslice_pick,
                          struct svga_host_surface_cache_key *key) /* OUT */
{
   struct svga_screen *ss = svga_screen(pipe->screen);
   struct svga_winsys_surface *handle;
   uint32_t i, j;
   unsigned z_offset = 0;

   SVGA_DBG(DEBUG_PERF, 
            "svga: Create surface view: face %d zslice %d mips %d..%d\n",
            face_pick, zslice_pick, start_mip, start_mip+num_mip-1);

   key->flags = 0;
   key->format = format;
   key->numMipLevels = num_mip;
   key->size.width = u_minify(tex->b.b.width0, start_mip);
   key->size.height = u_minify(tex->b.b.height0, start_mip);
   key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
   key->cachable = 1;
   assert(key->size.depth == 1);
   
   if(tex->b.b.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
      key->flags |= SVGA3D_SURFACE_CUBEMAP;
      key->numFaces = 6;
   } else {
      key->numFaces = 1;
   }

   if(key->format == SVGA3D_FORMAT_INVALID) {
      key->cachable = 0;
      return NULL;
   }

   SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
   handle = svga_screen_surface_create(ss, key);
   if (!handle) {
      key->cachable = 0;
      return NULL;
   }

   SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);

   if (face_pick < 0)
      face_pick = 0;

   if (zslice_pick >= 0)
       z_offset = zslice_pick;

   for (i = 0; i < key->numMipLevels; i++) {
      for (j = 0; j < key->numFaces; j++) {
         if(tex->defined[j + face_pick][i + start_mip]) {
            unsigned depth = (zslice_pick < 0 ?
                              u_minify(tex->b.b.depth0, i + start_mip) :
                              1);

            svga_texture_copy_handle(svga_context(pipe),
                                     tex->handle, 
                                     0, 0, z_offset, 
                                     i + start_mip, 
                                     j + face_pick,
                                     handle, 0, 0, 0, i, j,
                                     u_minify(tex->b.b.width0, i + start_mip),
                                     u_minify(tex->b.b.height0, i + start_mip),
                                     depth);
         }
      }
   }

   return handle;
}
Example #4
0
struct svga_winsys_surface *
svga_texture_view_surface(struct svga_context *svga,
                          struct svga_texture *tex,
                          unsigned bind_flags,
                          SVGA3dSurfaceFlags flags,
                          SVGA3dSurfaceFormat format,
                          unsigned start_mip,
                          unsigned num_mip,
                          int layer_pick,
                          unsigned num_layers,
                          int zslice_pick,
                          struct svga_host_surface_cache_key *key) /* OUT */
{
   struct svga_screen *ss = svga_screen(svga->pipe.screen);
   struct svga_winsys_surface *handle;
   uint32_t i, j;
   unsigned z_offset = 0;

   SVGA_DBG(DEBUG_PERF, 
            "svga: Create surface view: layer %d zslice %d mips %d..%d\n",
            layer_pick, zslice_pick, start_mip, start_mip+num_mip-1);

   key->flags = flags;
   key->format = format;
   key->numMipLevels = num_mip;
   key->size.width = u_minify(tex->b.b.width0, start_mip);
   key->size.height = u_minify(tex->b.b.height0, start_mip);
   key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
   key->cachable = 1;
   key->arraySize = 1;
   key->numFaces = 1;
   key->sampleCount = tex->b.b.nr_samples;

   if (key->sampleCount > 1) {
      key->flags |= SVGA3D_SURFACE_MASKABLE_ANTIALIAS;
   }
   
   if (tex->b.b.target == PIPE_TEXTURE_CUBE && layer_pick < 0) {
      key->flags |= SVGA3D_SURFACE_CUBEMAP;
      key->numFaces = 6;
   } else if (tex->b.b.target == PIPE_TEXTURE_1D_ARRAY ||
              tex->b.b.target == PIPE_TEXTURE_2D_ARRAY) {
      key->arraySize = num_layers;
   }

   if (key->format == SVGA3D_FORMAT_INVALID) {
      key->cachable = 0;
      return NULL;
   }

   SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
   handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, key);
   if (!handle) {
      key->cachable = 0;
      return NULL;
   }

   SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);

   if (layer_pick < 0)
      layer_pick = 0;

   if (zslice_pick >= 0)
      z_offset = zslice_pick;

   for (i = 0; i < key->numMipLevels; i++) {
      for (j = 0; j < key->numFaces * key->arraySize; j++) {
         if (svga_is_texture_level_defined(tex, j + layer_pick, i + start_mip)) {
            unsigned depth = (zslice_pick < 0 ?
                              u_minify(tex->b.b.depth0, i + start_mip) :
                              1);

            svga_texture_copy_handle(svga,
                                     tex->handle, 
                                     0, 0, z_offset, 
                                     i + start_mip, 
                                     j + layer_pick,
                                     handle, 0, 0, 0, i, j,
                                     u_minify(tex->b.b.width0, i + start_mip),
                                     u_minify(tex->b.b.height0, i + start_mip),
                                     depth);
         }
      }
   }

   return handle;
}