Пример #1
0
/**
 * Actually clear the tiles which were flagged as being in a clear state.
 */
static void
sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
{
   struct pipe_transfer *pt = tc->transfer;
   const uint w = tc->transfer->box.width;
   const uint h = tc->transfer->box.height;
   uint x, y;
   uint numCleared = 0;

   assert(pt->resource);
   /* clear the scratch tile to the clear value */
   if (tc->depth_stencil) {
      clear_tile(&tc->tile, pt->resource->format, tc->clear_val);
   } else {
      clear_tile_rgba(&tc->tile, pt->resource->format, tc->clear_color);
   }

   /* push the tile to all positions marked as clear */
   for (y = 0; y < h; y += TILE_SIZE) {
      for (x = 0; x < w; x += TILE_SIZE) {
         union tile_address addr = tile_address(x, y);

         if (is_clear_flag_set(tc->clear_flags, addr)) {
            /* write the scratch tile to the surface */
            if (tc->depth_stencil) {
               pipe_put_tile_raw(tc->pipe,
                                 pt,
                                 x, y, TILE_SIZE, TILE_SIZE,
                                 tc->tile.data.any, 0/*STRIDE*/);
            }
            else {
               pipe_put_tile_rgba(tc->pipe, pt,
                                  x, y, TILE_SIZE, TILE_SIZE,
                                  (float *) tc->tile.data.color);
            }
            numCleared++;
         }
      }
   }

   /* reset all clear flags to zero */
   memset(tc->clear_flags, 0, sizeof(tc->clear_flags));

#if 0
   debug_printf("num cleared: %u\n", numCleared);
#endif
}
Пример #2
0
/**
 * Get a tile from the cache.
 * \param x, y  position of tile, in pixels
 */
void *
lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
                   unsigned x, unsigned y )
{
   struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
   struct pipe_transfer *pt = tc->transfer;
   
   assert(tc->surface);
   assert(tc->transfer);

   switch(tile->status) {
   case LP_TILE_STATUS_CLEAR:
      /* don't get tile from framebuffer, just clear it */
      clear_tile(tile, tc->clear_color);
      tile->status = LP_TILE_STATUS_DEFINED;
      break;

   case LP_TILE_STATUS_UNDEFINED: {
      unsigned w = TILE_SIZE;
      unsigned h = TILE_SIZE;

      x &= ~(TILE_SIZE - 1);
      y &= ~(TILE_SIZE - 1);

      if (!pipe_clip_tile(x, y, &w, &h, tc->transfer))
         lp_tile_read_4ub(pt->format,
                          tile->color,
                          tc->transfer_map, tc->transfer->stride,
                          x, y, w, h);

      tile->status = LP_TILE_STATUS_DEFINED;
      break;
   }

   case LP_TILE_STATUS_DEFINED:
      /* nothing to do */
      break;
   }

   return tile->color;
}
Пример #3
0
/**
 * Get a tile from the cache.
 * \param x, y  position of tile, in pixels
 */
struct softpipe_cached_tile *
sp_find_cached_tile(struct softpipe_tile_cache *tc, 
                    union tile_address addr )
{
   struct pipe_transfer *pt = tc->transfer;
   
   /* cache pos/entry: */
   const int pos = CACHE_POS(addr.bits.x,
                             addr.bits.y);
   struct softpipe_cached_tile *tile = tc->entries + pos;

   if (addr.value != tile->addr.value) {

      assert(pt->resource);
      if (tile->addr.bits.invalid == 0) {
         /* put dirty tile back in framebuffer */
         if (tc->depth_stencil) {
            pipe_put_tile_raw(tc->pipe, pt,
                              tile->addr.bits.x * TILE_SIZE,
                              tile->addr.bits.y * TILE_SIZE,
                              TILE_SIZE, TILE_SIZE,
                              tile->data.depth32, 0/*STRIDE*/);
         }
         else {
            pipe_put_tile_rgba(tc->pipe, pt,
                               tile->addr.bits.x * TILE_SIZE,
                               tile->addr.bits.y * TILE_SIZE,
                               TILE_SIZE, TILE_SIZE,
                               (float *) tile->data.color);
         }
      }

      tile->addr = addr;

      if (is_clear_flag_set(tc->clear_flags, addr)) {
         /* don't get tile from framebuffer, just clear it */
         if (tc->depth_stencil) {
            clear_tile(tile, pt->resource->format, tc->clear_val);
         }
         else {
            clear_tile_rgba(tile, pt->resource->format, tc->clear_color);
         }
         clear_clear_flag(tc->clear_flags, addr);
      }
      else {
         /* get new tile data from transfer */
         if (tc->depth_stencil) {
            pipe_get_tile_raw(tc->pipe, pt,
                              tile->addr.bits.x * TILE_SIZE, 
                              tile->addr.bits.y * TILE_SIZE, 
                              TILE_SIZE, TILE_SIZE,
                              tile->data.depth32, 0/*STRIDE*/);
         }
         else {
            pipe_get_tile_rgba(tc->pipe, pt,
                               tile->addr.bits.x * TILE_SIZE, 
                               tile->addr.bits.y * TILE_SIZE,
                               TILE_SIZE, TILE_SIZE,
                               (float *) tile->data.color);
         }
      }
   }

   tc->last_tile = tile;
   return tile;
}
Пример #4
0
/**
 * Get a tile from the cache.
 * \param x, y  position of tile, in pixels
 */
struct softpipe_cached_tile *
sp_find_cached_tile(struct softpipe_tile_cache *tc,
                    union tile_address addr )
{
    struct pipe_transfer *pt = tc->transfer;
    /* cache pos/entry: */
    const int pos = CACHE_POS(addr.bits.x,
                              addr.bits.y);
    struct softpipe_cached_tile *tile = tc->entries[pos];

    if (!tile) {
        tile = sp_alloc_tile(tc);
        tc->entries[pos] = tile;
    }

    if (addr.value != tc->tile_addrs[pos].value) {

        assert(pt->resource);
        if (tc->tile_addrs[pos].bits.invalid == 0) {
            /* put dirty tile back in framebuffer */
            if (tc->depth_stencil) {
                pipe_put_tile_raw(tc->pipe, pt,
                                  tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                  tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                  TILE_SIZE, TILE_SIZE,
                                  tile->data.depth32, 0/*STRIDE*/);
            }
            else {
                if (util_format_is_pure_uint(tc->surface->format)) {
                    pipe_put_tile_ui_format(tc->pipe, pt,
                                            tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                            tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                            TILE_SIZE, TILE_SIZE,
                                            tc->surface->format,
                                            (unsigned *) tile->data.colorui128);
                } else if (util_format_is_pure_sint(tc->surface->format)) {
                    pipe_put_tile_i_format(tc->pipe, pt,
                                           tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                           tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                           TILE_SIZE, TILE_SIZE,
                                           tc->surface->format,
                                           (int *) tile->data.colori128);
                } else {
                    pipe_put_tile_rgba_format(tc->pipe, pt,
                                              tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                              tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                              TILE_SIZE, TILE_SIZE,
                                              tc->surface->format,
                                              (float *) tile->data.color);
                }
            }
        }

        tc->tile_addrs[pos] = addr;

        if (is_clear_flag_set(tc->clear_flags, addr)) {
            /* don't get tile from framebuffer, just clear it */
            if (tc->depth_stencil) {
                clear_tile(tile, pt->resource->format, tc->clear_val);
            }
            else {
                clear_tile_rgba(tile, pt->resource->format, &tc->clear_color);
            }
            clear_clear_flag(tc->clear_flags, addr);
        }
        else {
            /* get new tile data from transfer */
            if (tc->depth_stencil) {
                pipe_get_tile_raw(tc->pipe, pt,
                                  tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                  tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                  TILE_SIZE, TILE_SIZE,
                                  tile->data.depth32, 0/*STRIDE*/);
            }
            else {
                if (util_format_is_pure_uint(tc->surface->format)) {
                    pipe_get_tile_ui_format(tc->pipe, pt,
                                            tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                            tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                            TILE_SIZE, TILE_SIZE,
                                            tc->surface->format,
                                            (unsigned *) tile->data.colorui128);
                } else if (util_format_is_pure_sint(tc->surface->format)) {
                    pipe_get_tile_i_format(tc->pipe, pt,
                                           tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                           tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                           TILE_SIZE, TILE_SIZE,
                                           tc->surface->format,
                                           (int *) tile->data.colori128);
                } else {
                    pipe_get_tile_rgba_format(tc->pipe, pt,
                                              tc->tile_addrs[pos].bits.x * TILE_SIZE,
                                              tc->tile_addrs[pos].bits.y * TILE_SIZE,
                                              TILE_SIZE, TILE_SIZE,
                                              tc->surface->format,
                                              (float *) tile->data.color);
                }
            }
        }
    }

    tc->last_tile = tile;
    tc->last_tile_addr = addr;
    return tile;
}