From 953a309de9204490edcd011e700c06c7c25c0b9e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 11 Apr 2010 23:00:16 +0200 Subject: [PATCH] r300g: FS constants emission rework * The constant buffer emission is separated from RC state variables emission. * The immediates are emitted with FS code. --- src/gallium/drivers/r300/r300_emit.c | 145 +++++++++++++++++++++++++---- src/gallium/drivers/r300/r300_emit.h | 6 ++ src/gallium/drivers/r300/r300_fs.c | 20 ++++ src/gallium/drivers/r300/r300_fs.h | 5 + src/gallium/drivers/r300/r300_tgsi_to_rc.c | 1 - 5 files changed, 156 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 63cd41a..20d1c24 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -237,12 +237,17 @@ void r300_emit_fragment_program_code(struct r300_context* r300, struct rX00_fragment_program_code* generic_code) { struct r300_fragment_program_code * code = &generic_code->code.r300; - int i; + unsigned i; + unsigned imm_count = r300->fs->shader->immediates_count; + unsigned imm_first = r300->fs->shader->externals_count; + unsigned imm_end = generic_code->constants.Count; + struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); BEGIN_CS(15 + code->alu.length * 4 + - (code->tex.length ? (1 + code->tex.length) : 0)); + (code->tex.length ? (1 + code->tex.length) : 0) + + (imm_count ? imm_count * 5 : 0)); OUT_CS_REG(R300_US_CONFIG, code->config); OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); @@ -274,24 +279,38 @@ void r300_emit_fragment_program_code(struct r300_context* r300, OUT_CS(code->tex.inst[i]); } + /* Emit immediates. */ + if (imm_count) { + for(i = imm_first; i < imm_end; ++i) { + if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { + const float *data = constants[i].u.Immediate; + + OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); + 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; + unsigned i, count = r300->fs->shader->externals_count; CS_LOCALS(r300); - if (constants->Count == 0) + if (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]); + BEGIN_CS(count * 4 + 1); + 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]; OUT_CS(pack_float24(data[0])); OUT_CS(pack_float24(data[1])); OUT_CS(pack_float24(data[2])); @@ -300,6 +319,34 @@ void r300_emit_fs_constant_buffer(struct r300_context* r300, END_CS; } +void r300_emit_fs_constant_rc_state(struct r300_context* r300, + struct rc_constant_list* constants) +{ + unsigned i; + unsigned count = r300->fs->shader->rc_state_count; + unsigned first = r300->fs->shader->externals_count; + unsigned end = constants->Count; + CS_LOCALS(r300); + + if (count == 0) + return; + + BEGIN_CS(count * 5); + for(i = first; i < end; ++i) { + if (constants->Constants[i].Type == RC_CONSTANT_STATE) { + const float *data = get_shader_constant(r300, + &constants->Constants[i], 0); + + OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); + 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; +} + static void r300_emit_fragment_depth_config(struct r300_context* r300, struct r300_fragment_shader* fs) { @@ -320,11 +367,16 @@ void r500_emit_fragment_program_code(struct r300_context* r300, struct rX00_fragment_program_code* generic_code) { struct r500_fragment_program_code * code = &generic_code->code.r500; - int i; + unsigned i; + unsigned imm_count = r300->fs->shader->immediates_count; + unsigned imm_first = r300->fs->shader->externals_count; + unsigned imm_end = generic_code->constants.Count; + struct rc_constant *constants = generic_code->constants.Constants; CS_LOCALS(r300); BEGIN_CS(13 + - ((code->inst_end + 1) * 6)); + ((code->inst_end + 1) * 6) + + (imm_count ? imm_count * 7 : 0)); OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); OUT_CS_REG(R500_US_CODE_RANGE, @@ -344,25 +396,43 @@ void r500_emit_fragment_program_code(struct r300_context* r300, OUT_CS(code->inst[i].inst5); } + /* Emit immediates. */ + if (imm_count) { + for(i = imm_first; i < imm_end; ++i) { + if (constants[i].Type == RC_CONSTANT_IMMEDIATE) { + const float *data = constants[i].u.Immediate; + + OUT_CS_REG(R500_GA_US_VECTOR_INDEX, + R500_GA_US_VECTOR_INDEX_TYPE_CONST | + (i & R500_GA_US_VECTOR_INDEX_MASK)); + OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, 4); + 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; + unsigned i, count = r300->fs->shader->externals_count; CS_LOCALS(r300); - if (constants->Count == 0) + if (count == 0) return; - BEGIN_CS(constants->Count * 4 + 3); + BEGIN_CS(count * 4 + 3); 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_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]; + OUT_CS_32F(data[0]); OUT_CS_32F(data[1]); OUT_CS_32F(data[2]); @@ -371,6 +441,37 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, END_CS; } +void r500_emit_fs_constant_rc_state(struct r300_context* r300, + struct rc_constant_list* constants) +{ + unsigned i; + unsigned count = r300->fs->shader->rc_state_count; + unsigned first = r300->fs->shader->externals_count; + unsigned end = constants->Count; + CS_LOCALS(r300); + + if (count == 0) + return; + + BEGIN_CS(count * 7); + for(i = first; i < end; ++i) { + if (constants->Constants[i].Type == RC_CONSTANT_STATE) { + const float *data = get_shader_constant(r300, + &constants->Constants[i], 0); + + OUT_CS_REG(R500_GA_US_VECTOR_INDEX, + R500_GA_US_VECTOR_INDEX_TYPE_CONST | + (i & R500_GA_US_VECTOR_INDEX_MASK)); + OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, 4); + 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_fb_state(struct r300_context* r300, unsigned size, void* state) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; @@ -1099,9 +1200,13 @@ void r300_emit_dirty_state(struct r300_context* r300) if (r300screen->caps.is_r500) { r500_emit_fs_constant_buffer(r300, &r300->fs->shader->code.constants); + r500_emit_fs_constant_rc_state(r300, + &r300->fs->shader->code.constants); } else { r300_emit_fs_constant_buffer(r300, &r300->fs->shader->code.constants); + r300_emit_fs_constant_rc_state(r300, + &r300->fs->shader->code.constants); } r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 27251a6..19ab430 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -49,12 +49,18 @@ void r300_emit_fragment_program_code(struct r300_context* r300, void r300_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); +void r300_emit_fs_constant_rc_state(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); void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); +void r500_emit_fs_constant_rc_state(struct r300_context* r300, + struct rc_constant_list* constants); + void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state); void r300_emit_query_start(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index c3f51ec..4969c14 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -192,6 +192,7 @@ static void r300_translate_fragment_shader( struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; int wpos; + unsigned i; tgsi_scan_shader(tokens, &shader->info); r300_shader_read_fs_inputs(&shader->info, &shader->inputs); @@ -240,6 +241,7 @@ static void r300_translate_fragment_shader( /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); + if (compiler.Base.Error) { fprintf(stderr, "r300 FP: Compiler Error:\n%sUsing a dummy shader" " instead.\n", compiler.Base.ErrorMsg); @@ -252,6 +254,24 @@ static void r300_translate_fragment_shader( r300_dummy_fragment_shader(r300, shader); } + /* Initialize numbers of constants for each type. */ + shader->externals_count = ttr.immediate_offset; + shader->immediates_count = 0; + shader->rc_state_count = 0; + + for (i = shader->externals_count; i < shader->code.constants.Count; i++) { + switch (shader->code.constants.Constants[i].Type) { + case RC_CONSTANT_IMMEDIATE: + ++shader->immediates_count; + break; + case RC_CONSTANT_STATE: + ++shader->rc_state_count; + break; + default: + assert(0); + } + } + /* And, finally... */ rc_destroy(&compiler.Base); } diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index 0feba15..18da5f7 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -41,6 +41,11 @@ struct r300_fragment_shader_code { /* Bits 0-15: TRUE if it's a shadow sampler, FALSE otherwise. */ unsigned shadow_samplers; + /* Numbers of constants for each type. */ + unsigned externals_count; + unsigned immediates_count; + unsigned rc_state_count; + struct r300_fragment_program_external_state compare_state; struct rX00_fragment_program_code code; diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 3b3802e..21a1c45 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -383,4 +383,3 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, rc_calculate_inputs_outputs(ttr->compiler); } - -- 2.7.4