diff options
| author | Maciej Cencora <m.cencora@gmail.com> | 2009-10-21 21:17:43 +0200 | 
|---|---|---|
| committer | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-11-01 11:01:40 -0800 | 
| commit | 2db46af8758bf77a2748460f617d0ead5b08a454 (patch) | |
| tree | bd01c3cf0805ef3a2bd6bf981bdde12093adec84 | |
| parent | cab749a1d0046f59ca10f96d2e6343404e5f2616 (diff) | |
r300g: split constant buffer and shader emittion
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 157 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.h | 21 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 54 | 
5 files changed, 152 insertions, 98 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 02f201b49a..f974147ea4 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -22,8 +22,6 @@  #include "draw/draw_context.h" -#include "pipe/p_inlines.h" -  #include "tgsi/tgsi_scan.h"  #include "util/u_hash_table.h" diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index cee0734d21..b1738452de 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -26,6 +26,7 @@  #include "draw/draw_vertex.h"  #include "pipe/p_context.h" +#include "pipe/p_inlines.h"  struct r300_fragment_shader;  struct r300_vertex_shader; @@ -119,10 +120,10 @@ struct r300_ztop_state {  #define R300_NEW_BLEND           0x00000001  #define R300_NEW_BLEND_COLOR     0x00000002  #define R300_NEW_CLIP            0x00000004 -#define R300_NEW_CONSTANTS       0x00000008 -#define R300_NEW_DSA             0x00000010 -#define R300_NEW_FRAMEBUFFERS    0x00000020 -#define R300_NEW_FRAGMENT_SHADER 0x00000040 +#define R300_NEW_DSA             0x00000008 +#define R300_NEW_FRAMEBUFFERS    0x00000010 +#define R300_NEW_FRAGMENT_SHADER 0x00000020 +#define R300_NEW_FRAGMENT_SHADER_CONSTANTS    0x00000040  #define R300_NEW_RASTERIZER      0x00000080  #define R300_NEW_RS_BLOCK        0x00000100  #define R300_NEW_SAMPLER         0x00000200 @@ -132,9 +133,10 @@ struct r300_ztop_state {  #define R300_ANY_NEW_TEXTURES    0x03fc0000  #define R300_NEW_VERTEX_FORMAT   0x04000000  #define R300_NEW_VERTEX_SHADER   0x08000000 -#define R300_NEW_VIEWPORT        0x10000000 -#define R300_NEW_QUERY           0x20000000 -#define R300_NEW_KITCHEN_SINK    0x3fffffff +#define R300_NEW_VERTEX_SHADER_CONSTANTS    0x10000000 +#define R300_NEW_VIEWPORT        0x20000000 +#define R300_NEW_QUERY           0x40000000 +#define R300_NEW_KITCHEN_SINK    0x7fffffff  /* The next several objects are not pure Radeon state; they inherit from   * various Gallium classes. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 22cf9cac2a..de27f0939b 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -178,18 +178,15 @@ static uint32_t pack_float24(float f)  }  void r300_emit_fragment_program_code(struct r300_context* r300, -                                     struct rX00_fragment_program_code* generic_code, -                                     struct r300_constant_buffer* externals) +                                     struct rX00_fragment_program_code* generic_code)  {      struct r300_fragment_program_code * code = &generic_code->code.r300; -    struct rc_constant_list * constants = &generic_code->constants;      int i;      CS_LOCALS(r300);      BEGIN_CS(15 +               code->alu.length * 4 + -             (code->tex.length ? (1 + code->tex.length) : 0) + -             (constants->Count ? (1 + constants->Count * 4) : 0)); +             (code->tex.length ? (1 + code->tex.length) : 0));      OUT_CS_REG(R300_US_CONFIG, code->config);      OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); @@ -221,32 +218,41 @@ void r300_emit_fragment_program_code(struct r300_context* r300,              OUT_CS(code->tex.inst[i]);      } -    if (constants->Count) { -        OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4); -        for(i = 0; i < constants->Count; ++i) { -            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); -            OUT_CS(pack_float24(data[0])); -            OUT_CS(pack_float24(data[1])); -            OUT_CS(pack_float24(data[2])); -            OUT_CS(pack_float24(data[3])); -        } -    } +    END_CS; +} + +void r300_emit_fs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants) +{ +    int i; +    CS_LOCALS(r300); + +    if (constants->Count == 0) +        return; +    BEGIN_CS(constants->Count * 4 + 1); +    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4); +    for(i = 0; i < constants->Count; ++i) { +        const float * data = get_shader_constant(r300, +                                                 &constants->Constants[i], +                                                 &r300->shader_constants[PIPE_SHADER_FRAGMENT]); +        OUT_CS(pack_float24(data[0])); +        OUT_CS(pack_float24(data[1])); +        OUT_CS(pack_float24(data[2])); +        OUT_CS(pack_float24(data[3])); +    }      END_CS;  }  void r500_emit_fragment_program_code(struct r300_context* r300, -                                     struct rX00_fragment_program_code* generic_code, -                                     struct r300_constant_buffer* externals) +                                     struct rX00_fragment_program_code* generic_code)  {      struct r500_fragment_program_code * code = &generic_code->code.r500; -    struct rc_constant_list * constants = &generic_code->constants;      int i;      CS_LOCALS(r300);      BEGIN_CS(13 + -             ((code->inst_end + 1) * 6) + -             (constants->Count ? (3 + (constants->Count * 4)) : 0)); +             ((code->inst_end + 1) * 6));      OUT_CS_REG(R500_US_CONFIG, 0);      OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);      OUT_CS_REG(R500_US_CODE_RANGE, @@ -266,18 +272,30 @@ void r500_emit_fragment_program_code(struct r300_context* r300,          OUT_CS(code->inst[i].inst5);      } -    if (constants->Count) { -        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); -        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4); -        for (i = 0; i < constants->Count; i++) { -            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); -            OUT_CS_32F(data[0]); -            OUT_CS_32F(data[1]); -            OUT_CS_32F(data[2]); -            OUT_CS_32F(data[3]); -        } -    } +    END_CS; +} + +void r500_emit_fs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants) +{ +    int i; +    CS_LOCALS(r300); + +    if (constants->Count == 0) +        return; +    BEGIN_CS(constants->Count * 4 + 2); +    OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); +    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4); +    for (i = 0; i < constants->Count; i++) { +        const float * data = get_shader_constant(r300, +                                                 &constants->Constants[i], +                                                 &r300->shader_constants[PIPE_SHADER_FRAGMENT]); +        OUT_CS_32F(data[0]); +        OUT_CS_32F(data[1]); +        OUT_CS_32F(data[2]); +        OUT_CS_32F(data[3]); +    }      END_CS;  } @@ -621,8 +639,7 @@ void r300_emit_vertex_format_state(struct r300_context* r300)  }  void r300_emit_vertex_program_code(struct r300_context* r300, -                                   struct r300_vertex_program_code* code, -                                   struct r300_constant_buffer* constants) +                                   struct r300_vertex_program_code* code)  {      int i;      struct r300_screen* r300screen = r300_screen(r300->context.screen); @@ -635,12 +652,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300,          return;      } -    if (code->constants.Count) { -        BEGIN_CS(14 + code->length + (code->constants.Count * 4)); -    } else { -        BEGIN_CS(11 + code->length); -    } - +    BEGIN_CS(11 + code->length);      /* R300_VAP_PVS_CODE_CNTL_0       * R300_VAP_PVS_CONST_CNTL       * R300_VAP_PVS_CODE_CNTL_1 @@ -658,20 +670,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300,      for (i = 0; i < code->length; i++)          OUT_CS(code->body.d[i]); -    if (code->constants.Count) { -        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, -                (r300screen->caps->is_r500 ? -                 R500_PVS_CONST_START : R300_PVS_CONST_START)); -        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4); -        for (i = 0; i < code->constants.Count; i++) { -            const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants); -            OUT_CS_32F(data[0]); -            OUT_CS_32F(data[1]); -            OUT_CS_32F(data[2]); -            OUT_CS_32F(data[3]); -        } -    } -      OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |              R300_PVS_NUM_CNTLRS(5) |              R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) | @@ -683,7 +681,40 @@ void r300_emit_vertex_program_code(struct r300_context* r300,  void r300_emit_vertex_shader(struct r300_context* r300,                               struct r300_vertex_shader* vs)  { -    r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]); +    r300_emit_vertex_program_code(r300, &vs->code); +} + +void r300_emit_vs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants) +{ +    int i; +    struct r300_screen* r300screen = r300_screen(r300->context.screen); +    CS_LOCALS(r300); + +    if (!r300screen->caps->has_tcl) { +        debug_printf("r300: Implementation error: emit_vertex_shader called," +        " but has_tcl is FALSE!\n"); +        return; +    } + +    if (constants->Count == 0) +        return; + +    BEGIN_CS(constants->Count * 4 + 3); +    OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, +               (r300screen->caps->is_r500 ? +               R500_PVS_CONST_START : R300_PVS_CONST_START)); +    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4); +    for (i = 0; i < constants->Count; i++) { +        const float * data = get_shader_constant(r300, +                                                 &constants->Constants[i], +                                                 &r300->shader_constants[PIPE_SHADER_VERTEX]); +        OUT_CS_32F(data[0]); +        OUT_CS_32F(data[1]); +        OUT_CS_32F(data[2]); +        OUT_CS_32F(data[3]); +    } +    END_CS;  }  void r300_emit_viewport_state(struct r300_context* r300, @@ -822,13 +853,22 @@ validate:      if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {          if (r300screen->caps->is_r500) { -            r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]); +            r500_emit_fragment_program_code(r300, &r300->fs->code);          } else { -            r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]); +            r300_emit_fragment_program_code(r300, &r300->fs->code);          }          r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;      } +    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) { +        if (r300screen->caps->is_r500) { +            r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants); +        } else { +            r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants); +        } +        r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; +    } +      if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {          r300_emit_fb_state(r300, &r300->framebuffer_state);          r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS; @@ -887,6 +927,11 @@ validate:          r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;      } +    if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { +        r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants); +        r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS; +    } +      /* XXX      assert(r300->dirty_state == 0);      */ diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 02ac5bebbd..6befca72ce 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -23,6 +23,9 @@  #ifndef R300_EMIT_H  #define R300_EMIT_H +#include "r300_context.h" +#include "radeon_code.h" +  struct rX00_fragment_program_code;  struct r300_vertex_program_code; @@ -39,12 +42,16 @@ void r300_emit_dsa_state(struct r300_context* r300,                           struct r300_dsa_state* dsa);  void r300_emit_fragment_program_code(struct r300_context* r300, -                                     struct rX00_fragment_program_code* generic_code, -                                     struct r300_constant_buffer* externals); +                                     struct rX00_fragment_program_code* generic_code); + +void r300_emit_fs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants);  void r500_emit_fragment_program_code(struct r300_context* r300, -                                     struct rX00_fragment_program_code* generic_code, -                                     struct r300_constant_buffer* externals); +                                     struct rX00_fragment_program_code* generic_code); + +void r500_emit_fs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants);  void r300_emit_fb_state(struct r300_context* r300,                          struct pipe_framebuffer_state* fb); @@ -72,8 +79,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);  void r300_emit_vertex_format_state(struct r300_context* r300);  void r300_emit_vertex_program_code(struct r300_context* r300, -                                   struct r300_vertex_program_code* code, -                                   struct r300_constant_buffer* constants); +                                   struct r300_vertex_program_code* code); + +void r300_emit_vs_constant_buffer(struct r300_context* r300, +                                  struct rc_constant_list* constants);  void r300_emit_vertex_shader(struct r300_context* r300,                               struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 3ac627e959..4cf01389d2 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -166,31 +166,6 @@ static void r300_set_clip_state(struct pipe_context* pipe,      }  } -static void -    r300_set_constant_buffer(struct pipe_context* pipe, -                             uint shader, uint index, -                             const struct pipe_constant_buffer* buffer) -{ -    struct r300_context* r300 = r300_context(pipe); - -    /* This entire chunk of code seems ever-so-slightly baked. -     * It's as if I've got pipe_buffer* matryoshkas... */ -    if (buffer && buffer->buffer && buffer->buffer->size) { -        void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer, -                                             PIPE_BUFFER_USAGE_CPU_READ); -        memcpy(r300->shader_constants[shader].constants, -            map, buffer->buffer->size); -        pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer); - -        r300->shader_constants[shader].count = -            buffer->buffer->size / (sizeof(float) * 4); -    } else { -        r300->shader_constants[shader].count = 0; -    } - -    r300->dirty_state |= R300_NEW_CONSTANTS; -} -  /* Create a new depth, stencil, and alpha state based on the CSO dsa state.   *   * This contains the depth buffer, stencil buffer, alpha test, and such. @@ -345,7 +320,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)      r300->fs = fs; -    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; +    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;  }  /* Delete fragment shader state. */ @@ -702,7 +677,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)          draw_bind_vertex_shader(r300->draw, vs->draw);          r300->vs = vs; -        r300->dirty_state |= R300_NEW_VERTEX_SHADER; +        r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;      } else {          draw_bind_vertex_shader(r300->draw,                  (struct draw_vertex_shader*)shader); @@ -726,6 +701,31 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)      }  } +static void r300_set_constant_buffer(struct pipe_context *pipe, +                                     uint shader, uint index, +                                     const struct pipe_constant_buffer *buf) +{ +    struct r300_context* r300 = r300_context(pipe); +    void *mapped; + +    if (buf == NULL || buf->buffer->size == 0 || +        (mapped = pipe_buffer_map(pipe->screen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) +    { +        r300->shader_constants[shader].count = 0; +        return; +    } + +    assert((buf->buffer->size % 4 * sizeof(float)) == 0); +    memcpy(r300->shader_constants[shader].constants, mapped, buf->buffer->size); +    r300->shader_constants[shader].count = buf->buffer->size / (4 * sizeof(float)); +    pipe_buffer_unmap(pipe->screen, buf->buffer); + +    if (shader == PIPE_SHADER_VERTEX) +        r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; +    else if (shader == PIPE_SHADER_FRAGMENT) +        r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; +} +  void r300_init_state_functions(struct r300_context* r300)  {      r300->context.create_blend_state = r300_create_blend_state; | 
