summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-04-11 23:00:16 +0200
committerMarek Olšák <[email protected]>2010-04-12 04:16:08 +0200
commit953a309de9204490edcd011e700c06c7c25c0b9e (patch)
treeebb69c952ea4ca507a11c2e21bd2d51c75ad789f /src/gallium/drivers
parent132a590d5e76de7ddfacdb0dcc160429c309d19d (diff)
r300g: FS constants emission rework
* The constant buffer emission is separated from RC state variables emission. * The immediates are emitted with FS code.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c145
-rw-r--r--src/gallium/drivers/r300/r300_emit.h6
-rw-r--r--src/gallium/drivers/r300/r300_fs.c20
-rw-r--r--src/gallium/drivers/r300/r300_fs.h5
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c1
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 63cd41a57b7..20d1c244136 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 27251a60abd..19ab4308e68 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 c3f51ec932f..4969c1472b0 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 0feba154bbf..18da5f75625 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 3b3802ee2b2..21a1c45982d 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);
}
-