Example #1
0
/**
 * Copy an image between textures with the vgpu10 CopyRegion command.
 */
static void
copy_region_vgpu10(struct svga_context *svga, struct pipe_resource *src_tex,
                    unsigned src_x, unsigned src_y, unsigned src_z,
                    unsigned src_level, unsigned src_layer_face,
                    struct pipe_resource *dst_tex,
                    unsigned dst_x, unsigned dst_y, unsigned dst_z,
                    unsigned dst_level, unsigned dst_layer_face,
                    unsigned width, unsigned height, unsigned depth)
{
   uint32 srcSubResource, dstSubResource;
   struct svga_texture *dtex, *stex;

   stex = svga_texture(src_tex);
   dtex = svga_texture(dst_tex);

   svga_surfaces_flush(svga);

   srcSubResource = src_layer_face * (src_tex->last_level + 1) + src_level;
   dstSubResource = dst_layer_face * (dst_tex->last_level + 1) + dst_level;

   svga_texture_copy_region(svga, stex->handle, srcSubResource,
                            src_x, src_y, src_z,
                            dtex->handle, dstSubResource,
                            dst_x, dst_y, dst_z,
                            width, height, depth);

   /* Mark the texture subresource as defined. */
   svga_define_texture_level(dtex, dst_layer_face, dst_level);

   /* Mark the texture subresource as rendered-to. */
   svga_set_texture_rendered_to(dtex, dst_layer_face, dst_level);
}
Example #2
0
/**
 * Copy when src texture and dst texture are same with IntraSurfaceCopy
 * command.
 */
static void
intra_surface_copy(struct svga_context *svga, struct pipe_resource *tex,
                    unsigned src_x, unsigned src_y, unsigned src_z,
                    unsigned level, unsigned layer_face,
                    unsigned dst_x, unsigned dst_y, unsigned dst_z,
                    unsigned width, unsigned height, unsigned depth)
{
   enum pipe_error ret;
   SVGA3dCopyBox box;
   struct svga_texture *stex;

   /*
    * Makes sure we have flushed all buffered draw operations and also
    * synchronizes all surfaces with any emulated surface views.
    */
   svga_surfaces_flush(svga);

   stex = svga_texture(tex);

   box.x = dst_x;
   box.y = dst_y;
   box.z = dst_z;
   box.w = width;
   box.h = height;
   box.d = depth;
   box.srcx = src_x;
   box.srcy = src_y;
   box.srcz = src_z;

   ret = SVGA3D_vgpu10_IntraSurfaceCopy(svga->swc,
                                 stex->handle, level, layer_face,  &box);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
   ret = SVGA3D_vgpu10_IntraSurfaceCopy(svga->swc,
                                 stex->handle, level, layer_face, &box);
      assert(ret == PIPE_OK);
   }

   /* Mark the texture subresource as rendered-to. */
   svga_set_texture_rendered_to(stex, layer_face, level);
}
Example #3
0
static void svga_set_framebuffer_state(struct pipe_context *pipe,
				       const struct pipe_framebuffer_state *fb)
{
   struct svga_context *svga = svga_context(pipe);
   struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;
   boolean propagate = FALSE;
   unsigned i;

   /* make sure any pending drawing calls are flushed before changing
    * the framebuffer state
    */
   svga_hwtnl_flush_retry(svga);

   dst->width = fb->width;
   dst->height = fb->height;
   dst->nr_cbufs = fb->nr_cbufs;

   /* check if we need to propagate any of the target surfaces */
   for (i = 0; i < dst->nr_cbufs; i++) {
      struct pipe_surface *s = i < fb->nr_cbufs ? fb->cbufs[i] : NULL;
      if (dst->cbufs[i] && dst->cbufs[i] != s) {
         if (svga_surface_needs_propagation(dst->cbufs[i])) {
            propagate = TRUE;
            break;
         }
      }
   }

   if (propagate) {
      for (i = 0; i < dst->nr_cbufs; i++) {
         struct pipe_surface *s = i < fb->nr_cbufs ? fb->cbufs[i] : NULL;
         if (dst->cbufs[i] && dst->cbufs[i] != s)
            svga_propagate_surface(svga, dst->cbufs[i]);
      }
   }

   /* Check that all surfaces are the same size.
    * Actually, the virtual hardware may support rendertargets with
    * different size, depending on the host API and driver,
    */
   {
      int width = 0, height = 0;
      if (fb->zsbuf) {
         width = fb->zsbuf->width;
         height = fb->zsbuf->height;
      }
      for (i = 0; i < fb->nr_cbufs; ++i) {
         if (fb->cbufs[i]) {
            if (width && height) {
               if (fb->cbufs[i]->width != width ||
                   fb->cbufs[i]->height != height) {
                  debug_warning("Mixed-size color and depth/stencil surfaces "
                                "may not work properly");
               }
            }
            else {
               width = fb->cbufs[i]->width;
               height = fb->cbufs[i]->height;
            }
         }
      }
   }

   util_copy_framebuffer_state(dst, fb);

   /* Set the rendered-to flags */
   for (i = 0; i < dst->nr_cbufs; i++) {
      struct pipe_surface *s = dst->cbufs[i];
      if (s) {
         struct svga_texture *t = svga_texture(s->texture);
         svga_set_texture_rendered_to(t, s->u.tex.first_layer, s->u.tex.level);
      }
   }

   if (svga->curr.framebuffer.zsbuf)
   {
      switch (svga->curr.framebuffer.zsbuf->format) {
      case PIPE_FORMAT_Z16_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;
         break;
      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
      case PIPE_FORMAT_Z24X8_UNORM:
      case PIPE_FORMAT_S8_UINT_Z24_UNORM:
      case PIPE_FORMAT_X8Z24_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;
         break;
      case PIPE_FORMAT_Z32_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;
         break;
      case PIPE_FORMAT_Z32_FLOAT:
         svga->curr.depthscale = 1.0f / ((float)(1<<23));
         break;
      default:
         svga->curr.depthscale = 0.0f;
         break;
      }

      /* Set rendered-to flag */
      {
         struct pipe_surface *s = dst->zsbuf;
         struct svga_texture *t = svga_texture(s->texture);
         svga_set_texture_rendered_to(t, s->u.tex.first_layer, s->u.tex.level);
      }
   }
   else {
      svga->curr.depthscale = 0.0f;
   }

   svga->dirty |= SVGA_NEW_FRAME_BUFFER;
}
Example #4
0
/**
 * Try region copy using one of the region copy commands
 */
static bool
try_copy_region(struct svga_context *svga,
                const struct pipe_blit_info *blit)
{
   unsigned src_layer_face, src_z, dst_layer_face, dst_z;

   if (!can_blit_via_svga_copy_region(svga, blit))
      return false;

   adjust_z_layer(blit->src.resource->target, blit->src.box.z,
                  &src_layer_face, &src_z);

   adjust_z_layer(blit->dst.resource->target, blit->dst.box.z,
                  &dst_layer_face, &dst_z);

   if (can_blit_via_copy_region_vgpu10(svga, blit)) {
      svga_toggle_render_condition(svga, blit->render_condition_enable, FALSE);

      copy_region_vgpu10(svga,
                         blit->src.resource,
                         blit->src.box.x, blit->src.box.y, src_z,
                         blit->src.level, src_layer_face,
                         blit->dst.resource,
                         blit->dst.box.x, blit->dst.box.y, dst_z,
                         blit->dst.level, dst_layer_face,
                         blit->src.box.width, blit->src.box.height,
                         blit->src.box.depth);

      svga_toggle_render_condition(svga, blit->render_condition_enable, TRUE);

      return true;
   }

   if (can_blit_via_surface_copy(svga, blit)) {
      struct svga_texture *stex = svga_texture(blit->src.resource);
      struct svga_texture *dtex = svga_texture(blit->dst.resource);

      svga_surfaces_flush(svga);

      svga_texture_copy_handle(svga,
                               stex->handle,
                               blit->src.box.x, blit->src.box.y, src_z,
                               blit->src.level, src_layer_face,
                               dtex->handle,
                               blit->dst.box.x, blit->dst.box.y, dst_z,
                               blit->dst.level, dst_layer_face,
                               blit->src.box.width, blit->src.box.height,
                               blit->src.box.depth);

      svga_define_texture_level(dtex, dst_layer_face, blit->dst.level);
      svga_set_texture_rendered_to(dtex, dst_layer_face, blit->dst.level);
      return true;
   }

   if (can_blit_via_intra_surface_copy(svga, blit)) {
      intra_surface_copy(svga,
                         blit->src.resource,
                         blit->src.box.x, blit->src.box.y, src_z,
                         blit->src.level, src_layer_face,
                         blit->dst.box.x, blit->dst.box.y, dst_z,
                         blit->src.box.width, blit->src.box.height,
                         blit->src.box.depth);
      return true;
   }

   return false;
}
Example #5
0
static void svga_set_framebuffer_state(struct pipe_context *pipe,
				       const struct pipe_framebuffer_state *fb)
{
   struct svga_context *svga = svga_context(pipe);
   struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;
   boolean propagate = FALSE;
   unsigned i;

   dst->width = fb->width;
   dst->height = fb->height;
   dst->nr_cbufs = fb->nr_cbufs;

   /* check if we need to propagate any of the target surfaces */
   for (i = 0; i < dst->nr_cbufs; i++) {
      struct pipe_surface *s = i < fb->nr_cbufs ? fb->cbufs[i] : NULL;
      if (dst->cbufs[i] && dst->cbufs[i] != s) {
         if (svga_surface_needs_propagation(dst->cbufs[i])) {
            propagate = TRUE;
            break;
         }
      }
   }

   if (propagate) {
      /* make sure that drawing calls comes before propagation calls */
      svga_hwtnl_flush_retry( svga );
   
      for (i = 0; i < dst->nr_cbufs; i++) {
         struct pipe_surface *s = i < fb->nr_cbufs ? fb->cbufs[i] : NULL;
         if (dst->cbufs[i] && dst->cbufs[i] != s)
            svga_propagate_surface(svga, dst->cbufs[i]);
      }
   }

   /* XXX: Actually the virtual hardware may support rendertargets with
    * different size, depending on the host API and driver, but since we cannot
    * know that make no such assumption here. */
   for(i = 0; i < fb->nr_cbufs; ++i) {
      if (fb->zsbuf && fb->cbufs[i]) {
         assert(fb->zsbuf->width == fb->cbufs[i]->width); 
         assert(fb->zsbuf->height == fb->cbufs[i]->height); 
      }
   }

   util_copy_framebuffer_state(dst, fb);

   /* Set the rendered-to flags */
   for (i = 0; i < dst->nr_cbufs; i++) {
      struct pipe_surface *s = dst->cbufs[i];
      if (s) {
         struct svga_texture *t = svga_texture(s->texture);
         svga_set_texture_rendered_to(t, s->u.tex.first_layer, s->u.tex.level);
      }
   }

   if (svga->curr.framebuffer.zsbuf)
   {
      switch (svga->curr.framebuffer.zsbuf->format) {
      case PIPE_FORMAT_Z16_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;
         break;
      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
      case PIPE_FORMAT_Z24X8_UNORM:
      case PIPE_FORMAT_S8_UINT_Z24_UNORM:
      case PIPE_FORMAT_X8Z24_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;
         break;
      case PIPE_FORMAT_Z32_UNORM:
         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;
         break;
      case PIPE_FORMAT_Z32_FLOAT:
         svga->curr.depthscale = 1.0f / ((float)(1<<23));
         break;
      default:
         svga->curr.depthscale = 0.0f;
         break;
      }

      /* Set rendered-to flag */
      {
         struct pipe_surface *s = dst->zsbuf;
         struct svga_texture *t = svga_texture(s->texture);
         svga_set_texture_rendered_to(t, s->u.tex.first_layer, s->u.tex.level);
      }
   }
   else {
      svga->curr.depthscale = 0.0f;
   }

   svga->dirty |= SVGA_NEW_FRAME_BUFFER;
}