Ejemplo n.º 1
0
static enum pipe_error
try_clear(struct svga_context *svga, 
          unsigned buffers,
          const float *rgba,
          double depth,
          unsigned stencil)
{
   int 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)
      return ret;

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

   if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) {
      flags |= SVGA3D_CLEAR_COLOR;
      util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);

      rect.w = fb->cbufs[0]->width;
      rect.h = fb->cbufs[0]->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_USCALED_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)
         return ret;
   }

   ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, 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;
}
Ejemplo n.º 2
0
void
i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
                double depth, unsigned stencil,
                unsigned destx, unsigned desty, unsigned width, unsigned height)
{
   struct i915_context *i915 = i915_context(pipe);
   uint32_t clear_params, clear_color, clear_depth, clear_stencil,
            clear_color8888, packed_z_stencil;
   union util_color u_color;
   float f_depth = depth;
   struct i915_texture *cbuf_tex, *depth_tex;

   cbuf_tex = depth_tex = NULL;
   clear_params = 0;

   if (buffers & PIPE_CLEAR_COLOR) {
      struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];

      clear_params |= CLEARPARAM_WRITE_COLOR;
      cbuf_tex = i915_texture(cbuf->texture);
      util_pack_color(rgba, cbuf->format, &u_color);
      if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4)
         clear_color = u_color.ui;
      else
         clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);

      util_pack_color(rgba, cbuf->format, &u_color);
      clear_color8888 = u_color.ui;
   } else
      clear_color = clear_color8888 = 0;

   clear_depth = clear_stencil = 0;
   if (buffers & PIPE_CLEAR_DEPTH) {
      struct pipe_surface *zbuf = i915->framebuffer.zsbuf;

      clear_params |= CLEARPARAM_WRITE_DEPTH;
      depth_tex = i915_texture(zbuf->texture);
      packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);

      if (util_format_get_blocksize(depth_tex->b.b.format) == 4) {
         /* Avoid read-modify-write if there's no stencil. */
         if (buffers & PIPE_CLEAR_STENCIL
               || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_USCALED) {
            clear_params |= CLEARPARAM_WRITE_STENCIL;
            clear_stencil = packed_z_stencil & 0xff;
            clear_depth = packed_z_stencil;
         } else
            clear_depth = packed_z_stencil & 0xffffff00;
      } else {
         clear_depth = (clear_depth & 0xffff) | (clear_depth << 16);
      }
   }

   if (i915->hardware_dirty)
      i915_emit_hardware_state(i915);

   if (!BEGIN_BATCH(7 + 7)) {
      FLUSH_BATCH(NULL);

      i915_emit_hardware_state(i915);
      i915->vbo_flushed = 1;

      assert(BEGIN_BATCH(7 + 7));
   }

   OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
   OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT);
   OUT_BATCH(clear_color);
   OUT_BATCH(clear_depth);
   OUT_BATCH(clear_color8888);
   OUT_BATCH_F(f_depth);
   OUT_BATCH(clear_stencil);

   OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
   OUT_BATCH_F(destx + width);
   OUT_BATCH_F(desty + height);
   OUT_BATCH_F(destx);
   OUT_BATCH_F(desty + height);
   OUT_BATCH_F(destx);
   OUT_BATCH_F(desty);

   /* Flush after clear, its expected to be a costly operation.
    * This is not required, just a heuristic
    */
   FLUSH_BATCH(NULL);
}
Ejemplo n.º 3
0
void
i915_clear_emit(struct pipe_context *pipe, unsigned buffers,
                const union pipe_color_union *color,
                double depth, unsigned stencil,
                unsigned destx, unsigned desty, unsigned width, unsigned height)
{
   struct i915_context *i915 = i915_context(pipe);
   uint32_t clear_params, clear_color, clear_depth, clear_stencil,
            clear_color8888, packed_z_stencil;
   union util_color u_color;
   float f_depth = depth;
   struct i915_texture *cbuf_tex, *depth_tex;
   int depth_clear_bbp, color_clear_bbp;

   cbuf_tex = depth_tex = NULL;
   clear_params = 0;
   depth_clear_bbp = color_clear_bbp = 0;

   if (buffers & PIPE_CLEAR_COLOR) {
      struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];

      clear_params |= CLEARPARAM_WRITE_COLOR;
      cbuf_tex = i915_texture(cbuf->texture);

      util_pack_color(color->f, cbuf->format, &u_color);
      if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) {
         clear_color = u_color.ui;
         color_clear_bbp = 32;
      } else {
         clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);
         color_clear_bbp = 16;
      }

      /* correctly swizzle clear value */
      if (i915->current.target_fixup_format)
         util_pack_color(color->f, cbuf->format, &u_color);
      else
         util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
      clear_color8888 = u_color.ui;
   } else
      clear_color = clear_color8888 = 0;

   clear_depth = clear_stencil = 0;
   if (buffers & PIPE_CLEAR_DEPTH) {
      struct pipe_surface *zbuf = i915->framebuffer.zsbuf;

      clear_params |= CLEARPARAM_WRITE_DEPTH;
      depth_tex = i915_texture(zbuf->texture);
      packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);

      if (util_format_get_blocksize(depth_tex->b.b.format) == 4) {
         /* Avoid read-modify-write if there's no stencil. */
         if (buffers & PIPE_CLEAR_STENCIL
               || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) {
            clear_params |= CLEARPARAM_WRITE_STENCIL;
            clear_stencil = packed_z_stencil >> 24;
         }

         clear_depth = packed_z_stencil & 0xffffff;
         depth_clear_bbp = 32;
      } else {
Ejemplo n.º 4
0
/**
 * Fallback for pipe->clear_render_target() function.
 * XXX this looks too hackish to be really useful.
 * cpp > 4 looks like a gross hack at best...
 * Plus can't use these transfer fallbacks when clearing
 * multisampled surfaces for instance.
 * Clears all bound layers.
 */
void
util_clear_render_target(struct pipe_context *pipe,
                         struct pipe_surface *dst,
                         const union pipe_color_union *color,
                         unsigned dstx, unsigned dsty,
                         unsigned width, unsigned height)
{
   struct pipe_transfer *dst_trans;
   ubyte *dst_map;
   union util_color uc;
   unsigned max_layer;

   assert(dst->texture);
   if (!dst->texture)
      return;

   if (dst->texture->target == PIPE_BUFFER) {
      /*
       * The fill naturally works on the surface format, however
       * the transfer uses resource format which is just bytes for buffers.
       */
      unsigned dx, w;
      unsigned pixstride = util_format_get_blocksize(dst->format);
      dx = (dst->u.buf.first_element + dstx) * pixstride;
      w = width * pixstride;
      max_layer = 0;
      dst_map = pipe_transfer_map(pipe,
                                  dst->texture,
                                  0, 0,
                                  PIPE_TRANSFER_WRITE,
                                  dx, 0, w, 1,
                                  &dst_trans);
   }
   else {
      max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer;
      dst_map = pipe_transfer_map_3d(pipe,
                                     dst->texture,
                                     dst->u.tex.level,
                                     PIPE_TRANSFER_WRITE,
                                     dstx, dsty, dst->u.tex.first_layer,
                                     width, height, max_layer + 1, &dst_trans);
   }

   assert(dst_map);

   if (dst_map) {
      enum pipe_format format = dst->format;
      assert(dst_trans->stride > 0);

      if (util_format_is_pure_integer(format)) {
         /*
          * We expect int/uint clear values here, though some APIs
          * might disagree (but in any case util_pack_color()
          * couldn't handle it)...
          */
         if (util_format_is_pure_sint(format)) {
            util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1);
         }
         else {
            assert(util_format_is_pure_uint(format));
            util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
         }
      }
      else {
         util_pack_color(color->f, dst->format, &uc);
      }

      util_fill_box(dst_map, dst->format,
                    dst_trans->stride, dst_trans->layer_stride,
                    0, 0, 0, width, height, max_layer + 1, &uc);

      pipe->transfer_unmap(pipe, dst_trans);
   }
}
Ejemplo n.º 5
0
/**
 * Clear the rasterizer's current color tile.
 * This is a bin command called during bin processing.
 */
static void
lp_rast_clear_color(struct lp_rasterizer_task *task,
                    const union lp_rast_cmd_arg arg)
{
   const struct lp_scene *scene = task->scene;

   if (scene->fb.nr_cbufs) {
      unsigned i;
      union util_color uc;

      if (util_format_is_pure_integer(scene->fb.cbufs[0]->format)) {
         /*
          * We expect int/uint clear values here, though some APIs
          * might disagree (but in any case util_pack_color()
          * couldn't handle it)...
          */
         LP_DBG(DEBUG_RAST, "%s pure int 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
                    arg.clear_color.ui[0],
                    arg.clear_color.ui[1],
                    arg.clear_color.ui[2],
                    arg.clear_color.ui[3]);

         for (i = 0; i < scene->fb.nr_cbufs; i++) {
            enum pipe_format format = scene->fb.cbufs[i]->format;

            if (util_format_is_pure_sint(format)) {
               util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1);
            }
            else {
               assert(util_format_is_pure_uint(format));
               util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1);
            }

            util_fill_rect(scene->cbufs[i].map,
                           scene->fb.cbufs[i]->format,
                           scene->cbufs[i].stride,
                           task->x,
                           task->y,
                           TILE_SIZE,
                           TILE_SIZE,
                           &uc);
         }
      }
      else {
         uint8_t clear_color[4];

         for (i = 0; i < 4; ++i) {
            clear_color[i] = float_to_ubyte(arg.clear_color.f[i]);
         }

         LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
                    clear_color[0],
                    clear_color[1],
                    clear_color[2],
                    clear_color[3]);

         for (i = 0; i < scene->fb.nr_cbufs; i++) {

            util_pack_color(arg.clear_color.f,
                            scene->fb.cbufs[i]->format, &uc);

            util_fill_rect(scene->cbufs[i].map,
                           scene->fb.cbufs[i]->format,
                           scene->cbufs[i].stride,
                           task->x,
                           task->y,
                           TILE_SIZE,
                           TILE_SIZE,
                           &uc);
         }
      }
   }

   LP_COUNT(nr_color_tile_clear);
}
Ejemplo n.º 6
0
/*
 * Try to clear one color buffer of the attached fb, either by binning a clear
 * command or queuing up the clear for later (when binning is started).
 */
static boolean
lp_setup_try_clear_color_buffer(struct lp_setup_context *setup,
                                const union pipe_color_union *color,
                                unsigned cbuf)
{
   union lp_rast_cmd_arg clearrb_arg;
   union util_color uc;
   enum pipe_format format = setup->fb.cbufs[cbuf]->format;

   LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);

   if (util_format_is_pure_integer(format)) {
      /*
       * We expect int/uint clear values here, though some APIs
       * might disagree (but in any case util_pack_color()
       * couldn't handle it)...
       */
      if (util_format_is_pure_sint(format)) {
         util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1);
      }
      else {
         assert(util_format_is_pure_uint(format));
         util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
      }
   }
   else {
      util_pack_color(color->f, format, &uc);
   }

   if (setup->state == SETUP_ACTIVE) {
      struct lp_scene *scene = setup->scene;

      /* Add the clear to existing scene.  In the unusual case where
       * both color and depth-stencil are being cleared when there's
       * already been some rendering, we could discard the currently
       * binned scene and start again, but I don't see that as being
       * a common usage.
       */
      struct lp_rast_clear_rb *cc_scene =
         (struct lp_rast_clear_rb *)
            lp_scene_alloc_aligned(scene, sizeof(struct lp_rast_clear_rb), 8);

      if (!cc_scene) {
         return FALSE;
      }

      cc_scene->cbuf = cbuf;
      cc_scene->color_val = uc;
      clearrb_arg.clear_rb = cc_scene;

      if (!lp_scene_bin_everywhere(scene,
                                   LP_RAST_OP_CLEAR_COLOR,
                                   clearrb_arg))
         return FALSE;
   }
   else {
      /* Put ourselves into the 'pre-clear' state, specifically to try
       * and accumulate multiple clears to color and depth_stencil
       * buffers which the app or state-tracker might issue
       * separately.
       */
      set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ );

      assert(PIPE_CLEAR_COLOR0 == (1 << 2));
      setup->clear.flags |= 1 << (cbuf + 2);
      setup->clear.color_val[cbuf] = uc;
   }

   return TRUE;
}
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;
}