sp_tile_cache.c revision f4d744af24e07103f0f297b485f3dbca1fb7bc3b
18611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**************************************************************************
28611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
38611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
48611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * All Rights Reserved.
58611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
68611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Permission is hereby granted, free of charge, to any person obtaining a
78611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * copy of this software and associated documentation files (the
88611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * "Software"), to deal in the Software without restriction, including
98611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * without limitation the rights to use, copy, modify, merge, publish,
108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * distribute, sub license, and/or sell copies of the Software, and to
118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * permit persons to whom the Software is furnished to do so, subject to
128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * the following conditions:
138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * The above copyright notice and this permission notice (including the
158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * next paragraph) shall be included in all copies or substantial portions
168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * of the Software.
178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu **************************************************************************/
278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Texture tile caching.
308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *
318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Author:
328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu *    Brian Paul
338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "pipe/p_inlines.h"
368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "util/u_memory.h"
378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "util/u_tile.h"
388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "sp_context.h"
398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "sp_surface.h"
408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "sp_texture.h"
418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#include "sp_tile_cache.h"
428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#define NUM_ENTRIES 50
448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/** XXX move these */
478611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#define MAX_WIDTH 2048
488611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#define MAX_HEIGHT 2048
498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustruct softpipe_tile_cache
528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_screen *screen;
548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_surface *surface;  /**< the surface we're caching */
558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_transfer *transfer;
568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   void *transfer_map;
578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_texture *texture;  /**< if caching a texture */
588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct softpipe_cached_tile entries[NUM_ENTRIES];
598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   float clear_color[4];  /**< for color bufs */
618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint clear_val;        /**< for z+stencil, or packed color clear value */
628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   boolean depth_stencil; /**< Is the surface a depth/stencil format? */
638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_transfer *tex_trans;
658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   void *tex_trans_map;
668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   int tex_face, tex_level, tex_z;
678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct softpipe_cached_tile tile;  /**< scratch tile for clears */
698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu};
708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Return the position in the cache for the tile that contains win pos (x,y).
748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * We currently use a direct mapped cache so this is like a hack key.
758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * At some point we should investige something more sophisticated, like
768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * a LRU replacement policy.
778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#define CACHE_POS(x, y) \
798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES)
808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Is the tile at (x,y) in cleared state?
858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic INLINE uint
878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuis_clear_flag_set(const uint *bitvec, int x, int y)
888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   int pos, bit;
908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   x /= TILE_SIZE;
918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   y /= TILE_SIZE;
928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   pos = y * (MAX_WIDTH / TILE_SIZE) + x;
938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   bit = bitvec[pos / 32] & (1 << (pos & 31));
958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return bit;
968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
1008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Mark the tile at (x,y) as not cleared.
1018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
1028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic INLINE void
1038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuclear_clear_flag(uint *bitvec, int x, int y)
1048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
1058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   int pos;
1068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   x /= TILE_SIZE;
1078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   y /= TILE_SIZE;
1088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   pos = y * (MAX_WIDTH / TILE_SIZE) + x;
1098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
1108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   bitvec[pos / 32] &= ~(1 << (pos & 31));
1118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
1128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustruct softpipe_tile_cache *
1158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_create_tile_cache( struct pipe_screen *screen )
1168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
1178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct softpipe_tile_cache *tc;
1188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint pos;
1198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc = CALLOC_STRUCT( softpipe_tile_cache );
1218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc) {
1228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->screen = screen;
1238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      for (pos = 0; pos < NUM_ENTRIES; pos++) {
1248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->entries[pos].x =
1258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->entries[pos].y = -1;
1268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
1278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
1288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return tc;
1298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
1308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
1338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_destroy_tile_cache(struct softpipe_tile_cache *tc)
1348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
1358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_screen *screen;
1368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint pos;
1378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   for (pos = 0; pos < NUM_ENTRIES; pos++) {
1398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /*assert(tc->entries[pos].x < 0);*/
1408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
1418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->transfer) {
1428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      screen = tc->transfer->texture->screen;
1438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      screen->tex_transfer_destroy(tc->transfer);
1448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
1458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->tex_trans) {
1468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      screen = tc->tex_trans->texture->screen;
147f0edc3f155a136d87beccd5ecef75c2d4b6f6b64Iliyan Malchev      screen->tex_transfer_destroy(tc->tex_trans);
148f0edc3f155a136d87beccd5ecef75c2d4b6f6b64Iliyan Malchev   }
1498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   FREE( tc );
1518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
1528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
1558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Specify the surface to cache.
1568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
1578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
1588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
1598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                          struct pipe_surface *ps)
1608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
1618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   assert(!tc->texture);
1628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->transfer) {
1648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      struct pipe_screen *screen = tc->transfer->texture->screen;
1658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (ps == tc->surface)
1678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         return;
1688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (tc->transfer_map) {
1708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         screen->transfer_unmap(screen, tc->transfer);
1718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->transfer_map = NULL;
1728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
1738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      screen->tex_transfer_destroy(tc->transfer);
1758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->transfer = NULL;
1768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
1778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->surface = ps;
1798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (ps) {
1818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      struct pipe_screen *screen = ps->texture->screen;
1828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
1848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                              ps->level, ps->zslice,
1858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                              PIPE_TRANSFER_READ_WRITE,
1868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                              0, 0, ps->width, ps->height);
1878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
1898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_X8Z24_UNORM ||
1908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_Z24S8_UNORM ||
1918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_Z24X8_UNORM ||
1928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_Z16_UNORM ||
1938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_Z32_UNORM ||
1948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                           ps->format == PIPE_FORMAT_S8_UNORM);
1958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
1968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
1978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
1998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
2008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Return the transfer being cached.
2018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
2028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustruct pipe_surface *
2038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
2048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
2058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return tc->surface;
2068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
2078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
2108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
2118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
2128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->transfer && !tc->transfer_map)
2138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
2148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->tex_trans && !tc->tex_trans_map)
2168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
2178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
2188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
2218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
2228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
2238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->transfer_map) {
2248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->screen->transfer_unmap(tc->screen, tc->transfer);
2258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->transfer_map = NULL;
2268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->tex_trans_map) {
2298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
2308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->tex_trans_map = NULL;
2318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
2338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
2368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Specify the texture to cache.
2378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
2388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
2398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_set_texture(struct pipe_context *pipe,
2408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                          struct softpipe_tile_cache *tc,
2418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                          struct pipe_texture *texture)
2428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
2438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint i;
2448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   assert(!tc->transfer);
2468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2478611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   pipe_texture_reference(&tc->texture, texture);
2488611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->tex_trans) {
2508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      struct pipe_screen *screen = tc->tex_trans->texture->screen;
2518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (tc->tex_trans_map) {
2538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         screen->transfer_unmap(screen, tc->tex_trans);
2548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_trans_map = NULL;
2558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
2568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      screen->tex_transfer_destroy(tc->tex_trans);
2588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->tex_trans = NULL;
2598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* mark as entries as invalid/empty */
2628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* XXX we should try to avoid this when the teximage hasn't changed */
2638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   for (i = 0; i < NUM_ENTRIES; i++) {
2648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->entries[i].x = -1;
2658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->tex_face = -1; /* any invalid value here */
2688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
2698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
2728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Set pixels in a tile to the given clear color/value, float.
2738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
2748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic void
2758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuclear_tile_rgba(struct softpipe_cached_tile *tile,
2768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                enum pipe_format format,
2778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                const float clear_value[4])
2788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
2798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (clear_value[0] == 0.0 &&
2808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       clear_value[1] == 0.0 &&
2818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       clear_value[2] == 0.0 &&
2828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       clear_value[3] == 0.0) {
2838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      memset(tile->data.color, 0, sizeof(tile->data.color));
2848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   else {
2868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      uint i, j;
2878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      for (i = 0; i < TILE_SIZE; i++) {
2888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         for (j = 0; j < TILE_SIZE; j++) {
2898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->data.color[i][j][0] = clear_value[0];
2908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->data.color[i][j][1] = clear_value[1];
2918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->data.color[i][j][2] = clear_value[2];
2928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->data.color[i][j][3] = clear_value[3];
2938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
2948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
2958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
2968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
2978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
2998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
3008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Set a tile to a solid value/color.
3018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
3028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic void
3038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuclear_tile(struct softpipe_cached_tile *tile,
3048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu           enum pipe_format format,
3058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu           uint clear_value)
3068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
3078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint i, j;
3088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   switch (pf_get_size(format)) {
3108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   case 1:
3118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE);
3128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      break;
3138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   case 2:
3148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (clear_value == 0) {
3158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE);
3168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
3178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      else {
3188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         for (i = 0; i < TILE_SIZE; i++) {
3198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            for (j = 0; j < TILE_SIZE; j++) {
3208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               tile->data.depth16[i][j] = (ushort) clear_value;
3218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            }
3228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
3238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
3248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      break;
3258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   case 4:
3268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (clear_value == 0) {
3278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE);
3288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
3298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      else {
3308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         for (i = 0; i < TILE_SIZE; i++) {
3318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            for (j = 0; j < TILE_SIZE; j++) {
3328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               tile->data.color32[i][j] = clear_value;
3338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            }
3348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
3358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
3368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      break;
3378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   default:
3388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      assert(0);
3398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
3408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
3418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
3448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Actually clear the tiles which were flagged as being in a clear state.
3458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
3468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic void
3478611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_flush_clear(struct pipe_context *pipe,
3488611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                          struct softpipe_tile_cache *tc)
3498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
3508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_transfer *pt = tc->transfer;
3518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const uint w = tc->transfer->width;
3528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const uint h = tc->transfer->height;
3538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint x, y;
3548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint numCleared = 0;
3558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* clear the scratch tile to the clear value */
3578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   clear_tile(&tc->tile, pt->format, tc->clear_val);
3588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* push the tile to all positions marked as clear */
3608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   for (y = 0; y < h; y += TILE_SIZE) {
3618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      for (x = 0; x < w; x += TILE_SIZE) {
3628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (is_clear_flag_set(tc->clear_flags, x, y)) {
3638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            pipe_put_tile_raw(pt,
3648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              x, y, TILE_SIZE, TILE_SIZE,
3658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              tc->tile.data.color32, 0/*STRIDE*/);
3668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            /* do this? */
3688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            clear_clear_flag(tc->clear_flags, x, y);
3698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            numCleared++;
3718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
3728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
3738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
3748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#if 0
3758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   debug_printf("num cleared: %u\n", numCleared);
3768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#endif
3778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
3788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
3818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Flush the tile cache: write all dirty tiles back to the transfer.
3828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * any tiles "flagged" as cleared will be "really" cleared.
3838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
3848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
3858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_flush_tile_cache(struct softpipe_context *softpipe,
3868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                    struct softpipe_tile_cache *tc)
3878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
3888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_transfer *pt = tc->transfer;
3898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   int inuse = 0, pos;
3908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
3918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (pt) {
3928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /* caching a drawing transfer */
3938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      for (pos = 0; pos < NUM_ENTRIES; pos++) {
3948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         struct softpipe_cached_tile *tile = tc->entries + pos;
3958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (tile->x >= 0) {
3968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            if (tc->depth_stencil) {
3978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               pipe_put_tile_raw(pt,
3988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                 tile->x, tile->y, TILE_SIZE, TILE_SIZE,
3998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                 tile->data.depth32, 0/*STRIDE*/);
4008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            }
4018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            else {
4028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               pipe_put_tile_rgba(pt,
4038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                  tile->x, tile->y, TILE_SIZE, TILE_SIZE,
4048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                  (float *) tile->data.color);
4058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            }
4068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->x = tile->y = -1;  /* mark as empty */
4078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            inuse++;
4088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
4108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#if TILE_CLEAR_OPTIMIZATION
4128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      sp_tile_cache_flush_clear(&softpipe->pipe, tc);
4138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#endif
4148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
4158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   else if (tc->texture) {
4168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /* caching a texture, mark all entries as empty */
4178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      for (pos = 0; pos < NUM_ENTRIES; pos++) {
4188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->entries[pos].x = -1;
4198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
4208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tc->tex_face = -1;
4218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
4228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#if 0
4248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   debug_printf("flushed tiles in use: %d\n", inuse);
4258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#endif
4268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
4278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
4308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Get a tile from the cache.
4318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * \param x, y  position of tile, in pixels
4328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
4338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustruct softpipe_cached_tile *
4348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_get_cached_tile(struct softpipe_context *softpipe,
4358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                   struct softpipe_tile_cache *tc, int x, int y)
4368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
4378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_transfer *pt = tc->transfer;
4388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* tile pos in framebuffer: */
4408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const int tile_x = x & ~(TILE_SIZE - 1);
4418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const int tile_y = y & ~(TILE_SIZE - 1);
4428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* cache pos/entry: */
4448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const int pos = CACHE_POS(x, y);
4458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct softpipe_cached_tile *tile = tc->entries + pos;
4468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4478611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tile_x != tile->x ||
4488611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       tile_y != tile->y) {
4498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (tile->x != -1) {
4518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         /* put dirty tile back in framebuffer */
4528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (tc->depth_stencil) {
4538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            pipe_put_tile_raw(pt,
4548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              tile->x, tile->y, TILE_SIZE, TILE_SIZE,
4558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              tile->data.depth32, 0/*STRIDE*/);
4568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         else {
4588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            pipe_put_tile_rgba(pt,
4598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                               tile->x, tile->y, TILE_SIZE, TILE_SIZE,
4608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                               (float *) tile->data.color);
4618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
4638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->x = tile_x;
4658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->y = tile_y;
4668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (is_clear_flag_set(tc->clear_flags, x, y)) {
4688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         /* don't get tile from framebuffer, just clear it */
4698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (tc->depth_stencil) {
4708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            clear_tile(tile, pt->format, tc->clear_val);
4718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         else {
4738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            clear_tile_rgba(tile, pt->format, tc->clear_color);
4748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         clear_clear_flag(tc->clear_flags, x, y);
4768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
4778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      else {
4788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         /* get new tile data from transfer */
4798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (tc->depth_stencil) {
4808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            pipe_get_tile_raw(pt,
4818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              tile->x, tile->y, TILE_SIZE, TILE_SIZE,
4828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                              tile->data.depth32, 0/*STRIDE*/);
4838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         else {
4858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            pipe_get_tile_rgba(pt,
4868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                               tile->x, tile->y, TILE_SIZE, TILE_SIZE,
4878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                               (float *) tile->data.color);
4888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
4898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
4908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
4918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return tile;
4938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
4948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
4968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
4978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Given the texture face, level, zslice, x and y values, compute
4988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * the cache entry position/index where we'd hope to find the
4998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * cached texture tile.
5008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * This is basically a direct-map cache.
5018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * XXX There's probably lots of ways in which we can improve this.
5028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
5038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsustatic INLINE uint
5048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsutex_cache_pos(int x, int y, int z, int face, int level)
5058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
5068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint entry = x + y * 9 + z * 3 + face + level * 7;
5078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return entry % NUM_ENTRIES;
5088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
5098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
5128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Similar to sp_get_cached_tile() but for textures.
5138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Tiles are read-only and indexed with more params.
5148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
5158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuconst struct softpipe_cached_tile *
5168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_get_cached_tile_tex(struct softpipe_context *sp,
5178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                       struct softpipe_tile_cache *tc, int x, int y, int z,
5188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                       int face, int level)
5198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
5208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct pipe_screen *screen = sp->pipe.screen;
5218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* tile pos in framebuffer: */
5228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const int tile_x = x & ~(TILE_SIZE - 1);
5238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const int tile_y = y & ~(TILE_SIZE - 1);
5248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* cache pos/entry: */
5258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z,
5268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                  face, level);
5278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   struct softpipe_cached_tile *tile = tc->entries + pos;
5288611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5298611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tc->texture) {
5308611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      struct softpipe_texture *spt = softpipe_texture(tc->texture);
5318611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (spt->modified) {
5328611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         /* texture was modified, invalidate all cached tiles */
5338611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         uint p;
5348611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         for (p = 0; p < NUM_ENTRIES; p++) {
5358611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile = tc->entries + p;
5368611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tile->x = -1;
5378611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
5388611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         spt->modified = FALSE;
5398611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
5408611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
5418611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5428611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   if (tile_x != tile->x ||
5438611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       tile_y != tile->y ||
5448611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       z != tile->z ||
5458611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       face != tile->face ||
5468611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu       level != tile->level) {
5478611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /* cache miss */
5488611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5498611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#if 0
5508611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      printf("miss at %u  x=%d y=%d z=%d face=%d level=%d\n", pos,
5518611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu             x/TILE_SIZE, y/TILE_SIZE, z, face, level);
5528611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#endif
5538611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /* check if we need to get a new transfer */
5548611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      if (!tc->tex_trans ||
5558611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu          tc->tex_face != face ||
5568611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu          tc->tex_level != level ||
5578611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu          tc->tex_z != z) {
5588611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         /* get new transfer (view into texture) */
5598611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5608611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         if (tc->tex_trans) {
5618611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            if (tc->tex_trans_map) {
5628611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
5638611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu               tc->tex_trans_map = NULL;
5648611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            }
5658611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5668611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            screen->tex_transfer_destroy(tc->tex_trans);
5678611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu            tc->tex_trans = NULL;
5688611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         }
5698611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5708611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z,
5718611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                                  PIPE_TRANSFER_READ, 0, 0,
5728611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                                  tc->texture->width[level],
5738611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                                                  tc->texture->height[level]);
5748611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
5758611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5768611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_face = face;
5778611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_level = level;
5788611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu         tc->tex_z = z;
5798611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      }
5808611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5818611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      /* get tile from the transfer (view into texture) */
5828611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      pipe_get_tile_rgba(tc->tex_trans,
5838611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                         tile_x, tile_y, TILE_SIZE, TILE_SIZE,
5848611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                         (float *) tile->data.color);
5858611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->x = tile_x;
5868611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->y = tile_y;
5878611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->z = z;
5888611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->face = face;
5898611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->level = level;
5908611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
5918611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5928611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   return tile;
5938611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
5948611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5958611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
5968611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu/**
5978611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * When a whole surface is being cleared to a value we can avoid
5988611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * fetching tiles above.
5998611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu * Save the color and set a 'clearflag' for each tile of the screen.
6008611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu */
6018611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsuvoid
6028611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsusp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba,
6038611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu                    uint clearValue)
6048611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu{
6058611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   uint pos;
6068611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
6078611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->clear_color[0] = rgba[0];
6088611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->clear_color[1] = rgba[1];
6098611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->clear_color[2] = rgba[2];
6108611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->clear_color[3] = rgba[3];
6118611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
6128611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   tc->clear_val = clearValue;
6138611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
6148611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#if TILE_CLEAR_OPTIMIZATION
6158611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* set flags to indicate all the tiles are cleared */
6168611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
6178611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#else
6188611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   /* disable the optimization */
6198611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
6208611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu#endif
6218611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu
6228611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   for (pos = 0; pos < NUM_ENTRIES; pos++) {
6238611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      struct softpipe_cached_tile *tile = tc->entries + pos;
6248611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu      tile->x = tile->y = -1;
6258611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu   }
6268611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu}
6278611d5578ff014a1415b26e75e63aecbc4ad266cBrian Muramatsu