From: Marek Olšák Date: Mon, 12 Apr 2010 02:12:27 +0000 (+0200) Subject: r300g: atomize FS constant buffer X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=136bd184a29945ab7ae0636ecef65e9db97f8e4d;p=mesa.git r300g: atomize FS constant buffer --- diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 061322b75fd..bdc1ebedcc0 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -66,6 +66,7 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); + FREE(r300->fs_constants.state); FREE(r300); } @@ -117,11 +118,13 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(textures_state, 0); R300_INIT_ATOM(fs, 0); R300_INIT_ATOM(fs_rc_constant_state, 0); + R300_INIT_ATOM(fs_constants, 0); /* Replace emission functions for r500. */ if (r300->screen->caps.is_r500) { r300->fs.emit = r500_emit_fs; r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state; + r300->fs_constants.emit = r500_emit_fs_constants; } /* Some non-CSO atoms need explicit space to store the state locally. */ @@ -134,6 +137,7 @@ static void r300_setup_atoms(struct r300_context* r300) r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); + r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer); } struct pipe_context* r300_create_context(struct pipe_screen* screen, diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 2e248a4d6cd..d8bed53a6d5 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -360,6 +360,8 @@ struct r300_context { struct r300_atom fs; /* Fragment shader RC_CONSTANT_STATE variables. */ struct r300_atom fs_rc_constant_state; + /* Fragment shader constant buffer. */ + struct r300_atom fs_constants; /* Framebuffer state. */ struct r300_atom fb_state; /* Rasterizer state. */ diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h index 2bcf298c414..da85137625c 100644 --- a/src/gallium/drivers/r300/r300_defines.h +++ b/src/gallium/drivers/r300/r300_defines.h @@ -31,7 +31,6 @@ #define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV /* Non-atom dirty state flags. */ -#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 #define R300_NEW_KITCHEN_SINK 0x7fffffff diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index fd857a4ac19..d0f227f9424 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -320,22 +320,22 @@ void r300_emit_fs(struct r300_context* r300, unsigned size, void *state) END_CS; } -void r300_emit_fs_constant_buffer(struct r300_context* r300, - struct rc_constant_list* constants) +void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); + struct rc_constant_list *constants = &fs->shader->code.constants; + struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; unsigned i, count = fs->shader->externals_count; CS_LOCALS(r300); if (count == 0) return; - BEGIN_CS(count * 4 + 1); + BEGIN_CS(size); OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4); for(i = 0; i < count; ++i) { assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL); - const float *data = - r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i]; + const float *data = buf->constants[i]; OUT_CS(pack_float24(data[0])); OUT_CS(pack_float24(data[1])); OUT_CS(pack_float24(data[2])); @@ -439,10 +439,11 @@ void r500_emit_fs(struct r300_context* r300, unsigned size, void *state) END_CS; } -void r500_emit_fs_constant_buffer(struct r300_context* r300, - struct rc_constant_list* constants) +void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) { struct r300_fragment_shader *fs = r300_fs(r300); + struct rc_constant_list *constants = &fs->shader->code.constants; + struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; unsigned i, count = fs->shader->externals_count; CS_LOCALS(r300); @@ -454,8 +455,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4); for(i = 0; i < count; ++i) { assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL); - const float *data = - r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i]; + const float *data = buf->constants[i]; OUT_CS_32F(data[0]); OUT_CS_32F(data[1]); @@ -1211,17 +1211,6 @@ void r300_emit_dirty_state(struct r300_context* r300) } } - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) { - if (r300screen->caps.is_r500) { - r500_emit_fs_constant_buffer(r300, - &r300_fs(r300)->shader->code.constants); - } else { - r300_emit_fs_constant_buffer(r300, - &r300_fs(r300)->shader->code.constants); - } - r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { struct r300_vertex_shader* vs = r300->vs_state.state; if (vs->code.constants.Count) { diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 09737fbb597..d275bb211a8 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -47,8 +47,7 @@ unsigned r300_get_fs_atom_size(struct r300_context *r300); void r300_emit_fs(struct r300_context* r300, unsigned size, void *state); -void r300_emit_fs_constant_buffer(struct r300_context* r300, - struct rc_constant_list* constants); +void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state); void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state); @@ -56,8 +55,7 @@ unsigned r500_get_fs_atom_size(struct r300_context *r300); void r500_emit_fs(struct r300_context* r300, unsigned size, void *state); -void r500_emit_fs_constant_buffer(struct r300_context* r300, - struct rc_constant_list* constants); +void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state); void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index aacaa4e6afe..f1a062333a6 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -689,16 +689,17 @@ static void r300_mark_fs_code_dirty(struct r300_context *r300) r300->fs.dirty = TRUE; r300->fs_rc_constant_state.dirty = TRUE; + r300->fs_constants.dirty = TRUE; if (r300->screen->caps.is_r500) { r300->fs.size = r500_get_fs_atom_size(r300); r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 7; + r300->fs_constants.size = fs->shader->externals_count * 4 + 3; } else { r300->fs.size = r300_get_fs_atom_size(r300); r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 5; + r300->fs_constants.size = fs->shader->externals_count * 4 + 1; } - - r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } /* Bind fragment shader state. */ @@ -1379,25 +1380,18 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, struct pipe_resource *buf) { struct r300_context* r300 = r300_context(pipe); + struct r300_constant_buffer *cbuf; struct pipe_transfer *tr; void *mapped; int max_size = 0; - if (buf == NULL || buf->width0 == 0 || - (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL) - { - r300->shader_constants[shader].count = 0; - return; - } - - assert((buf->width0 % 4 * sizeof(float)) == 0); - - /* Check the size of the constant buffer. */ switch (shader) { case PIPE_SHADER_VERTEX: + cbuf = &r300->shader_constants[PIPE_SHADER_VERTEX]; max_size = 256; break; case PIPE_SHADER_FRAGMENT: + cbuf = (struct r300_constant_buffer*)r300->fs_constants.state; if (r300->screen->caps.is_r500) { max_size = 256; } else { @@ -1408,6 +1402,16 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, assert(0); } + if (buf == NULL || buf->width0 == 0 || + (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL) + { + cbuf->count = 0; + return; + } + + assert((buf->width0 % 4 * sizeof(float)) == 0); + + /* Check the size of the constant buffer. */ /* XXX Subtract immediates and RC_STATE_* variables. */ if (buf->width0 > (sizeof(float) * 4 * max_size)) { fprintf(stderr, "r300: Max size of the constant buffer is " @@ -1415,8 +1419,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, abort(); } - memcpy(r300->shader_constants[shader].constants, mapped, buf->width0); - r300->shader_constants[shader].count = buf->width0 / (4 * sizeof(float)); + memcpy(cbuf->constants, mapped, buf->width0); + cbuf->count = buf->width0 / (4 * sizeof(float)); pipe_buffer_unmap(pipe, buf, tr); if (shader == PIPE_SHADER_VERTEX) { @@ -1425,11 +1429,11 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, r300->pvs_flush.dirty = TRUE; } else if (r300->draw) { draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, - 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, + 0, cbuf->constants, buf->width0); } } else if (shader == PIPE_SHADER_FRAGMENT) { - r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; + r300->fs_constants.dirty = TRUE; } }