diff options
| author | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-10-16 08:39:59 -0700 | 
|---|---|---|
| committer | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-10-16 08:43:02 -0700 | 
| commit | fc8a156cfc539b9c04dc3527e4fc61cb4b0b688e (patch) | |
| tree | d9eafbd3c0645c66f0223143e1e9dcce56d3d3c9 /src | |
| parent | 3924d8611513eea74446d655b554596ab66381ff (diff) | |
r300g: Use a hash table to look up vertex info.
Need to move rs_block to this, too.
Also, I'm getting massive amounts of flicker for some reason; I bet we've gotta
re-re-examine PSC and friends. :C
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 18 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 10 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 26 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 72 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.h | 4 | 
6 files changed, 97 insertions, 35 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b243f88bb5..a1156d2de6 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -89,10 +89,23 @@ static boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,      return r300_draw_elements(pipe, NULL, 0, mode, start, count);  } -static void r300_destroy_context(struct pipe_context* context) { +static enum pipe_error r300_clear_hash_table(void* key, void* value, +                                             void* data) +{ +    FREE(key); +    FREE(value); +    return PIPE_OK; +} + +static void r300_destroy_context(struct pipe_context* context) +{      struct r300_context* r300 = r300_context(context);      struct r300_query* query, * temp; +    u_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table, +        NULL); +    u_hash_table_destroy(r300->shader_hash_table); +      draw_destroy(r300->draw);      /* Free the OQ BO. */ @@ -167,6 +180,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      r300->context.is_texture_referenced = r300_is_texture_referenced;      r300->context.is_buffer_referenced = r300_is_buffer_referenced; +    r300->shader_hash_table = u_hash_table_create(r300_shader_key_hash, +        r300_shader_key_compare); +      r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);      r300->rs_block = CALLOC_STRUCT(r300_rs_block);      r300->scissor_state = CALLOC_STRUCT(r300_scissor_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 2acce0fd4a..2a62c67fc7 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -30,12 +30,14 @@  #include "tgsi/tgsi_scan.h" +#include "util/u_hash_table.h"  #include "util/u_memory.h"  #include "util/u_simple_list.h"  #include "r300_clear.h"  #include "r300_query.h"  #include "r300_screen.h" +#include "r300_state_derived.h"  #include "r300_winsys.h"  struct r300_fragment_shader; @@ -248,6 +250,12 @@ struct r300_context {      struct r300_query *query_current;      struct r300_query query_list; +    /* Shader hash table. Used to store vertex formatting information, which +     * depends on the combination of both currently loaded shaders. */ +    struct u_hash_table* shader_hash_table; +    /* Vertex formatting information. */ +    struct r300_vertex_format* vertex_info; +      /* Various CSO state objects. */      /* Blend state. */      struct r300_blend_state* blend_state; @@ -278,8 +286,6 @@ struct r300_context {      /* Vertex buffers for Gallium. */      struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];      int vertex_buffer_count; -    /* Vertex information. */ -    struct r300_vertex_format vertex_info;      /* Vertex shader. */      struct r300_vertex_shader* vs;      /* Viewport state. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f3adc0968e..e6092cda9b 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -551,7 +551,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300)      DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "              "vertex size %d\n", r300->vbo, -            r300->vertex_info.vinfo.size); +            r300->vertex_info->vinfo.size);      /* Set the pointer to our vertex buffer. The emitted values are this:       * PACKET3 [3D_LOAD_VBPNTR]       * COUNT   [1] @@ -562,8 +562,8 @@ void r300_emit_vertex_buffer(struct r300_context* r300)      BEGIN_CS(7);      OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);      OUT_CS(1); -    OUT_CS(r300->vertex_info.vinfo.size | -            (r300->vertex_info.vinfo.size << 8)); +    OUT_CS(r300->vertex_info->vinfo.size | +            (r300->vertex_info->vinfo.size << 8));      OUT_CS(r300->vbo_offset);      OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);      END_CS; @@ -575,30 +575,30 @@ void r300_emit_vertex_format_state(struct r300_context* r300)      CS_LOCALS(r300);      BEGIN_CS(26); -    OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info.vinfo.size); +    OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size);      OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); -    OUT_CS(r300->vertex_info.vinfo.hwfmt[0]); -    OUT_CS(r300->vertex_info.vinfo.hwfmt[1]); +    OUT_CS(r300->vertex_info->vinfo.hwfmt[0]); +    OUT_CS(r300->vertex_info->vinfo.hwfmt[1]);      OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); -    OUT_CS(r300->vertex_info.vinfo.hwfmt[2]); -    OUT_CS(r300->vertex_info.vinfo.hwfmt[3]); +    OUT_CS(r300->vertex_info->vinfo.hwfmt[2]); +    OUT_CS(r300->vertex_info->vinfo.hwfmt[3]);      /* for (i = 0; i < 4; i++) {       *    debug_printf("hwfmt%d: 0x%08x\n", i, -     *            r300->vertex_info.vinfo.hwfmt[i]); +     *            r300->vertex_info->vinfo.hwfmt[i]);       * } */      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);      for (i = 0; i < 8; i++) { -        OUT_CS(r300->vertex_info.vap_prog_stream_cntl[i]); +        OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]);          /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i, -         *        r300->vertex_info.vap_prog_stream_cntl[i]); */ +         *        r300->vertex_info->vap_prog_stream_cntl[i]); */      }      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);      for (i = 0; i < 8; i++) { -        OUT_CS(r300->vertex_info.vap_prog_stream_cntl_ext[i]); +        OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]);          /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i, -         *        r300->vertex_info.vap_prog_stream_cntl_ext[i]); */ +         *        r300->vertex_info->vap_prog_stream_cntl_ext[i]); */      }      END_CS;  } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index b56f7a3d1e..4e778e1e57 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -67,7 +67,7 @@ r300_render_get_vertex_info(struct vbuf_render* render)      r300_update_derived_state(r300); -    return &r300->vertex_info.vinfo; +    return &r300->vertex_info->vinfo;  }  static boolean r300_render_allocate_vertices(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index f0861a9cf1..53027777d6 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -29,6 +29,27 @@  /* r300_state_derived: Various bits of state which are dependent upon   * currently bound CSO data. */ +struct r300_shader_key { +    struct r300_vertex_shader* vs; +    struct r300_fragment_shader* fs; +}; + +unsigned r300_shader_key_hash(void* key) { +    struct r300_shader_key* shader_key = (struct r300_shader_key*)key; +    unsigned vs = (unsigned)shader_key->vs; +    unsigned fs = (unsigned)shader_key->fs; + +    return (vs << 16) | (fs & 0xffff); +} + +int r300_shader_key_compare(void* key1, void* key2) { +    struct r300_shader_key* shader_key1 = (struct r300_shader_key*)key1; +    struct r300_shader_key* shader_key2 = (struct r300_shader_key*)key2; + +    return (shader_key1->vs == shader_key2->vs) && +        (shader_key1->fs == shader_key2->fs); +} +  /* Set up the vs_tab and routes. */  static void r300_vs_tab_routes(struct r300_context* r300,                                 struct r300_vertex_format* vformat) @@ -247,23 +268,41 @@ static void r300_vertex_psc(struct r300_context* r300,  /* Update the vertex format. */  static void r300_update_vertex_format(struct r300_context* r300)  { -    struct r300_vertex_format vformat; +    struct r300_shader_key* key; +    struct r300_vertex_format* vformat; +    void* value;      int i; -    memset(&vformat, 0, sizeof(struct r300_vertex_format)); -    for (i = 0; i < 16; i++) { -        vformat.vs_tab[i] = -1; -        vformat.fs_tab[i] = -1; -    } +    key = CALLOC_STRUCT(r300_shader_key); +    key->vs = r300->vs; +    key->fs = r300->fs; -    r300_vs_tab_routes(r300, &vformat); +    value = u_hash_table_get(r300->shader_hash_table, (void*)key); +    if (value) { +        debug_printf("r300: Hash table hit! vs: %p fs: %p\n", key->vs, +            key->fs); +        vformat = (struct r300_vertex_format*)value; +    } else { +        debug_printf("r300: Hash table miss... vs: %p fs: %p\n", key->vs, +            key->fs); +        vformat = CALLOC_STRUCT(r300_vertex_format); + +        for (i = 0; i < 16; i++) { +            vformat->vs_tab[i] = -1; +            vformat->fs_tab[i] = -1; +        } + +        r300_vs_tab_routes(r300, vformat); +        r300_vertex_psc(r300, vformat); -    r300_vertex_psc(r300, &vformat); +        if (u_hash_table_set(r300->shader_hash_table, (void*)key, +                (void*)vformat) != PIPE_OK) { +            debug_printf("r300: Hash table insertion error!\n"); +        } +    } -    if (memcmp(&r300->vertex_info, &vformat, -                sizeof(struct r300_vertex_format))) { -        memcpy(&r300->vertex_info, &vformat, -                sizeof(struct r300_vertex_format)); +    if (r300->vertex_info != vformat) { +        r300->vertex_info = vformat;          r300->dirty_state |= R300_NEW_VERTEX_FORMAT;      }  } @@ -271,7 +310,7 @@ static void r300_update_vertex_format(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 = &r300->vertex_info; +    struct r300_vertex_format* vformat = r300->vertex_info;      struct tgsi_shader_info* info = &r300->fs->info;      int i, cols = 0, texs = 0, cols_emitted = 0;      int* tab = vformat->fs_tab; @@ -337,7 +376,7 @@ static void r300_update_rs_block(struct r300_context* r300)  {      struct r300_rs_block* rs = r300->rs_block;      struct tgsi_shader_info* info = &r300->fs->info; -    int* tab = r300->vertex_info.fs_tab; +    int* tab = r300->vertex_info->fs_tab;      int col_count = 0, fp_offset = 0, i, tex_count = 0;      int rs_tex_comp = 0;      memset(rs, 0, sizeof(struct r300_rs_block)); @@ -477,10 +516,7 @@ static void r300_update_ztop(struct r300_context* r300)  void r300_update_derived_state(struct r300_context* r300)  { -    if (r300->dirty_state & -            (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) { -        r300_update_vertex_format(r300); -    } +    r300_update_vertex_format(r300);      if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) {          r300_update_fs_tab(r300); diff --git a/src/gallium/drivers/r300/r300_state_derived.h b/src/gallium/drivers/r300/r300_state_derived.h index 71a4a47b00..05ad535e2d 100644 --- a/src/gallium/drivers/r300/r300_state_derived.h +++ b/src/gallium/drivers/r300/r300_state_derived.h @@ -25,6 +25,10 @@  struct r300_context; +unsigned r300_shader_key_hash(void* key); + +int r300_shader_key_compare(void* key1, void* key2); +  void r300_update_derived_state(struct r300_context* r300);  #endif /* R300_STATE_DERIVED_H */ | 
