diff options
| -rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 76 | 
1 files changed, 53 insertions, 23 deletions
| diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index a5d129449e..c289c3d0e5 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -148,12 +148,14 @@ static void r300_prepare_for_rendering(struct r300_context *r300,                                         struct pipe_resource *index_buffer,                                         unsigned cs_dwords,                                         unsigned aos_offset, -                                       int index_bias) +                                       int index_bias, +                                       unsigned *end_cs_dwords)  {      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; +    unsigned end_dwords = 0;      /* Stencil ref fallback. */      if (r300->stencil_ref_bf_fallback) { @@ -175,7 +177,9 @@ static void r300_prepare_for_rendering(struct r300_context *r300,      }      /* Emitted in flush. */ -    cs_dwords += 26; /* emit_query_end */ +    end_dwords += 26; /* emit_query_end */ + +    cs_dwords += end_dwords;      /* Reserve requested CS space. */      if (!r300_check_cs(r300, cs_dwords)) { @@ -193,6 +197,9 @@ static void r300_prepare_for_rendering(struct r300_context *r300,          if (emit_aos_swtcl)              r300_emit_aos_swtcl(r300, flags & PREP_INDEXED);      } + +    if (end_cs_dwords) +        *end_cs_dwords = end_dwords;  }  static boolean immd_is_good_idea(struct r300_context *r300, @@ -294,7 +301,7 @@ static void r500_emit_draw_arrays_immediate(struct r300_context *r300,      dwords = 9 + count * vertex_size; -    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); +    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL);      BEGIN_CS(dwords);      OUT_CS_REG(R300_GA_COLOR_CONTROL, @@ -626,7 +633,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,      /* 15 dwords for emit_draw_elements */      r300_prepare_for_rendering(r300,          PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, -        indexBuffer, 15, 0, indexBias); +        indexBuffer, 15, 0, indexBias, NULL);      u_upload_flush(r300->upload_vb);      u_upload_flush(r300->upload_ib); @@ -647,7 +654,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,              if (count) {                  r300_prepare_for_rendering(r300,                      PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, -                    indexBuffer, 15, 0, indexBias); +                    indexBuffer, 15, 0, indexBias, NULL);              }          } while (count);      } @@ -694,7 +701,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,      } 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, start, 0, NULL);          if (alt_num_verts || count <= 65535) {              r300->emit_draw_arrays(r300, mode, count); @@ -710,7 +717,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,                  if (count) {                      r300_prepare_for_rendering(r300,                          PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, -                        start, 0); +                        start, 0, NULL);                  }              } while (count);          } @@ -953,7 +960,7 @@ static void r500_render_draw_arrays(struct vbuf_render* render,      (void) i; (void) ptr;      r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, -                               NULL, dwords, 0, 0); +                               NULL, dwords, 0, 0, NULL);      DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); @@ -991,30 +998,53 @@ static void r500_render_draw_elements(struct vbuf_render* render,      struct r300_render* r300render = r300_render(render);      struct r300_context* r300 = r300render->r300;      int i; -    unsigned dwords = 6 + (count+1)/2; +    unsigned end_cs_dwords;      unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /                           (r300render->r300->vertex_info.size * 4) - 1; +    unsigned short_count; +    struct r300_cs_info cs_info;      CS_LOCALS(r300); +    /* Reserve at least 256 dwords. +     * +     * 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, dwords, 0, 0); +        NULL, 256, 0, 0, &end_cs_dwords); -    BEGIN_CS(dwords); -    OUT_CS_REG(R300_GA_COLOR_CONTROL, -            r300_provoking_vertex_fixes(r300, r300render->prim)); -    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index); -    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2); -    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | -           r300render->hwprim); -    for (i = 0; i < count-1; i += 2) { -        OUT_CS(indices[i+1] << 16 | indices[i]); -    } -    if (count % 2) { -        OUT_CS(indices[count-1]); +    while (count) { +        r300->rws->get_cs_info(r300->rws, &cs_info); + +        short_count = MIN2(count, (cs_info.free - end_cs_dwords - 6) * 2); + +        BEGIN_CS(6 + (short_count+1)/2); +        OUT_CS_REG(R300_GA_COLOR_CONTROL, +                r300_provoking_vertex_fixes(r300, r300render->prim)); +        OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index); +        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2); +        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) | +               r300render->hwprim); +        for (i = 0; i < short_count-1; i += 2) { +            OUT_CS(indices[i+1] << 16 | indices[i]); +        } +        if (short_count % 2) { +            OUT_CS(indices[short_count-1]); +        } +        END_CS; + +        /* OK now subtract the emitted indices and see if we need to emit +         * another draw packet. */ +        indices += short_count; +        count -= short_count; + +        if (count) { +            r300_prepare_for_rendering(r300, +                PREP_EMIT_AOS_SWTCL | PREP_INDEXED, +                NULL, 256, 0, 0, &end_cs_dwords); +        }      } -    END_CS;  }  static void r300_render_draw_arrays(struct vbuf_render* render, | 
