Exemple #1
0
static enum pipe_error
draw_vgpu9(struct svga_hwtnl *hwtnl)
{
   struct svga_winsys_context *swc = hwtnl->cmd.swc;
   struct svga_context *svga = hwtnl->svga;
   enum pipe_error ret;
   struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
   struct svga_winsys_surface *ib_handle[QSZ];
   struct svga_winsys_surface *handle;
   SVGA3dVertexDecl *vdecl;
   SVGA3dPrimitiveRange *prim;
   unsigned i;

   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
      unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
      handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer);
      if (handle == NULL)
         return PIPE_ERROR_OUT_OF_MEMORY;

      vb_handle[i] = handle;
   }

   for (i = 0; i < hwtnl->cmd.prim_count; i++) {
      if (hwtnl->cmd.prim_ib[i]) {
         handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
         if (handle == NULL)
            return PIPE_ERROR_OUT_OF_MEMORY;
      }
      else
         handle = NULL;

      ib_handle[i] = handle;
   }

   if (svga->rebind.flags.rendertargets) {
      ret = svga_reemit_framebuffer_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   if (svga->rebind.flags.texture_samplers) {
      ret = svga_reemit_tss_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   if (svga->rebind.flags.vs) {
      ret = svga_reemit_vs_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   if (svga->rebind.flags.fs) {
      ret = svga_reemit_fs_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
            svga->curr.framebuffer.cbufs[0] ?
            svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
            hwtnl->cmd.prim_count);

   ret = SVGA3D_BeginDrawPrimitives(swc,
                                    &vdecl,
                                    hwtnl->cmd.vdecl_count,
                                    &prim, hwtnl->cmd.prim_count);
   if (ret != PIPE_OK)
      return ret;

   memcpy(vdecl,
          hwtnl->cmd.vdecl,
          hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);

   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
      /* check for 4-byte alignment */
      assert(vdecl[i].array.offset % 4 == 0);
      assert(vdecl[i].array.stride % 4 == 0);

      /* Given rangeHint is considered to be relative to indexBias, and
       * indexBias varies per primitive, we cannot accurately supply an
       * rangeHint when emitting more than one primitive per draw command.
       */
      if (hwtnl->cmd.prim_count == 1) {
         vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
         vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
      }
      else {
         vdecl[i].rangeHint.first = 0;
         vdecl[i].rangeHint.last = 0;
      }

      swc->surface_relocation(swc,
                              &vdecl[i].array.surfaceId,
                              NULL, vb_handle[i], SVGA_RELOC_READ);
   }

   memcpy(prim,
          hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);

   for (i = 0; i < hwtnl->cmd.prim_count; i++) {
      swc->surface_relocation(swc,
                              &prim[i].indexArray.surfaceId,
                              NULL, ib_handle[i], SVGA_RELOC_READ);
      pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
   }

   SVGA_FIFOCommitAll(swc);

   hwtnl->cmd.prim_count = 0;

   return PIPE_OK;
}
Exemple #2
0
static enum pipe_error
try_clear(struct svga_context *svga, 
          unsigned buffers,
          const union pipe_color_union *color,
          double depth,
          unsigned stencil)
{
   enum pipe_error ret = PIPE_OK;
   SVGA3dRect rect = { 0, 0, 0, 0 };
   boolean restore_viewport = FALSE;
   SVGA3dClearFlag flags = 0;
   struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
   union util_color uc = {0};

   ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR);
   if (ret != PIPE_OK)
      return ret;

   if (svga->rebind.rendertargets) {
      ret = svga_reemit_framebuffer_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   if (buffers & PIPE_CLEAR_COLOR) {
      flags |= SVGA3D_CLEAR_COLOR;
      util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);

      rect.w = fb->width;
      rect.h = fb->height;
   }

   if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
      if (buffers & PIPE_CLEAR_DEPTH)
         flags |= SVGA3D_CLEAR_DEPTH;

      if ((svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) &&
          (buffers & PIPE_CLEAR_STENCIL))
         flags |= SVGA3D_CLEAR_STENCIL;

      rect.w = MAX2(rect.w, fb->zsbuf->width);
      rect.h = MAX2(rect.h, fb->zsbuf->height);
   }

   if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
      restore_viewport = TRUE;
      ret = SVGA3D_SetViewport(svga->swc, &rect);
      if (ret != PIPE_OK)
         return ret;
   }

   ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, (float) depth, stencil,
                          rect.x, rect.y, rect.w, rect.h);
   if (ret != PIPE_OK)
      return ret;

   if (restore_viewport) {
      memcpy(&rect, &svga->state.hw_clear.viewport, sizeof rect);
      ret = SVGA3D_SetViewport(svga->swc, &rect);
   }
   
   return ret;
}
static enum pipe_error
try_clear(struct svga_context *svga, 
          unsigned buffers,
          const union pipe_color_union *color,
          double depth,
          unsigned stencil)
{
   enum pipe_error ret = PIPE_OK;
   SVGA3dRect rect = { 0, 0, 0, 0 };
   boolean restore_viewport = FALSE;
   SVGA3dClearFlag flags = 0;
   struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
   union util_color uc = {0};

   ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR);
   if (ret != PIPE_OK)
      return ret;

   if (svga->rebind.flags.rendertargets) {
      ret = svga_reemit_framebuffer_bindings(svga);
      if (ret != PIPE_OK) {
         return ret;
      }
   }

   if (buffers & PIPE_CLEAR_COLOR) {
      flags |= SVGA3D_CLEAR_COLOR;
      util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);

      rect.w = fb->width;
      rect.h = fb->height;
   }

   if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
      if (buffers & PIPE_CLEAR_DEPTH)
         flags |= SVGA3D_CLEAR_DEPTH;

      if (buffers & PIPE_CLEAR_STENCIL)
         flags |= SVGA3D_CLEAR_STENCIL;

      rect.w = MAX2(rect.w, fb->zsbuf->width);
      rect.h = MAX2(rect.h, fb->zsbuf->height);
   }

   if (!svga_have_vgpu10(svga) &&
       !svga_rects_equal(&rect, &svga->state.hw_clear.viewport)) {
      restore_viewport = TRUE;
      ret = SVGA3D_SetViewport(svga->swc, &rect);
      if (ret != PIPE_OK)
         return ret;
   }

   if (svga_have_vgpu10(svga)) {
      if (flags & SVGA3D_CLEAR_COLOR) {
         unsigned i;

         if (is_integer_target(fb, buffers) && !ints_fit_in_floats(color)) {
            clear_buffers_with_quad(svga, buffers, color, depth, stencil);
            /* We also cleared depth/stencil, so that's done */
            flags &= ~(SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL);
         }
         else {
            struct pipe_surface *rtv;

            /* Issue VGPU10 Clear commands */
            for (i = 0; i < fb->nr_cbufs; i++) {
               if ((fb->cbufs[i] == NULL) ||
                   !(buffers & (PIPE_CLEAR_COLOR0 << i)))
                  continue;

               rtv = svga_validate_surface_view(svga,
                                                svga_surface(fb->cbufs[i]));
               if (!rtv)
                  return PIPE_ERROR_OUT_OF_MEMORY;

               ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc,
                                                         rtv, color->f);
               if (ret != PIPE_OK)
                  return ret;
            }
         }
      }
      if (flags & (SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL)) {
         struct pipe_surface *dsv =
            svga_validate_surface_view(svga, svga_surface(fb->zsbuf));
         if (!dsv)
            return PIPE_ERROR_OUT_OF_MEMORY;

         ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, flags,
                                                   stencil, (float) depth);
         if (ret != PIPE_OK)
            return ret;
      }
   }
   else {
      ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui[0], (float) depth, stencil,
                             rect.x, rect.y, rect.w, rect.h);
      if (ret != PIPE_OK)
         return ret;
   }

   if (restore_viewport) {
      ret = SVGA3D_SetViewport(svga->swc, &svga->state.hw_clear.viewport);
   }
   
   return ret;
}