Esempio n. 1
0
struct pipe_screen* r300_screen_create(struct radeon_winsys *rws)
{
    struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);

    if (!r300screen) {
        FREE(r300screen);
        return NULL;
    }

    rws->query_info(rws, &r300screen->info);

    r300_init_debug(r300screen);
    r300_parse_chipset(r300screen->info.pci_id, &r300screen->caps);

    if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK))
        r300screen->caps.zmask_ram = 0;
    if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
        r300screen->caps.hiz_ram = 0;

    if (r300screen->info.drm_minor < 8)
        r300screen->caps.has_us_format = FALSE;

    r300screen->rws = rws;
    r300screen->screen.destroy = r300_destroy_screen;
    r300screen->screen.get_name = r300_get_name;
    r300screen->screen.get_vendor = r300_get_vendor;
    r300screen->screen.get_param = r300_get_param;
    r300screen->screen.get_shader_param = r300_get_shader_param;
    r300screen->screen.get_paramf = r300_get_paramf;
    r300screen->screen.get_video_param = r300_get_video_param;
    r300screen->screen.is_format_supported = r300_is_format_supported;
    r300screen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
    r300screen->screen.context_create = r300_create_context;
    r300screen->screen.fence_reference = r300_fence_reference;
    r300screen->screen.fence_signalled = r300_fence_signalled;
    r300screen->screen.fence_finish = r300_fence_finish;

    r300_init_screen_resource_functions(r300screen);

    util_format_s3tc_init();

    return &r300screen->screen;
}
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;
}
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]);
    }
}
Esempio n. 4
0
static void r300_setup_tiling(struct r300_screen *screen,
                              struct r300_resource *tex)
{
    enum pipe_format format = tex->b.b.b.format;
    boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
    boolean is_zb = util_format_is_depth_or_stencil(format);
    boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);

    tex->tex.microtile = RADEON_LAYOUT_LINEAR;
    tex->tex.macrotile[0] = RADEON_LAYOUT_LINEAR;

    if (!util_format_is_plain(format)) {
        return;
    }

    /* If height == 1, disable microtiling except for zbuffer. */
    if (!is_zb && (tex->b.b.b.height0 == 1 || dbg_no_tiling)) {
        return;
    }

    /* Set microtiling. */
    switch (util_format_get_blocksize(format)) {
        case 1:
        case 4:
        case 8:
            tex->tex.microtile = RADEON_LAYOUT_TILED;
            break;

        case 2:
            tex->tex.microtile = RADEON_LAYOUT_SQUARETILED;
            break;
    }

    if (dbg_no_tiling) {
        return;
    }

    /* Set macrotiling. */
    if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) &&
        r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) {
        tex->tex.macrotile[0] = RADEON_LAYOUT_TILED;
    }
}
static void r300_setup_tiling(struct r300_screen *screen,
                              struct r300_texture_desc *desc)
{
    struct r300_winsys_screen *rws = screen->rws;
    enum pipe_format format = desc->b.b.format;
    boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
    boolean is_zb = util_format_is_depth_or_stencil(format);
    boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);

    if (!util_format_is_plain(format)) {
        return;
    }

    /* If height == 1, disable microtiling except for zbuffer. */
    if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) {
        return;
    }

    /* Set microtiling. */
    switch (util_format_get_blocksize(format)) {
        case 1:
        case 4:
            desc->microtile = R300_BUFFER_TILED;
            break;

        case 2:
        case 8:
            if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
                desc->microtile = R300_BUFFER_SQUARETILED;
            }
            break;
    }

    if (dbg_no_tiling) {
        return;
    }

    /* Set macrotiling. */
    if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) &&
        r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) {
        desc->macrotile[0] = R300_BUFFER_TILED;
    }
}
Esempio n. 6
0
static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
                                  struct r300_resource *tex)
{
    unsigned i, bpp;
    boolean first_level_valid;

    bpp = util_format_get_blocksizebits(tex->b.b.b.format);

    /* 1) The texture must be point-sampled,
     * 2) The depth must be 16 or 32 bits.
     * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage
     *    with certain texture sizes. Macrotiling ensures the alignment. */
    first_level_valid = tex->b.b.b.nr_samples <= 1 &&
                       (bpp == 16 || bpp == 32) &&
                       tex->tex.macrotile[0];

    if (SCREEN_DBG_ON(rscreen, DBG_NO_CBZB))
        first_level_valid = FALSE;

    for (i = 0; i <= tex->b.b.b.last_level; i++)
        tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
}
Esempio n. 7
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");
}