Go to the source code of this file.
Data Structures | |
struct | softpipe_cached_tile |
Defines | |
#define | TILE_CLEAR_OPTIMIZATION 1 |
#define | TILE_SIZE 64 |
Cache tile size (width and height). | |
Functions | |
struct softpipe_tile_cache * | sp_create_tile_cache (struct pipe_screen *screen) |
void | sp_destroy_tile_cache (struct softpipe_tile_cache *tc) |
void | sp_tile_cache_set_surface (struct softpipe_tile_cache *tc, struct pipe_surface *sps) |
Specify the surface to cache. | |
struct pipe_surface * | sp_tile_cache_get_surface (struct softpipe_tile_cache *tc) |
Return the surface being cached. | |
void | sp_tile_cache_map_surfaces (struct softpipe_tile_cache *tc) |
void | sp_tile_cache_unmap_surfaces (struct softpipe_tile_cache *tc) |
void | sp_tile_cache_set_texture (struct pipe_context *pipe, struct softpipe_tile_cache *tc, struct pipe_texture *texture) |
Specify the texture to cache. | |
void | sp_flush_tile_cache (struct softpipe_context *softpipe, struct softpipe_tile_cache *tc) |
Flush the tile cache: write all dirty tiles back to the surface. | |
void | sp_tile_cache_clear (struct softpipe_tile_cache *tc, uint clearValue) |
When a whole surface is being cleared to a value we can avoid fetching tiles above. | |
struct softpipe_cached_tile * | sp_get_cached_tile (struct softpipe_context *softpipe, struct softpipe_tile_cache *tc, int x, int y) |
Get a tile from the cache. | |
struct softpipe_cached_tile * | sp_get_cached_tile_tex (struct pipe_context *pipe, struct softpipe_tile_cache *tc, int x, int y, int z, int face, int level) |
Similar to sp_get_cached_tile() but for textures. |
#define TILE_CLEAR_OPTIMIZATION 1 |
Definition at line 31 of file sp_tile_cache.h.
#define TILE_SIZE 64 |
Cache tile size (width and height).
This needs to be a power of two.
Definition at line 44 of file sp_tile_cache.h.
struct softpipe_tile_cache* sp_create_tile_cache | ( | struct pipe_screen * | screen | ) | [read] |
Definition at line 114 of file sp_tile_cache.c.
References CALLOC_STRUCT, softpipe_tile_cache::entries, NUM_ENTRIES, softpipe_tile_cache::screen, softpipe_cached_tile::x, and softpipe_cached_tile::y.
00115 { 00116 struct softpipe_tile_cache *tc; 00117 uint pos; 00118 00119 tc = CALLOC_STRUCT( softpipe_tile_cache ); 00120 if (tc) { 00121 tc->screen = screen; 00122 for (pos = 0; pos < NUM_ENTRIES; pos++) { 00123 tc->entries[pos].x = 00124 tc->entries[pos].y = -1; 00125 } 00126 } 00127 return tc; 00128 }
void sp_destroy_tile_cache | ( | struct softpipe_tile_cache * | tc | ) |
Definition at line 132 of file sp_tile_cache.c.
References FREE, NUM_ENTRIES, pipe_surface_reference(), softpipe_tile_cache::surface, and softpipe_tile_cache::tex_surf.
00133 { 00134 uint pos; 00135 00136 for (pos = 0; pos < NUM_ENTRIES; pos++) { 00137 /*assert(tc->entries[pos].x < 0);*/ 00138 } 00139 if (tc->surface) { 00140 pipe_surface_reference(&tc->surface, NULL); 00141 } 00142 if (tc->tex_surf) { 00143 pipe_surface_reference(&tc->tex_surf, NULL); 00144 } 00145 00146 FREE( tc ); 00147 }
void sp_flush_tile_cache | ( | struct softpipe_context * | softpipe, | |
struct softpipe_tile_cache * | tc | |||
) |
Flush the tile cache: write all dirty tiles back to the surface.
any tiles "flagged" as cleared will be "really" cleared.
Definition at line 366 of file sp_tile_cache.c.
References pipe_surface::buffer, softpipe_cached_tile::color, softpipe_cached_tile::data, debug_printf(), softpipe_cached_tile::depth32, softpipe_tile_cache::depth_stencil, softpipe_tile_cache::entries, NUM_ENTRIES, softpipe_context::pipe, pipe_put_tile_raw(), pipe_put_tile_rgba(), sp_tile_cache_flush_clear(), softpipe_tile_cache::surface, softpipe_tile_cache::tex_face, softpipe_tile_cache::texture, TILE_SIZE, softpipe_cached_tile::x, and softpipe_cached_tile::y.
00368 { 00369 struct pipe_surface *ps = tc->surface; 00370 int inuse = 0, pos; 00371 00372 if (ps && ps->buffer) { 00373 /* caching a drawing surface */ 00374 for (pos = 0; pos < NUM_ENTRIES; pos++) { 00375 struct softpipe_cached_tile *tile = tc->entries + pos; 00376 if (tile->x >= 0) { 00377 if (tc->depth_stencil) { 00378 pipe_put_tile_raw(ps, 00379 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00380 tile->data.depth32, 0/*STRIDE*/); 00381 } 00382 else { 00383 pipe_put_tile_rgba(ps, 00384 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00385 (float *) tile->data.color); 00386 } 00387 tile->x = tile->y = -1; /* mark as empty */ 00388 inuse++; 00389 } 00390 } 00391 00392 #if TILE_CLEAR_OPTIMIZATION 00393 sp_tile_cache_flush_clear(&softpipe->pipe, tc); 00394 #endif 00395 } 00396 else if (tc->texture) { 00397 /* caching a texture, mark all entries as empty */ 00398 for (pos = 0; pos < NUM_ENTRIES; pos++) { 00399 tc->entries[pos].x = -1; 00400 } 00401 tc->tex_face = -1; 00402 } 00403 00404 #if 0 00405 debug_printf("flushed tiles in use: %d\n", inuse); 00406 #endif 00407 }
struct softpipe_cached_tile* sp_get_cached_tile | ( | struct softpipe_context * | softpipe, | |
struct softpipe_tile_cache * | tc, | |||
int | x, | |||
int | y | |||
) | [read] |
Get a tile from the cache.
x,y | position of tile, in pixels |
Definition at line 415 of file sp_tile_cache.c.
References CACHE_POS, clear_clear_flag(), softpipe_tile_cache::clear_color, softpipe_tile_cache::clear_flags, clear_tile(), clear_tile_rgba(), softpipe_tile_cache::clear_val, softpipe_cached_tile::color, softpipe_cached_tile::data, softpipe_cached_tile::depth32, softpipe_tile_cache::depth_stencil, softpipe_tile_cache::entries, pipe_surface::format, is_clear_flag_set(), pipe_get_tile_raw(), pipe_get_tile_rgba(), pipe_put_tile_raw(), pipe_put_tile_rgba(), softpipe_tile_cache::surface, TILE_SIZE, softpipe_cached_tile::x, and softpipe_cached_tile::y.
00417 { 00418 struct pipe_surface *ps = tc->surface; 00419 00420 /* tile pos in framebuffer: */ 00421 const int tile_x = x & ~(TILE_SIZE - 1); 00422 const int tile_y = y & ~(TILE_SIZE - 1); 00423 00424 /* cache pos/entry: */ 00425 const int pos = CACHE_POS(x, y); 00426 struct softpipe_cached_tile *tile = tc->entries + pos; 00427 00428 if (tile_x != tile->x || 00429 tile_y != tile->y) { 00430 00431 if (tile->x != -1) { 00432 /* put dirty tile back in framebuffer */ 00433 if (tc->depth_stencil) { 00434 pipe_put_tile_raw(ps, 00435 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00436 tile->data.depth32, 0/*STRIDE*/); 00437 } 00438 else { 00439 pipe_put_tile_rgba(ps, 00440 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00441 (float *) tile->data.color); 00442 } 00443 } 00444 00445 tile->x = tile_x; 00446 tile->y = tile_y; 00447 00448 if (is_clear_flag_set(tc->clear_flags, x, y)) { 00449 /* don't get tile from framebuffer, just clear it */ 00450 if (tc->depth_stencil) { 00451 clear_tile(tile, ps->format, tc->clear_val); 00452 } 00453 else { 00454 clear_tile_rgba(tile, ps->format, tc->clear_color); 00455 } 00456 clear_clear_flag(tc->clear_flags, x, y); 00457 } 00458 else { 00459 /* get new tile data from surface */ 00460 if (tc->depth_stencil) { 00461 pipe_get_tile_raw(ps, 00462 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00463 tile->data.depth32, 0/*STRIDE*/); 00464 } 00465 else { 00466 pipe_get_tile_rgba(ps, 00467 tile->x, tile->y, TILE_SIZE, TILE_SIZE, 00468 (float *) tile->data.color); 00469 } 00470 } 00471 } 00472 00473 return tile; 00474 }
struct softpipe_cached_tile* sp_get_cached_tile_tex | ( | struct pipe_context * | pipe, | |
struct softpipe_tile_cache * | tc, | |||
int | x, | |||
int | y, | |||
int | z, | |||
int | face, | |||
int | level | |||
) | [read] |
Similar to sp_get_cached_tile() but for textures.
Tiles are read-only and indexed with more params.
Definition at line 497 of file sp_tile_cache.c.
References softpipe_cached_tile::color, softpipe_cached_tile::data, softpipe_tile_cache::entries, softpipe_cached_tile::face, FALSE, pipe_screen::get_tex_surface, softpipe_cached_tile::level, softpipe_texture::modified, NUM_ENTRIES, PIPE_BUFFER_USAGE_CPU_READ, pipe_get_tile_rgba(), softpipe_tile_cache::screen, pipe_context::screen, softpipe_texture(), pipe_screen::surface_map, pipe_screen::surface_unmap, tex_cache_pos(), softpipe_tile_cache::tex_face, softpipe_tile_cache::tex_level, softpipe_tile_cache::tex_surf, softpipe_tile_cache::tex_surf_map, softpipe_tile_cache::tex_z, softpipe_tile_cache::texture, TILE_SIZE, softpipe_cached_tile::x, softpipe_cached_tile::y, and softpipe_cached_tile::z.
00500 { 00501 struct pipe_screen *screen = pipe->screen; 00502 /* tile pos in framebuffer: */ 00503 const int tile_x = x & ~(TILE_SIZE - 1); 00504 const int tile_y = y & ~(TILE_SIZE - 1); 00505 /* cache pos/entry: */ 00506 const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z, 00507 face, level); 00508 struct softpipe_cached_tile *tile = tc->entries + pos; 00509 00510 if (tc->texture) { 00511 struct softpipe_texture *spt = softpipe_texture(tc->texture); 00512 if (spt->modified) { 00513 /* texture was modified, invalidate all cached tiles */ 00514 uint p; 00515 for (p = 0; p < NUM_ENTRIES; p++) { 00516 tile = tc->entries + p; 00517 tile->x = -1; 00518 } 00519 spt->modified = FALSE; 00520 } 00521 } 00522 00523 if (tile_x != tile->x || 00524 tile_y != tile->y || 00525 z != tile->z || 00526 face != tile->face || 00527 level != tile->level) { 00528 /* cache miss */ 00529 00530 #if 0 00531 printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos, 00532 x/TILE_SIZE, y/TILE_SIZE, z, face, level); 00533 #endif 00534 /* check if we need to get a new surface */ 00535 if (!tc->tex_surf || 00536 tc->tex_face != face || 00537 tc->tex_level != level || 00538 tc->tex_z != z) { 00539 /* get new surface (view into texture) */ 00540 00541 if (tc->tex_surf_map) 00542 tc->screen->surface_unmap(tc->screen, tc->tex_surf); 00543 00544 tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, 00545 PIPE_BUFFER_USAGE_CPU_READ); 00546 tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf, 00547 PIPE_BUFFER_USAGE_CPU_READ); 00548 00549 tc->tex_face = face; 00550 tc->tex_level = level; 00551 tc->tex_z = z; 00552 } 00553 00554 /* get tile from the surface (view into texture) */ 00555 pipe_get_tile_rgba(tc->tex_surf, 00556 tile_x, tile_y, TILE_SIZE, TILE_SIZE, 00557 (float *) tile->data.color); 00558 tile->x = tile_x; 00559 tile->y = tile_y; 00560 tile->z = z; 00561 tile->face = face; 00562 tile->level = level; 00563 } 00564 00565 return tile; 00566 }
void sp_tile_cache_clear | ( | struct softpipe_tile_cache * | tc, | |
uint | clearValue | |||
) |
When a whole surface is being cleared to a value we can avoid fetching tiles above.
Save the color and set a 'clearflag' for each tile of the screen.
Definition at line 575 of file sp_tile_cache.c.
References softpipe_tile_cache::clear_color, softpipe_tile_cache::clear_flags, softpipe_tile_cache::clear_val, softpipe_tile_cache::entries, pipe_surface::format, NUM_ENTRIES, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_X8R8G8B8_UNORM, softpipe_tile_cache::surface, softpipe_cached_tile::x, and softpipe_cached_tile::y.
00576 { 00577 uint r, g, b, a; 00578 uint pos; 00579 00580 tc->clear_val = clearValue; 00581 00582 switch (tc->surface->format) { 00583 case PIPE_FORMAT_R8G8B8A8_UNORM: 00584 case PIPE_FORMAT_R8G8B8X8_UNORM: 00585 r = (clearValue >> 24) & 0xff; 00586 g = (clearValue >> 16) & 0xff; 00587 b = (clearValue >> 8) & 0xff; 00588 a = (clearValue ) & 0xff; 00589 break; 00590 case PIPE_FORMAT_A8R8G8B8_UNORM: 00591 case PIPE_FORMAT_X8R8G8B8_UNORM: 00592 r = (clearValue >> 16) & 0xff; 00593 g = (clearValue >> 8) & 0xff; 00594 b = (clearValue ) & 0xff; 00595 a = (clearValue >> 24) & 0xff; 00596 break; 00597 case PIPE_FORMAT_B8G8R8A8_UNORM: 00598 case PIPE_FORMAT_B8G8R8X8_UNORM: 00599 r = (clearValue >> 8) & 0xff; 00600 g = (clearValue >> 16) & 0xff; 00601 b = (clearValue >> 24) & 0xff; 00602 a = (clearValue ) & 0xff; 00603 break; 00604 default: 00605 r = g = b = a = 0; 00606 } 00607 00608 tc->clear_color[0] = r / 255.0f; 00609 tc->clear_color[1] = g / 255.0f; 00610 tc->clear_color[2] = b / 255.0f; 00611 tc->clear_color[3] = a / 255.0f; 00612 00613 #if TILE_CLEAR_OPTIMIZATION 00614 /* set flags to indicate all the tiles are cleared */ 00615 memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); 00616 #else 00617 /* disable the optimization */ 00618 memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); 00619 #endif 00620 00621 for (pos = 0; pos < NUM_ENTRIES; pos++) { 00622 struct softpipe_cached_tile *tile = tc->entries + pos; 00623 tile->x = tile->y = -1; 00624 }
struct pipe_surface* sp_tile_cache_get_surface | ( | struct softpipe_tile_cache * | tc | ) | [read] |
Return the surface being cached.
Definition at line 187 of file sp_tile_cache.c.
References softpipe_tile_cache::surface.
00188 { 00189 return tc->surface; 00190 }
void sp_tile_cache_map_surfaces | ( | struct softpipe_tile_cache * | tc | ) |
Definition at line 194 of file sp_tile_cache.c.
References PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, softpipe_tile_cache::screen, softpipe_tile_cache::surface, pipe_screen::surface_map, softpipe_tile_cache::surface_map, softpipe_tile_cache::tex_surf, and softpipe_tile_cache::tex_surf_map.
00195 { 00196 if (tc->surface && !tc->surface_map) 00197 tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, 00198 PIPE_BUFFER_USAGE_CPU_WRITE | 00199 PIPE_BUFFER_USAGE_CPU_READ); 00200 00201 if (tc->tex_surf && !tc->tex_surf_map) 00202 tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf, 00203 PIPE_BUFFER_USAGE_CPU_READ); 00204 }
void sp_tile_cache_set_surface | ( | struct softpipe_tile_cache * | tc, | |
struct pipe_surface * | sps | |||
) |
Specify the surface to cache.
Definition at line 154 of file sp_tile_cache.c.
References assert, softpipe_tile_cache::depth_stencil, pipe_surface::format, PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_FORMAT_S8_UNORM, PIPE_FORMAT_S8Z24_UNORM, PIPE_FORMAT_X8Z24_UNORM, PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24S8_UNORM, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z32_UNORM, pipe_surface_reference(), softpipe_tile_cache::screen, softpipe_tile_cache::surface, pipe_screen::surface_map, softpipe_tile_cache::surface_map, pipe_screen::surface_unmap, and softpipe_tile_cache::texture.
00156 { 00157 assert(!tc->texture); 00158 00159 if (tc->surface_map) { 00160 tc->screen->surface_unmap(tc->screen, tc->surface); 00161 tc->surface_map = NULL; 00162 } 00163 00164 pipe_surface_reference(&tc->surface, ps); 00165 00166 if (tc->surface) { 00167 if (tc->surface_map) /* XXX: this is always NULL!? */ 00168 tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, 00169 PIPE_BUFFER_USAGE_CPU_READ | 00170 PIPE_BUFFER_USAGE_CPU_WRITE); 00171 00172 tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || 00173 ps->format == PIPE_FORMAT_X8Z24_UNORM || 00174 ps->format == PIPE_FORMAT_Z24S8_UNORM || 00175 ps->format == PIPE_FORMAT_Z24X8_UNORM || 00176 ps->format == PIPE_FORMAT_Z16_UNORM || 00177 ps->format == PIPE_FORMAT_Z32_UNORM || 00178 ps->format == PIPE_FORMAT_S8_UNORM); 00179 } 00180 }
void sp_tile_cache_set_texture | ( | struct pipe_context * | pipe, | |
struct softpipe_tile_cache * | tc, | |||
struct pipe_texture * | texture | |||
) |
Specify the texture to cache.
Definition at line 226 of file sp_tile_cache.c.
References assert, softpipe_tile_cache::entries, NUM_ENTRIES, pipe_surface_reference(), pipe_texture_reference(), softpipe_tile_cache::screen, softpipe_tile_cache::surface, pipe_screen::surface_unmap, softpipe_tile_cache::tex_face, softpipe_tile_cache::tex_surf, softpipe_tile_cache::tex_surf_map, softpipe_tile_cache::texture, and softpipe_cached_tile::x.
00229 { 00230 uint i; 00231 00232 assert(!tc->surface); 00233 00234 pipe_texture_reference(&tc->texture, texture); 00235 00236 if (tc->tex_surf_map) { 00237 tc->screen->surface_unmap(tc->screen, tc->tex_surf); 00238 tc->tex_surf_map = NULL; 00239 } 00240 pipe_surface_reference(&tc->tex_surf, NULL); 00241 00242 /* mark as entries as invalid/empty */ 00243 /* XXX we should try to avoid this when the teximage hasn't changed */ 00244 for (i = 0; i < NUM_ENTRIES; i++) { 00245 tc->entries[i].x = -1; 00246 } 00247 00248 tc->tex_face = -1; /* any invalid value here */ 00249 }
void sp_tile_cache_unmap_surfaces | ( | struct softpipe_tile_cache * | tc | ) |
Definition at line 208 of file sp_tile_cache.c.
References softpipe_tile_cache::screen, softpipe_tile_cache::surface, softpipe_tile_cache::surface_map, pipe_screen::surface_unmap, softpipe_tile_cache::tex_surf, and softpipe_tile_cache::tex_surf_map.
00209 { 00210 if (tc->surface_map) { 00211 tc->screen->surface_unmap(tc->screen, tc->surface); 00212 tc->surface_map = NULL; 00213 } 00214 00215 if (tc->tex_surf_map) { 00216 tc->screen->surface_unmap(tc->screen, tc->tex_surf); 00217 tc->tex_surf_map = NULL; 00218 } 00219 }