static void r300_setup_flags(struct r300_resource *tex)
{
    tex->tex.uses_stride_addressing =
        !util_is_power_of_two(tex->b.b.width0) ||
        (tex->tex.stride_in_bytes_override &&
         r300_stride_to_width(tex->b.b.format,
                         tex->tex.stride_in_bytes_override) != tex->b.b.width0);

    tex->tex.is_npot =
        tex->tex.uses_stride_addressing ||
        !util_is_power_of_two(tex->b.b.height0) ||
        !util_is_power_of_two(tex->b.b.depth0);
}
static void r300_tex_print_info(struct r300_resource *tex,
                                const char *func)
{
    fprintf(stderr,
            "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, "
            "LastLevel: %i, Size: %i, Format: %s, Samples: %i\n",
            func,
            tex->tex.macrotile[0] ? "YES" : " NO",
            tex->tex.microtile ? "YES" : " NO",
            r300_stride_to_width(tex->b.b.format, tex->tex.stride_in_bytes[0]),
            tex->b.b.width0, tex->b.b.height0, tex->b.b.depth0,
            tex->b.b.last_level, tex->tex.size_in_bytes,
            util_format_short_name(tex->b.b.format),
            tex->b.b.nr_samples);
}
static void r300_setup_cmask_properties(struct r300_screen *screen,
                                        struct r300_resource *tex)
{
    static unsigned cmask_align_x[4] = {16, 32, 48, 32};
    static unsigned cmask_align_y[4] = {16, 16, 16, 32};
    unsigned pipes, stride, cmask_num_dw, cmask_max_size;

    /* We need an AA colorbuffer, no mipmaps. */
    if (tex->b.b.nr_samples <= 1 ||
        tex->b.b.last_level > 0 ||
        util_format_is_depth_or_stencil(tex->b.b.format)) {
        return;
    }

    /* FP16 AA needs R500 and a fairly new DRM. */
    if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
         tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
        (!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
        return;
    }

    if (SCREEN_DBG_ON(screen, DBG_NO_CMASK)) {
        return;
    }

    /* CMASK is part of raster pipes. The number of Z pipes doesn't matter. */
    pipes = screen->info.r300_num_gb_pipes;

    /* The single-pipe cards have 5120 dwords of CMASK RAM,
     * the other cards have 4096 dwords of CMASK RAM per pipe. */
    cmask_max_size = pipes == 1 ? 5120 : pipes * 4096;

    stride = r300_stride_to_width(tex->b.b.format,
                                  tex->tex.stride_in_bytes[0]);
    stride = align(stride, 16);

    /* Get the CMASK size in dwords. */
    cmask_num_dw = r300_pixels_to_dwords(stride, tex->b.b.height0,
                                         cmask_align_x[pipes-1],
                                         cmask_align_y[pipes-1]);

    /* Check the CMASK size against the CMASK memory limit. */
    if (cmask_num_dw <= cmask_max_size) {
        tex->tex.cmask_dwords = cmask_num_dw;
        tex->tex.cmask_stride_in_pixels =
            util_align_npot(stride, cmask_align_x[pipes-1]);
    }
}
示例#4
0
void r300_texture_setup_format_state(struct r300_screen *screen,
                                     struct r300_resource *tex,
                                     enum pipe_format format,
                                     unsigned level,
                                     unsigned width0_override,
                                     unsigned height0_override,
                                     struct r300_texture_format_state *out)
{
    struct pipe_resource *pt = &tex->b.b;
    struct r300_texture_desc *desc = &tex->tex;
    boolean is_r500 = screen->caps.is_r500;
    unsigned width, height, depth;
    unsigned txwidth, txheight, txdepth;

    width = u_minify(width0_override, level);
    height = u_minify(height0_override, level);
    depth = u_minify(desc->depth0, level);

    txwidth = (width - 1) & 0x7ff;
    txheight = (height - 1) & 0x7ff;
    txdepth = util_logbase2(depth) & 0xf;

    /* Mask out all the fields we change. */
    out->format0 = 0;
    out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
    out->format2 &= R500_TXFORMAT_MSB;
    out->tile_config = 0;

    /* Set sampler state. */
    out->format0 =
        R300_TX_WIDTH(txwidth) |
        R300_TX_HEIGHT(txheight) |
        R300_TX_DEPTH(txdepth);

    if (desc->uses_stride_addressing) {
        unsigned stride =
            r300_stride_to_width(format, desc->stride_in_bytes[level]);
        /* rectangles love this */
        out->format0 |= R300_TX_PITCH_EN;
        out->format2 = (stride - 1) & 0x1fff;
    }

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

    /* large textures on r500 */
    if (is_r500)
    {
        unsigned us_width = txwidth;
        unsigned us_height = txheight;
        unsigned us_depth = txdepth;

        if (width > 2048) {
            out->format2 |= R500_TXWIDTH_BIT11;
        }
        if (height > 2048) {
            out->format2 |= R500_TXHEIGHT_BIT11;
        }

        /* The US_FORMAT register fixes an R500 TX addressing bug.
         * Don't ask why it must be set like this. I don't know it either. */
        if (width > 2048) {
            us_width = (0x000007FF + us_width) >> 1;
            us_depth |= 0x0000000D;
        }
        if (height > 2048) {
            us_height = (0x000007FF + us_height) >> 1;
            us_depth |= 0x0000000E;
        }
static void r300_setup_hyperz_properties(struct r300_screen *screen,
                                         struct r300_resource *tex)
{
    /* The tile size of 1 DWORD in ZMASK RAM is:
     *
     * GPU    Pipes    4x4 mode   8x8 mode
     * ------------------------------------------
     * R580   4P/1Z    32x32      64x64
     * RV570  3P/1Z    48x16      96x32
     * RV530  1P/2Z    32x16      64x32
     *        1P/1Z    16x16      32x32
     */
    static unsigned zmask_blocks_x_per_dw[4] = {4, 8, 12, 8};
    static unsigned zmask_blocks_y_per_dw[4] = {4, 4,  4, 8};

    /* In HIZ RAM, one dword is always 8x8 pixels (each byte is 4x4 pixels),
     * but the blocks have very weird ordering.
     *
     * With 2 pipes and an image of size 8xY, where Y >= 1,
     * clearing 4 dwords clears blocks like this:
     *
     *    01012323
     *
     * where numbers correspond to dword indices. The blocks are interleaved
     * in the X direction, so the alignment must be 4x1 blocks (32x8 pixels).
     *
     * With 4 pipes and an image of size 8xY, where Y >= 4,
     * clearing 8 dwords clears blocks like this:
     *    01012323
     *    45456767
     *    01012323
     *    45456767
     * where numbers correspond to dword indices. The blocks are interleaved
     * in both directions, so the alignment must be 4x4 blocks (32x32 pixels)
     */
    static unsigned hiz_align_x[4] = {8, 32, 48, 32};
    static unsigned hiz_align_y[4] = {8, 8, 8, 32};

    if (util_format_is_depth_or_stencil(tex->b.b.format) &&
        util_format_get_blocksizebits(tex->b.b.format) == 32 &&
        tex->tex.microtile) {
        unsigned i, pipes;

        if (screen->caps.family == CHIP_RV530) {
            pipes = screen->info.r300_num_z_pipes;
        } else {
            pipes = screen->info.r300_num_gb_pipes;
        }

        for (i = 0; i <= tex->b.b.last_level; i++) {
            unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;

            stride = r300_stride_to_width(tex->b.b.format,
                                          tex->tex.stride_in_bytes[i]);
            stride = align(stride, 16);
            height = u_minify(tex->b.b.height0, i);

            /* The 8x8 compression mode needs macrotiling. */
            zcompsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
                       tex->tex.macrotile[i] &&
                       tex->b.b.nr_samples <= 1 ? 8 : 4;

            /* Get the ZMASK buffer size in dwords. */
            zcomp_numdw = r300_pixels_to_dwords(stride, height,
                                zmask_blocks_x_per_dw[pipes-1] * zcompsize,
                                zmask_blocks_y_per_dw[pipes-1] * zcompsize);

            /* Check whether we have enough ZMASK memory. */
            if (util_format_get_blocksizebits(tex->b.b.format) == 32 &&
                zcomp_numdw <= screen->caps.zmask_ram * pipes) {
                tex->tex.zmask_dwords[i] = zcomp_numdw;
                tex->tex.zcomp8x8[i] = zcompsize == 8;

                tex->tex.zmask_stride_in_pixels[i] =
                    util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
            } else {
                tex->tex.zmask_dwords[i] = 0;
                tex->tex.zcomp8x8[i] = FALSE;
                tex->tex.zmask_stride_in_pixels[i] = 0;
            }

            /* Now setup HIZ. */
            stride = util_align_npot(stride, hiz_align_x[pipes-1]);
            height = align(height, hiz_align_y[pipes-1]);

            /* Get the HIZ buffer size in dwords. */
            hiz_numdw = (stride * height) / (8*8 * pipes);

            /* Check whether we have enough HIZ memory. */
            if (hiz_numdw <= screen->caps.hiz_ram * pipes) {
                tex->tex.hiz_dwords[i] = hiz_numdw;
                tex->tex.hiz_stride_in_pixels[i] = stride;
            } else {
                tex->tex.hiz_dwords[i] = 0;
                tex->tex.hiz_stride_in_pixels[i] = 0;
            }
        }
    }
}