32
32
#include "../r300_reg.h"
34
static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
36
struct rc_src_register reg = { 0, };
38
reg.File = RC_FILE_CONSTANT;
39
reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
40
reg.Swizzle = RC_SWIZZLE_WWWW;
45
* Transform TEX, TXP, TXB, and KIL instructions in the following way:
46
* - premultiply texture coordinates for RECT
47
* - extract operand swizzles
48
* - introduce a temporary register when write masks are needed
50
int r300_transform_TEX(
51
struct radeon_compiler * c,
52
struct rc_instruction* inst,
55
struct r300_fragment_program_compiler *compiler =
56
(struct r300_fragment_program_compiler*)data;
58
if (inst->U.I.Opcode != RC_OPCODE_TEX &&
59
inst->U.I.Opcode != RC_OPCODE_TXB &&
60
inst->U.I.Opcode != RC_OPCODE_TXP &&
61
inst->U.I.Opcode != RC_OPCODE_KIL)
64
/* ARB_shadow & EXT_shadow_funcs */
65
if (inst->U.I.Opcode != RC_OPCODE_KIL &&
66
c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) {
67
rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
69
if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
70
inst->U.I.Opcode = RC_OPCODE_MOV;
72
if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
73
inst->U.I.SrcReg[0].File = RC_FILE_NONE;
74
inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
76
inst->U.I.SrcReg[0] = shadow_ambient(c, inst->U.I.TexSrcUnit);
81
rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func;
82
unsigned int depthmode = compiler->state.unit[inst->U.I.TexSrcUnit].depth_texture_mode;
83
struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
84
struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
85
struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
88
inst_rcp->U.I.Opcode = RC_OPCODE_RCP;
89
inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
90
inst_rcp->U.I.DstReg.Index = rc_find_free_temporary(c);
91
inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;
92
inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
93
inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
95
inst_cmp->U.I.DstReg = inst->U.I.DstReg;
96
inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
97
inst->U.I.DstReg.Index = rc_find_free_temporary(c);
98
inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
100
inst_mad->U.I.Opcode = RC_OPCODE_MAD;
101
inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
102
inst_mad->U.I.DstReg.Index = rc_find_free_temporary(c);
103
inst_mad->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
104
inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
105
inst_mad->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
106
inst_mad->U.I.SrcReg[1].Index = inst_rcp->U.I.DstReg.Index;
107
inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
108
inst_mad->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
109
inst_mad->U.I.SrcReg[2].Index = inst->U.I.DstReg.Index;
110
if (depthmode == 0) /* GL_LUMINANCE */
111
inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
112
else if (depthmode == 2) /* GL_ALPHA */
113
inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
115
/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
116
* r < tex <=> -tex+r < 0
117
* r >= tex <=> not (-tex+r < 0 */
118
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
119
inst_mad->U.I.SrcReg[2].Negate = inst_mad->U.I.SrcReg[2].Negate ^ RC_MASK_XYZW;
121
inst_mad->U.I.SrcReg[0].Negate = inst_mad->U.I.SrcReg[0].Negate ^ RC_MASK_XYZW;
123
inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
124
/* DstReg has been filled out above */
125
inst_cmp->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
126
inst_cmp->U.I.SrcReg[0].Index = inst_mad->U.I.DstReg.Index;
128
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
136
inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
137
inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
138
inst_cmp->U.I.SrcReg[fail] = shadow_ambient(c, inst->U.I.TexSrcUnit);
142
/* Hardware uses [0..1]x[0..1] range for rectangle textures
143
* instead of [0..Width]x[0..Height].
144
* Add a scaling instruction.
146
if (inst->U.I.Opcode != RC_OPCODE_KIL && inst->U.I.TexSrcTarget == RC_TEXTURE_RECT) {
147
struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst->Prev);
149
inst_mul->U.I.Opcode = RC_OPCODE_MUL;
150
inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
151
inst_mul->U.I.DstReg.Index = rc_find_free_temporary(c);
152
inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
153
inst_mul->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
154
inst_mul->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
156
reset_srcreg(&inst->U.I.SrcReg[0]);
157
inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
158
inst->U.I.SrcReg[0].Index = inst_mul->U.I.DstReg.Index;
161
/* Cannot write texture to output registers or with masks */
162
if (inst->U.I.Opcode != RC_OPCODE_KIL &&
163
(inst->U.I.DstReg.File != RC_FILE_TEMPORARY || inst->U.I.DstReg.WriteMask != RC_MASK_XYZW)) {
164
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
166
inst_mov->U.I.Opcode = RC_OPCODE_MOV;
167
inst_mov->U.I.DstReg = inst->U.I.DstReg;
168
inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
169
inst_mov->U.I.SrcReg[0].Index = rc_find_free_temporary(c);
171
inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
172
inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index;
173
inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
177
/* Cannot read texture coordinate from constants file */
178
if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) {
179
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
181
inst_mov->U.I.Opcode = RC_OPCODE_MOV;
182
inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
183
inst_mov->U.I.DstReg.Index = rc_find_free_temporary(c);
184
inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
186
reset_srcreg(&inst->U.I.SrcReg[0]);
187
inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
188
inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
194
34
/* just some random things... */
195
void r300FragmentProgramDump(struct rX00_fragment_program_code *c)
35
void r300FragmentProgramDump(struct radeon_compiler *c, void *user)
197
struct r300_fragment_program_code *code = &c->code.r300;
37
struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c;
38
struct r300_fragment_program_code *code = &compiler->code->code.r300;
199
40
static int pc = 0;