Пример #1
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.
 */
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;
   void *dst_map;
   union util_color uc;

   assert(dst->texture);
   if (!dst->texture)
      return;
   /* XXX: should handle multiple layers */
   dst_map = pipe_transfer_map(pipe,
                               dst->texture,
                               dst->u.tex.level,
                               dst->u.tex.first_layer,
                               PIPE_TRANSFER_WRITE,
                               dstx, dsty, width, height, &dst_trans);

   assert(dst_map);

   if (dst_map) {
      assert(dst_trans->stride > 0);

      util_pack_color(color->f, dst->texture->format, &uc);
      util_fill_rect(dst_map, dst->texture->format,
                     dst_trans->stride,
                     0, 0, width, height, &uc);

      pipe->transfer_unmap(pipe, dst_trans);
   }
}
Пример #2
0
/**
 * Flush the tile cache: write all dirty tiles back to the transfer.
 * any tiles "flagged" as cleared will be "really" cleared.
 */
void
lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
{
   struct pipe_transfer *pt = tc->transfer;
   unsigned x, y;

   if(!pt)
      return;

   assert(tc->transfer_map);

   /* push the tile to all positions marked as clear */
   for (y = 0; y < pt->height; y += TILE_SIZE) {
      for (x = 0; x < pt->width; x += TILE_SIZE) {
         struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];

         if(tile->status != LP_TILE_STATUS_UNDEFINED) {
            unsigned w = TILE_SIZE;
            unsigned h = TILE_SIZE;

            if (!pipe_clip_tile(x, y, &w, &h, pt)) {
               switch(tile->status) {
               case LP_TILE_STATUS_CLEAR:
                  /* Actually clear the tiles which were flagged as being in a
                   * clear state. */
                  util_fill_rect(tc->transfer_map, &pt->block, pt->stride,
                                 x, y, w, h,
                                 tc->clear_val);
                  break;

               case LP_TILE_STATUS_DEFINED:
                  lp_tile_write_4ub(pt->format,
                                    tile->color,
                                    tc->transfer_map, pt->stride,
                                    x, y, w, h);
                  break;

               default:
                  assert(0);
                  break;
               }
            }

            tile->status = LP_TILE_STATUS_UNDEFINED;
         }
      }
   }
}
Пример #3
0
PUBLIC
Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y,
                           unsigned short width, unsigned short height, unsigned int color)
{
    XvMCSubpicturePrivate *subpicture_priv;
    XvMCContextPrivate *context_priv;
    struct pipe_context *pipe;
    struct pipe_sampler_view *dst;
    struct pipe_box dst_box = {x, y, 0, width, height, 1};
    struct pipe_transfer *transfer;
    union util_color uc;
    void *map;

    assert(dpy);

    if (!subpicture)
        return XvMCBadSubpicture;

    /* Convert color to float */
    util_format_read_4f(PIPE_FORMAT_B8G8R8A8_UNORM,
                        uc.f, 1, &color, 4,
                        0, 0, 1, 1);

    subpicture_priv = subpicture->privData;
    context_priv = subpicture_priv->context->privData;
    pipe = context_priv->pipe;
    dst = subpicture_priv->sampler;

    /* TODO: Assert clear rect is within bounds? Or clip? */
    transfer = pipe->get_transfer(pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, &dst_box);
    if (!transfer)
        return XvMCBadSubpicture;

    map = pipe->transfer_map(pipe, transfer);
    if (map) {
        util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0,
                       dst_box.width, dst_box.height, &uc);

        pipe->transfer_unmap(pipe, transfer);
    }

    pipe->transfer_destroy(pipe, transfer);

    return Success;
}
Пример #4
0
void
util_fill_box(ubyte * dst,
              enum pipe_format format,
              unsigned stride,
              unsigned layer_stride,
              unsigned x,
              unsigned y,
              unsigned z,
              unsigned width,
              unsigned height,
              unsigned depth,
              union util_color *uc)
{
   unsigned layer;
   dst += z * layer_stride;
   for (layer = z; layer < depth; layer++) {
      util_fill_rect(dst, format,
                     stride,
                     x, y, width, height, uc);
      dst += layer_stride;
   }
}
Пример #5
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.
 */
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;
   void *dst_map;
   union util_color uc;

   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;
      dst_map = pipe_transfer_map(pipe,
                                  dst->texture,
                                  0, 0,
                                  PIPE_TRANSFER_WRITE,
                                  dx, 0, w, 1,
                                  &dst_trans);
   }
   else {
      /* XXX: should handle multiple layers */
      dst_map = pipe_transfer_map(pipe,
                                  dst->texture,
                                  dst->u.tex.level,
                                  dst->u.tex.first_layer,
                                  PIPE_TRANSFER_WRITE,
                                  dstx, dsty, width, height, &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_rect(dst_map, dst->format,
                     dst_trans->stride,
                     0, 0, width, height, &uc);

      pipe->transfer_unmap(pipe, dst_trans);
   }
}
Пример #6
0
/**
 * Fallback for pipe->surface_fill() function.
 * XXX should probably put this in new u_surface.c file...
 */
void
util_surface_fill(struct pipe_context *pipe,
                  struct pipe_surface *dst,
                  unsigned dstx, unsigned dsty,
                  unsigned width, unsigned height, unsigned value)
{
   struct pipe_screen *screen = pipe->screen;
   struct pipe_transfer *dst_trans;
   void *dst_map;

   assert(dst->texture);
   if (!dst->texture)
      return;
   dst_trans = screen->get_tex_transfer(screen,
                                        dst->texture,
                                        dst->face,
                                        dst->level,
                                        dst->zslice,
                                        PIPE_TRANSFER_WRITE,
                                        dstx, dsty, width, height);

   dst_map = pipe->screen->transfer_map(screen, dst_trans);

   assert(dst_map);

   if (dst_map) {
      assert(dst_trans->stride > 0);

      switch (util_format_get_blocksize(dst_trans->texture->format)) {
      case 1:
      case 2:
      case 4:
         util_fill_rect(dst_map, dst_trans->texture->format, dst_trans->stride,
                        0, 0, width, height, value);
         break;
      case 8:
         {
            /* expand the 4-byte clear value to an 8-byte value */
            ushort *row = (ushort *) dst_map;
            ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
            ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
            ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
            ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
            unsigned i, j;
            val0 = (val0 << 8) | val0;
            val1 = (val1 << 8) | val1;
            val2 = (val2 << 8) | val2;
            val3 = (val3 << 8) | val3;
            for (i = 0; i < height; i++) {
               for (j = 0; j < width; j++) {
                  row[j*4+0] = val0;
                  row[j*4+1] = val1;
                  row[j*4+2] = val2;
                  row[j*4+3] = val3;
               }
               row += dst_trans->stride/2;
            }
         }
         break;
      default:
         assert(0);
         break;
      }
   }

   pipe->screen->transfer_unmap(pipe->screen, dst_trans);
   screen->tex_transfer_destroy(dst_trans);
}
Пример #7
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);
}