#include "r300_texture.h"
#include "r300_screen.h"
+#include "radeon_winsys.h"
+
#define TILE_WIDTH 0
#define TILE_HEIGHT 1
state->format2 |= R500_TXHEIGHT_BIT11;
}
}
- assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048));
SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
pt->width0, pt->height0, pt->last_level);
}
+void r300_texture_reinterpret_format(struct pipe_screen *screen,
+ struct pipe_texture *tex,
+ enum pipe_format new_format)
+{
+ struct r300_screen *r300screen = r300_screen(screen);
+
+ SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
+ util_format_name(tex->format), util_format_name(new_format));
+
+ tex->format = new_format;
+
+ r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
+}
+
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
unsigned zslice, unsigned face)
{
* 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.
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);
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);
}
{
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",
- pf_name(base->format));
+ 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;
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");
}
}
{
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
struct r300_screen* rscreen = r300_screen(screen);
+ struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
if (!tex) {
return NULL;
tex->buffer = screen->buffer_create(screen, 2048,
PIPE_BUFFER_USAGE_PIXEL,
tex->size);
+ winsys->buffer_set_tiling(winsys, tex->buffer,
+ tex->pitch[0],
+ tex->microtile != R300_BUFFER_LINEAR,
+ tex->macrotile != R300_BUFFER_LINEAR);
if (!tex->buffer) {
FREE(tex);