Exemple #1
0
static void r300_setup_miptree(struct r300_screen *screen,
                               struct r300_resource *tex,
                               boolean align_for_cbzb)
{
    struct pipe_resource *base = &tex->b.b.b;
    unsigned stride, size, layer_size, nblocksy, i;
    boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
    boolean aligned_for_cbzb;

    tex->tex.size_in_bytes = 0;

    SCREEN_DBG(screen, DBG_TEXALLOC,
        "r300: Making miptree for texture, format %s\n",
        util_format_short_name(base->format));

    for (i = 0; i <= base->last_level; i++) {
        /* Let's see if this miplevel can be macrotiled. */
        tex->tex.macrotile[i] =
            (tex->tex.macrotile[0] == RADEON_LAYOUT_TILED &&
             r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) &&
             r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ?
             RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;

        stride = r300_texture_get_stride(screen, tex, i);

        /* Compute the number of blocks in Y, see if the CBZB clear can be
         * used on the texture. */
        aligned_for_cbzb = FALSE;
        if (align_for_cbzb && tex->tex.cbzb_allowed[i])
            nblocksy = r300_texture_get_nblocksy(tex, i, &aligned_for_cbzb);
        else
            nblocksy = r300_texture_get_nblocksy(tex, i, NULL);

        layer_size = stride * nblocksy;

        if (base->nr_samples) {
            layer_size *= base->nr_samples;
        }

        if (base->target == PIPE_TEXTURE_CUBE)
            size = layer_size * 6;
        else
            size = layer_size * u_minify(tex->tex.depth0, i);

        tex->tex.offset_in_bytes[i] = tex->tex.size_in_bytes;
        tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size;
        tex->tex.layer_size_in_bytes[i] = layer_size;
        tex->tex.stride_in_bytes[i] = stride;
        tex->tex.stride_in_pixels[i] = stride_to_width(tex->b.b.b.format, stride);
        tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb;

        SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
                "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
                i, u_minify(tex->tex.width0, i), u_minify(tex->tex.height0, i),
                u_minify(tex->tex.depth0, i), stride, tex->tex.size_in_bytes,
                tex->tex.macrotile[i] ? "TRUE" : "FALSE");
    }
}
Exemple #2
0
/**
 * Return the stride, in bytes, of the texture images of the given texture
 * at the given level.
 */
unsigned r300_texture_get_stride(struct r300_screen* screen,
                                 struct r300_texture* tex, unsigned level)
{
    unsigned tile_width, width;

    if (tex->stride_override)
        return tex->stride_override;

    /* Check the level. */
    if (level > tex->tex.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, tex->tex.last_level);
        return 0;
    }

    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,
                                                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);
    }
}
/**
 * Return the stride, in bytes, of the texture image of the given texture
 * at the given level.
 */
static unsigned r300_texture_get_stride(struct r300_screen *screen,
                                        struct r300_texture_desc *desc,
                                        unsigned level)
{
    unsigned tile_width, width, stride;

    if (desc->stride_in_bytes_override)
        return desc->stride_in_bytes_override;

    /* Check the level. */
    if (level > desc->b.b.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, desc->b.b.last_level);
        return 0;
    }

    width = u_minify(desc->b.b.width0, level);

    if (util_format_is_plain(desc->b.b.format)) {
        tile_width = r300_get_pixel_alignment(desc->b.b.format,
                                              desc->b.b.nr_samples,
                                              desc->microtile,
                                              desc->macrotile[level],
                                              DIM_WIDTH);
        width = align(width, tile_width);

        stride = util_format_get_stride(desc->b.b.format, width);

        /* Some IGPs need a minimum stride of 64 bytes, hmm... */
        if (!desc->macrotile[level] &&
            (screen->caps.family == CHIP_FAMILY_RS600 ||
             screen->caps.family == CHIP_FAMILY_RS690 ||
             screen->caps.family == CHIP_FAMILY_RS740)) {
            unsigned min_stride;

            if (desc->microtile) {
                unsigned tile_height =
                        r300_get_pixel_alignment(desc->b.b.format,
                                                 desc->b.b.nr_samples,
                                                 desc->microtile,
                                                 desc->macrotile[level],
                                                 DIM_HEIGHT);

                min_stride = 64 / tile_height;
            } else {
                min_stride = 64;
            }

            return stride < min_stride ? min_stride : stride;
        }

        /* The alignment to 32 bytes is sort of implied by the layout... */
        return stride;
    } else {
        return align(util_format_get_stride(desc->b.b.format, width), 32);
    }
}
Exemple #4
0
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);
}
Exemple #5
0
static void r300_setup_miptree(struct r300_screen* screen,
                               struct r300_texture* tex)
{
    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;

        if (base->target == PIPE_TEXTURE_CUBE)
            size = layer_size * 6;
        else
            size = layer_size * u_minify(base->depth0, i);

        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, macrotiled %s\n",
                   i, u_minify(base->width0, i), u_minify(base->height0, i),
                   u_minify(base->depth0, i), stride, tex->size,
                   tex->mip_macrotile[i] ? "TRUE" : "FALSE");
    }
}
Exemple #6
0
/**
 * Return the stride, in bytes, of the texture image of the given texture
 * at the given level.
 */
static unsigned r300_texture_get_stride(struct r300_screen *screen,
                                        struct r300_resource *tex,
                                        unsigned level)
{
    unsigned tile_width, width, stride;
    boolean is_rs690 = (screen->caps.family == CHIP_FAMILY_RS600 ||
                        screen->caps.family == CHIP_FAMILY_RS690 ||
                        screen->caps.family == CHIP_FAMILY_RS740);

    if (tex->tex.stride_in_bytes_override)
        return tex->tex.stride_in_bytes_override;

    /* Check the level. */
    if (level > tex->b.b.b.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, tex->b.b.b.last_level);
        return 0;
    }

    width = u_minify(tex->tex.width0, level);

    if (util_format_is_plain(tex->b.b.b.format)) {
        tile_width = r300_get_pixel_alignment(tex->b.b.b.format,
                                              tex->b.b.b.nr_samples,
                                              tex->tex.microtile,
                                              tex->tex.macrotile[level],
                                              DIM_WIDTH, is_rs690);
        width = align(width, tile_width);

        stride = util_format_get_stride(tex->b.b.b.format, width);
        /* The alignment to 32 bytes is sort of implied by the layout... */
        return stride;
    } else {
        return align(util_format_get_stride(tex->b.b.b.format, width), is_rs690 ? 64 : 32);
    }
}
Exemple #7
0
/* Not required to implement u_resource_vtbl, consider moving to another file:
 */
struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
                                          struct pipe_resource* texture,
					  unsigned face,
					  unsigned level,
					  unsigned zslice,
					  unsigned flags)
{
    struct r300_texture* tex = r300_texture(texture);
    struct r300_surface* surface = CALLOC_STRUCT(r300_surface);

    if (surface) {
        uint32_t offset, tile_height;

        pipe_reference_init(&surface->base.reference, 1);
        pipe_resource_reference(&surface->base.texture, texture);
        surface->base.format = texture->format;
        surface->base.width = u_minify(texture->width0, level);
        surface->base.height = u_minify(texture->height0, level);
        surface->base.usage = flags;
        surface->base.zslice = zslice;
        surface->base.face = face;
        surface->base.level = level;

        surface->buffer = tex->buffer;

        /* Prefer VRAM if there are multiple domains to choose from. */
        surface->domain = tex->domain;
        if (surface->domain & R300_DOMAIN_VRAM)
            surface->domain &= ~R300_DOMAIN_GTT;

        surface->offset = r300_texture_get_offset(&tex->desc,
                                                  level, zslice, face);
        surface->pitch = tex->fb_state.pitch[level];
        surface->format = tex->fb_state.format;

        /* Parameters for the CBZB clear. */
        surface->cbzb_allowed = tex->desc.cbzb_allowed[level];
        surface->cbzb_width = align(surface->base.width, 64);

        /* Height must be aligned to the size of a tile. */
        tile_height = r300_get_pixel_alignment(tex->desc.b.b.format,
                                               tex->desc.b.b.nr_samples,
                                               tex->desc.microtile,
                                               tex->desc.macrotile[level],
                                               DIM_HEIGHT, 0);

        surface->cbzb_height = align((surface->base.height + 1) / 2,
                                     tile_height);

        /* Offset must be aligned to 2K and must point at the beginning
         * of a scanline. */
        offset = surface->offset +
                 tex->desc.stride_in_bytes[level] * surface->cbzb_height;
        surface->cbzb_midpoint_offset = offset & ~2047;

        surface->cbzb_pitch = surface->pitch & 0x1ffffc;

        if (util_format_get_blocksizebits(surface->base.format) == 32)
            surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
        else
            surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;

        SCREEN_DBG(r300_screen(screen), DBG_CBZB,
                   "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
                   surface->cbzb_allowed ? "YES" : " NO",
                   surface->cbzb_width, surface->cbzb_height,
                   offset & 2047,
                   tex->desc.microtile ? "YES" : " NO",
                   tex->desc.macrotile[level] ? "YES" : " NO");
    }

    return &surface->base;
}
Exemple #8
0
static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
{
    struct r300_texture_format_state* state = &tex->state;
    struct pipe_texture *pt = &tex->tex;
    unsigned i;
    boolean is_r500 = screen->caps->is_r500;

    /* Set sampler state. */
    state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
                     R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);

    if (tex->is_npot) {
        /* rectangles love this */
        state->format0 |= R300_TX_PITCH_EN;
        state->format2 = (tex->pitch[0] - 1) & 0x1fff;
    } else {
        /* power of two textures (3D, mipmaps, and no pitch) */
        state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
    }

    state->format1 = r300_translate_texformat(pt->format);
    if (pt->target == PIPE_TEXTURE_CUBE) {
        state->format1 |= R300_TX_FORMAT_CUBIC_MAP;
    }
    if (pt->target == PIPE_TEXTURE_3D) {
        state->format1 |= R300_TX_FORMAT_3D;
    }

    /* large textures on r500 */
    if (is_r500)
    {
        if (pt->width0 > 2048) {
            state->format2 |= R500_TXWIDTH_BIT11;
        }
        if (pt->height0 > 2048) {
            state->format2 |= R500_TXHEIGHT_BIT11;
        }
    }

    SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
               pt->width0, pt->height0, pt->last_level);

    /* Set framebuffer state. */
    if (util_format_is_depth_or_stencil(tex->tex.format)) {
        for (i = 0; i <= tex->tex.last_level; i++) {
            tex->fb_state.depthpitch[i] =
                tex->pitch[i] |
                R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
                R300_DEPTHMICROTILE(tex->microtile);
        }
        tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format);
    } else {
        for (i = 0; i <= tex->tex.last_level; i++) {
            tex->fb_state.colorpitch[i] =
                tex->pitch[i] |
                r300_translate_colorformat(tex->tex.format) |
                R300_COLOR_TILE(tex->mip_macrotile[i]) |
                R300_COLOR_MICROTILE(tex->microtile);
        }
        tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format);
    }
}