summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-01-06 00:31:55 +0100
committerMarek Olšák <[email protected]>2013-01-06 14:44:12 +0100
commit25b3c0a52cb0834d683b99e141305424ea5695b6 (patch)
tree691245a38f2fffaa750a285deb6d503574984871
parent2f358feda311570610729658cfc2897090c14327 (diff)
r300g/compiler: add shader emulation for the alpha_to_one state
-rw-r--r--src/gallium/drivers/r300/compiler/r3xx_fragprog.c7
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_code.h2
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_program_alu.c28
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_program_alu.h3
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_program_constants.h1
5 files changed, 41 insertions, 0 deletions
diff --git a/src/gallium/drivers/r300/compiler/r3xx_fragprog.c b/src/gallium/drivers/r300/compiler/r3xx_fragprog.c
index 8ef2d24fc99..7c9a3521162 100644
--- a/src/gallium/drivers/r300/compiler/r3xx_fragprog.c
+++ b/src/gallium/drivers/r300/compiler/r3xx_fragprog.c
@@ -82,8 +82,14 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{
int is_r500 = c->Base.is_r500;
int opt = !c->Base.disable_optimizations;
+ int alpha2one = c->state.alpha_to_one;
/* Lists of instruction transformations. */
+ struct radeon_program_transformation force_alpha_to_one[] = {
+ { &rc_force_output_alpha_to_one, c },
+ { 0, 0 }
+ };
+
struct radeon_program_transformation rewrite_tex[] = {
{ &radeonTransformTEX, c },
{ 0, 0 }
@@ -117,6 +123,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{"unroll loops", 1, is_r500, rc_unroll_loops, NULL},
{"transform loops", 1, !is_r500, rc_transform_loops, NULL},
{"emulate branches", 1, !is_r500, rc_emulate_branches, NULL},
+ {"force alpha to one", 1, alpha2one, rc_local_transform, force_alpha_to_one},
{"transform TEX", 1, 1, rc_local_transform, rewrite_tex},
{"transform IF", 1, is_r500, rc_local_transform, rewrite_if},
{"native rewrite", 1, is_r500, rc_local_transform, native_rewrite_r500},
diff --git a/src/gallium/drivers/r300/compiler/radeon_code.h b/src/gallium/drivers/r300/compiler/radeon_code.h
index 44d550068fd..beafc26ffec 100644
--- a/src/gallium/drivers/r300/compiler/radeon_code.h
+++ b/src/gallium/drivers/r300/compiler/radeon_code.h
@@ -182,6 +182,8 @@ struct r300_fragment_program_external_state {
*/
unsigned convert_unorm_to_snorm:1;
} unit[16];
+
+ unsigned alpha_to_one:1;
};
diff --git a/src/gallium/drivers/r300/compiler/radeon_program_alu.c b/src/gallium/drivers/r300/compiler/radeon_program_alu.c
index f4ee86de5d0..4dc4250699e 100644
--- a/src/gallium/drivers/r300/compiler/radeon_program_alu.c
+++ b/src/gallium/drivers/r300/compiler/radeon_program_alu.c
@@ -1283,3 +1283,31 @@ void rc_transform_KILP(struct radeon_compiler * c, void *user)
}
}
}
+
+int rc_force_output_alpha_to_one(struct radeon_compiler *c,
+ struct rc_instruction *inst, void *data)
+{
+ struct r300_fragment_program_compiler *fragc = (struct r300_fragment_program_compiler*)c;
+ const struct rc_opcode_info *info = rc_get_opcode_info(inst->U.I.Opcode);
+ unsigned tmp;
+
+ if (!info->HasDstReg || inst->U.I.DstReg.File != RC_FILE_OUTPUT ||
+ inst->U.I.DstReg.Index == fragc->OutputDepth)
+ return 1;
+
+ tmp = rc_find_free_temporary(c);
+
+ /* Insert MOV after inst, set alpha to 1. */
+ emit1(c, inst, RC_OPCODE_MOV, 0, inst->U.I.DstReg,
+ srcregswz(RC_FILE_TEMPORARY, tmp, RC_SWIZZLE_XYZ1));
+
+ /* Re-route the destination of inst to the source of mov. */
+ inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
+ inst->U.I.DstReg.Index = tmp;
+
+ /* Move the saturate output modifier to the MOV instruction
+ * (for better copy propagation). */
+ inst->Next->U.I.SaturateMode = inst->U.I.SaturateMode;
+ inst->U.I.SaturateMode = RC_SATURATE_NONE;
+ return 1;
+}
diff --git a/src/gallium/drivers/r300/compiler/radeon_program_alu.h b/src/gallium/drivers/r300/compiler/radeon_program_alu.h
index b5f361e624f..8f8dc70d52e 100644
--- a/src/gallium/drivers/r300/compiler/radeon_program_alu.h
+++ b/src/gallium/drivers/r300/compiler/radeon_program_alu.h
@@ -63,4 +63,7 @@ int radeonTransformDeriv(
void rc_transform_KILP(struct radeon_compiler * c,
void *user);
+int rc_force_output_alpha_to_one(struct radeon_compiler *c,
+ struct rc_instruction *inst, void *data);
+
#endif /* __RADEON_PROGRAM_ALU_H_ */
diff --git a/src/gallium/drivers/r300/compiler/radeon_program_constants.h b/src/gallium/drivers/r300/compiler/radeon_program_constants.h
index 4dbf6497ed9..e54c6a892dc 100644
--- a/src/gallium/drivers/r300/compiler/radeon_program_constants.h
+++ b/src/gallium/drivers/r300/compiler/radeon_program_constants.h
@@ -126,6 +126,7 @@ typedef enum {
#define RC_SWIZZLE_XYZW RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_W)
#define RC_SWIZZLE_XYZ0 RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO)
+#define RC_SWIZZLE_XYZ1 RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ONE)
#define RC_SWIZZLE_XYZZ RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z)
#define RC_SWIZZLE_XXXX RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_X)
#define RC_SWIZZLE_YYYY RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_Y)