X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_render.c;h=60700cf30372888d7f726f85854860395194df98;hb=ab130400cf91ab471e265e58193c95f04c7aeeda;hp=987fbaf6a4294f6b425f640dcf39202309dd426b;hpb=3f4680d8e229d87e62972d0632c577873944d89d;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 987fbaf6a42..60700cf3037 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -118,13 +118,13 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } -static boolean index_bias_supported(struct r300_context *r300) +boolean r500_index_bias_supported(struct r300_context *r300) { return r300->screen->caps.is_r500 && r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); } -static void r500_emit_index_bias(struct r300_context *r300, int index_bias) +void r500_emit_index_bias(struct r300_context *r300, int index_bias) { CS_LOCALS(r300); @@ -179,33 +179,21 @@ enum r300_prepare_flags { /** * Check if the requested number of dwords is available in the CS and - * if not, flush. Then validate buffers and emit dirty state. + * if not, flush. * \param r300 The context. * \param flags See r300_prepare_flags. - * \param index_buffer The index buffer to validate. The parameter may be NULL. * \param cs_dwords The number of dwords to reserve in CS. - * \param aos_offset The offset passed to emit_aos. - * \param index_bias The index bias to emit. - * \param end_cs_dwords The number of free dwords which must be available - * at the end of CS after drawing in case the CS space - * management is performed by a draw_* function manually. - * The parameter may be NULL. + * \return TRUE if the CS was flushed */ -static void r300_prepare_for_rendering(struct r300_context *r300, - enum r300_prepare_flags flags, - struct pipe_resource *index_buffer, - unsigned cs_dwords, - int aos_offset, - int index_bias, - unsigned *end_cs_dwords) +static boolean r300_reserve_cs_dwords(struct r300_context *r300, + enum r300_prepare_flags flags, + unsigned cs_dwords) { - unsigned end_dwords = 0; boolean flushed = FALSE; boolean first_draw = flags & PREP_FIRST_DRAW; boolean emit_aos = flags & PREP_EMIT_AOS; boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL; - boolean indexed = flags & PREP_INDEXED; - boolean hw_index_bias = index_bias_supported(r300); + boolean hw_index_bias = r500_index_bias_supported(r300); /* Add dirty state, index offset, and AOS. */ if (first_draw) { @@ -221,11 +209,7 @@ static void r300_prepare_for_rendering(struct r300_context *r300, cs_dwords += 7; /* emit_aos_swtcl */ } - /* Emitted in flush. */ - end_dwords += 26; /* emit_query_end */ - end_dwords += r300->hyperz_state.size; /* emit_hyperz_end */ - - cs_dwords += end_dwords; + cs_dwords += r300_get_num_cs_end_dwords(r300); /* Reserve requested CS space. */ if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) { @@ -233,9 +217,39 @@ static void r300_prepare_for_rendering(struct r300_context *r300, flushed = TRUE; } + return flushed; +} + +/** + * Validate buffers and emit dirty state. + * \param r300 The context. + * \param flags See r300_prepare_flags. + * \param index_buffer The index buffer to validate. The parameter may be NULL. + * \param aos_offset The offset passed to emit_aos. + * \param index_bias The index bias to emit. + * \return TRUE if rendering should be skipped + */ +static boolean r300_emit_states(struct r300_context *r300, + enum r300_prepare_flags flags, + struct pipe_resource *index_buffer, + int aos_offset, + int index_bias) +{ + boolean first_draw = flags & PREP_FIRST_DRAW; + boolean emit_aos = flags & PREP_EMIT_AOS; + boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL; + boolean indexed = flags & PREP_INDEXED; + boolean hw_index_bias = r500_index_bias_supported(r300); + /* Validate buffers and emit dirty state if needed. */ - if (first_draw || flushed) { - r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, index_buffer); + if (first_draw) { + if (!r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, + index_buffer)) { + fprintf(stderr, "r300: CS space validation failed. " + "(not enough memory?) Skipping rendering.\n"); + return FALSE; + } + r300_emit_dirty_state(r300); if (hw_index_bias) { if (r300->screen->caps.has_tcl) @@ -251,8 +265,31 @@ static void r300_prepare_for_rendering(struct r300_context *r300, r300_emit_aos_swtcl(r300, indexed); } - if (end_cs_dwords) - *end_cs_dwords = end_dwords; + return TRUE; +} + +/** + * Check if the requested number of dwords is available in the CS and + * if not, flush. Then validate buffers and emit dirty state. + * \param r300 The context. + * \param flags See r300_prepare_flags. + * \param index_buffer The index buffer to validate. The parameter may be NULL. + * \param cs_dwords The number of dwords to reserve in CS. + * \param aos_offset The offset passed to emit_aos. + * \param index_bias The index bias to emit. + * \return TRUE if rendering should be skipped + */ +static boolean r300_prepare_for_rendering(struct r300_context *r300, + enum r300_prepare_flags flags, + struct pipe_resource *index_buffer, + unsigned cs_dwords, + int aos_offset, + int index_bias) +{ + if (r300_reserve_cs_dwords(r300, flags, cs_dwords)) + flags |= PREP_FIRST_DRAW; + + return r300_emit_states(r300, flags, index_buffer, aos_offset, index_bias); } static boolean immd_is_good_idea(struct r300_context *r300, @@ -313,11 +350,14 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; unsigned vertex_element_count = r300->velems->count; - unsigned i, v, vbi, dwords; + unsigned i, v, vbi; /* Size of the vertex, in dwords. */ unsigned vertex_size = r300->velems->vertex_size_dwords; + /* The number of dwords for this draw operation. */ + unsigned dwords = 9 + count * vertex_size; + /* Size of the vertex element, in dwords. */ unsigned size[PIPE_MAX_ATTRIBS]; @@ -332,6 +372,9 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, CS_LOCALS(r300); + if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0)) + return; + /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ for (i = 0; i < vertex_element_count; i++) { velem = &r300->velems->velem[i]; @@ -351,10 +394,6 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, mapelem[i] = map[vbi] + (velem->src_offset / 4); } - dwords = 9 + count * vertex_size; - - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL); - BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); @@ -496,30 +535,9 @@ static void r300_draw_range_elements(struct pipe_context* pipe, r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); unsigned short_count; int buffer_offset = 0, index_offset = 0; /* for index bias emulation */ - boolean translate = FALSE; unsigned new_offset; - if (r300->skip_rendering) { - return; - } - - if (!u_trim_pipe_prim(mode, &count)) { - return; - } - - /* Index buffer range checking. */ - if ((start + count) * indexSize > indexBuffer->width0) { - fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n"); - 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; - } - - if (indexBias && !index_bias_supported(r300)) { + if (indexBias && !r500_index_bias_supported(r300)) { r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset); } @@ -530,10 +548,12 @@ static void r300_draw_range_elements(struct pipe_context* pipe, r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset); start = new_offset; - /* 15 dwords for emit_draw_elements */ - r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, - indexBuffer, 15, buffer_offset, indexBias, NULL); + + /* 15 dwords for emit_draw_elements. Give up if the function fails. */ + if (!r300_prepare_for_rendering(r300, + PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | + PREP_INDEXED, indexBuffer, 15, buffer_offset, indexBias)) + goto done; if (alt_num_verts || count <= 65535) { r300_emit_draw_elements(r300, indexBuffer, indexSize, @@ -550,20 +570,18 @@ static void r300_draw_range_elements(struct pipe_context* pipe, /* 15 dwords for emit_draw_elements */ if (count) { - r300_prepare_for_rendering(r300, - PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, - indexBuffer, 15, buffer_offset, indexBias, NULL); + if (!r300_prepare_for_rendering(r300, + PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, + indexBuffer, 15, buffer_offset, indexBias)) + goto done; } } while (count); } +done: if (indexBuffer != orgIndexBuffer) { pipe_resource_reference( &indexBuffer, NULL ); } - - if (translate) { - r300_end_vertex_translate(r300); - } } static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, @@ -574,30 +592,17 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, 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. */ - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, - NULL, 9, start, 0, NULL); + /* 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)) + return; if (alt_num_verts || count <= 65535) { r300_emit_draw_arrays(r300, mode, count); @@ -609,19 +614,15 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, start += short_count; count -= short_count; - /* 9 spare dwords for emit_draw_arrays. */ + /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (count) { - r300_prepare_for_rendering(r300, - PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, - start, 0, NULL); + if (!r300_prepare_for_rendering(r300, + PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, + start, 0)) + return; } } while (count); } - u_upload_flush(r300->upload_vb); - } - - if (translate) { - r300_end_vertex_translate(r300); } } @@ -629,13 +630,42 @@ static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); + unsigned count = info->count; + boolean translate = FALSE; + boolean indexed = info->indexed && r300->index_buffer.buffer; + unsigned start_indexed = 0; - if (info->indexed && r300->index_buffer.buffer) { - unsigned offset; + if (r300->skip_rendering) { + return; + } + if (!u_trim_pipe_prim(info->mode, &count)) { + return; + } + + /* Index buffer range checking. */ + if (indexed) { assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); - offset = r300->index_buffer.offset / r300->index_buffer.index_size; + /* Compute start for draw_elements, taking the offset into account. */ + start_indexed = + info->start + + (r300->index_buffer.offset / r300->index_buffer.index_size); + + if ((start_indexed + count) * r300->index_buffer.index_size > + r300->index_buffer.buffer->width0) { + fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n"); + 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; + } + + if (indexed) { r300_draw_range_elements(pipe, r300->index_buffer.buffer, r300->index_buffer.index_size, @@ -643,14 +673,17 @@ static void r300_draw_vbo(struct pipe_context* pipe, info->min_index, info->max_index, info->mode, - info->start + offset, - info->count); - } - else { + start_indexed, + count); + } else { r300_draw_arrays(pipe, info->mode, info->start, - info->count); + count); + } + + if (translate) { + r300_end_vertex_translate(r300); } } @@ -668,7 +701,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, struct pipe_transfer *ib_transfer = NULL; unsigned count = info->count; int i; - void* indices = NULL; + void *indices = NULL; + boolean indexed = info->indexed && r300->index_buffer.buffer; if (r300->skip_rendering) { return; @@ -680,44 +714,45 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); + r300_reserve_cs_dwords(r300, + PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | + (indexed ? PREP_INDEXED : 0), + indexed ? 256 : 6); + for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe, - r300->vertex_buffer[i].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, buf); + if (r300->vertex_buffer[i].buffer) { + void *buf = pipe_buffer_map(pipe, + r300->vertex_buffer[i].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, buf); + } } - if (info->indexed && r300->index_buffer.buffer) { + if (indexed) { indices = pipe_buffer_map(pipe, r300->index_buffer.buffer, PIPE_TRANSFER_READ, &ib_transfer); - if (indices) - indices = (void *) ((char *) indices + r300->index_buffer.offset); } - draw_set_mapped_element_buffer_range(r300->draw, (indices) ? - r300->index_buffer.index_size : 0, - info->index_bias, - info->min_index, - info->max_index, - indices); - - draw_arrays(r300->draw, info->mode, info->start, count); + draw_set_mapped_index_buffer(r300->draw, indices); - /* XXX Not sure whether this is the best fix. - * It prevents CS from being rejected and weird assertion failures. */ + r300->draw_vbo_locked = TRUE; + r300->draw_first_emitted = FALSE; + draw_vbo(r300->draw, info); draw_flush(r300->draw); + r300->draw_vbo_locked = FALSE; for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + if (r300->vertex_buffer[i].buffer) { + pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, + vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + } } - if (ib_transfer) { + if (indexed) { pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer); - draw_set_mapped_element_buffer_range(r300->draw, 0, 0, info->start, - info->start + count - 1, NULL); + draw_set_mapped_index_buffer(r300->draw, NULL); } } @@ -735,9 +770,6 @@ struct r300_render { unsigned hwprim; /* VBO */ - struct pipe_resource* vbo; - size_t vbo_size; - size_t vbo_offset; size_t vbo_max_used; void * vbo_ptr; @@ -768,35 +800,40 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, struct pipe_screen* screen = r300->context.screen; size_t size = (size_t)vertex_size * (size_t)count; - if (size + r300render->vbo_offset > r300render->vbo_size) + DBG(r300, DBG_DRAW, "r300: render_allocate_vertices (size: %d)\n", size); + + if (size + r300->draw_vbo_offset > r300->draw_vbo_size) { - pipe_resource_reference(&r300->vbo, NULL); - r300render->vbo = pipe_buffer_create(screen, - PIPE_BIND_VERTEX_BUFFER, - R300_MAX_DRAW_VBO_SIZE); - r300render->vbo_offset = 0; - r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE; + pipe_resource_reference(&r300->vbo, NULL); + r300->vbo = pipe_buffer_create(screen, + PIPE_BIND_VERTEX_BUFFER, + R300_MAX_DRAW_VBO_SIZE); + r300->draw_vbo_offset = 0; + r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE; } r300render->vertex_size = vertex_size; - r300->vbo = r300render->vbo; - r300->vbo_offset = r300render->vbo_offset; - return (r300render->vbo) ? TRUE : FALSE; + return (r300->vbo) ? TRUE : FALSE; } static void* r300_render_map_vertices(struct vbuf_render* render) { struct r300_render* r300render = r300_render(render); + struct r300_context* r300 = r300render->r300; assert(!r300render->vbo_transfer); + DBG(r300, DBG_DRAW, "r300: render_map_vertices\n"); + r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context, - r300render->vbo, + r300->vbo, PIPE_TRANSFER_WRITE, &r300render->vbo_transfer); - return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); + assert(r300render->vbo_ptr); + + return ((uint8_t*)r300render->vbo_ptr + r300->draw_vbo_offset); } static void r300_render_unmap_vertices(struct vbuf_render* render, @@ -805,12 +842,15 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, { struct r300_render* r300render = r300_render(render); struct pipe_context* context = &r300render->r300->context; + struct r300_context* r300 = r300render->r300; assert(r300render->vbo_transfer); + DBG(r300, DBG_DRAW, "r300: render_unmap_vertices\n"); + r300render->vbo_max_used = MAX2(r300render->vbo_max_used, r300render->vertex_size * (max + 1)); - pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer); + pipe_buffer_unmap(context, r300->vbo, r300render->vbo_transfer); r300render->vbo_transfer = NULL; } @@ -818,8 +858,11 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, static void r300_render_release_vertices(struct vbuf_render* render) { struct r300_render* r300render = r300_render(render); + struct r300_context* r300 = r300render->r300; + + DBG(r300, DBG_DRAW, "r300: render_release_vertices\n"); - r300render->vbo_offset += r300render->vbo_max_used; + r300->draw_vbo_offset += r300render->vbo_max_used; r300render->vbo_max_used = 0; } @@ -847,11 +890,20 @@ static void r300_render_draw_arrays(struct vbuf_render* render, CS_LOCALS(r300); (void) i; (void) ptr; - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, - NULL, dwords, 0, 0, NULL); - DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count); + if (r300->draw_first_emitted) { + if (!r300_prepare_for_rendering(r300, + PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, + NULL, 6, 0, 0)) + return; + } else { + if (!r300_emit_states(r300, + PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, + NULL, 0, 0)) + return; + } + /* Uncomment to dump all VBOs rendered through this interface. * Slow and noisy! ptr = pipe_buffer_map(&r300render->r300->context, @@ -877,6 +929,8 @@ static void r300_render_draw_arrays(struct vbuf_render* render, OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300render->hwprim); END_CS; + + r300->draw_first_emitted = TRUE; } static void r300_render_draw_elements(struct vbuf_render* render, @@ -887,7 +941,7 @@ static void r300_render_draw_elements(struct vbuf_render* render, struct r300_context* r300 = r300render->r300; int i; unsigned end_cs_dwords; - unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) / + unsigned max_index = (r300->draw_vbo_size - r300->draw_vbo_offset) / (r300render->r300->vertex_info.size * 4) - 1; unsigned short_count; unsigned free_dwords; @@ -895,13 +949,22 @@ static void r300_render_draw_elements(struct vbuf_render* render, CS_LOCALS(r300); DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count); - /* Reserve at least 256 dwords. - * - * Below we manage the CS space manually because there may be more + if (r300->draw_first_emitted) { + if (!r300_prepare_for_rendering(r300, + PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + NULL, 256, 0, 0)) + return; + } else { + if (!r300_emit_states(r300, + PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + NULL, 0, 0)) + return; + } + + /* Below we manage the CS space manually because there may be more * indices than it can fit in CS. */ - r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0, &end_cs_dwords); + + end_cs_dwords = r300_get_num_cs_end_dwords(r300); while (count) { free_dwords = r300->cs->ndw - r300->cs->cdw; @@ -929,11 +992,16 @@ static void r300_render_draw_elements(struct vbuf_render* render, count -= short_count; if (count) { - r300_prepare_for_rendering(r300, - PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0, &end_cs_dwords); + if (!r300_prepare_for_rendering(r300, + PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + NULL, 256, 0, 0)) + return; + + end_cs_dwords = r300_get_num_cs_end_dwords(r300); } } + + r300->draw_first_emitted = TRUE; } static void r300_render_destroy(struct vbuf_render* render) @@ -961,10 +1029,6 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300) r300render->base.release_vertices = r300_render_release_vertices; r300render->base.destroy = r300_render_destroy; - r300render->vbo = NULL; - r300render->vbo_size = 0; - r300render->vbo_offset = 0; - return &r300render->base; } @@ -991,11 +1055,19 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300) return stage; } +void r300_draw_flush_vbuf(struct r300_context *r300) +{ + pipe_resource_reference(&r300->vbo, NULL); + r300->draw_vbo_size = 0; +} + /**************************************************************************** * End of SW TCL functions * ***************************************************************************/ -/* If we used a quad to draw a rectangle, the pixels on the main diagonal +/* This functions is used to draw a rectangle for the blitter module. + * + * If we rendered a quad, the pixels on the main diagonal * would be computed and stored twice, which makes the clear/copy codepaths * somewhat inefficient. Instead we use a rectangular point sprite. */ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, @@ -1025,7 +1097,8 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, r300->clip_state.dirty = FALSE; r300->viewport_state.dirty = FALSE; - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL); + if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0)) + goto done; DBG(r300, DBG_DRAW, "r300: draw_rectangle\n"); @@ -1069,6 +1142,7 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, } END_CS; +done: /* Restore the state. */ r300->clip_state.dirty = TRUE; r300->rs_state.dirty = TRUE;