From: Maciej Cencora Date: Wed, 21 Oct 2009 19:17:43 +0000 (+0200) Subject: r300g: split constant buffer and shader emittion X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2db46af8758bf77a2748460f617d0ead5b08a454;p=mesa.git r300g: split constant buffer and shader emittion --- diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 02f201b49ad..f974147ea43 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 cee0734d213..b1738452de0 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 22cf9cac2a3..de27f0939b0 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 02ac5bebbd9..6befca72ced 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 3ac627e9599..4cf01389d2b 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;