diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/drivers/r300/Makefile | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 14 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 26 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_cs.h | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 50 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.h | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 209 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_render.h | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 15 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 14 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_inlines.h | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_vbo.c | 170 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_vbo.h | 36 | 
13 files changed, 446 insertions, 113 deletions
| diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index f73d80de88..d13bb7a36b 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -17,6 +17,7 @@ C_SOURCES = \  	r300_state.c \  	r300_state_derived.c \  	r300_state_invariant.c \ +	r300_vbo.c \  	r300_vs.c \  	r300_texture.c \  	r300_tgsi_to_rc.c diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index f974147ea4..b520e5929e 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -104,6 +104,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,                                           struct r300_winsys* r300_winsys)  {      struct r300_context* r300 = CALLOC_STRUCT(r300_context); +    struct r300_screen* r300screen = r300_screen(screen);      if (!r300)          return NULL; @@ -119,9 +120,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      r300->context.clear = r300_clear; -    r300->context.draw_arrays = r300_draw_arrays; -    r300->context.draw_elements = r300_draw_elements; -    r300->context.draw_range_elements = r300_swtcl_draw_range_elements; +    if (r300screen->caps->has_tcl) +    { +        r300->context.draw_arrays = r300_draw_arrays; +        r300->context.draw_elements = r300_draw_elements; +        r300->context.draw_range_elements = r300_draw_range_elements; +    } +    else +    { +        assert(0); +    }      r300->context.is_texture_referenced = r300_is_texture_referenced;      r300->context.is_buffer_referenced = r300_is_buffer_referenced; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 850e5a41c9..8d14c53f49 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -216,18 +216,19 @@ struct r300_texture {      struct r300_texture_state state;  }; -struct r300_vertex_format { +struct r300_vertex_info {      /* Parent class */      struct vertex_info vinfo; -    /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ -    uint32_t vap_prog_stream_cntl[8]; -    /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ -    uint32_t vap_prog_stream_cntl_ext[8];      /* Map of vertex attributes into PVS memory for HW TCL,       * or GA memory for SW TCL. */      int vs_tab[16];      /* Map of rasterizer attributes from GB through RS to US. */      int fs_tab[16]; + +    /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ +    uint32_t vap_prog_stream_cntl[8]; +    /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ +    uint32_t vap_prog_stream_cntl_ext[8];  };  extern struct pipe_viewport_state r300_viewport_identity; @@ -256,7 +257,7 @@ struct r300_context {       * depends on the combination of both currently loaded shaders. */      struct util_hash_table* shader_hash_table;      /* Vertex formatting information. */ -    struct r300_vertex_format* vertex_info; +    struct r300_vertex_info* vertex_info;      /* Various CSO state objects. */      /* Blend state. */ @@ -285,12 +286,6 @@ struct r300_context {      /* Texture states. */      struct r300_texture* textures[8];      int texture_count; -    /* Vertex buffers for Gallium. */ -    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; -    int vertex_buffer_count; -    /* Vertex elements for Gallium. */ -    struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; -    int vertex_element_count;      /* Vertex shader. */      struct r300_vertex_shader* vs;      /* Viewport state. */ @@ -298,6 +293,13 @@ struct r300_context {      /* ZTOP state. */      struct r300_ztop_state ztop_state; +    /* Vertex buffers for Gallium. */ +    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; +    int vbuf_count; +    /* Vertex elements for Gallium. */ +    struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; +    int aos_count; +      /* Bitmask of dirty state objects. */      uint32_t dirty_state;      /* Flag indicating whether or not the HW is dirty. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 883f0a02dc..86ba91db52 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -34,8 +34,8 @@  #define MAX_CS_SIZE 64 * 1024 / 4 -#define VERY_VERBOSE_CS 0 -#define VERY_VERBOSE_REGISTERS 0 +#define VERY_VERBOSE_CS 1 +#define VERY_VERBOSE_REGISTERS 1  /* XXX stolen from radeon_drm.h */  #define RADEON_GEM_DOMAIN_CPU  0x1 diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 69ce5966e8..ec1d521800 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -582,7 +582,48 @@ void r300_emit_texture(struct r300_context* r300,      END_CS;  } -void r300_emit_vertex_buffer(struct r300_context* r300) +void r300_emit_aos(struct r300_context* r300, unsigned offset) +{ +    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; +    struct pipe_vertex_element *velem = r300->vertex_element; +    CS_LOCALS(r300); +    int i; +    unsigned packet_size = (r300->aos_count * 3 + 1) / 2; +    BEGIN_CS(2 + packet_size + r300->aos_count * 2); +    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); +    OUT_CS(r300->aos_count); +    for (i = 0; i < r300->aos_count - 1; i += 2) { +        int buf_num1 = velem[i].vertex_buffer_index; +        int buf_num2 = velem[i+1].vertex_buffer_index; +        assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0); +        assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0); +        OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) | +               (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22)); +        OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset + +               offset * vbuf[buf_num1].stride); +        OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset + +               offset * vbuf[buf_num2].stride); +    } +    if (r300->aos_count & 1) { +        int buf_num = velem[i].vertex_buffer_index; +        assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0); +        OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6)); +        OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset + +               offset * vbuf[buf_num].stride); +    } + +    for (i = 0; i < r300->aos_count; i++) { +        cs_winsys->write_cs_reloc(cs_winsys, +                                  vbuf[velem[i].vertex_buffer_index].buffer, +                                  RADEON_GEM_DOMAIN_GTT, +                                  0, +                                  0); +        cs_count -= 2; +    } +    END_CS; +} +#if 0 +void r300_emit_draw_packet(struct r300_context* r300)  {      CS_LOCALS(r300); @@ -605,6 +646,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300)      OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);      END_CS;  } +#endif  void r300_emit_vertex_format_state(struct r300_context* r300)  { @@ -771,8 +813,6 @@ void r300_emit_dirty_state(struct r300_context* r300)          return;      } -    r300_update_derived_state(r300); -      /* Clean out BOs. */      r300->winsys->reset_bos(r300->winsys); @@ -823,7 +863,7 @@ validate:              goto validate;          }      } else { -        debug_printf("No VBO while emitting dirty state!\n"); +        // debug_printf("No VBO while emitting dirty state!\n");      }      if (!r300->winsys->validate(r300->winsys)) {          r300->context.flush(&r300->context, 0, NULL); @@ -951,7 +991,7 @@ validate:      */      /* Finally, emit the VBO. */ -    r300_emit_vertex_buffer(r300); +    //r300_emit_vertex_buffer(r300);      r300->dirty_hw++;  } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 6befca72ce..7c83c5166d 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -29,6 +29,8 @@  struct rX00_fragment_program_code;  struct r300_vertex_program_code; +void r300_emit_aos(struct r300_context* r300, unsigned offset); +  void r300_emit_blend_state(struct r300_context* r300,                             struct r300_blend_state* blend); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index c36350d29e..0df9a94610 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -20,6 +20,9 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* r300_render: Vertex and index buffer primitive emission. Contains both + * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */ +  #include "draw/draw_context.h"  #include "draw/draw_vbuf.h" @@ -34,11 +37,12 @@  #include "r300_reg.h"  #include "r300_render.h"  #include "r300_state_derived.h" +#include "r300_vbo.h"  /* r300_render: Vertex and index buffer primitive emission. */  #define R300_MAX_VBO_SIZE  (1024 * 1024) -static uint32_t r300_translate_primitive(unsigned prim) +uint32_t r300_translate_primitive(unsigned prim)  {      switch (prim) {          case PIPE_PRIM_POINTS: @@ -66,6 +70,94 @@ static uint32_t r300_translate_primitive(unsigned prim)      }  } +static void r300_emit_draw_arrays(struct r300_context *r300, +                                  unsigned mode, +                                  unsigned count) +{ +    CS_LOCALS(r300); + +    BEGIN_CS(4); +    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count); +    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); +    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | +           r300_translate_primitive(mode)); +    END_CS; +} + +static void r300_emit_draw_elements(struct r300_context *r300, +                                    struct pipe_buffer* indexBuffer, +                                    unsigned indexSize, +                                    unsigned minIndex, +                                    unsigned maxIndex, +                                    unsigned mode, +                                    unsigned start, +                                    unsigned count) +{ +    uint32_t count_dwords; +    uint32_t offset_dwords = indexSize * start / sizeof(uint32_t); +    CS_LOCALS(r300); + +    /* XXX most of these are stupid */ +    assert(indexSize == 4 || indexSize == 2); +    assert((start * indexSize)  % 4 == 0); +    assert(offset_dwords == 0); + +    BEGIN_CS(10); +    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); +    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); +    if (indexSize == 4) { +        count_dwords = count + start; +        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | +               R300_VAP_VF_CNTL__INDEX_SIZE_32bit | +               r300_translate_primitive(mode)); +    } else { +        count_dwords = (count + start + 1) / 2; +        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | +               r300_translate_primitive(mode)); +    } + +    /* INDX_BUFFER is a truly special packet3. +     * Unlike most other packet3, where the offset is after the count, +     * the order is reversed, so the relocation ends up carrying the +     * size of the indexbuf instead of the offset. +     * +     * XXX Fix offset +     */ +    OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); +    OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | +           (0 << R300_INDX_BUFFER_SKIP_SHIFT)); +    OUT_CS(offset_dwords); +    OUT_CS_RELOC(indexBuffer, count_dwords, +        RADEON_GEM_DOMAIN_GTT, 0, 0); + +    END_CS; +} + + +static boolean r300_setup_vertex_buffers(struct r300_context *r300) +{ +    unsigned vbuf_count = r300->aos_count; +    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; +    struct pipe_vertex_element *velem = r300->vertex_element; + +validate: +    for (int i = 0; i < vbuf_count; i++) { +        if (!r300->winsys->add_buffer(r300->winsys, +                vbuf[velem[i].vertex_buffer_index].buffer, +            RADEON_GEM_DOMAIN_GTT, 0)) { +            r300->context.flush(&r300->context, 0, NULL); +            goto validate; +        } +    } + +    if (!r300->winsys->validate(r300->winsys)) { +        r300->context.flush(&r300->context, 0, NULL); +        return r300->winsys->validate(r300->winsys); +    } + +    return TRUE; +} +  /* This is the fast-path drawing & emission for HW TCL. */  boolean r300_draw_range_elements(struct pipe_context* pipe,                                   struct pipe_buffer* indexBuffer, @@ -77,87 +169,31 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,                                   unsigned count)  {      struct r300_context* r300 = r300_context(pipe); -    uint32_t prim = r300_translate_primitive(mode); -    struct pipe_vertex_buffer* aos = r300->vertex_buffers; -    unsigned aos_count = r300->vertex_buffer_count; -    short* indices; -    unsigned packet_size; -    unsigned i; -    bool invalid = FALSE; -     -    CS_LOCALS(r300);      if (!u_trim_pipe_prim(mode, &count)) {          return FALSE;      } -validate: -    for (i = 0; i < aos_count; i++) { -        if (!r300->winsys->add_buffer(r300->winsys, aos[i].buffer, -                    RADEON_GEM_DOMAIN_GTT, 0)) { -            pipe->flush(pipe, 0, NULL); -            goto validate; -        } -    } -    if (!r300->winsys->validate(r300->winsys)) { -        pipe->flush(pipe, 0, NULL); -        if (invalid) { -            /* Well, hell. */ -            debug_printf("r300: Stuck in validation loop, gonna quit now."); -            exit(1); -        } -        invalid = TRUE; -        goto validate; +    if (count > 65535) { +        return FALSE;      } -    r300_emit_dirty_state(r300); - -    packet_size = (aos_count >> 1) * 3 + (aos_count & 1) * 2; +    r300_update_derived_state(r300); -    BEGIN_CS(3 + packet_size + (aos_count * 2)); -    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); -    OUT_CS(aos_count); -    for (i = 0; i < aos_count - 1; i += 2) { -        OUT_CS(aos[i].stride | -            (aos[i].stride << 8) | -            (aos[i + 1].stride << 16) | -            (aos[i + 1].stride << 24)); -        OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride); -        OUT_CS(aos[i + 1].buffer_offset + start * 4 * aos[i + 1].stride); -    } -    if (aos_count & 1) { -        OUT_CS(aos[i].stride | (aos[i].stride << 8)); -        OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride); -    } -    for (i = 0; i < aos_count; i++) { -        OUT_CS_RELOC(aos[i].buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); +    if (!r300_setup_vertex_buffers(r300)) { +        return FALSE;      } -    END_CS; -    if (indexBuffer) { -        indices = (short*)pipe_buffer_map(pipe->screen, indexBuffer, -                                          PIPE_BUFFER_USAGE_CPU_READ); +    setup_vertex_attributes(r300); -        /* Set the starting point. */ -        indices += start; +    setup_index_buffer(r300, indexBuffer, indexSize); -        BEGIN_CS(2 + (count+1)/2); -        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count + 1)/2); -        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | prim); -        for (i = 0; i < count - 1; i += 2) { -            OUT_CS(indices[i + 1] << 16 | indices[i]); -        } -        if (count % 2) { -            OUT_CS(indices[count - 1]); -        } -        END_CS; -    } else { -        BEGIN_CS(2); -        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); -        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | -               prim); -        END_CS; -    } +    r300_emit_dirty_state(r300); + +    r300_emit_aos(r300, 0); + +    r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, +                            mode, start, count);      return TRUE;  } @@ -175,7 +211,31 @@ boolean r300_draw_elements(struct pipe_context* pipe,  boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,                           unsigned start, unsigned count)  { -    return pipe->draw_elements(pipe, NULL, 0, mode, start, 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;  }  /**************************************************************************** @@ -183,7 +243,8 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,   * keep these functions separated so that they are easier to locate. ~C.    *   ***************************************************************************/ -/* Draw-based drawing for SW TCL chipsets. */ +/* Draw-based drawing for SW TCL chipsets. + * XXX currently broken as fucking hell. */  boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,                                         struct pipe_buffer* indexBuffer,                                         unsigned indexSize, @@ -193,6 +254,8 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,                                         unsigned start,                                         unsigned count)  { +    assert(0); +#if 0      struct r300_context* r300 = r300_context(pipe);      int i; @@ -233,7 +296,7 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,          draw_set_mapped_element_buffer_range(r300->draw, 0, start,                                               start + count - 1, NULL);      } - +#endif      return TRUE;  } diff --git a/src/gallium/drivers/r300/r300_render.h b/src/gallium/drivers/r300/r300_render.h index 3d8f47ba75..3f8ac1fb7a 100644 --- a/src/gallium/drivers/r300/r300_render.h +++ b/src/gallium/drivers/r300/r300_render.h @@ -23,6 +23,8 @@  #ifndef R300_RENDER_H  #define R300_RENDER_H +uint32_t r300_translate_primitive(unsigned prim); +  boolean r300_draw_range_elements(struct pipe_context* pipe,                                   struct pipe_buffer* indexBuffer,                                   unsigned indexSize, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 658a8cba13..e0b85ab768 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -577,6 +577,8 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,      if (count > 8) {          return;      } +     +    r300->context.flush(&r300->context, 0, NULL);      for (i = 0; i < count; i++) {          if (r300->textures[i] != (struct r300_texture*)texture[i]) { @@ -664,10 +666,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,  {      struct r300_context* r300 = r300_context(pipe); -    memcpy(r300->vertex_buffers, buffers, +    memcpy(r300->vertex_buffer, buffers,          sizeof(struct pipe_vertex_buffer) * count); - -    r300->vertex_buffer_count = count; +    r300->vbuf_count = count;      if (r300->draw) {          draw_flush(r300->draw); @@ -681,10 +682,10 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,  {      struct r300_context* r300 = r300_context(pipe); -    memcpy(r300->vertex_elements, elements, -        sizeof(struct pipe_vertex_element) * count); - -    r300->vertex_element_count = count; +    memcpy(r300->vertex_element, +           elements, +           sizeof(struct pipe_vertex_element) * count); +    r300->aos_count = count;      if (r300->draw) {          draw_flush(r300->draw); diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 7d000e9e2d..14d7bb094c 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -63,7 +63,7 @@ int r300_shader_key_compare(void* key1, void* key2) {  /* Set up the vs_tab and routes. */  static void r300_vs_tab_routes(struct r300_context* r300, -                               struct r300_vertex_format* vformat) +                               struct r300_vertex_info* vformat)  {      struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct vertex_info* vinfo = &vformat->vinfo; @@ -219,7 +219,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,  /* Update the PSC tables. */  static void r300_vertex_psc(struct r300_context* r300, -                            struct r300_vertex_format* vformat) +                            struct r300_vertex_info* vformat)  {      struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct vertex_info* vinfo = &vformat->vinfo; @@ -282,7 +282,7 @@ static void r300_vertex_psc(struct r300_context* r300,  /* Set up the mappings from GB to US, for RS block. */  static void r300_update_fs_tab(struct r300_context* r300, -                               struct r300_vertex_format* vformat) +                               struct r300_vertex_info* vformat)  {      struct tgsi_shader_info* info = &r300->fs->info;      int i, cols = 0, texs = 0, cols_emitted = 0; @@ -455,13 +455,13 @@ static void r300_update_rs_block(struct r300_context* r300,  /* Update the vertex format. */  static void r300_update_derived_shader_state(struct r300_context* r300)  { -    struct r300_shader_key* key; -    struct r300_vertex_format* vformat; +    struct r300_vertex_info* vformat;      struct r300_rs_block* rs_block; -    struct r300_shader_derived_value* value;      int i;      /* +    struct r300_shader_key* key; +    struct r300_shader_derived_value* value;      key = CALLOC_STRUCT(r300_shader_key);      key->vs = r300->vs;      key->fs = r300->fs; @@ -486,7 +486,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300)      } */      /* XXX This will be refactored ASAP. */ -    vformat = CALLOC_STRUCT(r300_vertex_format); +    vformat = CALLOC_STRUCT(r300_vertex_info);      rs_block = CALLOC_STRUCT(r300_rs_block);      for (i = 0; i < 16; i++) { diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 52b9650fc1..e53db3d0b5 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -434,8 +434,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {      unsigned components = pf_component_count(format);      if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) { -        debug_printf("r300: Bad format %s in %s\n", pf_name(format), -            __FUNCTION__); +        debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format), +            __FUNCTION__, __LINE__);          return 0;      } @@ -447,6 +447,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {                      result = R300_DATA_TYPE_FLOAT_1 + (components - 1);                      break;                  default: +                    debug_printf("r300: Bad format %s in %s:%d\n", +                        pf_name(format), __FUNCTION__, __LINE__);                      assert(0);              }              break; @@ -470,10 +472,16 @@ r300_translate_vertex_data_type(enum pipe_format format) {                      }                      break;                  default: +                    debug_printf("r300: Bad format %s in %s:%d\n", +                        pf_name(format), __FUNCTION__, __LINE__); +                    debug_printf("r300: pf_size_x(format) == %d\n", +                        pf_size_x(format));                      assert(0);              }              break;          default: +            debug_printf("r300: Bad format %s in %s:%d\n", +                pf_name(format), __FUNCTION__, __LINE__);              assert(0);      } @@ -492,8 +500,8 @@ static INLINE uint16_t  r300_translate_vertex_data_swizzle(enum pipe_format format) {      if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) { -        debug_printf("r300: Bad format %s in %s\n", pf_name(format), -            __FUNCTION__); +        debug_printf("r300: Bad format %s in %s:%d\n", +            pf_name(format), __FUNCTION__, __LINE__);          return 0;      } diff --git a/src/gallium/drivers/r300/r300_vbo.c b/src/gallium/drivers/r300/r300_vbo.c new file mode 100644 index 0000000000..d8b356a061 --- /dev/null +++ b/src/gallium/drivers/r300/r300_vbo.c @@ -0,0 +1,170 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* r300_vbo: Various helpers for emitting vertex buffers. Needs cleanup, + * refactoring, etc. */ + +#include "r300_vbo.h" + +#include "pipe/p_format.h" + +#include "r300_cs.h" +#include "r300_context.h" +#include "r300_state_inlines.h" +#include "r300_reg.h" +#include "r300_winsys.h" + +static INLINE void setup_vertex_attribute(struct r300_vertex_info *vinfo, +                                          struct pipe_vertex_element *vert_elem, +                                          unsigned attr_num) +{ +    uint16_t hw_fmt1, hw_fmt2; + +    hw_fmt1 = r300_translate_vertex_data_type(vert_elem->src_format) | +        (attr_num << R300_DST_VEC_LOC_SHIFT); +    hw_fmt2 = r300_translate_vertex_data_swizzle(vert_elem->src_format); + +    if (attr_num % 2 == 0) +    { +        vinfo->vap_prog_stream_cntl[attr_num >> 1] = hw_fmt1; +        vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] = hw_fmt2; +    } +    else +    { +        vinfo->vap_prog_stream_cntl[attr_num >> 1] |= hw_fmt1 << 16; +        vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] |= hw_fmt2 << 16; +    } +} + +static void finish_vertex_attribs_setup(struct r300_vertex_info *vinfo, +                                        unsigned attribs_num) +{ +    uint32_t last_vec_bit = (attribs_num % 2 == 0) ? +        (R300_LAST_VEC << 16) : R300_LAST_VEC; + +    assert(attribs_num > 0 && attribs_num <= 16); +    vinfo->vap_prog_stream_cntl[(attribs_num - 1) >> 1] |= last_vec_bit; +} + +void setup_vertex_attributes(struct r300_context *r300) +{ +    struct pipe_vertex_element *vert_elem; +    int i; + +    for (i = 0; i < r300->aos_count; i++) { +        vert_elem = &r300->vertex_element[i]; +        setup_vertex_attribute(r300->vertex_info, vert_elem, i); +    } + +    finish_vertex_attribs_setup(r300->vertex_info, r300->aos_count); +} + +/* XXX WTF are these doing? */ +static void setup_vertex_array(struct r300_context *r300, struct pipe_vertex_element *element) +{ +} + +static void finish_vertex_arrays_setup(struct r300_context *r300) +{ +} + +/* XXX move/integrate this with the checks in r300_state_inlines */ +static boolean format_is_supported(enum pipe_format format, int nr_components) +{ +    if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) +        return FALSE; + +    if ((pf_size_x(format) != pf_size_y(format)) || +        (pf_size_x(format) != pf_size_z(format)) || +        (pf_size_x(format) != pf_size_w(format))) +        return FALSE; + +    /* Following should be supported as long as stride is 4 bytes aligned */ +    if (pf_size_x(format) != 1 && nr_components != 4) +        return FALSE; + +    if (pf_size_x(format) != 2 && !(nr_components == 2 || nr_components == 4)) +        return FALSE; + +    if (pf_size_x(format) == 3 || pf_size_x(format) > 4) +        return FALSE; + +    return TRUE; +} + +static INLINE int get_buffer_offset(struct r300_context *r300, +                                    unsigned int buf_nr, +                                    unsigned int elem_offset) +{ +    return r300->vertex_buffer[buf_nr].buffer_offset + elem_offset; +} + +/** + */ +static void setup_vertex_buffers(struct r300_context *r300) +{ +    struct pipe_vertex_element *vert_elem; +    int i; + +    for (i = 0; i < r300->aos_count; i++) +    { +        vert_elem = &r300->vertex_element[i]; +        if (!format_is_supported(vert_elem->src_format, +                                 vert_elem->nr_components)) { +            /* XXX use translate module to convert the data */ +            assert(0); +            /* +            struct pipe_buffer *buf; +            const unsigned int max_index = r300->vertex_buffers[vert_elem->vertex_buffer_index].max_index; +            buf = pipe_buffer_create(r300->context.screen, 4, usage, vert_elem->nr_components * max_index * sizeof(float)); +            */ +        } + +        if (get_buffer_offset(r300, +                              vert_elem->vertex_buffer_index, +                              vert_elem->src_offset) % 4) { +            /* XXX need to align buffer */ +            assert(0); +        } +        setup_vertex_array(r300, vert_elem); +    } + +    finish_vertex_arrays_setup(r300); +} + +void setup_index_buffer(struct r300_context *r300, +                        struct pipe_buffer* indexBuffer, +                        unsigned indexSize) +{ +    /* XXX I call BS; why is this different from the assert in r300_render? */ +    assert(indexSize = 2); + +    if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, +                                  RADEON_GEM_DOMAIN_GTT, 0)) { +        assert(0); +    } + +    if (!r300->winsys->validate(r300->winsys)) { +        assert(0); +    } +} diff --git a/src/gallium/drivers/r300/r300_vbo.h b/src/gallium/drivers/r300/r300_vbo.h new file mode 100644 index 0000000000..7afa75899c --- /dev/null +++ b/src/gallium/drivers/r300/r300_vbo.h @@ -0,0 +1,36 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef R300_VBO_H +#define R300_VBO_H + +struct r300_context; +struct pipe_buffer; + +void setup_vertex_attributes(struct r300_context *r300); + +void setup_index_buffer(struct r300_context *r300, +                        struct pipe_buffer* indexBuffer, +                        unsigned indexSize); + +#endif | 
