boolean r300_texture_desc_init(struct r300_screen *rscreen,
                               struct r300_texture_desc *desc,
                               const struct pipe_resource *base,
                               enum r300_buffer_tiling microtile,
                               enum r300_buffer_tiling macrotile,
                               unsigned stride_in_bytes_override,
                               unsigned max_buffer_size)
{
    desc->b.b = *base;
    desc->b.b.screen = &rscreen->screen;

    desc->stride_in_bytes_override = stride_in_bytes_override;

    if (microtile == R300_BUFFER_SELECT_LAYOUT ||
        macrotile == R300_BUFFER_SELECT_LAYOUT) {
        r300_setup_tiling(rscreen, desc);
    } else {
        desc->microtile = microtile;
        desc->macrotile[0] = macrotile;
        assert(desc->b.b.last_level == 0);
    }

    r300_setup_flags(desc);
    r300_setup_cbzb_flags(rscreen, desc);

    /* Setup the miptree description. */
    r300_setup_miptree(rscreen, desc, TRUE);
    /* If the required buffer size is larger the given max size,
     * try again without the alignment for the CBZB clear. */
    if (max_buffer_size && desc->size_in_bytes > max_buffer_size) {
        r300_setup_miptree(rscreen, desc, FALSE);
    }

    r300_texture_3d_fix_mipmapping(rscreen, desc);

    if (max_buffer_size) {
        /* Make sure the buffer we got is large enough. */
        if (desc->size_in_bytes > max_buffer_size) {
            fprintf(stderr, "r300: texture_from_handle: The buffer is not "
                            "large enough. Got: %i, Need: %i, Info:\n",
                            max_buffer_size, desc->size_in_bytes);
            r300_tex_print_info(rscreen, desc, "texture_from_handle");
            return FALSE;
        }

        desc->buffer_size_in_bytes = max_buffer_size;
    } else {
        desc->buffer_size_in_bytes = desc->size_in_bytes;
    }

    if (SCREEN_DBG_ON(rscreen, DBG_TEX))
        r300_tex_print_info(rscreen, desc, "texture_from_handle");

    return TRUE;
}
示例#2
0
boolean r300_texture_desc_init(struct r300_screen *rscreen,
                               struct r300_resource *tex,
                               const struct pipe_resource *base)
{
    tex->b.b.b.target = base->target;
    tex->b.b.b.format = base->format;
    tex->b.b.b.width0 = base->width0;
    tex->b.b.b.height0 = base->height0;
    tex->b.b.b.depth0 = base->depth0;
    tex->b.b.b.array_size = base->array_size;
    tex->b.b.b.last_level = base->last_level;
    tex->b.b.b.nr_samples = base->nr_samples;
    tex->tex.width0 = base->width0;
    tex->tex.height0 = base->height0;
    tex->tex.depth0 = base->depth0;

    r300_setup_flags(tex);

    /* Align a 3D NPOT texture to POT. */
    if (base->target == PIPE_TEXTURE_3D && tex->tex.is_npot) {
        tex->tex.width0 = util_next_power_of_two(tex->tex.width0);
        tex->tex.height0 = util_next_power_of_two(tex->tex.height0);
        tex->tex.depth0 = util_next_power_of_two(tex->tex.depth0);
    }

    /* Setup tiling. */
    if (tex->tex.microtile == RADEON_LAYOUT_UNKNOWN) {
        r300_setup_tiling(rscreen, tex);
    }

    r300_setup_cbzb_flags(rscreen, tex);

    /* Setup the miptree description. */
    r300_setup_miptree(rscreen, tex, TRUE);
    /* If the required buffer size is larger the given max size,
     * try again without the alignment for the CBZB clear. */
    if (tex->buf_size && tex->tex.size_in_bytes > tex->buf_size) {
        r300_setup_miptree(rscreen, tex, FALSE);
    }

    r300_setup_hyperz_properties(rscreen, tex);

    if (tex->buf_size) {
        /* Make sure the buffer we got is large enough. */
        if (tex->tex.size_in_bytes > tex->buf_size) {
            fprintf(stderr, "r300: texture_desc_init: The buffer is not "
                            "large enough. Got: %i, Need: %i, Info:\n",
                            tex->buf_size, tex->tex.size_in_bytes);
            r300_tex_print_info(tex, "texture_desc_init");
            return FALSE;
        }

        tex->tex.buffer_size_in_bytes = tex->buf_size;
    } else {
        tex->tex.buffer_size_in_bytes = tex->tex.size_in_bytes;
    }

    if (SCREEN_DBG_ON(rscreen, DBG_TEX))
        r300_tex_print_info(tex, "texture_desc_init");

    return TRUE;
}
void r300_texture_desc_init(struct r300_screen *rscreen,
                            struct r300_resource *tex,
                            const struct pipe_resource *base)
{
    tex->b.b.target = base->target;
    tex->b.b.format = base->format;
    tex->b.b.width0 = base->width0;
    tex->b.b.height0 = base->height0;
    tex->b.b.depth0 = base->depth0;
    tex->b.b.array_size = base->array_size;
    tex->b.b.last_level = base->last_level;
    tex->b.b.nr_samples = base->nr_samples;
    tex->tex.width0 = base->width0;
    tex->tex.height0 = base->height0;
    tex->tex.depth0 = base->depth0;

    /* There is a CB memory addressing hardware bug that limits the width
     * of the MSAA buffer in some cases in R520. In order to get around it,
     * the following code lowers the sample count depending on the format and
     * the width.
     *
     * The only catch is that all MSAA colorbuffers and a zbuffer which are
     * supposed to be used together should always be bound together. Only
     * then the correct minimum sample count of all bound buffers is used
     * for rendering. */
    if (rscreen->caps.is_r500) {
        /* FP16 6x MSAA buffers are limited to a width of 1360 pixels. */
        if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
             tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
            tex->b.b.nr_samples == 6 && tex->b.b.width0 > 1360) {
            tex->b.b.nr_samples = 4;
        }

        /* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */
        if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
             tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
            tex->b.b.nr_samples == 4 && tex->b.b.width0 > 2048) {
            tex->b.b.nr_samples = 2;
        }
    }

    /* 32-bit 6x MSAA buffers are limited to a width of 2720 pixels.
     * This applies to all R300-R500 cards. */
    if (util_format_get_blocksizebits(tex->b.b.format) == 32 &&
        !util_format_is_depth_or_stencil(tex->b.b.format) &&
        tex->b.b.nr_samples == 6 && tex->b.b.width0 > 2720) {
        tex->b.b.nr_samples = 4;
    }

    r300_setup_flags(tex);

    /* Align a 3D NPOT texture to POT. */
    if (base->target == PIPE_TEXTURE_3D && tex->tex.is_npot) {
        tex->tex.width0 = util_next_power_of_two(tex->tex.width0);
        tex->tex.height0 = util_next_power_of_two(tex->tex.height0);
        tex->tex.depth0 = util_next_power_of_two(tex->tex.depth0);
    }

    /* Setup tiling. */
    if (tex->tex.microtile == RADEON_LAYOUT_UNKNOWN) {
        r300_setup_tiling(rscreen, tex);
    }

    r300_setup_cbzb_flags(rscreen, tex);

    /* Setup the miptree description. */
    r300_setup_miptree(rscreen, tex, TRUE);
    /* If the required buffer size is larger than the given max size,
     * try again without the alignment for the CBZB clear. */
    if (tex->buf && tex->tex.size_in_bytes > tex->buf->size) {
        r300_setup_miptree(rscreen, tex, FALSE);

        /* Make sure the buffer we got is large enough. */
        if (tex->tex.size_in_bytes > tex->buf->size) {
            fprintf(stderr,
                "r300: I got a pre-allocated buffer to use it as a texture "
                "storage, but the buffer is too small. I'll use the buffer "
                "anyway, because I can't crash here, but it's dangerous. "
                "This can be a DDX bug. Got: %iB, Need: %iB, Info:\n",
                tex->buf->size, tex->tex.size_in_bytes);
            r300_tex_print_info(tex, "texture_desc_init");
            /* Ooops, what now. Apps will break if we fail this,
             * so just pretend everything's okay. */
        }
    }

    r300_setup_hyperz_properties(rscreen, tex);
    r300_setup_cmask_properties(rscreen, tex);

    if (SCREEN_DBG_ON(rscreen, DBG_TEX))
        r300_tex_print_info(tex, "texture_desc_init");
}