diff options
Diffstat (limited to 'src')
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) |