diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 48 |
3 files changed, 45 insertions, 10 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index ba64b3eb725..ac2b08b41c2 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -207,6 +207,9 @@ struct r300_texture { /* Size of one zslice or face based on the texture target */ unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS]; + /* Whether the mipmap level is macrotiled. */ + enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS]; + /** * If non-zero, override the natural texture layout with * a custom stride (in bytes). diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 5a4196c5e36..88fe166359b 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -424,7 +424,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | r300_translate_colorformat(tex->tex.format) | - R300_COLOR_TILE(tex->macrotile) | + R300_COLOR_TILE(tex->mip_macrotile[surf->level]) | R300_COLOR_MICROTILE(tex->microtile), 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -445,7 +445,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | - R300_DEPTHMACROTILE(tex->macrotile) | + R300_DEPTHMACROTILE(tex->mip_macrotile[surf->level]) | R300_DEPTHMICROTILE(tex->microtile), 0, RADEON_GEM_DOMAIN_VRAM, 0); } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index f3325be87ae..34a49bec34c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -123,18 +123,40 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile * of the given texture. */ -static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim) +static unsigned r300_texture_get_tile_size(struct r300_texture* tex, + int dim, boolean macrotile) { unsigned pixsize, tile_size; pixsize = util_format_get_blocksize(tex->tex.format); - tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim] * - (tex->macrotile == R300_BUFFER_TILED ? 8 : 1); + tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim]; + + if (macrotile) { + tile_size *= 8; + } assert(tile_size); return tile_size; } +/* Return true if macrotiling should be enabled on the miplevel. */ +static boolean r300_texture_macro_switch(struct r300_texture *tex, + unsigned level, + boolean rv350_mode) +{ + unsigned tile_width, width; + + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE); + width = u_minify(tex->tex.width0, level); + + /* See TX_FILTER1_n.MACRO_SWITCH. */ + if (rv350_mode) { + return width >= tile_width; + } else { + return width > tile_width; + } +} + /** * Return the stride, in bytes, of the texture images of the given texture * at the given level. @@ -157,8 +179,10 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, width = u_minify(tex->tex.width0, level); if (!util_format_is_compressed(tex->tex.format)) { - tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH); + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, + tex->mip_macrotile[level]); width = align(width, tile_width); + return util_format_get_stride(tex->tex.format, width); } else { return align(util_format_get_stride(tex->tex.format, width), 32); @@ -173,7 +197,8 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, height = u_minify(tex->tex.height0, level); if (!util_format_is_compressed(tex->tex.format)) { - tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT); + tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT, + tex->mip_macrotile[level]); height = align(height, tile_height); } @@ -185,11 +210,17 @@ static void r300_setup_miptree(struct r300_screen* screen, { struct pipe_texture* base = &tex->tex; unsigned stride, size, layer_size, nblocksy, i; + boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350; SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", util_format_name(base->format)); for (i = 0; i <= base->last_level; i++) { + /* Let's see if this miplevel can be macrotiled. */ + tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED && + r300_texture_macro_switch(tex, i, rv350_mode)) ? + R300_BUFFER_TILED : R300_BUFFER_LINEAR; + stride = r300_texture_get_stride(screen, tex, i); nblocksy = r300_texture_get_nblocksy(tex, i); layer_size = stride * nblocksy; @@ -199,15 +230,16 @@ static void r300_setup_miptree(struct r300_screen* screen, else size = layer_size * u_minify(base->depth0, i); - tex->offset[i] = align(tex->size, 32); + tex->offset[i] = tex->size; tex->size = tex->offset[i] + size; tex->layer_size[i] = layer_size; tex->pitch[i] = stride / util_format_get_blocksize(base->format); SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " - "(%dx%dx%d px, pitch %d bytes) %d bytes total\n", + "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", i, u_minify(base->width0, i), u_minify(base->height0, i), - u_minify(base->depth0, i), stride, tex->size); + u_minify(base->depth0, i), stride, tex->size, + tex->mip_macrotile[i] ? "TRUE" : "FALSE"); } } |