summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_emit.c
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/r300/r300_emit.c
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/r300/r300_emit.c')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c145
1 files changed, 125 insertions, 20 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;
}