Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sp_tex_tile_cache.c 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /**************************************************************************
  2. *
  3. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. /**
  28. * Texture tile caching.
  29. *
  30. * Author:
  31. * Brian Paul
  32. */
  33. #include "util/u_inlines.h"
  34. #include "util/u_memory.h"
  35. #include "util/u_tile.h"
  36. #include "util/u_math.h"
  37. #include "sp_context.h"
  38. #include "sp_texture.h"
  39. #include "sp_tex_tile_cache.h"
  40. struct softpipe_tex_tile_cache *
  41. sp_create_tex_tile_cache( struct pipe_context *pipe )
  42. {
  43. struct softpipe_tex_tile_cache *tc;
  44. uint pos;
  45. tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
  46. if (tc) {
  47. tc->pipe = pipe;
  48. for (pos = 0; pos < NUM_ENTRIES; pos++) {
  49. tc->entries[pos].addr.bits.invalid = 1;
  50. }
  51. tc->last_tile = &tc->entries[0]; /* any tile */
  52. }
  53. return tc;
  54. }
  55. void
  56. sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
  57. {
  58. uint pos;
  59. for (pos = 0; pos < NUM_ENTRIES; pos++) {
  60. /*assert(tc->entries[pos].x < 0);*/
  61. }
  62. if (tc->transfer) {
  63. tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
  64. }
  65. if (tc->tex_trans) {
  66. tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
  67. }
  68. FREE( tc );
  69. }
  70. void
  71. sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc)
  72. {
  73. if (tc->tex_trans && !tc->tex_trans_map)
  74. tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
  75. }
  76. void
  77. sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc)
  78. {
  79. if (tc->tex_trans_map) {
  80. tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
  81. tc->tex_trans_map = NULL;
  82. }
  83. }
  84. /**
  85. * Invalidate all cached tiles for the cached texture.
  86. * Should be called when the texture is modified.
  87. */
  88. void
  89. sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)
  90. {
  91. unsigned i;
  92. assert(tc);
  93. assert(tc->texture);
  94. for (i = 0; i < NUM_ENTRIES; i++) {
  95. tc->entries[i].addr.bits.invalid = 1;
  96. }
  97. }
  98. /**
  99. * Specify the sampler view to cache.
  100. */
  101. void
  102. sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
  103. struct pipe_sampler_view *view)
  104. {
  105. struct pipe_texture *texture = view ? view->texture : NULL;
  106. uint i;
  107. assert(!tc->transfer);
  108. if (tc->texture != texture) {
  109. pipe_texture_reference(&tc->texture, texture);
  110. if (tc->tex_trans) {
  111. if (tc->tex_trans_map) {
  112. tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
  113. tc->tex_trans_map = NULL;
  114. }
  115. tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
  116. tc->tex_trans = NULL;
  117. }
  118. if (view) {
  119. tc->swizzle_r = view->swizzle_r;
  120. tc->swizzle_g = view->swizzle_g;
  121. tc->swizzle_b = view->swizzle_b;
  122. tc->swizzle_a = view->swizzle_a;
  123. tc->format = view->format;
  124. }
  125. /* mark as entries as invalid/empty */
  126. /* XXX we should try to avoid this when the teximage hasn't changed */
  127. for (i = 0; i < NUM_ENTRIES; i++) {
  128. tc->entries[i].addr.bits.invalid = 1;
  129. }
  130. tc->tex_face = -1; /* any invalid value here */
  131. }
  132. }
  133. /**
  134. * Flush the tile cache: write all dirty tiles back to the transfer.
  135. * any tiles "flagged" as cleared will be "really" cleared.
  136. */
  137. void
  138. sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
  139. {
  140. int pos;
  141. if (tc->texture) {
  142. /* caching a texture, mark all entries as empty */
  143. for (pos = 0; pos < NUM_ENTRIES; pos++) {
  144. tc->entries[pos].addr.bits.invalid = 1;
  145. }
  146. tc->tex_face = -1;
  147. }
  148. }
  149. /**
  150. * Given the texture face, level, zslice, x and y values, compute
  151. * the cache entry position/index where we'd hope to find the
  152. * cached texture tile.
  153. * This is basically a direct-map cache.
  154. * XXX There's probably lots of ways in which we can improve this.
  155. */
  156. static INLINE uint
  157. tex_cache_pos( union tex_tile_address addr )
  158. {
  159. uint entry = (addr.bits.x +
  160. addr.bits.y * 9 +
  161. addr.bits.z * 3 +
  162. addr.bits.face +
  163. addr.bits.level * 7);
  164. return entry % NUM_ENTRIES;
  165. }
  166. /**
  167. * Similar to sp_get_cached_tile() but for textures.
  168. * Tiles are read-only and indexed with more params.
  169. */
  170. const struct softpipe_tex_cached_tile *
  171. sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
  172. union tex_tile_address addr )
  173. {
  174. struct softpipe_tex_cached_tile *tile;
  175. tile = tc->entries + tex_cache_pos( addr );
  176. if (addr.value != tile->addr.value) {
  177. /* cache miss. Most misses are because we've invaldiated the
  178. * texture cache previously -- most commonly on binding a new
  179. * texture. Currently we effectively flush the cache on texture
  180. * bind.
  181. */
  182. #if 0
  183. _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n"
  184. " tile %u: x=%d y=%d z=%d face=%d level=%d\n",
  185. pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level,
  186. pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level);
  187. #endif
  188. /* check if we need to get a new transfer */
  189. if (!tc->tex_trans ||
  190. tc->tex_face != addr.bits.face ||
  191. tc->tex_level != addr.bits.level ||
  192. tc->tex_z != addr.bits.z) {
  193. /* get new transfer (view into texture) */
  194. if (tc->tex_trans) {
  195. if (tc->tex_trans_map) {
  196. tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
  197. tc->tex_trans_map = NULL;
  198. }
  199. tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
  200. tc->tex_trans = NULL;
  201. }
  202. tc->tex_trans =
  203. tc->pipe->get_transfer(tc->pipe, tc->texture,
  204. addr.bits.face,
  205. addr.bits.level,
  206. addr.bits.z,
  207. PIPE_TRANSFER_READ, 0, 0,
  208. u_minify(tc->texture->width0, addr.bits.level),
  209. u_minify(tc->texture->height0, addr.bits.level));
  210. tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
  211. tc->tex_face = addr.bits.face;
  212. tc->tex_level = addr.bits.level;
  213. tc->tex_z = addr.bits.z;
  214. }
  215. /* get tile from the transfer (view into texture) */
  216. pipe_get_tile_swizzle(tc->pipe,
  217. tc->tex_trans,
  218. addr.bits.x * TILE_SIZE,
  219. addr.bits.y * TILE_SIZE,
  220. TILE_SIZE,
  221. TILE_SIZE,
  222. tc->swizzle_r,
  223. tc->swizzle_g,
  224. tc->swizzle_b,
  225. tc->swizzle_a,
  226. tc->format,
  227. (float *) tile->data.color);
  228. tile->addr = addr;
  229. }
  230. tc->last_tile = tile;
  231. return tile;
  232. }