boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
                         unsigned start, unsigned count)
{
    struct r300_context* r300 = r300_context(pipe);

    if (!u_trim_pipe_prim(mode, &count)) {
        return FALSE;
    }

    if (count > 65535) {
        return FALSE;
    }

    r300_update_derived_state(r300);

    if (!r300_setup_vertex_buffers(r300)) {
        return FALSE;
    }

    setup_vertex_attributes(r300);

    r300_emit_dirty_state(r300);

    r300_emit_aos(r300, start);

    r300_emit_draw_arrays(r300, mode, count);

    return TRUE;
}
Exemple #2
0
static void r300_draw_arrays(struct r300_context *r300,
                             const struct pipe_draw_info *info,
                             int instance_id)
{
    boolean alt_num_verts = r300->screen->caps.is_r500 &&
                            info->count > 65536;
    unsigned start = info->start;
    unsigned count = info->count;
    unsigned short_count;

    /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
    if (!r300_prepare_for_rendering(r300,
                                    PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS,
                                    NULL, 9, start, 0, instance_id))
        return;

    if (alt_num_verts || count <= 65535) {
        r300_emit_draw_arrays(r300, info->mode, count);
    } else {
        do {
            /* The maximum must be divisible by 4 and 3,
             * so that quad and triangle lists are split correctly.
             *
             * Strips, loops, and fans won't work. */
            short_count = MIN2(count, 65532);
            r300_emit_draw_arrays(r300, info->mode, short_count);

            start += short_count;
            count -= short_count;

            /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
            if (count) {
                if (!r300_prepare_for_rendering(r300,
                                                PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9,
                                                start, 0, instance_id))
                    return;
            }
        } while (count);
    }
}
static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
                             unsigned start, unsigned count)
{
    struct r300_context* r300 = r300_context(pipe);
    boolean alt_num_verts = r300->screen->caps.is_r500 &&
                            count > 65536 &&
                            r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
    unsigned short_count;
    boolean translate = FALSE;

    if (r300->skip_rendering) {
        return;
    }

    if (!u_trim_pipe_prim(mode, &count)) {
        return;
    }

    /* Set up fallback for incompatible vertex layout if needed. */
    if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
        r300_begin_vertex_translate(r300);
        translate = TRUE;
    }

    r300_update_derived_state(r300);

    if (immd_is_good_idea(r300, count)) {
        r300_emit_draw_arrays_immediate(r300, mode, start, count);
    } else {
        /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
        if (!r300_prepare_for_rendering(r300,
                PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
                NULL, 9, start, 0))
            goto done;

        if (alt_num_verts || count <= 65535) {
            r300_emit_draw_arrays(r300, mode, count);
        } else {
            do {
                short_count = MIN2(count, 65535);
                r300_emit_draw_arrays(r300, mode, short_count);

                start += short_count;
                count -= short_count;

                /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
                if (count) {
                    if (!r300_prepare_for_rendering(r300,
                            PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
                            start, 0))
                        goto done;
                }
            } while (count);
        }
    }

done:
    if (translate) {
        r300_end_vertex_translate(r300);
    }
}