mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
r300: Remove all Mesa dependencies from the shader compiler
In particular, this removes the dependency on prog_instruction, which unfortunately creates some code duplication, but also opens a path towards adding some hardware-specific things in there. Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
This commit is contained in:
parent
d6d71e5bf4
commit
d1b4351e60
29 changed files with 2266 additions and 1358 deletions
|
|
@ -24,9 +24,7 @@ C_SOURCES = \
|
|||
r300_tgsi_to_rc.c
|
||||
|
||||
LIBRARY_INCLUDES = \
|
||||
-I$(TOP)/src/mesa/drivers/dri/r300/compiler \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/include
|
||||
-I$(TOP)/src/mesa/drivers/dri/r300/compiler
|
||||
|
||||
COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
|
||||
|
||||
|
|
|
|||
|
|
@ -33,152 +33,151 @@
|
|||
static unsigned translate_opcode(unsigned opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case TGSI_OPCODE_ARL: return OPCODE_ARL;
|
||||
case TGSI_OPCODE_MOV: return OPCODE_MOV;
|
||||
case TGSI_OPCODE_LIT: return OPCODE_LIT;
|
||||
case TGSI_OPCODE_RCP: return OPCODE_RCP;
|
||||
case TGSI_OPCODE_RSQ: return OPCODE_RSQ;
|
||||
case TGSI_OPCODE_EXP: return OPCODE_EXP;
|
||||
case TGSI_OPCODE_LOG: return OPCODE_LOG;
|
||||
case TGSI_OPCODE_MUL: return OPCODE_MUL;
|
||||
case TGSI_OPCODE_ADD: return OPCODE_ADD;
|
||||
case TGSI_OPCODE_DP3: return OPCODE_DP3;
|
||||
case TGSI_OPCODE_DP4: return OPCODE_DP4;
|
||||
case TGSI_OPCODE_DST: return OPCODE_DST;
|
||||
case TGSI_OPCODE_MIN: return OPCODE_MIN;
|
||||
case TGSI_OPCODE_MAX: return OPCODE_MAX;
|
||||
case TGSI_OPCODE_SLT: return OPCODE_SLT;
|
||||
case TGSI_OPCODE_SGE: return OPCODE_SGE;
|
||||
case TGSI_OPCODE_MAD: return OPCODE_MAD;
|
||||
case TGSI_OPCODE_SUB: return OPCODE_SUB;
|
||||
case TGSI_OPCODE_LRP: return OPCODE_LRP;
|
||||
/* case TGSI_OPCODE_CND: return OPCODE_CND; */
|
||||
/* case TGSI_OPCODE_CND0: return OPCODE_CND0; */
|
||||
case TGSI_OPCODE_DP2A: return OPCODE_DP2A;
|
||||
case TGSI_OPCODE_ARL: return RC_OPCODE_ARL;
|
||||
case TGSI_OPCODE_MOV: return RC_OPCODE_MOV;
|
||||
case TGSI_OPCODE_LIT: return RC_OPCODE_LIT;
|
||||
case TGSI_OPCODE_RCP: return RC_OPCODE_RCP;
|
||||
case TGSI_OPCODE_RSQ: return RC_OPCODE_RSQ;
|
||||
case TGSI_OPCODE_EXP: return RC_OPCODE_EXP;
|
||||
case TGSI_OPCODE_LOG: return RC_OPCODE_LOG;
|
||||
case TGSI_OPCODE_MUL: return RC_OPCODE_MUL;
|
||||
case TGSI_OPCODE_ADD: return RC_OPCODE_ADD;
|
||||
case TGSI_OPCODE_DP3: return RC_OPCODE_DP3;
|
||||
case TGSI_OPCODE_DP4: return RC_OPCODE_DP4;
|
||||
case TGSI_OPCODE_DST: return RC_OPCODE_DST;
|
||||
case TGSI_OPCODE_MIN: return RC_OPCODE_MIN;
|
||||
case TGSI_OPCODE_MAX: return RC_OPCODE_MAX;
|
||||
case TGSI_OPCODE_SLT: return RC_OPCODE_SLT;
|
||||
case TGSI_OPCODE_SGE: return RC_OPCODE_SGE;
|
||||
case TGSI_OPCODE_MAD: return RC_OPCODE_MAD;
|
||||
case TGSI_OPCODE_SUB: return RC_OPCODE_SUB;
|
||||
case TGSI_OPCODE_LRP: return RC_OPCODE_LRP;
|
||||
/* case TGSI_OPCODE_CND: return RC_OPCODE_CND; */
|
||||
/* case TGSI_OPCODE_CND0: return RC_OPCODE_CND0; */
|
||||
/* case TGSI_OPCODE_DP2A: return RC_OPCODE_DP2A; */
|
||||
/* gap */
|
||||
case TGSI_OPCODE_FRC: return OPCODE_FRC;
|
||||
/* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */
|
||||
case TGSI_OPCODE_FLR: return OPCODE_FLR;
|
||||
/* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */
|
||||
case TGSI_OPCODE_EX2: return OPCODE_EX2;
|
||||
case TGSI_OPCODE_LG2: return OPCODE_LG2;
|
||||
case TGSI_OPCODE_POW: return OPCODE_POW;
|
||||
case TGSI_OPCODE_XPD: return OPCODE_XPD;
|
||||
case TGSI_OPCODE_FRC: return RC_OPCODE_FRC;
|
||||
/* case TGSI_OPCODE_CLAMP: return RC_OPCODE_CLAMP; */
|
||||
case TGSI_OPCODE_FLR: return RC_OPCODE_FLR;
|
||||
/* case TGSI_OPCODE_ROUND: return RC_OPCODE_ROUND; */
|
||||
case TGSI_OPCODE_EX2: return RC_OPCODE_EX2;
|
||||
case TGSI_OPCODE_LG2: return RC_OPCODE_LG2;
|
||||
case TGSI_OPCODE_POW: return RC_OPCODE_POW;
|
||||
case TGSI_OPCODE_XPD: return RC_OPCODE_XPD;
|
||||
/* gap */
|
||||
case TGSI_OPCODE_ABS: return OPCODE_ABS;
|
||||
case TGSI_OPCODE_RCC: return OPCODE_RCC;
|
||||
case TGSI_OPCODE_DPH: return OPCODE_DPH;
|
||||
case TGSI_OPCODE_COS: return OPCODE_COS;
|
||||
case TGSI_OPCODE_DDX: return OPCODE_DDX;
|
||||
case TGSI_OPCODE_DDY: return OPCODE_DDY;
|
||||
/* case TGSI_OPCODE_KILP: return OPCODE_KILP; */
|
||||
case TGSI_OPCODE_PK2H: return OPCODE_PK2H;
|
||||
case TGSI_OPCODE_PK2US: return OPCODE_PK2US;
|
||||
case TGSI_OPCODE_PK4B: return OPCODE_PK4B;
|
||||
case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB;
|
||||
case TGSI_OPCODE_RFL: return OPCODE_RFL;
|
||||
case TGSI_OPCODE_SEQ: return OPCODE_SEQ;
|
||||
case TGSI_OPCODE_SFL: return OPCODE_SFL;
|
||||
case TGSI_OPCODE_SGT: return OPCODE_SGT;
|
||||
case TGSI_OPCODE_SIN: return OPCODE_SIN;
|
||||
case TGSI_OPCODE_SLE: return OPCODE_SLE;
|
||||
case TGSI_OPCODE_SNE: return OPCODE_SNE;
|
||||
case TGSI_OPCODE_STR: return OPCODE_STR;
|
||||
case TGSI_OPCODE_TEX: return OPCODE_TEX;
|
||||
case TGSI_OPCODE_TXD: return OPCODE_TXD;
|
||||
case TGSI_OPCODE_TXP: return OPCODE_TXP;
|
||||
case TGSI_OPCODE_UP2H: return OPCODE_UP2H;
|
||||
case TGSI_OPCODE_UP2US: return OPCODE_UP2US;
|
||||
case TGSI_OPCODE_UP4B: return OPCODE_UP4B;
|
||||
case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB;
|
||||
case TGSI_OPCODE_X2D: return OPCODE_X2D;
|
||||
case TGSI_OPCODE_ARA: return OPCODE_ARA;
|
||||
case TGSI_OPCODE_ARR: return OPCODE_ARR;
|
||||
case TGSI_OPCODE_BRA: return OPCODE_BRA;
|
||||
case TGSI_OPCODE_CAL: return OPCODE_CAL;
|
||||
case TGSI_OPCODE_RET: return OPCODE_RET;
|
||||
case TGSI_OPCODE_SSG: return OPCODE_SSG;
|
||||
case TGSI_OPCODE_CMP: return OPCODE_CMP;
|
||||
case TGSI_OPCODE_SCS: return OPCODE_SCS;
|
||||
case TGSI_OPCODE_TXB: return OPCODE_TXB;
|
||||
/* case TGSI_OPCODE_NRM: return OPCODE_NRM; */
|
||||
/* case TGSI_OPCODE_DIV: return OPCODE_DIV; */
|
||||
case TGSI_OPCODE_DP2: return OPCODE_DP2;
|
||||
case TGSI_OPCODE_TXL: return OPCODE_TXL;
|
||||
case TGSI_OPCODE_BRK: return OPCODE_BRK;
|
||||
case TGSI_OPCODE_IF: return OPCODE_IF;
|
||||
/* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */
|
||||
/* case TGSI_OPCODE_REP: return OPCODE_REP; */
|
||||
case TGSI_OPCODE_ELSE: return OPCODE_ELSE;
|
||||
case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF;
|
||||
case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP;
|
||||
/* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */
|
||||
case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA;
|
||||
case TGSI_OPCODE_POPA: return OPCODE_POPA;
|
||||
/* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */
|
||||
/* case TGSI_OPCODE_I2F: return OPCODE_I2F; */
|
||||
case TGSI_OPCODE_NOT: return OPCODE_NOT;
|
||||
case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC;
|
||||
/* case TGSI_OPCODE_SHL: return OPCODE_SHL; */
|
||||
/* case TGSI_OPCODE_SHR: return OPCODE_SHR; */
|
||||
case TGSI_OPCODE_AND: return OPCODE_AND;
|
||||
case TGSI_OPCODE_OR: return OPCODE_OR;
|
||||
/* case TGSI_OPCODE_MOD: return OPCODE_MOD; */
|
||||
case TGSI_OPCODE_XOR: return OPCODE_XOR;
|
||||
/* case TGSI_OPCODE_SAD: return OPCODE_SAD; */
|
||||
/* case TGSI_OPCODE_TXF: return OPCODE_TXF; */
|
||||
/* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */
|
||||
case TGSI_OPCODE_CONT: return OPCODE_CONT;
|
||||
/* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */
|
||||
/* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */
|
||||
/* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */
|
||||
case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB;
|
||||
/* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */
|
||||
case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB;
|
||||
case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1;
|
||||
case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2;
|
||||
case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3;
|
||||
case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4;
|
||||
case TGSI_OPCODE_NOP: return OPCODE_NOP;
|
||||
case TGSI_OPCODE_ABS: return RC_OPCODE_ABS;
|
||||
/* case TGSI_OPCODE_RCC: return RC_OPCODE_RCC; */
|
||||
case TGSI_OPCODE_DPH: return RC_OPCODE_DPH;
|
||||
case TGSI_OPCODE_COS: return RC_OPCODE_COS;
|
||||
case TGSI_OPCODE_DDX: return RC_OPCODE_DDX;
|
||||
case TGSI_OPCODE_DDY: return RC_OPCODE_DDY;
|
||||
/* case TGSI_OPCODE_KILP: return RC_OPCODE_KILP; */
|
||||
/* case TGSI_OPCODE_PK2H: return RC_OPCODE_PK2H; */
|
||||
/* case TGSI_OPCODE_PK2US: return RC_OPCODE_PK2US; */
|
||||
/* case TGSI_OPCODE_PK4B: return RC_OPCODE_PK4B; */
|
||||
/* case TGSI_OPCODE_PK4UB: return RC_OPCODE_PK4UB; */
|
||||
/* case TGSI_OPCODE_RFL: return RC_OPCODE_RFL; */
|
||||
case TGSI_OPCODE_SEQ: return RC_OPCODE_SEQ;
|
||||
case TGSI_OPCODE_SFL: return RC_OPCODE_SFL;
|
||||
case TGSI_OPCODE_SGT: return RC_OPCODE_SGT;
|
||||
case TGSI_OPCODE_SIN: return RC_OPCODE_SIN;
|
||||
case TGSI_OPCODE_SLE: return RC_OPCODE_SLE;
|
||||
case TGSI_OPCODE_SNE: return RC_OPCODE_SNE;
|
||||
/* case TGSI_OPCODE_STR: return RC_OPCODE_STR; */
|
||||
case TGSI_OPCODE_TEX: return RC_OPCODE_TEX;
|
||||
case TGSI_OPCODE_TXD: return RC_OPCODE_TXD;
|
||||
case TGSI_OPCODE_TXP: return RC_OPCODE_TXP;
|
||||
/* case TGSI_OPCODE_UP2H: return RC_OPCODE_UP2H; */
|
||||
/* case TGSI_OPCODE_UP2US: return RC_OPCODE_UP2US; */
|
||||
/* case TGSI_OPCODE_UP4B: return RC_OPCODE_UP4B; */
|
||||
/* case TGSI_OPCODE_UP4UB: return RC_OPCODE_UP4UB; */
|
||||
/* case TGSI_OPCODE_X2D: return RC_OPCODE_X2D; */
|
||||
/* case TGSI_OPCODE_ARA: return RC_OPCODE_ARA; */
|
||||
/* case TGSI_OPCODE_ARR: return RC_OPCODE_ARR; */
|
||||
/* case TGSI_OPCODE_BRA: return RC_OPCODE_BRA; */
|
||||
/* case TGSI_OPCODE_CAL: return RC_OPCODE_CAL; */
|
||||
/* case TGSI_OPCODE_RET: return RC_OPCODE_RET; */
|
||||
/* case TGSI_OPCODE_SSG: return RC_OPCODE_SSG; */
|
||||
case TGSI_OPCODE_CMP: return RC_OPCODE_CMP;
|
||||
case TGSI_OPCODE_SCS: return RC_OPCODE_SCS;
|
||||
case TGSI_OPCODE_TXB: return RC_OPCODE_TXB;
|
||||
/* case TGSI_OPCODE_NRM: return RC_OPCODE_NRM; */
|
||||
/* case TGSI_OPCODE_DIV: return RC_OPCODE_DIV; */
|
||||
/* case TGSI_OPCODE_DP2: return RC_OPCODE_DP2; */
|
||||
case TGSI_OPCODE_TXL: return RC_OPCODE_TXL;
|
||||
/* case TGSI_OPCODE_BRK: return RC_OPCODE_BRK; */
|
||||
/* case TGSI_OPCODE_IF: return RC_OPCODE_IF; */
|
||||
/* case TGSI_OPCODE_LOOP: return RC_OPCODE_LOOP; */
|
||||
/* case TGSI_OPCODE_REP: return RC_OPCODE_REP; */
|
||||
/* case TGSI_OPCODE_ELSE: return RC_OPCODE_ELSE; */
|
||||
/* case TGSI_OPCODE_ENDIF: return RC_OPCODE_ENDIF; */
|
||||
/* case TGSI_OPCODE_ENDLOOP: return RC_OPCODE_ENDLOOP; */
|
||||
/* case TGSI_OPCODE_ENDREP: return RC_OPCODE_ENDREP; */
|
||||
/* case TGSI_OPCODE_PUSHA: return RC_OPCODE_PUSHA; */
|
||||
/* case TGSI_OPCODE_POPA: return RC_OPCODE_POPA; */
|
||||
/* case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL; */
|
||||
/* case TGSI_OPCODE_I2F: return RC_OPCODE_I2F; */
|
||||
/* case TGSI_OPCODE_NOT: return RC_OPCODE_NOT; */
|
||||
/* case TGSI_OPCODE_TRUNC: return RC_OPCODE_TRUNC; */
|
||||
/* case TGSI_OPCODE_SHL: return RC_OPCODE_SHL; */
|
||||
/* case TGSI_OPCODE_SHR: return RC_OPCODE_SHR; */
|
||||
/* case TGSI_OPCODE_AND: return RC_OPCODE_AND; */
|
||||
/* case TGSI_OPCODE_OR: return RC_OPCODE_OR; */
|
||||
/* case TGSI_OPCODE_MOD: return RC_OPCODE_MOD; */
|
||||
/* case TGSI_OPCODE_XOR: return RC_OPCODE_XOR; */
|
||||
/* case TGSI_OPCODE_SAD: return RC_OPCODE_SAD; */
|
||||
/* case TGSI_OPCODE_TXF: return RC_OPCODE_TXF; */
|
||||
/* case TGSI_OPCODE_TXQ: return RC_OPCODE_TXQ; */
|
||||
/* case TGSI_OPCODE_CONT: return RC_OPCODE_CONT; */
|
||||
/* case TGSI_OPCODE_EMIT: return RC_OPCODE_EMIT; */
|
||||
/* case TGSI_OPCODE_ENDPRIM: return RC_OPCODE_ENDPRIM; */
|
||||
/* case TGSI_OPCODE_BGNLOOP2: return RC_OPCODE_BGNLOOP2; */
|
||||
/* case TGSI_OPCODE_BGNSUB: return RC_OPCODE_BGNSUB; */
|
||||
/* case TGSI_OPCODE_ENDLOOP2: return RC_OPCODE_ENDLOOP2; */
|
||||
/* case TGSI_OPCODE_ENDSUB: return RC_OPCODE_ENDSUB; */
|
||||
/* case TGSI_OPCODE_NOISE1: return RC_OPCODE_NOISE1; */
|
||||
/* case TGSI_OPCODE_NOISE2: return RC_OPCODE_NOISE2; */
|
||||
/* case TGSI_OPCODE_NOISE3: return RC_OPCODE_NOISE3; */
|
||||
/* case TGSI_OPCODE_NOISE4: return RC_OPCODE_NOISE4; */
|
||||
case TGSI_OPCODE_NOP: return RC_OPCODE_NOP;
|
||||
/* gap */
|
||||
case TGSI_OPCODE_NRM4: return OPCODE_NRM4;
|
||||
/* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */
|
||||
/* case TGSI_OPCODE_IFC: return OPCODE_IFC; */
|
||||
/* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */
|
||||
case TGSI_OPCODE_KIL: return OPCODE_KIL;
|
||||
case TGSI_OPCODE_END: return OPCODE_END;
|
||||
case TGSI_OPCODE_SWZ: return OPCODE_SWZ;
|
||||
/* case TGSI_OPCODE_NRM4: return RC_OPCODE_NRM4; */
|
||||
/* case TGSI_OPCODE_CALLNZ: return RC_OPCODE_CALLNZ; */
|
||||
/* case TGSI_OPCODE_IFC: return RC_OPCODE_IFC; */
|
||||
/* case TGSI_OPCODE_BREAKC: return RC_OPCODE_BREAKC; */
|
||||
case TGSI_OPCODE_KIL: return RC_OPCODE_KIL;
|
||||
case TGSI_OPCODE_SWZ: return RC_OPCODE_SWZ;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown opcode: %i\n", opcode);
|
||||
abort();
|
||||
return RC_OPCODE_ILLEGAL_OPCODE;
|
||||
}
|
||||
|
||||
static unsigned translate_saturate(unsigned saturate)
|
||||
{
|
||||
switch(saturate) {
|
||||
case TGSI_SAT_NONE: return SATURATE_OFF;
|
||||
case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE;
|
||||
case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE;
|
||||
default:
|
||||
fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
|
||||
/* fall-through */
|
||||
case TGSI_SAT_NONE: return RC_SATURATE_NONE;
|
||||
case TGSI_SAT_ZERO_ONE: return RC_SATURATE_ZERO_ONE;
|
||||
case TGSI_SAT_MINUS_PLUS_ONE: return RC_SATURATE_MINUS_PLUS_ONE;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
|
||||
abort();
|
||||
}
|
||||
|
||||
static unsigned translate_register_file(unsigned file)
|
||||
{
|
||||
switch(file) {
|
||||
case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT;
|
||||
case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT;
|
||||
case TGSI_FILE_INPUT: return PROGRAM_INPUT;
|
||||
case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT;
|
||||
case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY;
|
||||
case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS;
|
||||
case TGSI_FILE_CONSTANT: return RC_FILE_CONSTANT;
|
||||
case TGSI_FILE_IMMEDIATE: return RC_FILE_CONSTANT;
|
||||
case TGSI_FILE_INPUT: return RC_FILE_INPUT;
|
||||
case TGSI_FILE_OUTPUT: return RC_FILE_OUTPUT;
|
||||
default:
|
||||
fprintf(stderr, "Unhandled register file: %i\n", file);
|
||||
/* fall-through */
|
||||
case TGSI_FILE_TEMPORARY: return RC_FILE_TEMPORARY;
|
||||
case TGSI_FILE_ADDRESS: return RC_FILE_ADDRESS;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unhandled register file: %i\n", file);
|
||||
abort();
|
||||
}
|
||||
|
||||
static int translate_register_index(
|
||||
|
|
@ -194,7 +193,7 @@ static int translate_register_index(
|
|||
|
||||
static void transform_dstreg(
|
||||
struct tgsi_to_rc * ttr,
|
||||
struct prog_dst_register * dst,
|
||||
struct rc_dst_register * dst,
|
||||
struct tgsi_full_dst_register * src)
|
||||
{
|
||||
dst->File = translate_register_file(src->DstRegister.File);
|
||||
|
|
@ -205,7 +204,7 @@ static void transform_dstreg(
|
|||
|
||||
static void transform_srcreg(
|
||||
struct tgsi_to_rc * ttr,
|
||||
struct prog_src_register * dst,
|
||||
struct rc_src_register * dst,
|
||||
struct tgsi_full_src_register * src)
|
||||
{
|
||||
dst->File = translate_register_file(src->SrcRegister.File);
|
||||
|
|
@ -221,37 +220,37 @@ static void transform_srcreg(
|
|||
(src->SrcRegisterExtSwz.NegateY << 1) |
|
||||
(src->SrcRegisterExtSwz.NegateZ << 2) |
|
||||
(src->SrcRegisterExtSwz.NegateW << 3);
|
||||
dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;
|
||||
dst->Negate ^= src->SrcRegister.Negate ? RC_MASK_XYZW : 0;
|
||||
}
|
||||
|
||||
static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src)
|
||||
{
|
||||
switch(src.Texture) {
|
||||
case TGSI_TEXTURE_1D:
|
||||
dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_1D;
|
||||
break;
|
||||
case TGSI_TEXTURE_2D:
|
||||
dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_2D;
|
||||
break;
|
||||
case TGSI_TEXTURE_3D:
|
||||
dst->I.TexSrcTarget = TEXTURE_3D_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_3D;
|
||||
break;
|
||||
case TGSI_TEXTURE_CUBE:
|
||||
dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_CUBE;
|
||||
break;
|
||||
case TGSI_TEXTURE_RECT:
|
||||
dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_RECT;
|
||||
break;
|
||||
case TGSI_TEXTURE_SHADOW1D:
|
||||
dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_1D;
|
||||
dst->I.TexShadow = 1;
|
||||
break;
|
||||
case TGSI_TEXTURE_SHADOW2D:
|
||||
dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_2D;
|
||||
dst->I.TexShadow = 1;
|
||||
break;
|
||||
case TGSI_TEXTURE_SHADOWRECT:
|
||||
dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
|
||||
dst->I.TexSrcTarget = RC_TEXTURE_RECT;
|
||||
dst->I.TexShadow = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ C_SOURCES = \
|
|||
radeon_compiler.c \
|
||||
radeon_nqssadce.c \
|
||||
radeon_program.c \
|
||||
radeon_opcodes.c \
|
||||
radeon_program_alu.c \
|
||||
radeon_program_pair.c \
|
||||
r3xx_fragprog.c \
|
||||
|
|
|
|||
|
|
@ -27,17 +27,17 @@
|
|||
|
||||
#include "r300_fragprog.h"
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../r300_reg.h"
|
||||
|
||||
static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
|
||||
static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
|
||||
{
|
||||
struct prog_src_register reg = { 0, };
|
||||
struct rc_src_register reg = { 0, };
|
||||
|
||||
reg.File = PROGRAM_STATE_VAR;
|
||||
reg.File = RC_FILE_CONSTANT;
|
||||
reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
|
||||
reg.Swizzle = SWIZZLE_WWWW;
|
||||
reg.Swizzle = RC_SWIZZLE_WWWW;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int t
|
|||
* - extract operand swizzles
|
||||
* - introduce a temporary register when write masks are needed
|
||||
*/
|
||||
GLboolean r300_transform_TEX(
|
||||
int r300_transform_TEX(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction* inst,
|
||||
void* data)
|
||||
|
|
@ -55,77 +55,77 @@ GLboolean r300_transform_TEX(
|
|||
struct r300_fragment_program_compiler *compiler =
|
||||
(struct r300_fragment_program_compiler*)data;
|
||||
|
||||
if (inst->I.Opcode != OPCODE_TEX &&
|
||||
inst->I.Opcode != OPCODE_TXB &&
|
||||
inst->I.Opcode != OPCODE_TXP &&
|
||||
inst->I.Opcode != OPCODE_KIL)
|
||||
return GL_FALSE;
|
||||
if (inst->I.Opcode != RC_OPCODE_TEX &&
|
||||
inst->I.Opcode != RC_OPCODE_TXB &&
|
||||
inst->I.Opcode != RC_OPCODE_TXP &&
|
||||
inst->I.Opcode != RC_OPCODE_KIL)
|
||||
return 0;
|
||||
|
||||
/* ARB_shadow & EXT_shadow_funcs */
|
||||
if (inst->I.Opcode != OPCODE_KIL &&
|
||||
if (inst->I.Opcode != RC_OPCODE_KIL &&
|
||||
c->Program.ShadowSamplers & (1 << inst->I.TexSrcUnit)) {
|
||||
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
rc_compare_func comparefunc = compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
|
||||
if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
|
||||
if (comparefunc == GL_ALWAYS) {
|
||||
inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
|
||||
inst->I.SrcReg[0].Swizzle = SWIZZLE_1111;
|
||||
if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
|
||||
inst->I.SrcReg[0].File = RC_FILE_NONE;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
|
||||
} else {
|
||||
inst->I.SrcReg[0] = shadow_ambient(c, inst->I.TexSrcUnit);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
} else {
|
||||
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
GLuint depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
|
||||
rc_compare_func comparefunc = compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
unsigned int depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
|
||||
struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
|
||||
struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
|
||||
struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
|
||||
int pass, fail;
|
||||
|
||||
inst_rcp->I.Opcode = OPCODE_RCP;
|
||||
inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_rcp->I.Opcode = RC_OPCODE_RCP;
|
||||
inst_rcp->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_rcp->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
|
||||
inst_rcp->I.DstReg.WriteMask = RC_MASK_W;
|
||||
inst_rcp->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
|
||||
inst_rcp->I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
inst_cmp->I.DstReg = inst->I.DstReg;
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
|
||||
inst_mad->I.Opcode = OPCODE_MAD;
|
||||
inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.Opcode = RC_OPCODE_MAD;
|
||||
inst_mad->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_mad->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
inst_mad->I.SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
|
||||
inst_mad->I.SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
|
||||
inst_mad->I.SrcReg[1].File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.SrcReg[1].Index = inst_rcp->I.DstReg.Index;
|
||||
inst_mad->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.SrcReg[2].Index = inst->I.DstReg.Index;
|
||||
if (depthmode == 0) /* GL_LUMINANCE */
|
||||
inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
|
||||
inst_mad->I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
|
||||
else if (depthmode == 2) /* GL_ALPHA */
|
||||
inst_mad->I.SrcReg[2].Swizzle = SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
|
||||
* r < tex <=> -tex+r < 0
|
||||
* r >= tex <=> not (-tex+r < 0 */
|
||||
if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
|
||||
inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ NEGATE_XYZW;
|
||||
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
|
||||
inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ RC_MASK_XYZW;
|
||||
else
|
||||
inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ NEGATE_XYZW;
|
||||
inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ RC_MASK_XYZW;
|
||||
|
||||
inst_cmp->I.Opcode = OPCODE_CMP;
|
||||
inst_cmp->I.Opcode = RC_OPCODE_CMP;
|
||||
/* DstReg has been filled out above */
|
||||
inst_cmp->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst_cmp->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst_cmp->I.SrcReg[0].Index = inst_mad->I.DstReg.Index;
|
||||
|
||||
if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
|
||||
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
|
||||
pass = 1;
|
||||
fail = 2;
|
||||
} else {
|
||||
|
|
@ -133,8 +133,8 @@ GLboolean r300_transform_TEX(
|
|||
fail = 1;
|
||||
}
|
||||
|
||||
inst_cmp->I.SrcReg[pass].File = PROGRAM_BUILTIN;
|
||||
inst_cmp->I.SrcReg[pass].Swizzle = SWIZZLE_1111;
|
||||
inst_cmp->I.SrcReg[pass].File = RC_FILE_NONE;
|
||||
inst_cmp->I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
|
||||
inst_cmp->I.SrcReg[fail] = shadow_ambient(c, inst->I.TexSrcUnit);
|
||||
}
|
||||
}
|
||||
|
|
@ -143,52 +143,52 @@ GLboolean r300_transform_TEX(
|
|||
* instead of [0..Width]x[0..Height].
|
||||
* Add a scaling instruction.
|
||||
*/
|
||||
if (inst->I.Opcode != OPCODE_KIL && inst->I.TexSrcTarget == TEXTURE_RECT_INDEX) {
|
||||
if (inst->I.Opcode != RC_OPCODE_KIL && inst->I.TexSrcTarget == RC_TEXTURE_RECT) {
|
||||
struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst->Prev);
|
||||
|
||||
inst_mul->I.Opcode = OPCODE_MUL;
|
||||
inst_mul->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mul->I.Opcode = RC_OPCODE_MUL;
|
||||
inst_mul->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mul->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_mul->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
inst_mul->I.SrcReg[1].File = PROGRAM_STATE_VAR;
|
||||
inst_mul->I.SrcReg[1].File = RC_FILE_CONSTANT;
|
||||
inst_mul->I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_TEXRECT_FACTOR, inst->I.TexSrcUnit);
|
||||
|
||||
reset_srcreg(&inst->I.SrcReg[0]);
|
||||
inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[0].Index = inst_mul->I.DstReg.Index;
|
||||
}
|
||||
|
||||
/* Cannot write texture to output registers or with masks */
|
||||
if (inst->I.Opcode != OPCODE_KIL &&
|
||||
(inst->I.DstReg.File != PROGRAM_TEMPORARY || inst->I.DstReg.WriteMask != WRITEMASK_XYZW)) {
|
||||
if (inst->I.Opcode != RC_OPCODE_KIL &&
|
||||
(inst->I.DstReg.File != RC_FILE_TEMPORARY || inst->I.DstReg.WriteMask != RC_MASK_XYZW)) {
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
|
||||
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg = inst->I.DstReg;
|
||||
inst_mov->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.SrcReg[0].Index = rc_find_free_temporary(c);
|
||||
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
|
||||
/* Cannot read texture coordinate from constants file */
|
||||
if (inst->I.SrcReg[0].File != PROGRAM_TEMPORARY && inst->I.SrcReg[0].File != PROGRAM_INPUT) {
|
||||
if (inst->I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->I.SrcReg[0].File != RC_FILE_INPUT) {
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
|
||||
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_mov->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
|
||||
reset_srcreg(&inst->I.SrcReg[0]);
|
||||
inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[0].Index = inst_mov->I.DstReg.Index;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* just some random things... */
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@
|
|||
#ifndef __R300_FRAGPROG_H_
|
||||
#define __R300_FRAGPROG_H_
|
||||
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "radeon_compiler.h"
|
||||
#include "radeon_program.h"
|
||||
|
||||
|
|
@ -44,6 +41,6 @@ extern void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler
|
|||
|
||||
extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c);
|
||||
|
||||
extern GLboolean r300_transform_TEX(struct radeon_compiler * c, struct rc_instruction* inst, void* data);
|
||||
extern int r300_transform_TEX(struct radeon_compiler * c, struct rc_instruction* inst, void* data);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -69,64 +69,64 @@ struct r300_emit_state {
|
|||
/**
|
||||
* Mark a temporary register as used.
|
||||
*/
|
||||
static void use_temporary(struct r300_fragment_program_code *code, GLuint index)
|
||||
static void use_temporary(struct r300_fragment_program_code *code, unsigned int index)
|
||||
{
|
||||
if (index > code->pixsize)
|
||||
code->pixsize = index;
|
||||
}
|
||||
|
||||
|
||||
static GLuint translate_rgb_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
|
||||
static unsigned int translate_rgb_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case OPCODE_CMP: return R300_ALU_OUTC_CMP;
|
||||
case OPCODE_DP3: return R300_ALU_OUTC_DP3;
|
||||
case OPCODE_DP4: return R300_ALU_OUTC_DP4;
|
||||
case OPCODE_FRC: return R300_ALU_OUTC_FRC;
|
||||
case RC_OPCODE_CMP: return R300_ALU_OUTC_CMP;
|
||||
case RC_OPCODE_DP3: return R300_ALU_OUTC_DP3;
|
||||
case RC_OPCODE_DP4: return R300_ALU_OUTC_DP4;
|
||||
case RC_OPCODE_FRC: return R300_ALU_OUTC_FRC;
|
||||
default:
|
||||
error("translate_rgb_opcode(%i): Unknown opcode", opcode);
|
||||
/* fall through */
|
||||
case OPCODE_NOP:
|
||||
case RC_OPCODE_NOP:
|
||||
/* fall through */
|
||||
case OPCODE_MAD: return R300_ALU_OUTC_MAD;
|
||||
case OPCODE_MAX: return R300_ALU_OUTC_MAX;
|
||||
case OPCODE_MIN: return R300_ALU_OUTC_MIN;
|
||||
case OPCODE_REPL_ALPHA: return R300_ALU_OUTC_REPL_ALPHA;
|
||||
case RC_OPCODE_MAD: return R300_ALU_OUTC_MAD;
|
||||
case RC_OPCODE_MAX: return R300_ALU_OUTC_MAX;
|
||||
case RC_OPCODE_MIN: return R300_ALU_OUTC_MIN;
|
||||
case RC_OPCODE_REPL_ALPHA: return R300_ALU_OUTC_REPL_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint translate_alpha_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
|
||||
static unsigned int translate_alpha_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case OPCODE_CMP: return R300_ALU_OUTA_CMP;
|
||||
case OPCODE_DP3: return R300_ALU_OUTA_DP4;
|
||||
case OPCODE_DP4: return R300_ALU_OUTA_DP4;
|
||||
case OPCODE_EX2: return R300_ALU_OUTA_EX2;
|
||||
case OPCODE_FRC: return R300_ALU_OUTA_FRC;
|
||||
case OPCODE_LG2: return R300_ALU_OUTA_LG2;
|
||||
case RC_OPCODE_CMP: return R300_ALU_OUTA_CMP;
|
||||
case RC_OPCODE_DP3: return R300_ALU_OUTA_DP4;
|
||||
case RC_OPCODE_DP4: return R300_ALU_OUTA_DP4;
|
||||
case RC_OPCODE_EX2: return R300_ALU_OUTA_EX2;
|
||||
case RC_OPCODE_FRC: return R300_ALU_OUTA_FRC;
|
||||
case RC_OPCODE_LG2: return R300_ALU_OUTA_LG2;
|
||||
default:
|
||||
error("translate_rgb_opcode(%i): Unknown opcode", opcode);
|
||||
/* fall through */
|
||||
case OPCODE_NOP:
|
||||
case RC_OPCODE_NOP:
|
||||
/* fall through */
|
||||
case OPCODE_MAD: return R300_ALU_OUTA_MAD;
|
||||
case OPCODE_MAX: return R300_ALU_OUTA_MAX;
|
||||
case OPCODE_MIN: return R300_ALU_OUTA_MIN;
|
||||
case OPCODE_RCP: return R300_ALU_OUTA_RCP;
|
||||
case OPCODE_RSQ: return R300_ALU_OUTA_RSQ;
|
||||
case RC_OPCODE_MAD: return R300_ALU_OUTA_MAD;
|
||||
case RC_OPCODE_MAX: return R300_ALU_OUTA_MAX;
|
||||
case RC_OPCODE_MIN: return R300_ALU_OUTA_MIN;
|
||||
case RC_OPCODE_RCP: return R300_ALU_OUTA_RCP;
|
||||
case RC_OPCODE_RSQ: return R300_ALU_OUTA_RSQ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit one paired ALU instruction.
|
||||
*/
|
||||
static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
|
||||
static int emit_alu(void* data, struct radeon_pair_instruction* inst)
|
||||
{
|
||||
PROG_CODE;
|
||||
|
||||
if (code->alu.length >= R300_PFS_MAX_ALU_INST) {
|
||||
error("Too many ALU instructions");
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ip = code->alu.length++;
|
||||
|
|
@ -136,7 +136,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
|
|||
code->alu.inst[ip].alpha_inst = translate_alpha_opcode(c, inst->Alpha.Opcode);
|
||||
|
||||
for(j = 0; j < 3; ++j) {
|
||||
GLuint src = inst->RGB.Src[j].Index | (inst->RGB.Src[j].Constant << 5);
|
||||
unsigned int src = inst->RGB.Src[j].Index | (inst->RGB.Src[j].Constant << 5);
|
||||
if (!inst->RGB.Src[j].Constant)
|
||||
use_temporary(code, inst->RGB.Src[j].Index);
|
||||
code->alu.inst[ip].rgb_addr |= src << (6*j);
|
||||
|
|
@ -146,7 +146,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
|
|||
use_temporary(code, inst->Alpha.Src[j].Index);
|
||||
code->alu.inst[ip].alpha_addr |= src << (6*j);
|
||||
|
||||
GLuint arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle);
|
||||
unsigned int arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle);
|
||||
arg |= inst->RGB.Arg[j].Abs << 6;
|
||||
arg |= inst->RGB.Arg[j].Negate << 5;
|
||||
code->alu.inst[ip].rgb_inst |= arg << (7*j);
|
||||
|
|
@ -186,17 +186,17 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
|
|||
if (inst->Alpha.DepthWriteMask) {
|
||||
code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_DEPTH;
|
||||
emit->node_flags |= R300_W_OUT;
|
||||
c->code->writes_depth = GL_TRUE;
|
||||
c->code->writes_depth = 1;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finish the current node without advancing to the next one.
|
||||
*/
|
||||
static GLboolean finish_node(struct r300_emit_state * emit)
|
||||
static int finish_node(struct r300_emit_state * emit)
|
||||
{
|
||||
struct r300_fragment_program_compiler * c = emit->compiler;
|
||||
struct r300_fragment_program_code *code = &emit->compiler->code->code.r300;
|
||||
|
|
@ -204,9 +204,9 @@ static GLboolean finish_node(struct r300_emit_state * emit)
|
|||
if (code->alu.length == emit->node_first_alu) {
|
||||
/* Generate a single NOP for this node */
|
||||
struct radeon_pair_instruction inst;
|
||||
_mesa_bzero(&inst, sizeof(inst));
|
||||
memset(&inst, 0, sizeof(inst));
|
||||
if (!emit_alu(emit, &inst))
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned alu_offset = emit->node_first_alu;
|
||||
|
|
@ -217,7 +217,7 @@ static GLboolean finish_node(struct r300_emit_state * emit)
|
|||
if (code->tex.length == emit->node_first_tex) {
|
||||
if (emit->current_node > 0) {
|
||||
error("Node %i has no TEX instructions", emit->current_node);
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tex_end = 0;
|
||||
|
|
@ -240,7 +240,7 @@ static GLboolean finish_node(struct r300_emit_state * emit)
|
|||
(tex_end << R300_TEX_SIZE_SHIFT) |
|
||||
emit->node_flags;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -248,43 +248,43 @@ static GLboolean finish_node(struct r300_emit_state * emit)
|
|||
* Begin a block of texture instructions.
|
||||
* Create the necessary indirection.
|
||||
*/
|
||||
static GLboolean begin_tex(void* data)
|
||||
static int begin_tex(void* data)
|
||||
{
|
||||
PROG_CODE;
|
||||
|
||||
if (code->alu.length == emit->node_first_alu &&
|
||||
code->tex.length == emit->node_first_tex) {
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (emit->current_node == 3) {
|
||||
error("Too many texture indirections");
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!finish_node(emit))
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
emit->current_node++;
|
||||
emit->node_first_tex = code->tex.length;
|
||||
emit->node_first_alu = code->alu.length;
|
||||
emit->node_flags = 0;
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static GLboolean emit_tex(void* data, struct radeon_pair_texture_instruction* inst)
|
||||
static int emit_tex(void* data, struct radeon_pair_texture_instruction* inst)
|
||||
{
|
||||
PROG_CODE;
|
||||
|
||||
if (code->tex.length >= R300_PFS_MAX_TEX_INST) {
|
||||
error("Too many TEX instructions");
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint unit = inst->TexSrcUnit;
|
||||
GLuint dest = inst->DestIndex;
|
||||
GLuint opcode;
|
||||
unsigned int unit = inst->TexSrcUnit;
|
||||
unsigned int dest = inst->DestIndex;
|
||||
unsigned int opcode;
|
||||
|
||||
switch(inst->Opcode) {
|
||||
case RADEON_OPCODE_KIL: opcode = R300_TEX_OP_KIL; break;
|
||||
|
|
@ -293,7 +293,7 @@ static GLboolean emit_tex(void* data, struct radeon_pair_texture_instruction* in
|
|||
case RADEON_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break;
|
||||
default:
|
||||
error("Unknown texture opcode %i", inst->Opcode);
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inst->Opcode == RADEON_OPCODE_KIL) {
|
||||
|
|
@ -310,7 +310,7 @@ static GLboolean emit_tex(void* data, struct radeon_pair_texture_instruction* in
|
|||
(dest << R300_DST_ADDR_SHIFT) |
|
||||
(unit << R300_TEX_ID_SHIFT) |
|
||||
(opcode << R300_TEX_INST_SHIFT);
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -333,7 +333,7 @@ void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
|
|||
memset(&emit, 0, sizeof(emit));
|
||||
emit.compiler = compiler;
|
||||
|
||||
_mesa_bzero(code, sizeof(struct r300_fragment_program_code));
|
||||
memset(code, 0, sizeof(struct r300_fragment_program_code));
|
||||
|
||||
radeonPairProgram(compiler, &pair_handler, &emit);
|
||||
if (compiler->Base.Error)
|
||||
|
|
|
|||
|
|
@ -33,16 +33,18 @@
|
|||
|
||||
#include "r300_fragprog_swizzle.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../r300_reg.h"
|
||||
#include "radeon_nqssadce.h"
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, SWIZZLE_##y, SWIZZLE_##z, SWIZZLE_ZERO))
|
||||
#define MAKE_SWZ3(x, y, z) (RC_MAKE_SWIZZLE(RC_SWIZZLE_##x, RC_SWIZZLE_##y, RC_SWIZZLE_##z, RC_SWIZZLE_ZERO))
|
||||
|
||||
struct swizzle_data {
|
||||
GLuint hash; /**< swizzle value this matches */
|
||||
GLuint base; /**< base value for hw swizzle */
|
||||
GLuint stride; /**< difference in base between arg0/1/2 */
|
||||
unsigned int hash; /**< swizzle value this matches */
|
||||
unsigned int base; /**< base value for hw swizzle */
|
||||
unsigned int stride; /**< difference in base between arg0/1/2 */
|
||||
};
|
||||
|
||||
static const struct swizzle_data native_swizzles[] = {
|
||||
|
|
@ -65,15 +67,15 @@ static const int num_native_swizzles = sizeof(native_swizzles)/sizeof(native_swi
|
|||
* Find a native RGB swizzle that matches the given swizzle.
|
||||
* Returns 0 if none found.
|
||||
*/
|
||||
static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle)
|
||||
static const struct swizzle_data* lookup_native_swizzle(unsigned int swizzle)
|
||||
{
|
||||
int i, comp;
|
||||
|
||||
for(i = 0; i < num_native_swizzles; ++i) {
|
||||
const struct swizzle_data* sd = &native_swizzles[i];
|
||||
for(comp = 0; comp < 3; ++comp) {
|
||||
GLuint swz = GET_SWZ(swizzle, comp);
|
||||
if (swz == SWIZZLE_NIL)
|
||||
unsigned int swz = GET_SWZ(swizzle, comp);
|
||||
if (swz == RC_SWIZZLE_UNUSED)
|
||||
continue;
|
||||
if (swz != GET_SWZ(sd->hash, comp))
|
||||
break;
|
||||
|
|
@ -90,71 +92,71 @@ static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle)
|
|||
* Check whether the given instruction supports the swizzle and negate
|
||||
* combinations in the given source register.
|
||||
*/
|
||||
GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
|
||||
int r300FPIsNativeSwizzle(rc_opcode opcode, struct rc_src_register reg)
|
||||
{
|
||||
if (reg.Abs)
|
||||
reg.Negate = NEGATE_NONE;
|
||||
reg.Negate = RC_MASK_NONE;
|
||||
|
||||
if (opcode == OPCODE_KIL ||
|
||||
opcode == OPCODE_TEX ||
|
||||
opcode == OPCODE_TXB ||
|
||||
opcode == OPCODE_TXP) {
|
||||
if (opcode == RC_OPCODE_KIL ||
|
||||
opcode == RC_OPCODE_TEX ||
|
||||
opcode == RC_OPCODE_TXB ||
|
||||
opcode == RC_OPCODE_TXP) {
|
||||
int j;
|
||||
|
||||
if (reg.Abs || reg.Negate)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
for(j = 0; j < 4; ++j) {
|
||||
GLuint swz = GET_SWZ(reg.Swizzle, j);
|
||||
if (swz == SWIZZLE_NIL)
|
||||
unsigned int swz = GET_SWZ(reg.Swizzle, j);
|
||||
if (swz == RC_SWIZZLE_UNUSED)
|
||||
continue;
|
||||
if (swz != j)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GLuint relevant = 0;
|
||||
unsigned int relevant = 0;
|
||||
int j;
|
||||
|
||||
for(j = 0; j < 3; ++j)
|
||||
if (GET_SWZ(reg.Swizzle, j) != SWIZZLE_NIL)
|
||||
if (GET_SWZ(reg.Swizzle, j) != RC_SWIZZLE_UNUSED)
|
||||
relevant |= 1 << j;
|
||||
|
||||
if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant))
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
if (!lookup_native_swizzle(reg.Swizzle))
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate MOV dst, src using only native swizzles.
|
||||
*/
|
||||
void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src)
|
||||
void r300FPBuildSwizzle(struct nqssadce_state *s, struct rc_dst_register dst, struct rc_src_register src)
|
||||
{
|
||||
if (src.Abs)
|
||||
src.Negate = NEGATE_NONE;
|
||||
src.Negate = RC_MASK_NONE;
|
||||
|
||||
while(dst.WriteMask) {
|
||||
const struct swizzle_data *best_swizzle = 0;
|
||||
GLuint best_matchcount = 0;
|
||||
GLuint best_matchmask = 0;
|
||||
unsigned int best_matchcount = 0;
|
||||
unsigned int best_matchmask = 0;
|
||||
int i, comp;
|
||||
|
||||
for(i = 0; i < num_native_swizzles; ++i) {
|
||||
const struct swizzle_data *sd = &native_swizzles[i];
|
||||
GLuint matchcount = 0;
|
||||
GLuint matchmask = 0;
|
||||
unsigned int matchcount = 0;
|
||||
unsigned int matchmask = 0;
|
||||
for(comp = 0; comp < 3; ++comp) {
|
||||
if (!GET_BIT(dst.WriteMask, comp))
|
||||
continue;
|
||||
GLuint swz = GET_SWZ(src.Swizzle, comp);
|
||||
if (swz == SWIZZLE_NIL)
|
||||
unsigned int swz = GET_SWZ(src.Swizzle, comp);
|
||||
if (swz == RC_SWIZZLE_UNUSED)
|
||||
continue;
|
||||
if (swz == GET_SWZ(sd->hash, comp)) {
|
||||
/* check if the negate bit of current component
|
||||
|
|
@ -170,17 +172,17 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
|
|||
best_swizzle = sd;
|
||||
best_matchcount = matchcount;
|
||||
best_matchmask = matchmask;
|
||||
if (matchmask == (dst.WriteMask & WRITEMASK_XYZ))
|
||||
if (matchmask == (dst.WriteMask & RC_MASK_XYZ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct rc_instruction *inst = rc_insert_new_instruction(s->Compiler, s->IP->Prev);
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
inst->I.DstReg = dst;
|
||||
inst->I.DstReg.WriteMask &= (best_matchmask | WRITEMASK_W);
|
||||
inst->I.DstReg.WriteMask &= (best_matchmask | RC_MASK_W);
|
||||
inst->I.SrcReg[0] = src;
|
||||
inst->I.SrcReg[0].Negate = (best_matchmask & src.Negate) ? NEGATE_XYZW : NEGATE_NONE;
|
||||
inst->I.SrcReg[0].Negate = (best_matchmask & src.Negate) ? RC_MASK_XYZW : RC_MASK_NONE;
|
||||
/* Note: We rely on NqSSA/DCE to set unused swizzle components to NIL */
|
||||
|
||||
dst.WriteMask &= ~inst->I.DstReg.WriteMask;
|
||||
|
|
@ -192,12 +194,12 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
|
|||
* Translate an RGB (XYZ) swizzle into the hardware code for the given
|
||||
* instruction source.
|
||||
*/
|
||||
GLuint r300FPTranslateRGBSwizzle(GLuint src, GLuint swizzle)
|
||||
unsigned int r300FPTranslateRGBSwizzle(unsigned int src, unsigned int swizzle)
|
||||
{
|
||||
const struct swizzle_data* sd = lookup_native_swizzle(swizzle);
|
||||
|
||||
if (!sd) {
|
||||
_mesa_printf("Not a native swizzle: %08x\n", swizzle);
|
||||
fprintf(stderr, "Not a native swizzle: %08x\n", swizzle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -209,15 +211,15 @@ GLuint r300FPTranslateRGBSwizzle(GLuint src, GLuint swizzle)
|
|||
* Translate an Alpha (W) swizzle into the hardware code for the given
|
||||
* instruction source.
|
||||
*/
|
||||
GLuint r300FPTranslateAlphaSwizzle(GLuint src, GLuint swizzle)
|
||||
unsigned int r300FPTranslateAlphaSwizzle(unsigned int src, unsigned int swizzle)
|
||||
{
|
||||
if (swizzle < 3)
|
||||
return swizzle + 3*src;
|
||||
|
||||
switch(swizzle) {
|
||||
case SWIZZLE_W: return R300_ALU_ARGA_SRC0A + src;
|
||||
case SWIZZLE_ONE: return R300_ALU_ARGA_ONE;
|
||||
case SWIZZLE_ZERO: return R300_ALU_ARGA_ZERO;
|
||||
case RC_SWIZZLE_W: return R300_ALU_ARGA_SRC0A + src;
|
||||
case RC_SWIZZLE_ONE: return R300_ALU_ARGA_ONE;
|
||||
case RC_SWIZZLE_ZERO: return R300_ALU_ARGA_ZERO;
|
||||
default: return R300_ALU_ARGA_ONE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,15 +28,14 @@
|
|||
#ifndef __R300_FRAGPROG_SWIZZLE_H_
|
||||
#define __R300_FRAGPROG_SWIZZLE_H_
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include "radeon_program.h"
|
||||
|
||||
struct nqssadce_state;
|
||||
|
||||
GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg);
|
||||
void r300FPBuildSwizzle(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src);
|
||||
int r300FPIsNativeSwizzle(rc_opcode opcode, struct rc_src_register reg);
|
||||
void r300FPBuildSwizzle(struct nqssadce_state*, struct rc_dst_register dst, struct rc_src_register src);
|
||||
|
||||
GLuint r300FPTranslateRGBSwizzle(GLuint src, GLuint swizzle);
|
||||
GLuint r300FPTranslateAlphaSwizzle(GLuint src, GLuint swizzle);
|
||||
unsigned int r300FPTranslateRGBSwizzle(unsigned int src, unsigned int swizzle);
|
||||
unsigned int r300FPTranslateAlphaSwizzle(unsigned int src, unsigned int swizzle);
|
||||
|
||||
#endif /* __R300_FRAGPROG_SWIZZLE_H_ */
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@
|
|||
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "shader/prog_statevars.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "radeon_nqssadce.h"
|
||||
#include "radeon_program_alu.h"
|
||||
|
|
@ -36,8 +34,8 @@
|
|||
static void nqssadce_init(struct nqssadce_state* s)
|
||||
{
|
||||
struct r300_fragment_program_compiler * c = s->UserData;
|
||||
s->Outputs[c->OutputColor].Sourced = WRITEMASK_XYZW;
|
||||
s->Outputs[c->OutputDepth].Sourced = WRITEMASK_W;
|
||||
s->Outputs[c->OutputColor].Sourced = RC_MASK_XYZW;
|
||||
s->Outputs[c->OutputDepth].Sourced = RC_MASK_W;
|
||||
}
|
||||
|
||||
static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
|
||||
|
|
@ -45,35 +43,35 @@ static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
|
|||
struct rc_instruction *rci;
|
||||
|
||||
for (rci = c->Base.Program.Instructions.Next; rci != &c->Base.Program.Instructions; rci = rci->Next) {
|
||||
struct prog_instruction * inst = &rci->I;
|
||||
struct rc_sub_instruction * inst = &rci->I;
|
||||
|
||||
if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != c->OutputDepth)
|
||||
if (inst->DstReg.File != RC_FILE_OUTPUT || inst->DstReg.Index != c->OutputDepth)
|
||||
continue;
|
||||
|
||||
if (inst->DstReg.WriteMask & WRITEMASK_Z) {
|
||||
inst->DstReg.WriteMask = WRITEMASK_W;
|
||||
if (inst->DstReg.WriteMask & RC_MASK_Z) {
|
||||
inst->DstReg.WriteMask = RC_MASK_W;
|
||||
} else {
|
||||
inst->DstReg.WriteMask = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MOV:
|
||||
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
case RC_OPCODE_FRC:
|
||||
case RC_OPCODE_MOV:
|
||||
inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
break;
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MUL:
|
||||
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
|
||||
case RC_OPCODE_ADD:
|
||||
case RC_OPCODE_MAX:
|
||||
case RC_OPCODE_MIN:
|
||||
case RC_OPCODE_MUL:
|
||||
inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
inst->SrcReg[1] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[1]);
|
||||
break;
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_MAD:
|
||||
inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
|
||||
inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
|
||||
case RC_OPCODE_CMP:
|
||||
case RC_OPCODE_MAD:
|
||||
inst->SrcReg[0] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[0]);
|
||||
inst->SrcReg[1] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[1]);
|
||||
inst->SrcReg[2] = lmul_swizzle(RC_SWIZZLE_ZZZZ, inst->SrcReg[2]);
|
||||
break;
|
||||
default:
|
||||
// Scalar instructions needn't be reswizzled
|
||||
|
|
@ -104,7 +102,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
|
|||
}
|
||||
|
||||
if (c->Base.Debug) {
|
||||
_mesa_printf("Fragment Program: After native rewrite:\n");
|
||||
fprintf(stderr, "Fragment Program: After native rewrite:\n");
|
||||
rc_print_program(&c->Base.Program);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
@ -126,7 +124,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
|
|||
}
|
||||
|
||||
if (c->Base.Debug) {
|
||||
_mesa_printf("Compiler: after NqSSA-DCE:\n");
|
||||
fprintf(stderr, "Compiler: after NqSSA-DCE:\n");
|
||||
rc_print_program(&c->Base.Program);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@
|
|||
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../r300_reg.h"
|
||||
|
||||
#include "radeon_nqssadce.h"
|
||||
#include "radeon_program.h"
|
||||
#include "radeon_program_alu.h"
|
||||
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
|
||||
/*
|
||||
* Take an already-setup and valid source then swizzle it appropriately to
|
||||
|
|
@ -42,103 +42,82 @@
|
|||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_src_class(vpi->SrcReg[x].File), \
|
||||
NEGATE_NONE) | (vpi->SrcReg[x].RelAddr << 4))
|
||||
RC_MASK_NONE) | (vpi->SrcReg[x].RelAddr << 4))
|
||||
|
||||
|
||||
static unsigned long t_dst_mask(GLuint mask)
|
||||
static unsigned long t_dst_mask(unsigned int mask)
|
||||
{
|
||||
/* WRITEMASK_* is equivalent to VSF_FLAG_* */
|
||||
return mask & WRITEMASK_XYZW;
|
||||
/* RC_MASK_* is equivalent to VSF_FLAG_* */
|
||||
return mask & RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
static unsigned long t_dst_class(gl_register_file file)
|
||||
static unsigned long t_dst_class(rc_register_file file)
|
||||
{
|
||||
|
||||
switch (file) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
return PVS_DST_REG_TEMPORARY;
|
||||
case PROGRAM_OUTPUT:
|
||||
return PVS_DST_REG_OUT;
|
||||
case PROGRAM_ADDRESS:
|
||||
return PVS_DST_REG_A0;
|
||||
/*
|
||||
case PROGRAM_INPUT:
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
case PROGRAM_ENV_PARAM:
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_WRITE_ONLY:
|
||||
case PROGRAM_ADDRESS:
|
||||
*/
|
||||
default:
|
||||
fprintf(stderr, "problem in %s", __FUNCTION__);
|
||||
_mesa_exit(-1);
|
||||
return -1;
|
||||
fprintf(stderr, "%s: Bad register file %i\n", __FUNCTION__, file);
|
||||
/* fall-through */
|
||||
case RC_FILE_TEMPORARY:
|
||||
return PVS_DST_REG_TEMPORARY;
|
||||
case RC_FILE_OUTPUT:
|
||||
return PVS_DST_REG_OUT;
|
||||
case RC_FILE_ADDRESS:
|
||||
return PVS_DST_REG_A0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long t_dst_index(struct r300_vertex_program_code *vp,
|
||||
struct prog_dst_register *dst)
|
||||
struct rc_dst_register *dst)
|
||||
{
|
||||
if (dst->File == PROGRAM_OUTPUT)
|
||||
if (dst->File == RC_FILE_OUTPUT)
|
||||
return vp->outputs[dst->Index];
|
||||
|
||||
return dst->Index;
|
||||
}
|
||||
|
||||
static unsigned long t_src_class(gl_register_file file)
|
||||
static unsigned long t_src_class(rc_register_file file)
|
||||
{
|
||||
switch (file) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
return PVS_SRC_REG_TEMPORARY;
|
||||
case PROGRAM_INPUT:
|
||||
return PVS_SRC_REG_INPUT;
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
case PROGRAM_ENV_PARAM:
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
case PROGRAM_STATE_VAR:
|
||||
return PVS_SRC_REG_CONSTANT;
|
||||
/*
|
||||
case PROGRAM_OUTPUT:
|
||||
case PROGRAM_WRITE_ONLY:
|
||||
case PROGRAM_ADDRESS:
|
||||
*/
|
||||
default:
|
||||
fprintf(stderr, "problem in %s", __FUNCTION__);
|
||||
_mesa_exit(-1);
|
||||
return -1;
|
||||
fprintf(stderr, "%s: Bad register file %i\n", __FUNCTION__, file);
|
||||
/* fall-through */
|
||||
case RC_FILE_TEMPORARY:
|
||||
return PVS_SRC_REG_TEMPORARY;
|
||||
case RC_FILE_INPUT:
|
||||
return PVS_SRC_REG_INPUT;
|
||||
case RC_FILE_CONSTANT:
|
||||
return PVS_SRC_REG_CONSTANT;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean t_src_conflict(struct prog_src_register a, struct prog_src_register b)
|
||||
static int t_src_conflict(struct rc_src_register a, struct rc_src_register b)
|
||||
{
|
||||
unsigned long aclass = t_src_class(a.File);
|
||||
unsigned long bclass = t_src_class(b.File);
|
||||
|
||||
if (aclass != bclass)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
if (aclass == PVS_SRC_REG_TEMPORARY)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
if (a.RelAddr || b.RelAddr)
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
if (a.Index != b.Index)
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INLINE unsigned long t_swizzle(GLubyte swizzle)
|
||||
static inline unsigned long t_swizzle(unsigned int swizzle)
|
||||
{
|
||||
/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
|
||||
/* this is in fact a NOP as the Mesa RC_SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
static unsigned long t_src_index(struct r300_vertex_program_code *vp,
|
||||
struct prog_src_register *src)
|
||||
struct rc_src_register *src)
|
||||
{
|
||||
if (src->File == PROGRAM_INPUT) {
|
||||
if (src->File == RC_FILE_INPUT) {
|
||||
assert(vp->inputs[src->Index] != -1);
|
||||
return vp->inputs[src->Index];
|
||||
} else {
|
||||
|
|
@ -154,9 +133,9 @@ static unsigned long t_src_index(struct r300_vertex_program_code *vp,
|
|||
/* these two functions should probably be merged... */
|
||||
|
||||
static unsigned long t_src(struct r300_vertex_program_code *vp,
|
||||
struct prog_src_register *src)
|
||||
struct rc_src_register *src)
|
||||
{
|
||||
/* src->Negate uses the NEGATE_ flags from program_instruction.h,
|
||||
/* src->Negate uses the RC_MASK_ flags from program_instruction.h,
|
||||
* which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
|
||||
*/
|
||||
return PVS_SRC_OPERAND(t_src_index(vp, src),
|
||||
|
|
@ -169,9 +148,9 @@ static unsigned long t_src(struct r300_vertex_program_code *vp,
|
|||
}
|
||||
|
||||
static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
|
||||
struct prog_src_register *src)
|
||||
struct rc_src_register *src)
|
||||
{
|
||||
/* src->Negate uses the NEGATE_ flags from program_instruction.h,
|
||||
/* src->Negate uses the RC_MASK_ flags from program_instruction.h,
|
||||
* which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
|
||||
*/
|
||||
return PVS_SRC_OPERAND(t_src_index(vp, src),
|
||||
|
|
@ -180,79 +159,79 @@ static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
|
|||
t_swizzle(GET_SWZ(src->Swizzle, 0)),
|
||||
t_swizzle(GET_SWZ(src->Swizzle, 0)),
|
||||
t_src_class(src->File),
|
||||
src->Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
src->Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
|
||||
(src->RelAddr << 4);
|
||||
}
|
||||
|
||||
static GLboolean valid_dst(struct r300_vertex_program_code *vp,
|
||||
struct prog_dst_register *dst)
|
||||
static int valid_dst(struct r300_vertex_program_code *vp,
|
||||
struct rc_dst_register *dst)
|
||||
{
|
||||
if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
|
||||
return GL_FALSE;
|
||||
} else if (dst->File == PROGRAM_ADDRESS) {
|
||||
if (dst->File == RC_FILE_OUTPUT && vp->outputs[dst->Index] == -1) {
|
||||
return 0;
|
||||
} else if (dst->File == RC_FILE_ADDRESS) {
|
||||
assert(dst->Index == 0);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ei_vector1(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
unsigned int hw_opcode,
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
0,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, RC_SWIZZLE_ZERO);
|
||||
}
|
||||
|
||||
static void ei_vector2(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
unsigned int hw_opcode,
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
0,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = t_src(vp, &vpi->SrcReg[1]);
|
||||
inst[3] = __CONST(1, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(1, RC_SWIZZLE_ZERO);
|
||||
}
|
||||
|
||||
static void ei_math1(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
unsigned int hw_opcode,
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_TRUE,
|
||||
GL_FALSE,
|
||||
1,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, RC_SWIZZLE_ZERO);
|
||||
}
|
||||
|
||||
static void ei_lit(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
//LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
|
||||
|
||||
inst[0] = PVS_OP_DST_OPERAND(ME_LIGHT_COEFF_DX,
|
||||
GL_TRUE,
|
||||
GL_FALSE,
|
||||
1,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
|
|
@ -262,27 +241,27 @@ static void ei_lit(struct r300_vertex_program_code *vp,
|
|||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
vpi->SrcReg[0].Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
|
||||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
vpi->SrcReg[0].Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
|
||||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
vpi->SrcReg[0].Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
}
|
||||
|
||||
static void ei_mad(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
/* Remarks about hardware limitations of MAD
|
||||
* (please preserve this comment, as this information is _NOT_
|
||||
|
|
@ -310,22 +289,22 @@ static void ei_mad(struct r300_vertex_program_code *vp,
|
|||
* according to AMD docs, this should improve performance by one clock
|
||||
* as a nice side bonus.
|
||||
*/
|
||||
if (vpi->SrcReg[0].File == PROGRAM_TEMPORARY &&
|
||||
vpi->SrcReg[1].File == PROGRAM_TEMPORARY &&
|
||||
vpi->SrcReg[2].File == PROGRAM_TEMPORARY &&
|
||||
if (vpi->SrcReg[0].File == RC_FILE_TEMPORARY &&
|
||||
vpi->SrcReg[1].File == RC_FILE_TEMPORARY &&
|
||||
vpi->SrcReg[2].File == RC_FILE_TEMPORARY &&
|
||||
vpi->SrcReg[0].Index != vpi->SrcReg[1].Index &&
|
||||
vpi->SrcReg[0].Index != vpi->SrcReg[2].Index &&
|
||||
vpi->SrcReg[1].Index != vpi->SrcReg[2].Index) {
|
||||
inst[0] = PVS_OP_DST_OPERAND(PVS_MACRO_OP_2CLK_MADD,
|
||||
GL_FALSE,
|
||||
GL_TRUE,
|
||||
0,
|
||||
1,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
} else {
|
||||
inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
0,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
|
|
@ -336,17 +315,17 @@ static void ei_mad(struct r300_vertex_program_code *vp,
|
|||
}
|
||||
|
||||
static void ei_pow(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst)
|
||||
struct rc_sub_instruction *vpi,
|
||||
unsigned int * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(ME_POWER_FUNC_FF,
|
||||
GL_TRUE,
|
||||
GL_FALSE,
|
||||
1,
|
||||
0,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
|
||||
inst[3] = t_src_scalar(vp, &vpi->SrcReg[1]);
|
||||
}
|
||||
|
||||
|
|
@ -361,8 +340,8 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
|
|||
compiler->SetHwInputOutput(compiler);
|
||||
|
||||
for(rci = compiler->Base.Program.Instructions.Next; rci != &compiler->Base.Program.Instructions; rci = rci->Next) {
|
||||
struct prog_instruction *vpi = &rci->I;
|
||||
GLuint *inst = compiler->code->body.d + compiler->code->length;
|
||||
struct rc_sub_instruction *vpi = &rci->I;
|
||||
unsigned int *inst = compiler->code->body.d + compiler->code->length;
|
||||
|
||||
/* Skip instructions writing to non-existing destination */
|
||||
if (!valid_dst(compiler->code, &vpi->DstReg))
|
||||
|
|
@ -374,26 +353,26 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
|
|||
}
|
||||
|
||||
switch (vpi->Opcode) {
|
||||
case OPCODE_ADD: ei_vector2(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case OPCODE_ARL: ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst); break;
|
||||
case OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break;
|
||||
case OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break;
|
||||
case OPCODE_EX2: ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst); break;
|
||||
case OPCODE_EXP: ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst); break;
|
||||
case OPCODE_FRC: ei_vector1(compiler->code, VE_FRACTION, vpi, inst); break;
|
||||
case OPCODE_LG2: ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst); break;
|
||||
case OPCODE_LIT: ei_lit(compiler->code, vpi, inst); break;
|
||||
case OPCODE_LOG: ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst); break;
|
||||
case OPCODE_MAD: ei_mad(compiler->code, vpi, inst); break;
|
||||
case OPCODE_MAX: ei_vector2(compiler->code, VE_MAXIMUM, vpi, inst); break;
|
||||
case OPCODE_MIN: ei_vector2(compiler->code, VE_MINIMUM, vpi, inst); break;
|
||||
case OPCODE_MOV: ei_vector1(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case OPCODE_MUL: ei_vector2(compiler->code, VE_MULTIPLY, vpi, inst); break;
|
||||
case OPCODE_POW: ei_pow(compiler->code, vpi, inst); break;
|
||||
case OPCODE_RCP: ei_math1(compiler->code, ME_RECIP_DX, vpi, inst); break;
|
||||
case OPCODE_RSQ: ei_math1(compiler->code, ME_RECIP_SQRT_DX, vpi, inst); break;
|
||||
case OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
|
||||
case OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
|
||||
case RC_OPCODE_ADD: ei_vector2(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case RC_OPCODE_ARL: ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst); break;
|
||||
case RC_OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break;
|
||||
case RC_OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break;
|
||||
case RC_OPCODE_EX2: ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst); break;
|
||||
case RC_OPCODE_EXP: ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst); break;
|
||||
case RC_OPCODE_FRC: ei_vector1(compiler->code, VE_FRACTION, vpi, inst); break;
|
||||
case RC_OPCODE_LG2: ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst); break;
|
||||
case RC_OPCODE_LIT: ei_lit(compiler->code, vpi, inst); break;
|
||||
case RC_OPCODE_LOG: ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst); break;
|
||||
case RC_OPCODE_MAD: ei_mad(compiler->code, vpi, inst); break;
|
||||
case RC_OPCODE_MAX: ei_vector2(compiler->code, VE_MAXIMUM, vpi, inst); break;
|
||||
case RC_OPCODE_MIN: ei_vector2(compiler->code, VE_MINIMUM, vpi, inst); break;
|
||||
case RC_OPCODE_MOV: ei_vector1(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case RC_OPCODE_MUL: ei_vector2(compiler->code, VE_MULTIPLY, vpi, inst); break;
|
||||
case RC_OPCODE_POW: ei_pow(compiler->code, vpi, inst); break;
|
||||
case RC_OPCODE_RCP: ei_math1(compiler->code, ME_RECIP_DX, vpi, inst); break;
|
||||
case RC_OPCODE_RSQ: ei_math1(compiler->code, ME_RECIP_SQRT_DX, vpi, inst); break;
|
||||
case RC_OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
|
||||
case RC_OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
|
||||
default:
|
||||
rc_error(&compiler->Base, "Unknown opcode %i\n", vpi->Opcode);
|
||||
return;
|
||||
|
|
@ -407,36 +386,35 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
|
|||
}
|
||||
|
||||
struct temporary_allocation {
|
||||
GLuint Allocated:1;
|
||||
GLuint HwTemp:15;
|
||||
unsigned int Allocated:1;
|
||||
unsigned int HwTemp:15;
|
||||
struct rc_instruction * LastRead;
|
||||
};
|
||||
|
||||
static void allocate_temporary_registers(struct r300_vertex_program_compiler * compiler)
|
||||
{
|
||||
struct rc_instruction *inst;
|
||||
GLuint num_orig_temps = 0;
|
||||
GLboolean hwtemps[VSF_MAX_FRAGMENT_TEMPS];
|
||||
unsigned int num_orig_temps = 0;
|
||||
char hwtemps[VSF_MAX_FRAGMENT_TEMPS];
|
||||
struct temporary_allocation * ta;
|
||||
GLuint i, j;
|
||||
unsigned int i, j;
|
||||
|
||||
compiler->code->num_temporaries = 0;
|
||||
memset(hwtemps, 0, sizeof(hwtemps));
|
||||
|
||||
/* Pass 1: Count original temporaries and allocate structures */
|
||||
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
|
||||
GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
GLuint numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
for (i = 0; i < numsrcs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY) {
|
||||
for (i = 0; i < opcode->NumSrcRegs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_TEMPORARY) {
|
||||
if (inst->I.SrcReg[i].Index >= num_orig_temps)
|
||||
num_orig_temps = inst->I.SrcReg[i].Index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (numdsts) {
|
||||
if (inst->I.DstReg.File == PROGRAM_TEMPORARY) {
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->I.DstReg.File == RC_FILE_TEMPORARY) {
|
||||
if (inst->I.DstReg.Index >= num_orig_temps)
|
||||
num_orig_temps = inst->I.DstReg.Index + 1;
|
||||
}
|
||||
|
|
@ -449,32 +427,31 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
|
|||
|
||||
/* Pass 2: Determine original temporary lifetimes */
|
||||
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
|
||||
GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
for (i = 0; i < numsrcs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY)
|
||||
for (i = 0; i < opcode->NumSrcRegs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_TEMPORARY)
|
||||
ta[inst->I.SrcReg[i].Index].LastRead = inst;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 3: Register allocation */
|
||||
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
|
||||
GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
GLuint numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
for (i = 0; i < numsrcs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY) {
|
||||
GLuint orig = inst->I.SrcReg[i].Index;
|
||||
for (i = 0; i < opcode->NumSrcRegs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_TEMPORARY) {
|
||||
unsigned int orig = inst->I.SrcReg[i].Index;
|
||||
inst->I.SrcReg[i].Index = ta[orig].HwTemp;
|
||||
|
||||
if (ta[orig].Allocated && inst == ta[orig].LastRead)
|
||||
hwtemps[ta[orig].HwTemp] = GL_FALSE;
|
||||
hwtemps[ta[orig].HwTemp] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (numdsts) {
|
||||
if (inst->I.DstReg.File == PROGRAM_TEMPORARY) {
|
||||
GLuint orig = inst->I.DstReg.Index;
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->I.DstReg.File == RC_FILE_TEMPORARY) {
|
||||
unsigned int orig = inst->I.DstReg.Index;
|
||||
|
||||
if (!ta[orig].Allocated) {
|
||||
for(j = 0; j < VSF_MAX_FRAGMENT_TEMPS; ++j) {
|
||||
|
|
@ -484,9 +461,9 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
|
|||
if (j >= VSF_MAX_FRAGMENT_TEMPS) {
|
||||
fprintf(stderr, "Out of hw temporaries\n");
|
||||
} else {
|
||||
ta[orig].Allocated = GL_TRUE;
|
||||
ta[orig].Allocated = 1;
|
||||
ta[orig].HwTemp = j;
|
||||
hwtemps[j] = GL_TRUE;
|
||||
hwtemps[j] = 1;
|
||||
|
||||
if (j >= compiler->code->num_temporaries)
|
||||
compiler->code->num_temporaries = j + 1;
|
||||
|
|
@ -504,45 +481,45 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
|
|||
* Vertex engine cannot read two inputs or two constants at the same time.
|
||||
* Introduce intermediate MOVs to temporary registers to account for this.
|
||||
*/
|
||||
static GLboolean transform_source_conflicts(
|
||||
static int transform_source_conflicts(
|
||||
struct radeon_compiler *c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
GLuint num_operands = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
if (num_operands == 3) {
|
||||
if (opcode->NumSrcRegs == 3) {
|
||||
if (t_src_conflict(inst->I.SrcReg[1], inst->I.SrcReg[2])
|
||||
|| t_src_conflict(inst->I.SrcReg[0], inst->I.SrcReg[2])) {
|
||||
int tmpreg = rc_find_free_temporary(c);
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.DstReg.Index = tmpreg;
|
||||
inst_mov->I.SrcReg[0] = inst->I.SrcReg[2];
|
||||
|
||||
reset_srcreg(&inst->I.SrcReg[2]);
|
||||
inst->I.SrcReg[2].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[2].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[2].Index = tmpreg;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_operands >= 2) {
|
||||
if (opcode->NumSrcRegs >= 2) {
|
||||
if (t_src_conflict(inst->I.SrcReg[1], inst->I.SrcReg[0])) {
|
||||
int tmpreg = rc_find_free_temporary(c);
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.DstReg.Index = tmpreg;
|
||||
inst_mov->I.SrcReg[0] = inst->I.SrcReg[1];
|
||||
|
||||
reset_srcreg(&inst->I.SrcReg[1]);
|
||||
inst->I.SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[1].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[1].Index = tmpreg;
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void addArtificialOutputs(struct r300_vertex_program_compiler * compiler)
|
||||
|
|
@ -553,15 +530,15 @@ static void addArtificialOutputs(struct r300_vertex_program_compiler * compiler)
|
|||
if ((compiler->RequiredOutputs & (1 << i)) &&
|
||||
!(compiler->Base.Program.OutputsWritten & (1 << i))) {
|
||||
struct rc_instruction * inst = rc_insert_new_instruction(&compiler->Base, compiler->Base.Program.Instructions.Prev);
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
|
||||
inst->I.DstReg.File = PROGRAM_OUTPUT;
|
||||
inst->I.DstReg.File = RC_FILE_OUTPUT;
|
||||
inst->I.DstReg.Index = i;
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
|
||||
inst->I.SrcReg[0].File = PROGRAM_CONSTANT;
|
||||
inst->I.SrcReg[0].File = RC_FILE_CONSTANT;
|
||||
inst->I.SrcReg[0].Index = 0;
|
||||
inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
|
||||
|
||||
compiler->Base.Program.OutputsWritten |= 1 << i;
|
||||
}
|
||||
|
|
@ -573,18 +550,18 @@ static void nqssadceInit(struct nqssadce_state* s)
|
|||
struct r300_vertex_program_compiler * compiler = s->UserData;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < VERT_RESULT_MAX; ++i) {
|
||||
for(i = 0; i < 32; ++i) {
|
||||
if (compiler->RequiredOutputs & (1 << i))
|
||||
s->Outputs[i].Sourced = WRITEMASK_XYZW;
|
||||
s->Outputs[i].Sourced = RC_MASK_XYZW;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
|
||||
static int swizzleIsNative(rc_opcode opcode, struct rc_src_register reg)
|
||||
{
|
||||
(void) opcode;
|
||||
(void) reg;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,15 +27,17 @@
|
|||
|
||||
#include "r500_fragprog.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../r300_reg.h"
|
||||
|
||||
static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
|
||||
static struct rc_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
|
||||
{
|
||||
struct prog_src_register reg = { 0, };
|
||||
struct rc_src_register reg = { 0, };
|
||||
|
||||
reg.File = PROGRAM_STATE_VAR;
|
||||
reg.File = RC_FILE_CONSTANT;
|
||||
reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
|
||||
reg.Swizzle = SWIZZLE_WWWW;
|
||||
reg.Swizzle = RC_SWIZZLE_WWWW;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +46,7 @@ static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int t
|
|||
* - implement texture compare (shadow extensions)
|
||||
* - extract non-native source / destination operands
|
||||
*/
|
||||
GLboolean r500_transform_TEX(
|
||||
int r500_transform_TEX(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void* data)
|
||||
|
|
@ -52,77 +54,77 @@ GLboolean r500_transform_TEX(
|
|||
struct r300_fragment_program_compiler *compiler =
|
||||
(struct r300_fragment_program_compiler*)data;
|
||||
|
||||
if (inst->I.Opcode != OPCODE_TEX &&
|
||||
inst->I.Opcode != OPCODE_TXB &&
|
||||
inst->I.Opcode != OPCODE_TXP &&
|
||||
inst->I.Opcode != OPCODE_KIL)
|
||||
return GL_FALSE;
|
||||
if (inst->I.Opcode != RC_OPCODE_TEX &&
|
||||
inst->I.Opcode != RC_OPCODE_TXB &&
|
||||
inst->I.Opcode != RC_OPCODE_TXP &&
|
||||
inst->I.Opcode != RC_OPCODE_KIL)
|
||||
return 0;
|
||||
|
||||
/* ARB_shadow & EXT_shadow_funcs */
|
||||
if (inst->I.Opcode != OPCODE_KIL &&
|
||||
if (inst->I.Opcode != RC_OPCODE_KIL &&
|
||||
c->Program.ShadowSamplers & (1 << inst->I.TexSrcUnit)) {
|
||||
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
rc_compare_func comparefunc = compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
|
||||
if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) {
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
|
||||
if (comparefunc == GL_ALWAYS) {
|
||||
inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
|
||||
inst->I.SrcReg[0].Swizzle = SWIZZLE_1111;
|
||||
if (comparefunc == RC_COMPARE_FUNC_ALWAYS) {
|
||||
inst->I.SrcReg[0].File = RC_FILE_NONE;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
|
||||
} else {
|
||||
inst->I.SrcReg[0] = shadow_ambient(c, inst->I.TexSrcUnit);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
} else {
|
||||
GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
GLuint depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
|
||||
rc_compare_func comparefunc = compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
|
||||
unsigned int depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
|
||||
struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
|
||||
struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
|
||||
struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
|
||||
int pass, fail;
|
||||
|
||||
inst_rcp->I.Opcode = OPCODE_RCP;
|
||||
inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_rcp->I.Opcode = RC_OPCODE_RCP;
|
||||
inst_rcp->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_rcp->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
|
||||
inst_rcp->I.DstReg.WriteMask = RC_MASK_W;
|
||||
inst_rcp->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
|
||||
inst_rcp->I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
inst_cmp->I.DstReg = inst->I.DstReg;
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
|
||||
inst_mad->I.Opcode = OPCODE_MAD;
|
||||
inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.Opcode = RC_OPCODE_MAD;
|
||||
inst_mad->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_mad->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
inst_mad->I.SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
|
||||
inst_mad->I.SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.SrcReg[0].Swizzle = RC_SWIZZLE_ZZZZ;
|
||||
inst_mad->I.SrcReg[1].File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.SrcReg[1].Index = inst_rcp->I.DstReg.Index;
|
||||
inst_mad->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.SrcReg[2].Index = inst->I.DstReg.Index;
|
||||
if (depthmode == 0) /* GL_LUMINANCE */
|
||||
inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
|
||||
inst_mad->I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_Z);
|
||||
else if (depthmode == 2) /* GL_ALPHA */
|
||||
inst_mad->I.SrcReg[2].Swizzle = SWIZZLE_WWWW;
|
||||
inst_mad->I.SrcReg[2].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
/* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
|
||||
* r < tex <=> -tex+r < 0
|
||||
* r >= tex <=> not (-tex+r < 0 */
|
||||
if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
|
||||
inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ NEGATE_XYZW;
|
||||
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL)
|
||||
inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ RC_MASK_XYZW;
|
||||
else
|
||||
inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ NEGATE_XYZW;
|
||||
inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ RC_MASK_XYZW;
|
||||
|
||||
inst_cmp->I.Opcode = OPCODE_CMP;
|
||||
inst_cmp->I.Opcode = RC_OPCODE_CMP;
|
||||
/* DstReg has been filled out above */
|
||||
inst_cmp->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst_cmp->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst_cmp->I.SrcReg[0].Index = inst_mad->I.DstReg.Index;
|
||||
|
||||
if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
|
||||
if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER) {
|
||||
pass = 1;
|
||||
fail = 2;
|
||||
} else {
|
||||
|
|
@ -130,97 +132,97 @@ GLboolean r500_transform_TEX(
|
|||
fail = 1;
|
||||
}
|
||||
|
||||
inst_cmp->I.SrcReg[pass].File = PROGRAM_BUILTIN;
|
||||
inst_cmp->I.SrcReg[pass].Swizzle = SWIZZLE_1111;
|
||||
inst_cmp->I.SrcReg[pass].File = RC_FILE_NONE;
|
||||
inst_cmp->I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
|
||||
inst_cmp->I.SrcReg[fail] = shadow_ambient(c, inst->I.TexSrcUnit);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cannot write texture to output registers */
|
||||
if (inst->I.Opcode != OPCODE_KIL && inst->I.DstReg.File != PROGRAM_TEMPORARY) {
|
||||
if (inst->I.Opcode != RC_OPCODE_KIL && inst->I.DstReg.File != RC_FILE_TEMPORARY) {
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
|
||||
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg = inst->I.DstReg;
|
||||
inst_mov->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.SrcReg[0].Index = rc_find_free_temporary(c);
|
||||
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
/* Cannot read texture coordinate from constants file */
|
||||
if (inst->I.SrcReg[0].File != PROGRAM_TEMPORARY && inst->I.SrcReg[0].File != PROGRAM_INPUT) {
|
||||
if (inst->I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->I.SrcReg[0].File != RC_FILE_INPUT) {
|
||||
struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
|
||||
|
||||
inst_mov->I.Opcode = OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->I.Opcode = RC_OPCODE_MOV;
|
||||
inst_mov->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mov->I.DstReg.Index = rc_find_free_temporary(c);
|
||||
inst_mov->I.SrcReg[0] = inst->I.SrcReg[0];
|
||||
|
||||
reset_srcreg(&inst->I.SrcReg[0]);
|
||||
inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[0].Index = inst_mov->I.DstReg.Index;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
|
||||
int r500FPIsNativeSwizzle(rc_opcode opcode, struct rc_src_register reg)
|
||||
{
|
||||
GLuint relevant;
|
||||
unsigned int relevant;
|
||||
int i;
|
||||
|
||||
if (opcode == OPCODE_TEX ||
|
||||
opcode == OPCODE_TXB ||
|
||||
opcode == OPCODE_TXP ||
|
||||
opcode == OPCODE_KIL) {
|
||||
if (opcode == RC_OPCODE_TEX ||
|
||||
opcode == RC_OPCODE_TXB ||
|
||||
opcode == RC_OPCODE_TXP ||
|
||||
opcode == RC_OPCODE_KIL) {
|
||||
if (reg.Abs)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
if (opcode == OPCODE_KIL && (reg.Swizzle != SWIZZLE_NOOP || reg.Negate != NEGATE_NONE))
|
||||
return GL_FALSE;
|
||||
if (opcode == RC_OPCODE_KIL && (reg.Swizzle != RC_SWIZZLE_XYZW || reg.Negate != RC_MASK_NONE))
|
||||
return 0;
|
||||
|
||||
if (reg.Negate)
|
||||
reg.Negate ^= NEGATE_XYZW;
|
||||
reg.Negate ^= RC_MASK_XYZW;
|
||||
|
||||
for(i = 0; i < 4; ++i) {
|
||||
GLuint swz = GET_SWZ(reg.Swizzle, i);
|
||||
if (swz == SWIZZLE_NIL) {
|
||||
unsigned int swz = GET_SWZ(reg.Swizzle, i);
|
||||
if (swz == RC_SWIZZLE_UNUSED) {
|
||||
reg.Negate &= ~(1 << i);
|
||||
continue;
|
||||
}
|
||||
if (swz >= 4)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reg.Negate)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
return GL_TRUE;
|
||||
} else if (opcode == OPCODE_DDX || opcode == OPCODE_DDY) {
|
||||
return 1;
|
||||
} else if (opcode == RC_OPCODE_DDX || opcode == RC_OPCODE_DDY) {
|
||||
/* DDX/MDH and DDY/MDV explicitly ignore incoming swizzles;
|
||||
* if it doesn't fit perfectly into a .xyzw case... */
|
||||
if (reg.Swizzle == SWIZZLE_NOOP && !reg.Abs && !reg.Negate)
|
||||
return GL_TRUE;
|
||||
if (reg.Swizzle == RC_SWIZZLE_XYZW && !reg.Abs && !reg.Negate)
|
||||
return 1;
|
||||
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
} else {
|
||||
/* ALU instructions support almost everything */
|
||||
if (reg.Abs)
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
|
||||
relevant = 0;
|
||||
for(i = 0; i < 3; ++i) {
|
||||
GLuint swz = GET_SWZ(reg.Swizzle, i);
|
||||
if (swz != SWIZZLE_NIL && swz != SWIZZLE_ZERO)
|
||||
unsigned int swz = GET_SWZ(reg.Swizzle, i);
|
||||
if (swz != RC_SWIZZLE_UNUSED && swz != RC_SWIZZLE_ZERO)
|
||||
relevant |= 1 << i;
|
||||
}
|
||||
if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant))
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,14 +232,14 @@ GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
|
|||
* The only thing we *cannot* do in an ALU instruction is per-component
|
||||
* negation. Therefore, we split the MOV into two instructions when necessary.
|
||||
*/
|
||||
void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src)
|
||||
void r500FPBuildSwizzle(struct nqssadce_state *s, struct rc_dst_register dst, struct rc_src_register src)
|
||||
{
|
||||
GLuint negatebase[2] = { 0, 0 };
|
||||
unsigned int negatebase[2] = { 0, 0 };
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 4; ++i) {
|
||||
GLuint swz = GET_SWZ(src.Swizzle, i);
|
||||
if (swz == SWIZZLE_NIL)
|
||||
unsigned int swz = GET_SWZ(src.Swizzle, i);
|
||||
if (swz == RC_SWIZZLE_UNUSED)
|
||||
continue;
|
||||
negatebase[GET_BIT(src.Negate, i)] |= 1 << i;
|
||||
}
|
||||
|
|
@ -247,11 +249,11 @@ void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
|
|||
continue;
|
||||
|
||||
struct rc_instruction *inst = rc_insert_new_instruction(s->Compiler, s->IP->Prev);
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
inst->I.DstReg = dst;
|
||||
inst->I.DstReg.WriteMask = negatebase[i];
|
||||
inst->I.SrcReg[0] = src;
|
||||
inst->I.SrcReg[0].Negate = (i == 0) ? NEGATE_NONE : NEGATE_XYZW;
|
||||
inst->I.SrcReg[0].Negate = (i == 0) ? RC_MASK_NONE : RC_MASK_XYZW;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@
|
|||
#ifndef __R500_FRAGPROG_H_
|
||||
#define __R500_FRAGPROG_H_
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "radeon_compiler.h"
|
||||
#include "radeon_nqssadce.h"
|
||||
|
||||
|
|
@ -43,11 +40,11 @@ extern void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler
|
|||
|
||||
extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);
|
||||
|
||||
extern GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg);
|
||||
extern int r500FPIsNativeSwizzle(rc_opcode opcode, struct rc_src_register reg);
|
||||
|
||||
extern void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src);
|
||||
extern void r500FPBuildSwizzle(struct nqssadce_state *s, struct rc_dst_register dst, struct rc_src_register src);
|
||||
|
||||
extern GLboolean r500_transform_TEX(
|
||||
extern int r500_transform_TEX(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void* data);
|
||||
|
|
|
|||
|
|
@ -60,63 +60,63 @@
|
|||
} while(0)
|
||||
|
||||
|
||||
static GLuint translate_rgb_op(struct r300_fragment_program_compiler *c, GLuint opcode)
|
||||
static unsigned int translate_rgb_op(struct r300_fragment_program_compiler *c, rc_opcode opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case OPCODE_CMP: return R500_ALU_RGBA_OP_CMP;
|
||||
case OPCODE_DDX: return R500_ALU_RGBA_OP_MDH;
|
||||
case OPCODE_DDY: return R500_ALU_RGBA_OP_MDV;
|
||||
case OPCODE_DP3: return R500_ALU_RGBA_OP_DP3;
|
||||
case OPCODE_DP4: return R500_ALU_RGBA_OP_DP4;
|
||||
case OPCODE_FRC: return R500_ALU_RGBA_OP_FRC;
|
||||
case RC_OPCODE_CMP: return R500_ALU_RGBA_OP_CMP;
|
||||
case RC_OPCODE_DDX: return R500_ALU_RGBA_OP_MDH;
|
||||
case RC_OPCODE_DDY: return R500_ALU_RGBA_OP_MDV;
|
||||
case RC_OPCODE_DP3: return R500_ALU_RGBA_OP_DP3;
|
||||
case RC_OPCODE_DP4: return R500_ALU_RGBA_OP_DP4;
|
||||
case RC_OPCODE_FRC: return R500_ALU_RGBA_OP_FRC;
|
||||
default:
|
||||
error("translate_rgb_op(%d): unknown opcode\n", opcode);
|
||||
/* fall through */
|
||||
case OPCODE_NOP:
|
||||
case RC_OPCODE_NOP:
|
||||
/* fall through */
|
||||
case OPCODE_MAD: return R500_ALU_RGBA_OP_MAD;
|
||||
case OPCODE_MAX: return R500_ALU_RGBA_OP_MAX;
|
||||
case OPCODE_MIN: return R500_ALU_RGBA_OP_MIN;
|
||||
case OPCODE_REPL_ALPHA: return R500_ALU_RGBA_OP_SOP;
|
||||
case RC_OPCODE_MAD: return R500_ALU_RGBA_OP_MAD;
|
||||
case RC_OPCODE_MAX: return R500_ALU_RGBA_OP_MAX;
|
||||
case RC_OPCODE_MIN: return R500_ALU_RGBA_OP_MIN;
|
||||
case RC_OPCODE_REPL_ALPHA: return R500_ALU_RGBA_OP_SOP;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint translate_alpha_op(struct r300_fragment_program_compiler *c, GLuint opcode)
|
||||
static unsigned int translate_alpha_op(struct r300_fragment_program_compiler *c, rc_opcode opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case OPCODE_CMP: return R500_ALPHA_OP_CMP;
|
||||
case OPCODE_COS: return R500_ALPHA_OP_COS;
|
||||
case OPCODE_DDX: return R500_ALPHA_OP_MDH;
|
||||
case OPCODE_DDY: return R500_ALPHA_OP_MDV;
|
||||
case OPCODE_DP3: return R500_ALPHA_OP_DP;
|
||||
case OPCODE_DP4: return R500_ALPHA_OP_DP;
|
||||
case OPCODE_EX2: return R500_ALPHA_OP_EX2;
|
||||
case OPCODE_FRC: return R500_ALPHA_OP_FRC;
|
||||
case OPCODE_LG2: return R500_ALPHA_OP_LN2;
|
||||
case RC_OPCODE_CMP: return R500_ALPHA_OP_CMP;
|
||||
case RC_OPCODE_COS: return R500_ALPHA_OP_COS;
|
||||
case RC_OPCODE_DDX: return R500_ALPHA_OP_MDH;
|
||||
case RC_OPCODE_DDY: return R500_ALPHA_OP_MDV;
|
||||
case RC_OPCODE_DP3: return R500_ALPHA_OP_DP;
|
||||
case RC_OPCODE_DP4: return R500_ALPHA_OP_DP;
|
||||
case RC_OPCODE_EX2: return R500_ALPHA_OP_EX2;
|
||||
case RC_OPCODE_FRC: return R500_ALPHA_OP_FRC;
|
||||
case RC_OPCODE_LG2: return R500_ALPHA_OP_LN2;
|
||||
default:
|
||||
error("translate_alpha_op(%d): unknown opcode\n", opcode);
|
||||
/* fall through */
|
||||
case OPCODE_NOP:
|
||||
case RC_OPCODE_NOP:
|
||||
/* fall through */
|
||||
case OPCODE_MAD: return R500_ALPHA_OP_MAD;
|
||||
case OPCODE_MAX: return R500_ALPHA_OP_MAX;
|
||||
case OPCODE_MIN: return R500_ALPHA_OP_MIN;
|
||||
case OPCODE_RCP: return R500_ALPHA_OP_RCP;
|
||||
case OPCODE_RSQ: return R500_ALPHA_OP_RSQ;
|
||||
case OPCODE_SIN: return R500_ALPHA_OP_SIN;
|
||||
case RC_OPCODE_MAD: return R500_ALPHA_OP_MAD;
|
||||
case RC_OPCODE_MAX: return R500_ALPHA_OP_MAX;
|
||||
case RC_OPCODE_MIN: return R500_ALPHA_OP_MIN;
|
||||
case RC_OPCODE_RCP: return R500_ALPHA_OP_RCP;
|
||||
case RC_OPCODE_RSQ: return R500_ALPHA_OP_RSQ;
|
||||
case RC_OPCODE_SIN: return R500_ALPHA_OP_SIN;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint fix_hw_swizzle(GLuint swz)
|
||||
static unsigned int fix_hw_swizzle(unsigned int swz)
|
||||
{
|
||||
if (swz == 5) swz = 6;
|
||||
if (swz == SWIZZLE_NIL) swz = 4;
|
||||
if (swz == RC_SWIZZLE_UNUSED) swz = 4;
|
||||
return swz;
|
||||
}
|
||||
|
||||
static GLuint translate_arg_rgb(struct radeon_pair_instruction *inst, int arg)
|
||||
static unsigned int translate_arg_rgb(struct radeon_pair_instruction *inst, int arg)
|
||||
{
|
||||
GLuint t = inst->RGB.Arg[arg].Source;
|
||||
unsigned int t = inst->RGB.Arg[arg].Source;
|
||||
int comp;
|
||||
t |= inst->RGB.Arg[arg].Negate << 11;
|
||||
t |= inst->RGB.Arg[arg].Abs << 12;
|
||||
|
|
@ -127,22 +127,22 @@ static GLuint translate_arg_rgb(struct radeon_pair_instruction *inst, int arg)
|
|||
return t;
|
||||
}
|
||||
|
||||
static GLuint translate_arg_alpha(struct radeon_pair_instruction *inst, int i)
|
||||
static unsigned int translate_arg_alpha(struct radeon_pair_instruction *inst, int i)
|
||||
{
|
||||
GLuint t = inst->Alpha.Arg[i].Source;
|
||||
unsigned int t = inst->Alpha.Arg[i].Source;
|
||||
t |= fix_hw_swizzle(inst->Alpha.Arg[i].Swizzle) << 2;
|
||||
t |= inst->Alpha.Arg[i].Negate << 5;
|
||||
t |= inst->Alpha.Arg[i].Abs << 6;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void use_temporary(struct r500_fragment_program_code* code, GLuint index)
|
||||
static void use_temporary(struct r500_fragment_program_code* code, unsigned int index)
|
||||
{
|
||||
if (index > code->max_temp_idx)
|
||||
code->max_temp_idx = index;
|
||||
}
|
||||
|
||||
static GLuint use_source(struct r500_fragment_program_code* code, struct radeon_pair_instruction_source src)
|
||||
static unsigned int use_source(struct r500_fragment_program_code* code, struct radeon_pair_instruction_source src)
|
||||
{
|
||||
if (!src.Constant)
|
||||
use_temporary(code, src.Index);
|
||||
|
|
@ -153,13 +153,13 @@ static GLuint use_source(struct r500_fragment_program_code* code, struct radeon_
|
|||
/**
|
||||
* Emit a paired ALU instruction.
|
||||
*/
|
||||
static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
|
||||
static int emit_paired(void *data, struct radeon_pair_instruction *inst)
|
||||
{
|
||||
PROG_CODE;
|
||||
|
||||
if (code->inst_end >= 511) {
|
||||
error("emit_alu: Too many instructions");
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ip = ++code->inst_end;
|
||||
|
|
@ -177,7 +177,7 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
|
|||
code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18);
|
||||
if (inst->Alpha.DepthWriteMask) {
|
||||
code->inst[ip].inst4 |= R500_ALPHA_W_OMASK;
|
||||
c->code->writes_depth = GL_TRUE;
|
||||
c->code->writes_depth = 1;
|
||||
}
|
||||
|
||||
code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex);
|
||||
|
|
@ -206,12 +206,12 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
|
|||
code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT;
|
||||
code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GLuint translate_strq_swizzle(GLuint swizzle)
|
||||
static unsigned int translate_strq_swizzle(unsigned int swizzle)
|
||||
{
|
||||
GLuint swiz = 0;
|
||||
unsigned int swiz = 0;
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
swiz |= (GET_SWZ(swizzle, i) & 0x3) << i*2;
|
||||
|
|
@ -221,13 +221,13 @@ static GLuint translate_strq_swizzle(GLuint swizzle)
|
|||
/**
|
||||
* Emit a single TEX instruction
|
||||
*/
|
||||
static GLboolean emit_tex(void *data, struct radeon_pair_texture_instruction *inst)
|
||||
static int emit_tex(void *data, struct radeon_pair_texture_instruction *inst)
|
||||
{
|
||||
PROG_CODE;
|
||||
|
||||
if (code->inst_end >= 511) {
|
||||
error("emit_tex: Too many instructions");
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ip = ++code->inst_end;
|
||||
|
|
@ -238,7 +238,7 @@ static GLboolean emit_tex(void *data, struct radeon_pair_texture_instruction *in
|
|||
code->inst[ip].inst1 = R500_TEX_ID(inst->TexSrcUnit)
|
||||
| R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED;
|
||||
|
||||
if (inst->TexSrcTarget == TEXTURE_RECT_INDEX)
|
||||
if (inst->TexSrcTarget == RC_TEXTURE_RECT)
|
||||
code->inst[ip].inst1 |= R500_TEX_UNSCALED;
|
||||
|
||||
switch (inst->Opcode) {
|
||||
|
|
@ -264,7 +264,7 @@ static GLboolean emit_tex(void *data, struct radeon_pair_texture_instruction *in
|
|||
| R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G
|
||||
| R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct radeon_pair_handler pair_handler = {
|
||||
|
|
@ -277,7 +277,7 @@ void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
|
|||
{
|
||||
struct r500_fragment_program_code *code = &compiler->code->code.r500;
|
||||
|
||||
_mesa_bzero(code, sizeof(*code));
|
||||
memset(code, 0, sizeof(*code));
|
||||
code->max_temp_idx = 1;
|
||||
code->inst_end = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "main/mtypes.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "radeon_code.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "radeon_program.h"
|
||||
|
||||
void rc_constants_init(struct rc_constant_list * c)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
|
|
@ -143,7 +145,7 @@ unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float da
|
|||
if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
|
||||
for(unsigned comp = 0; comp < c->Constants[index].Size; ++comp) {
|
||||
if (c->Constants[index].u.Immediate[comp] == data) {
|
||||
*swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
|
||||
*swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +158,7 @@ unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float da
|
|||
if (free_index >= 0) {
|
||||
unsigned comp = c->Constants[free_index].Size++;
|
||||
c->Constants[free_index].u.Immediate[comp] = data;
|
||||
*swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
|
||||
*swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp);
|
||||
return free_index;
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +166,7 @@ unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float da
|
|||
constant.Type = RC_CONSTANT_IMMEDIATE;
|
||||
constant.Size = 1;
|
||||
constant.u.Immediate[0] = data;
|
||||
*swizzle = SWIZZLE_XXXX;
|
||||
*swizzle = RC_SWIZZLE_XXXX;
|
||||
|
||||
return rc_constants_add(c, &constant);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,23 @@ unsigned rc_constants_add_state(struct rc_constant_list * c, unsigned state1, un
|
|||
unsigned rc_constants_add_immediate_vec4(struct rc_constant_list * c, const float * data);
|
||||
unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle);
|
||||
|
||||
/**
|
||||
* Compare functions.
|
||||
*
|
||||
* \note By design, RC_COMPARE_FUNC_xxx + GL_NEVER gives you
|
||||
* the correct GL compare function.
|
||||
*/
|
||||
typedef enum {
|
||||
RC_COMPARE_FUNC_NEVER = 0,
|
||||
RC_COMPARE_FUNC_LESS,
|
||||
RC_COMPARE_FUNC_EQUAL,
|
||||
RC_COMPARE_FUNC_LEQUAL,
|
||||
RC_COMPARE_FUNC_GREATER,
|
||||
RC_COMPARE_FUNC_NOTEQUAL,
|
||||
RC_COMPARE_FUNC_GEQUAL,
|
||||
RC_COMPARE_FUNC_ALWAYS
|
||||
} rc_compare_func;
|
||||
|
||||
/**
|
||||
* Stores state that influences the compilation of a fragment program.
|
||||
*/
|
||||
|
|
@ -105,10 +122,12 @@ struct r300_fragment_program_external_state {
|
|||
|
||||
/**
|
||||
* If the sampler is used as a shadow sampler,
|
||||
* this field is (texture_compare_func - GL_NEVER).
|
||||
* [e.g. if compare function is GL_LEQUAL, this field is 3]
|
||||
* this field specifies the compare function.
|
||||
*
|
||||
* Otherwise, this field is \ref RC_COMPARE_FUNC_NEVER (aka 0).
|
||||
*
|
||||
* Otherwise, this field is 0.
|
||||
* \sa rc_compare_func
|
||||
*/
|
||||
unsigned texture_compare_func : 3;
|
||||
} unit[16];
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "radeon_compiler.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "radeon_program.h"
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ void rc_init(struct radeon_compiler * c)
|
|||
memory_pool_init(&c->Pool);
|
||||
c->Program.Instructions.Prev = &c->Program.Instructions;
|
||||
c->Program.Instructions.Next = &c->Program.Instructions;
|
||||
c->Program.Instructions.I.Opcode = OPCODE_END;
|
||||
c->Program.Instructions.I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
|
||||
}
|
||||
|
||||
void rc_destroy(struct radeon_compiler * c)
|
||||
|
|
@ -60,7 +62,7 @@ void rc_error(struct radeon_compiler * c, const char * fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
|
||||
c->Error = GL_TRUE;
|
||||
c->Error = 1;
|
||||
|
||||
if (!c->ErrorMsg) {
|
||||
/* Only remember the first error */
|
||||
|
|
@ -95,18 +97,18 @@ void rc_error(struct radeon_compiler * c, const char * fmt, ...)
|
|||
* Rewrite the program such that everything that source the given input
|
||||
* register will source new_input instead.
|
||||
*/
|
||||
void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_register new_input)
|
||||
void rc_move_input(struct radeon_compiler * c, unsigned input, struct rc_src_register new_input)
|
||||
{
|
||||
struct rc_instruction * inst;
|
||||
|
||||
c->Program.InputsRead &= ~(1 << input);
|
||||
|
||||
for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
|
||||
const unsigned numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
unsigned i;
|
||||
|
||||
for(i = 0; i < numsrcs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_INPUT && inst->I.SrcReg[i].Index == input) {
|
||||
for(i = 0; i < opcode->NumSrcRegs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_INPUT && inst->I.SrcReg[i].Index == input) {
|
||||
inst->I.SrcReg[i].File = new_input.File;
|
||||
inst->I.SrcReg[i].Index = new_input.Index;
|
||||
inst->I.SrcReg[i].Swizzle = combine_swizzles(new_input.Swizzle, inst->I.SrcReg[i].Swizzle);
|
||||
|
|
@ -134,10 +136,10 @@ void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_ou
|
|||
c->Program.OutputsWritten &= ~(1 << output);
|
||||
|
||||
for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
|
||||
const unsigned numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
if (numdsts) {
|
||||
if (inst->I.DstReg.File == PROGRAM_OUTPUT && inst->I.DstReg.Index == output) {
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->I.DstReg.File == RC_FILE_OUTPUT && inst->I.DstReg.Index == output) {
|
||||
inst->I.DstReg.Index = new_output;
|
||||
inst->I.DstReg.WriteMask &= writemask;
|
||||
|
||||
|
|
@ -157,33 +159,33 @@ void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_ou
|
|||
struct rc_instruction * inst;
|
||||
|
||||
for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
|
||||
const unsigned numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
|
||||
if (numdsts) {
|
||||
if (inst->I.DstReg.File == PROGRAM_OUTPUT && inst->I.DstReg.Index == output) {
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->I.DstReg.File == RC_FILE_OUTPUT && inst->I.DstReg.Index == output) {
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = tempreg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.DstReg.File = PROGRAM_OUTPUT;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
inst->I.DstReg.File = RC_FILE_OUTPUT;
|
||||
inst->I.DstReg.Index = output;
|
||||
|
||||
inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[0].Index = tempreg;
|
||||
inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
|
||||
|
||||
inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.DstReg.File = PROGRAM_OUTPUT;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
inst->I.DstReg.File = RC_FILE_OUTPUT;
|
||||
inst->I.DstReg.Index = dup_output;
|
||||
|
||||
inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[0].Index = tempreg;
|
||||
inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
|
||||
|
||||
c->Program.OutputsWritten |= 1 << dup_output;
|
||||
}
|
||||
|
|
@ -201,59 +203,59 @@ void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsig
|
|||
|
||||
/* perspective divide */
|
||||
struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
|
||||
inst_rcp->I.Opcode = OPCODE_RCP;
|
||||
inst_rcp->I.Opcode = RC_OPCODE_RCP;
|
||||
|
||||
inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_rcp->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_rcp->I.DstReg.Index = tempregi;
|
||||
inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
|
||||
inst_rcp->I.DstReg.WriteMask = RC_MASK_W;
|
||||
|
||||
inst_rcp->I.SrcReg[0].File = PROGRAM_INPUT;
|
||||
inst_rcp->I.SrcReg[0].File = RC_FILE_INPUT;
|
||||
inst_rcp->I.SrcReg[0].Index = new_input;
|
||||
inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
|
||||
inst_rcp->I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst_rcp);
|
||||
inst_mul->I.Opcode = OPCODE_MUL;
|
||||
inst_mul->I.Opcode = RC_OPCODE_MUL;
|
||||
|
||||
inst_mul->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mul->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mul->I.DstReg.Index = tempregi;
|
||||
inst_mul->I.DstReg.WriteMask = WRITEMASK_XYZ;
|
||||
inst_mul->I.DstReg.WriteMask = RC_MASK_XYZ;
|
||||
|
||||
inst_mul->I.SrcReg[0].File = PROGRAM_INPUT;
|
||||
inst_mul->I.SrcReg[0].File = RC_FILE_INPUT;
|
||||
inst_mul->I.SrcReg[0].Index = new_input;
|
||||
|
||||
inst_mul->I.SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
inst_mul->I.SrcReg[1].File = RC_FILE_TEMPORARY;
|
||||
inst_mul->I.SrcReg[1].Index = tempregi;
|
||||
inst_mul->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
|
||||
inst_mul->I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
/* viewport transformation */
|
||||
struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_mul);
|
||||
inst_mad->I.Opcode = OPCODE_MAD;
|
||||
inst_mad->I.Opcode = RC_OPCODE_MAD;
|
||||
|
||||
inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.DstReg.Index = tempregi;
|
||||
inst_mad->I.DstReg.WriteMask = WRITEMASK_XYZ;
|
||||
inst_mad->I.DstReg.WriteMask = RC_MASK_XYZ;
|
||||
|
||||
inst_mad->I.SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst_mad->I.SrcReg[0].File = RC_FILE_TEMPORARY;
|
||||
inst_mad->I.SrcReg[0].Index = tempregi;
|
||||
inst_mad->I.SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
inst_mad->I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
|
||||
|
||||
inst_mad->I.SrcReg[1].File = PROGRAM_STATE_VAR;
|
||||
inst_mad->I.SrcReg[1].File = RC_FILE_CONSTANT;
|
||||
inst_mad->I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
|
||||
inst_mad->I.SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
inst_mad->I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
|
||||
|
||||
inst_mad->I.SrcReg[2].File = PROGRAM_STATE_VAR;
|
||||
inst_mad->I.SrcReg[2].File = RC_FILE_CONSTANT;
|
||||
inst_mad->I.SrcReg[2].Index = inst_mad->I.SrcReg[1].Index;
|
||||
inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
inst_mad->I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
|
||||
|
||||
struct rc_instruction * inst;
|
||||
for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) {
|
||||
const unsigned numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
unsigned i;
|
||||
|
||||
for(i = 0; i < numsrcs; i++) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_INPUT &&
|
||||
for(i = 0; i < opcode->NumSrcRegs; i++) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_INPUT &&
|
||||
inst->I.SrcReg[i].Index == wpos) {
|
||||
inst->I.SrcReg[i].File = PROGRAM_TEMPORARY;
|
||||
inst->I.SrcReg[i].File = RC_FILE_TEMPORARY;
|
||||
inst->I.SrcReg[i].Index = tempregi;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,36 +23,11 @@
|
|||
#ifndef RADEON_COMPILER_H
|
||||
#define RADEON_COMPILER_H
|
||||
|
||||
#include "main/mtypes.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
|
||||
#include "memory_pool.h"
|
||||
#include "radeon_code.h"
|
||||
#include "radeon_program.h"
|
||||
|
||||
|
||||
struct rc_instruction {
|
||||
struct rc_instruction * Prev;
|
||||
struct rc_instruction * Next;
|
||||
struct prog_instruction I;
|
||||
};
|
||||
|
||||
struct rc_program {
|
||||
/**
|
||||
* Instructions.Next points to the first instruction,
|
||||
* Instructions.Prev points to the last instruction.
|
||||
*/
|
||||
struct rc_instruction Instructions;
|
||||
|
||||
/* Long term, we should probably remove InputsRead & OutputsWritten,
|
||||
* since updating dependent state can be fragile, and they aren't
|
||||
* actually used very often. */
|
||||
uint32_t InputsRead;
|
||||
uint32_t OutputsWritten;
|
||||
uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */
|
||||
|
||||
struct rc_constant_list Constants;
|
||||
};
|
||||
|
||||
struct radeon_compiler {
|
||||
struct memory_pool Pool;
|
||||
struct rc_program Program;
|
||||
|
|
@ -69,7 +44,7 @@ void rc_error(struct radeon_compiler * c, const char * fmt, ...);
|
|||
|
||||
void rc_calculate_inputs_outputs(struct radeon_compiler * c);
|
||||
|
||||
void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_register new_input);
|
||||
void rc_move_input(struct radeon_compiler * c, unsigned input, struct rc_src_register new_input);
|
||||
void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask);
|
||||
void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output);
|
||||
void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input);
|
||||
|
|
@ -95,7 +70,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c);
|
|||
struct r300_vertex_program_compiler {
|
||||
struct radeon_compiler Base;
|
||||
struct r300_vertex_program_code *code;
|
||||
GLbitfield RequiredOutputs;
|
||||
uint32_t RequiredOutputs;
|
||||
|
||||
void * UserData;
|
||||
void (*SetHwInputOutput)(struct r300_vertex_program_compiler * c);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@
|
|||
* @file
|
||||
*
|
||||
* "Not-quite SSA" and Dead-Code Elimination.
|
||||
*
|
||||
* @note This code uses SWIZZLE_NIL in a source register to indicate that
|
||||
* the corresponding component is ignored by the corresponding instruction.
|
||||
*/
|
||||
|
||||
#include "radeon_nqssadce.h"
|
||||
|
|
@ -43,76 +40,55 @@
|
|||
* Return the @ref register_state for the given register (or 0 for untracked
|
||||
* registers, i.e. constants).
|
||||
*/
|
||||
static struct register_state *get_reg_state(struct nqssadce_state* s, GLuint file, GLuint index)
|
||||
static struct register_state *get_reg_state(struct nqssadce_state* s, rc_register_file file, unsigned int index)
|
||||
{
|
||||
if (index >= RC_REGISTER_MAX_INDEX)
|
||||
return 0;
|
||||
|
||||
switch(file) {
|
||||
case PROGRAM_TEMPORARY: return &s->Temps[index];
|
||||
case PROGRAM_OUTPUT: return &s->Outputs[index];
|
||||
case PROGRAM_ADDRESS: return &s->Address;
|
||||
case RC_FILE_TEMPORARY: return &s->Temps[index];
|
||||
case RC_FILE_OUTPUT: return &s->Outputs[index];
|
||||
case RC_FILE_ADDRESS: return &s->Address;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Left multiplication of a register with a swizzle
|
||||
*
|
||||
* @note Works correctly only for X, Y, Z, W swizzles, not for constant swizzles.
|
||||
*/
|
||||
struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg)
|
||||
{
|
||||
struct prog_src_register tmp = srcreg;
|
||||
int i;
|
||||
tmp.Swizzle = 0;
|
||||
tmp.Negate = NEGATE_NONE;
|
||||
for(i = 0; i < 4; ++i) {
|
||||
GLuint swz = GET_SWZ(swizzle, i);
|
||||
if (swz < 4) {
|
||||
tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
|
||||
tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
|
||||
} else {
|
||||
tmp.Swizzle |= swz << (i*3);
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
static void track_used_srcreg(struct nqssadce_state* s,
|
||||
GLint src, GLuint sourced)
|
||||
int src, unsigned int sourced)
|
||||
{
|
||||
struct prog_instruction * inst = &s->IP->I;
|
||||
struct rc_sub_instruction * inst = &s->IP->I;
|
||||
int i;
|
||||
GLuint deswz_source = 0;
|
||||
unsigned int deswz_source = 0;
|
||||
|
||||
for(i = 0; i < 4; ++i) {
|
||||
if (GET_BIT(sourced, i)) {
|
||||
GLuint swz = GET_SWZ(inst->SrcReg[src].Swizzle, i);
|
||||
unsigned int swz = GET_SWZ(inst->SrcReg[src].Swizzle, i);
|
||||
deswz_source |= 1 << swz;
|
||||
} else {
|
||||
inst->SrcReg[src].Swizzle &= ~(7 << (3*i));
|
||||
inst->SrcReg[src].Swizzle |= SWIZZLE_NIL << (3*i);
|
||||
inst->SrcReg[src].Swizzle |= RC_SWIZZLE_UNUSED << (3*i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!s->Descr->IsNativeSwizzle(inst->Opcode, inst->SrcReg[src])) {
|
||||
struct prog_dst_register dstreg = inst->DstReg;
|
||||
dstreg.File = PROGRAM_TEMPORARY;
|
||||
struct rc_dst_register dstreg = inst->DstReg;
|
||||
dstreg.File = RC_FILE_TEMPORARY;
|
||||
dstreg.Index = rc_find_free_temporary(s->Compiler);
|
||||
dstreg.WriteMask = sourced;
|
||||
|
||||
s->Descr->BuildSwizzle(s, dstreg, inst->SrcReg[src]);
|
||||
|
||||
inst->SrcReg[src].File = PROGRAM_TEMPORARY;
|
||||
inst->SrcReg[src].File = RC_FILE_TEMPORARY;
|
||||
inst->SrcReg[src].Index = dstreg.Index;
|
||||
inst->SrcReg[src].Swizzle = 0;
|
||||
inst->SrcReg[src].Negate = NEGATE_NONE;
|
||||
inst->SrcReg[src].Negate = RC_MASK_NONE;
|
||||
inst->SrcReg[src].Abs = 0;
|
||||
for(i = 0; i < 4; ++i) {
|
||||
if (GET_BIT(sourced, i))
|
||||
inst->SrcReg[src].Swizzle |= i << (3*i);
|
||||
else
|
||||
inst->SrcReg[src].Swizzle |= SWIZZLE_NIL << (3*i);
|
||||
inst->SrcReg[src].Swizzle |= RC_SWIZZLE_UNUSED << (3*i);
|
||||
}
|
||||
deswz_source = sourced;
|
||||
}
|
||||
|
|
@ -120,9 +96,9 @@ static void track_used_srcreg(struct nqssadce_state* s,
|
|||
struct register_state *regstate;
|
||||
|
||||
if (inst->SrcReg[src].RelAddr) {
|
||||
regstate = get_reg_state(s, PROGRAM_ADDRESS, 0);
|
||||
regstate = get_reg_state(s, RC_FILE_ADDRESS, 0);
|
||||
if (regstate)
|
||||
regstate->Sourced |= WRITEMASK_X;
|
||||
regstate->Sourced |= RC_MASK_X;
|
||||
} else {
|
||||
regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index);
|
||||
if (regstate)
|
||||
|
|
@ -130,21 +106,21 @@ static void track_used_srcreg(struct nqssadce_state* s,
|
|||
}
|
||||
}
|
||||
|
||||
static void unalias_srcregs(struct rc_instruction *inst, GLuint oldindex, GLuint newindex)
|
||||
static void unalias_srcregs(struct rc_instruction *inst, unsigned int oldindex, unsigned int newindex)
|
||||
{
|
||||
int nsrc = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
int i;
|
||||
for(i = 0; i < nsrc; ++i)
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY && inst->I.SrcReg[i].Index == oldindex)
|
||||
for(i = 0; i < opcode->NumSrcRegs; ++i)
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_TEMPORARY && inst->I.SrcReg[i].Index == oldindex)
|
||||
inst->I.SrcReg[i].Index = newindex;
|
||||
}
|
||||
|
||||
static void unalias_temporary(struct nqssadce_state* s, GLuint oldindex)
|
||||
static void unalias_temporary(struct nqssadce_state* s, unsigned int oldindex)
|
||||
{
|
||||
GLuint newindex = rc_find_free_temporary(s->Compiler);
|
||||
unsigned int newindex = rc_find_free_temporary(s->Compiler);
|
||||
struct rc_instruction * inst;
|
||||
for(inst = s->Compiler->Program.Instructions.Next; inst != s->IP; inst = inst->Next) {
|
||||
if (inst->I.DstReg.File == PROGRAM_TEMPORARY && inst->I.DstReg.Index == oldindex)
|
||||
if (inst->I.DstReg.File == RC_FILE_TEMPORARY && inst->I.DstReg.Index == oldindex)
|
||||
inst->I.DstReg.Index = newindex;
|
||||
unalias_srcregs(inst, oldindex, newindex);
|
||||
}
|
||||
|
|
@ -157,13 +133,10 @@ static void unalias_temporary(struct nqssadce_state* s, GLuint oldindex)
|
|||
*/
|
||||
static void process_instruction(struct nqssadce_state* s)
|
||||
{
|
||||
struct prog_instruction *inst = &s->IP->I;
|
||||
GLuint WriteMask;
|
||||
struct rc_sub_instruction *inst = &s->IP->I;
|
||||
unsigned int WriteMask;
|
||||
|
||||
if (inst->Opcode == OPCODE_END)
|
||||
return;
|
||||
|
||||
if (inst->Opcode != OPCODE_KIL) {
|
||||
if (inst->Opcode != RC_OPCODE_KIL) {
|
||||
struct register_state *regstate = get_reg_state(s, inst->DstReg.File, inst->DstReg.Index);
|
||||
if (!regstate) {
|
||||
rc_error(s->Compiler, "NqssaDce: bad destination register (%i[%i])\n",
|
||||
|
|
@ -181,67 +154,67 @@ static void process_instruction(struct nqssadce_state* s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (inst->DstReg.File == PROGRAM_TEMPORARY && !regstate->Sourced)
|
||||
if (inst->DstReg.File == RC_FILE_TEMPORARY && !regstate->Sourced)
|
||||
unalias_temporary(s, inst->DstReg.Index);
|
||||
}
|
||||
|
||||
WriteMask = inst->DstReg.WriteMask;
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_ARL:
|
||||
case OPCODE_DDX:
|
||||
case OPCODE_DDY:
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MOV:
|
||||
case RC_OPCODE_ARL:
|
||||
case RC_OPCODE_DDX:
|
||||
case RC_OPCODE_DDY:
|
||||
case RC_OPCODE_FRC:
|
||||
case RC_OPCODE_MOV:
|
||||
track_used_srcreg(s, 0, WriteMask);
|
||||
break;
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MUL:
|
||||
case OPCODE_SGE:
|
||||
case OPCODE_SLT:
|
||||
case RC_OPCODE_ADD:
|
||||
case RC_OPCODE_MAX:
|
||||
case RC_OPCODE_MIN:
|
||||
case RC_OPCODE_MUL:
|
||||
case RC_OPCODE_SGE:
|
||||
case RC_OPCODE_SLT:
|
||||
track_used_srcreg(s, 0, WriteMask);
|
||||
track_used_srcreg(s, 1, WriteMask);
|
||||
break;
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_MAD:
|
||||
case RC_OPCODE_CMP:
|
||||
case RC_OPCODE_MAD:
|
||||
track_used_srcreg(s, 0, WriteMask);
|
||||
track_used_srcreg(s, 1, WriteMask);
|
||||
track_used_srcreg(s, 2, WriteMask);
|
||||
break;
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case RC_OPCODE_COS:
|
||||
case RC_OPCODE_EX2:
|
||||
case RC_OPCODE_LG2:
|
||||
case RC_OPCODE_RCP:
|
||||
case RC_OPCODE_RSQ:
|
||||
case RC_OPCODE_SIN:
|
||||
track_used_srcreg(s, 0, 0x1);
|
||||
break;
|
||||
case OPCODE_DP3:
|
||||
case RC_OPCODE_DP3:
|
||||
track_used_srcreg(s, 0, 0x7);
|
||||
track_used_srcreg(s, 1, 0x7);
|
||||
break;
|
||||
case OPCODE_DP4:
|
||||
case RC_OPCODE_DP4:
|
||||
track_used_srcreg(s, 0, 0xf);
|
||||
track_used_srcreg(s, 1, 0xf);
|
||||
break;
|
||||
case OPCODE_KIL:
|
||||
case OPCODE_TEX:
|
||||
case OPCODE_TXB:
|
||||
case OPCODE_TXP:
|
||||
case RC_OPCODE_KIL:
|
||||
case RC_OPCODE_TEX:
|
||||
case RC_OPCODE_TXB:
|
||||
case RC_OPCODE_TXP:
|
||||
track_used_srcreg(s, 0, 0xf);
|
||||
break;
|
||||
case OPCODE_DST:
|
||||
case RC_OPCODE_DST:
|
||||
track_used_srcreg(s, 0, 0x6);
|
||||
track_used_srcreg(s, 1, 0xa);
|
||||
break;
|
||||
case OPCODE_EXP:
|
||||
case OPCODE_LOG:
|
||||
case OPCODE_POW:
|
||||
case RC_OPCODE_EXP:
|
||||
case RC_OPCODE_LOG:
|
||||
case RC_OPCODE_POW:
|
||||
track_used_srcreg(s, 0, 0x3);
|
||||
break;
|
||||
case OPCODE_LIT:
|
||||
case RC_OPCODE_LIT:
|
||||
track_used_srcreg(s, 0, 0xb);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -261,16 +234,16 @@ void rc_calculate_inputs_outputs(struct radeon_compiler * c)
|
|||
|
||||
for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next)
|
||||
{
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
int i;
|
||||
int num_src_regs = _mesa_num_inst_src_regs(inst->I.Opcode);
|
||||
|
||||
for (i = 0; i < num_src_regs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == PROGRAM_INPUT)
|
||||
for (i = 0; i < opcode->NumSrcRegs; ++i) {
|
||||
if (inst->I.SrcReg[i].File == RC_FILE_INPUT)
|
||||
c->Program.InputsRead |= 1 << inst->I.SrcReg[i].Index;
|
||||
}
|
||||
|
||||
if (_mesa_num_inst_dst_regs(inst->I.Opcode)) {
|
||||
if (inst->I.DstReg.File == PROGRAM_OUTPUT)
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->I.DstReg.File == RC_FILE_OUTPUT)
|
||||
c->Program.OutputsWritten |= 1 << inst->I.DstReg.Index;
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +253,7 @@ void radeonNqssaDce(struct radeon_compiler * c, struct radeon_nqssadce_descr* de
|
|||
{
|
||||
struct nqssadce_state s;
|
||||
|
||||
_mesa_bzero(&s, sizeof(s));
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.Compiler = c;
|
||||
s.Descr = descr;
|
||||
s.UserData = data;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ struct register_state {
|
|||
* Bitmask indicating which components of the register are sourced
|
||||
* by later instructions.
|
||||
*/
|
||||
GLuint Sourced : 4;
|
||||
unsigned int Sourced : 4;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -54,8 +54,8 @@ struct nqssadce_state {
|
|||
/**
|
||||
* Which registers are read by subsequent instructions?
|
||||
*/
|
||||
struct register_state Temps[MAX_PROGRAM_TEMPS];
|
||||
struct register_state Outputs[VERT_RESULT_MAX];
|
||||
struct register_state Temps[RC_REGISTER_MAX_INDEX];
|
||||
struct register_state Outputs[RC_REGISTER_MAX_INDEX];
|
||||
struct register_state Address;
|
||||
|
||||
void * UserData;
|
||||
|
|
@ -75,17 +75,18 @@ struct radeon_nqssadce_descr {
|
|||
/**
|
||||
* Check whether the given swizzle, absolute and negate combination
|
||||
* can be implemented natively by the hardware for this opcode.
|
||||
*
|
||||
* \return 1 if the swizzle is native for the given opcode
|
||||
*/
|
||||
GLboolean (*IsNativeSwizzle)(GLuint opcode, struct prog_src_register reg);
|
||||
int (*IsNativeSwizzle)(rc_opcode opcode, struct rc_src_register reg);
|
||||
|
||||
/**
|
||||
* Emit (at the current IP) the instruction MOV dst, src;
|
||||
* The transformation will work recursively on the emitted instruction(s).
|
||||
*/
|
||||
void (*BuildSwizzle)(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src);
|
||||
void (*BuildSwizzle)(struct nqssadce_state*, struct rc_dst_register dst, struct rc_src_register src);
|
||||
};
|
||||
|
||||
void radeonNqssaDce(struct radeon_compiler * c, struct radeon_nqssadce_descr* descr, void * data);
|
||||
struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg);
|
||||
|
||||
#endif /* __RADEON_PROGRAM_NQSSADCE_H_ */
|
||||
|
|
|
|||
318
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
Normal file
318
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Nicolai Haehnle.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "radeon_opcodes.h"
|
||||
|
||||
struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
|
||||
{
|
||||
.Opcode = RC_OPCODE_NOP,
|
||||
.Name = "NOP"
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_ILLEGAL_OPCODE,
|
||||
.Name = "ILLEGAL OPCODE"
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_ABS,
|
||||
.Name = "ABS",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_ADD,
|
||||
.Name = "ADD",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_ARL,
|
||||
.Name = "ARL",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_CMP,
|
||||
.Name = "CMP",
|
||||
.NumSrcRegs = 3,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_COS,
|
||||
.Name = "COS",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DDX,
|
||||
.Name = "DDX",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DDY,
|
||||
.Name = "DDY",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DP3,
|
||||
.Name = "DP3",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DP4,
|
||||
.Name = "DP4",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DPH,
|
||||
.Name = "DPH",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_DST,
|
||||
.Name = "DST",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_EX2,
|
||||
.Name = "EX2",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_EXP,
|
||||
.Name = "EXP",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_FLR,
|
||||
.Name = "FLR",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_FRC,
|
||||
.Name = "FRC",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_KIL,
|
||||
.Name = "KIL",
|
||||
.NumSrcRegs = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_LG2,
|
||||
.Name = "LG2",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_LIT,
|
||||
.Name = "LIT",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_LOG,
|
||||
.Name = "LOG",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_LRP,
|
||||
.Name = "LRP",
|
||||
.NumSrcRegs = 3,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_MAD,
|
||||
.Name = "MAD",
|
||||
.NumSrcRegs = 3,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_MAX,
|
||||
.Name = "MAX",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_MIN,
|
||||
.Name = "MIN",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_MOV,
|
||||
.Name = "MOV",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_MUL,
|
||||
.Name = "MUL",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_POW,
|
||||
.Name = "POW",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_RCP,
|
||||
.Name = "RCP",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_RSQ,
|
||||
.Name = "RSQ",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SCS,
|
||||
.Name = "SCS",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SEQ,
|
||||
.Name = "SEQ",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SFL,
|
||||
.Name = "SFL",
|
||||
.NumSrcRegs = 0,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SGE,
|
||||
.Name = "SGE",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SGT,
|
||||
.Name = "SGT",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SIN,
|
||||
.Name = "SIN",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SLE,
|
||||
.Name = "SLE",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SLT,
|
||||
.Name = "SLT",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SNE,
|
||||
.Name = "SNE",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SUB,
|
||||
.Name = "SUB",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_SWZ,
|
||||
.Name = "SWZ",
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_XPD,
|
||||
.Name = "XPD",
|
||||
.NumSrcRegs = 2,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_TEX,
|
||||
.Name = "TEX",
|
||||
.HasTexture = 1,
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_TXB,
|
||||
.Name = "TXB",
|
||||
.HasTexture = 1,
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_TXD,
|
||||
.Name = "TXD",
|
||||
.HasTexture = 1,
|
||||
.NumSrcRegs = 3,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_TXL,
|
||||
.Name = "TXL",
|
||||
.HasTexture = 1,
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_TXP,
|
||||
.Name = "TXP",
|
||||
.HasTexture = 1,
|
||||
.NumSrcRegs = 1,
|
||||
.HasDstReg = 1
|
||||
},
|
||||
{
|
||||
.Opcode = RC_OPCODE_REPL_ALPHA,
|
||||
.Name = "REPL_ALPHA",
|
||||
.HasDstReg = 1
|
||||
}
|
||||
};
|
||||
202
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
Normal file
202
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Nicolai Haehnle.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RADEON_OPCODES_H
|
||||
#define RADEON_OPCODES_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* Opcodes understood by the Radeon compiler.
|
||||
*/
|
||||
typedef enum {
|
||||
RC_OPCODE_NOP = 0,
|
||||
RC_OPCODE_ILLEGAL_OPCODE,
|
||||
|
||||
/** vec4 instruction: dst.c = abs(src0.c); */
|
||||
RC_OPCODE_ABS,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c + src1.c; */
|
||||
RC_OPCODE_ADD,
|
||||
|
||||
/** special instruction: load address register
|
||||
* dst.x = floor(src.x), where dst must be an address register */
|
||||
RC_OPCODE_ARL,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */
|
||||
RC_OPCODE_CMP,
|
||||
|
||||
/** scalar instruction: dst = cos(src0.x) */
|
||||
RC_OPCODE_COS,
|
||||
|
||||
/** special instruction: take vec4 partial derivative in X direction
|
||||
* dst.c = d src0.c / dx */
|
||||
RC_OPCODE_DDX,
|
||||
|
||||
/** special instruction: take vec4 partial derivative in Y direction
|
||||
* dst.c = d src0.c / dy */
|
||||
RC_OPCODE_DDY,
|
||||
|
||||
/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z */
|
||||
RC_OPCODE_DP3,
|
||||
|
||||
/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z + src0.w*src1.w */
|
||||
RC_OPCODE_DP4,
|
||||
|
||||
/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z + src1.w */
|
||||
RC_OPCODE_DPH,
|
||||
|
||||
/** special instruction, see ARB_fragment_program */
|
||||
RC_OPCODE_DST,
|
||||
|
||||
/** scalar instruction: dst = 2**src0.x */
|
||||
RC_OPCODE_EX2,
|
||||
|
||||
/** special instruction, see ARB_vertex_program */
|
||||
RC_OPCODE_EXP,
|
||||
|
||||
/** vec4 instruction: dst.c = floor(src0.c) */
|
||||
RC_OPCODE_FLR,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c - floor(src0.c) */
|
||||
RC_OPCODE_FRC,
|
||||
|
||||
/** special instruction: stop execution if any component of src0 is negative */
|
||||
RC_OPCODE_KIL,
|
||||
|
||||
/** scalar instruction: dst = log_2(src0.x) */
|
||||
RC_OPCODE_LG2,
|
||||
|
||||
/** special instruction, see ARB_vertex_program */
|
||||
RC_OPCODE_LIT,
|
||||
|
||||
/** special instruction, see ARB_vertex_program */
|
||||
RC_OPCODE_LOG,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c*src1.c + (1 - src0.c)*src2.c */
|
||||
RC_OPCODE_LRP,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c*src1.c + src2.c */
|
||||
RC_OPCODE_MAD,
|
||||
|
||||
/** vec4 instruction: dst.c = max(src0.c, src1.c) */
|
||||
RC_OPCODE_MAX,
|
||||
|
||||
/** vec4 instruction: dst.c = min(src0.c, src1.c) */
|
||||
RC_OPCODE_MIN,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c */
|
||||
RC_OPCODE_MOV,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c*src1.c */
|
||||
RC_OPCODE_MUL,
|
||||
|
||||
/** scalar instruction: dst = src0.x ** src1.x */
|
||||
RC_OPCODE_POW,
|
||||
|
||||
/** scalar instruction: dst = 1 / src0.x */
|
||||
RC_OPCODE_RCP,
|
||||
|
||||
/** scalar instruction: dst = 1 / sqrt(src0.x) */
|
||||
RC_OPCODE_RSQ,
|
||||
|
||||
/** special instruction, see ARB_fragment_program */
|
||||
RC_OPCODE_SCS,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c == src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SEQ,
|
||||
|
||||
/** vec4 instruction: dst.c = 0.0 */
|
||||
RC_OPCODE_SFL,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c >= src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SGE,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c > src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SGT,
|
||||
|
||||
/** scalar instruction: dst = sin(src0.x) */
|
||||
RC_OPCODE_SIN,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c <= src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SLE,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c < src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SLT,
|
||||
|
||||
/** vec4 instruction: dst.c = (src0.c != src1.c) ? 1.0 : 0.0 */
|
||||
RC_OPCODE_SNE,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c - src1.c */
|
||||
RC_OPCODE_SUB,
|
||||
|
||||
/** vec4 instruction: dst.c = src0.c */
|
||||
RC_OPCODE_SWZ,
|
||||
|
||||
/** special instruction, see ARB_fragment_program */
|
||||
RC_OPCODE_XPD,
|
||||
|
||||
RC_OPCODE_TEX,
|
||||
RC_OPCODE_TXB,
|
||||
RC_OPCODE_TXD,
|
||||
RC_OPCODE_TXL,
|
||||
RC_OPCODE_TXP,
|
||||
|
||||
/** special instruction, used in R300-R500 fragment program pair instructions
|
||||
* indicates that the result of the alpha operation shall be replicated
|
||||
* across all other channels */
|
||||
RC_OPCODE_REPL_ALPHA,
|
||||
|
||||
MAX_RC_OPCODE
|
||||
} rc_opcode;
|
||||
|
||||
|
||||
struct rc_opcode_info {
|
||||
rc_opcode Opcode;
|
||||
const char * Name;
|
||||
|
||||
/** true if the instruction reads from a texture.
|
||||
*
|
||||
* \note This is false for the KIL instruction, even though KIL is
|
||||
* a texture instruction from a hardware point of view. */
|
||||
unsigned int HasTexture:1;
|
||||
|
||||
unsigned int NumSrcRegs:2;
|
||||
unsigned int HasDstReg:1;
|
||||
};
|
||||
|
||||
extern struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE];
|
||||
|
||||
static inline const struct rc_opcode_info * rc_get_opcode_info(rc_opcode opcode)
|
||||
{
|
||||
assert((unsigned int)opcode < MAX_RC_OPCODE);
|
||||
assert(rc_opcodes[opcode].Opcode == opcode);
|
||||
|
||||
return &rc_opcodes[opcode];
|
||||
}
|
||||
|
||||
#endif /* RADEON_OPCODES_H */
|
||||
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
#include "radeon_program.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "radeon_compiler.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -69,37 +69,57 @@ void radeonLocalTransform(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
GLint rc_find_free_temporary(struct radeon_compiler * c)
|
||||
/**
|
||||
* Left multiplication of a register with a swizzle
|
||||
*/
|
||||
struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
|
||||
{
|
||||
GLboolean used[MAX_PROGRAM_TEMPS];
|
||||
GLuint i;
|
||||
struct rc_src_register tmp = srcreg;
|
||||
int i;
|
||||
tmp.Swizzle = 0;
|
||||
tmp.Negate = 0;
|
||||
for(i = 0; i < 4; ++i) {
|
||||
rc_swizzle swz = GET_SWZ(swizzle, i);
|
||||
if (swz < 4) {
|
||||
tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
|
||||
tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
|
||||
} else {
|
||||
tmp.Swizzle |= swz << (i*3);
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
unsigned int rc_find_free_temporary(struct radeon_compiler * c)
|
||||
{
|
||||
char used[RC_REGISTER_MAX_INDEX];
|
||||
unsigned int i;
|
||||
|
||||
memset(used, 0, sizeof(used));
|
||||
|
||||
for (struct rc_instruction * rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
|
||||
const struct prog_instruction *inst = &rcinst->I;
|
||||
const GLuint nsrc = _mesa_num_inst_src_regs(inst->Opcode);
|
||||
const GLuint ndst = _mesa_num_inst_dst_regs(inst->Opcode);
|
||||
GLuint k;
|
||||
const struct rc_sub_instruction *inst = &rcinst->I;
|
||||
const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
|
||||
unsigned int k;
|
||||
|
||||
for (k = 0; k < nsrc; k++) {
|
||||
if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
|
||||
used[inst->SrcReg[k].Index] = GL_TRUE;
|
||||
for (k = 0; k < opcode->NumSrcRegs; k++) {
|
||||
if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
|
||||
used[inst->SrcReg[k].Index] = 1;
|
||||
}
|
||||
|
||||
if (ndst) {
|
||||
if (inst->DstReg.File == PROGRAM_TEMPORARY)
|
||||
used[inst->DstReg.Index] = GL_TRUE;
|
||||
if (opcode->HasDstReg) {
|
||||
if (inst->DstReg.File == RC_FILE_TEMPORARY)
|
||||
used[inst->DstReg.Index] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
|
||||
for (i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
|
||||
if (!used[i])
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
rc_error(c, "Ran out of temporary registers\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -107,10 +127,13 @@ struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c)
|
|||
{
|
||||
struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
|
||||
|
||||
inst->Prev = 0;
|
||||
inst->Next = 0;
|
||||
memset(inst, 0, sizeof(struct rc_instruction));
|
||||
|
||||
_mesa_init_instructions(&inst->I, 1);
|
||||
inst->I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
|
||||
inst->I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZW;
|
||||
inst->I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZW;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
|
@ -135,14 +158,142 @@ void rc_remove_instruction(struct rc_instruction * inst)
|
|||
inst->Next->Prev = inst->Prev;
|
||||
}
|
||||
|
||||
static const char * textarget_to_string(rc_texture_target target)
|
||||
{
|
||||
switch(target) {
|
||||
case RC_TEXTURE_2D_ARRAY: return "2D_ARRAY";
|
||||
case RC_TEXTURE_1D_ARRAY: return "1D_ARRAY";
|
||||
case RC_TEXTURE_CUBE: return "CUBE";
|
||||
case RC_TEXTURE_3D: return "3D";
|
||||
case RC_TEXTURE_RECT: return "RECT";
|
||||
case RC_TEXTURE_2D: return "2D";
|
||||
case RC_TEXTURE_1D: return "1D";
|
||||
default: return "BAD_TEXTURE_TARGET";
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_print_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)
|
||||
{
|
||||
if (file == RC_FILE_NONE) {
|
||||
fprintf(f, "none");
|
||||
} else {
|
||||
const char * filename;
|
||||
switch(file) {
|
||||
case RC_FILE_TEMPORARY: filename = "temp"; break;
|
||||
case RC_FILE_INPUT: filename = "input"; break;
|
||||
case RC_FILE_OUTPUT: filename = "output"; break;
|
||||
case RC_FILE_ADDRESS: filename = "addr"; break;
|
||||
case RC_FILE_CONSTANT: filename = "const"; break;
|
||||
default: filename = "BAD FILE"; break;
|
||||
}
|
||||
fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_print_mask(FILE * f, unsigned int mask)
|
||||
{
|
||||
if (mask & RC_MASK_X) fprintf(f, "x");
|
||||
if (mask & RC_MASK_Y) fprintf(f, "y");
|
||||
if (mask & RC_MASK_Z) fprintf(f, "z");
|
||||
if (mask & RC_MASK_W) fprintf(f, "w");
|
||||
}
|
||||
|
||||
static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)
|
||||
{
|
||||
rc_print_register(f, dst.File, dst.Index, dst.RelAddr);
|
||||
if (dst.WriteMask != RC_MASK_XYZW) {
|
||||
fprintf(f, ".");
|
||||
rc_print_mask(f, dst.WriteMask);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)
|
||||
{
|
||||
unsigned int comp;
|
||||
for(comp = 0; comp < 4; ++comp) {
|
||||
rc_swizzle swz = GET_SWZ(swizzle, comp);
|
||||
if (GET_BIT(negate, comp))
|
||||
fprintf(f, "-");
|
||||
switch(swz) {
|
||||
case RC_SWIZZLE_X: fprintf(f, "x"); break;
|
||||
case RC_SWIZZLE_Y: fprintf(f, "y"); break;
|
||||
case RC_SWIZZLE_Z: fprintf(f, "z"); break;
|
||||
case RC_SWIZZLE_W: fprintf(f, "w"); break;
|
||||
case RC_SWIZZLE_ZERO: fprintf(f, "0"); break;
|
||||
case RC_SWIZZLE_ONE: fprintf(f, "1"); break;
|
||||
case RC_SWIZZLE_HALF: fprintf(f, "H"); break;
|
||||
case RC_SWIZZLE_UNUSED: fprintf(f, "_"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_print_src_register(FILE * f, struct rc_src_register src)
|
||||
{
|
||||
int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);
|
||||
|
||||
if (src.Negate == RC_MASK_XYZW)
|
||||
fprintf(f, "-");
|
||||
if (src.Abs)
|
||||
fprintf(f, "|");
|
||||
|
||||
rc_print_register(f, src.File, src.Index, src.RelAddr);
|
||||
|
||||
if (src.Abs && !trivial_negate)
|
||||
fprintf(f, "|");
|
||||
|
||||
if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {
|
||||
fprintf(f, ".");
|
||||
rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);
|
||||
}
|
||||
|
||||
if (src.Abs && trivial_negate)
|
||||
fprintf(f, "|");
|
||||
}
|
||||
|
||||
static void rc_print_instruction(FILE * f, struct rc_instruction * inst)
|
||||
{
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
|
||||
unsigned int reg;
|
||||
|
||||
fprintf(f, "%s", opcode->Name);
|
||||
|
||||
switch(inst->I.SaturateMode) {
|
||||
case RC_SATURATE_NONE: break;
|
||||
case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;
|
||||
case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;
|
||||
default: fprintf(f, "_BAD_SAT"); break;
|
||||
}
|
||||
|
||||
if (opcode->HasDstReg) {
|
||||
fprintf(f, " ");
|
||||
rc_print_dst_register(f, inst->I.DstReg);
|
||||
if (opcode->NumSrcRegs)
|
||||
fprintf(f, ",");
|
||||
}
|
||||
|
||||
for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
|
||||
if (reg > 0)
|
||||
fprintf(f, ",");
|
||||
fprintf(f, " ");
|
||||
rc_print_src_register(f, inst->I.SrcReg[reg]);
|
||||
}
|
||||
|
||||
if (opcode->HasTexture) {
|
||||
fprintf(f, ", %s%s[%u]",
|
||||
textarget_to_string(inst->I.TexSrcTarget),
|
||||
inst->I.TexShadow ? "SHADOW" : "",
|
||||
inst->I.TexSrcUnit);
|
||||
}
|
||||
|
||||
fprintf(f, ";\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print program to stderr, default options.
|
||||
*/
|
||||
void rc_print_program(const struct rc_program *prog)
|
||||
{
|
||||
GLuint indent = 0;
|
||||
GLuint linenum = 1;
|
||||
unsigned int linenum = 0;
|
||||
struct rc_instruction *inst;
|
||||
|
||||
fprintf(stderr, "# Radeon Compiler Program\n");
|
||||
|
|
@ -150,11 +301,7 @@ void rc_print_program(const struct rc_program *prog)
|
|||
for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
|
||||
fprintf(stderr, "%3d: ", linenum);
|
||||
|
||||
/* Massive hack: We rely on the fact that the printers do not actually
|
||||
* use the gl_program argument (last argument) in debug mode */
|
||||
indent = _mesa_fprint_instruction_opt(
|
||||
stderr, &inst->I,
|
||||
indent, PROG_PRINT_DEBUG, 0);
|
||||
rc_print_instruction(stderr, inst);
|
||||
|
||||
linenum++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,37 +28,211 @@
|
|||
#ifndef __RADEON_PROGRAM_H_
|
||||
#define __RADEON_PROGRAM_H_
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "radeon_opcodes.h"
|
||||
#include "radeon_code.h"
|
||||
|
||||
struct radeon_compiler;
|
||||
struct rc_instruction;
|
||||
struct rc_program;
|
||||
|
||||
enum {
|
||||
PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
|
||||
typedef enum {
|
||||
RC_SATURATE_NONE = 0,
|
||||
RC_SATURATE_ZERO_ONE,
|
||||
RC_SATURATE_MINUS_PLUS_ONE
|
||||
} rc_saturate_mode;
|
||||
|
||||
typedef enum {
|
||||
RC_TEXTURE_2D_ARRAY,
|
||||
RC_TEXTURE_1D_ARRAY,
|
||||
RC_TEXTURE_CUBE,
|
||||
RC_TEXTURE_3D,
|
||||
RC_TEXTURE_RECT,
|
||||
RC_TEXTURE_2D,
|
||||
RC_TEXTURE_1D
|
||||
} rc_texture_target;
|
||||
|
||||
typedef enum {
|
||||
/**
|
||||
* Used to indicate unused register descriptions and
|
||||
* source register that use a constant swizzle.
|
||||
*/
|
||||
RC_FILE_NONE = 0,
|
||||
RC_FILE_TEMPORARY,
|
||||
|
||||
/**
|
||||
* Input register.
|
||||
*
|
||||
* \note The compiler attaches no implicit semantics to input registers.
|
||||
* Fragment/vertex program specific semantics must be defined explicitly
|
||||
* using the appropriate compiler interfaces.
|
||||
*/
|
||||
RC_FILE_INPUT,
|
||||
|
||||
/**
|
||||
* Output register.
|
||||
*
|
||||
* \note The compiler attaches no implicit semantics to input registers.
|
||||
* Fragment/vertex program specific semantics must be defined explicitly
|
||||
* using the appropriate compiler interfaces.
|
||||
*/
|
||||
RC_FILE_OUTPUT,
|
||||
RC_FILE_ADDRESS,
|
||||
|
||||
/**
|
||||
* Indicates a constant from the \ref rc_constant_list .
|
||||
*/
|
||||
RC_FILE_CONSTANT
|
||||
} rc_register_file;
|
||||
|
||||
#define RC_REGISTER_INDEX_BITS 10
|
||||
#define RC_REGISTER_MAX_INDEX (1 << RC_REGISTER_INDEX_BITS)
|
||||
|
||||
typedef enum {
|
||||
RC_SWIZZLE_X = 0,
|
||||
RC_SWIZZLE_Y,
|
||||
RC_SWIZZLE_Z,
|
||||
RC_SWIZZLE_W,
|
||||
RC_SWIZZLE_ZERO,
|
||||
RC_SWIZZLE_ONE,
|
||||
RC_SWIZZLE_HALF,
|
||||
RC_SWIZZLE_UNUSED
|
||||
} rc_swizzle;
|
||||
|
||||
#define RC_MAKE_SWIZZLE(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
|
||||
#define RC_MAKE_SWIZZLE_SMEAR(a) RC_MAKE_SWIZZLE((a),(a),(a),(a))
|
||||
#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
|
||||
#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
|
||||
|
||||
#define RC_SWIZZLE_XYZW RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_W)
|
||||
#define RC_SWIZZLE_XXXX RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_X)
|
||||
#define RC_SWIZZLE_YYYY RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_Y)
|
||||
#define RC_SWIZZLE_ZZZZ RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_Z)
|
||||
#define RC_SWIZZLE_WWWW RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_W)
|
||||
#define RC_SWIZZLE_0000 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ZERO)
|
||||
#define RC_SWIZZLE_1111 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ONE)
|
||||
|
||||
/**
|
||||
* \name Bitmasks for components of vectors.
|
||||
*
|
||||
* Used for write masks, negation masks, etc.
|
||||
*/
|
||||
/*@{*/
|
||||
#define RC_MASK_NONE 0
|
||||
#define RC_MASK_X 1
|
||||
#define RC_MASK_Y 2
|
||||
#define RC_MASK_Z 4
|
||||
#define RC_MASK_W 8
|
||||
#define RC_MASK_XY (RC_MASK_X|RC_MASK_Y)
|
||||
#define RC_MASK_XYZ (RC_MASK_X|RC_MASK_Y|RC_MASK_Z)
|
||||
#define RC_MASK_XYW (RC_MASK_X|RC_MASK_Y|RC_MASK_W)
|
||||
#define RC_MASK_XYZW (RC_MASK_X|RC_MASK_Y|RC_MASK_Z|RC_MASK_W)
|
||||
/*@}*/
|
||||
|
||||
struct rc_src_register {
|
||||
rc_register_file File:3;
|
||||
|
||||
/** Negative values may be used for relative addressing. */
|
||||
signed int Index:(RC_REGISTER_INDEX_BITS+1);
|
||||
unsigned int RelAddr:1;
|
||||
|
||||
unsigned int Swizzle:12;
|
||||
|
||||
/** Take the component-wise absolute value */
|
||||
unsigned int Abs:1;
|
||||
|
||||
/** Post-Abs negation. */
|
||||
unsigned int Negate:4;
|
||||
};
|
||||
|
||||
struct rc_dst_register {
|
||||
rc_register_file File:3;
|
||||
|
||||
/** Negative values may be used for relative addressing. */
|
||||
signed int Index:(RC_REGISTER_INDEX_BITS+1);
|
||||
unsigned int RelAddr:1;
|
||||
|
||||
unsigned int WriteMask:4;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instructions are maintained by the compiler in a doubly linked list
|
||||
* of these structures.
|
||||
*
|
||||
* This instruction format is intended to be expanded for hardware-specific
|
||||
* trickery. At different stages of compilation, a different set of
|
||||
* instruction types may be valid.
|
||||
*/
|
||||
struct rc_sub_instruction {
|
||||
struct rc_src_register SrcReg[3];
|
||||
struct rc_dst_register DstReg;
|
||||
|
||||
/**
|
||||
* Opcode of this instruction, according to \ref rc_opcode enums.
|
||||
*/
|
||||
rc_opcode Opcode:8;
|
||||
|
||||
/**
|
||||
* Saturate each value of the result to the range [0,1] or [-1,1],
|
||||
* according to \ref rc_saturate_mode enums.
|
||||
*/
|
||||
rc_saturate_mode SaturateMode:2;
|
||||
|
||||
/**
|
||||
* \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
|
||||
*/
|
||||
/*@{*/
|
||||
/** Source texture unit. */
|
||||
unsigned int TexSrcUnit:5;
|
||||
|
||||
/** Source texture target, one of the \ref rc_texture_target enums */
|
||||
rc_texture_target TexSrcTarget:3;
|
||||
|
||||
/** True if tex instruction should do shadow comparison */
|
||||
unsigned int TexShadow:1;
|
||||
/*@}*/
|
||||
};
|
||||
|
||||
struct rc_instruction {
|
||||
struct rc_instruction * Prev;
|
||||
struct rc_instruction * Next;
|
||||
|
||||
struct rc_sub_instruction I;
|
||||
};
|
||||
|
||||
struct rc_program {
|
||||
/**
|
||||
* Instructions.Next points to the first instruction,
|
||||
* Instructions.Prev points to the last instruction.
|
||||
*/
|
||||
struct rc_instruction Instructions;
|
||||
|
||||
/* Long term, we should probably remove InputsRead & OutputsWritten,
|
||||
* since updating dependent state can be fragile, and they aren't
|
||||
* actually used very often. */
|
||||
uint32_t InputsRead;
|
||||
uint32_t OutputsWritten;
|
||||
uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */
|
||||
|
||||
struct rc_constant_list Constants;
|
||||
};
|
||||
|
||||
enum {
|
||||
OPCODE_REPL_ALPHA = MAX_OPCODE /**< used in paired instructions */
|
||||
OPCODE_REPL_ALPHA = MAX_RC_OPCODE /**< used in paired instructions */
|
||||
};
|
||||
|
||||
#define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO)
|
||||
#define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
|
||||
|
||||
static inline GLuint get_swz(GLuint swz, GLuint idx)
|
||||
static inline rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
|
||||
{
|
||||
if (idx & 0x4)
|
||||
return idx;
|
||||
return GET_SWZ(swz, idx);
|
||||
}
|
||||
|
||||
static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, GLuint swz_z, GLuint swz_w)
|
||||
static inline unsigned int combine_swizzles4(unsigned int src,
|
||||
rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
|
||||
{
|
||||
GLuint ret = 0;
|
||||
unsigned int ret = 0;
|
||||
|
||||
ret |= get_swz(src, swz_x);
|
||||
ret |= get_swz(src, swz_y) << 3;
|
||||
|
|
@ -68,22 +242,24 @@ static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, G
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline GLuint combine_swizzles(GLuint src, GLuint swz)
|
||||
static inline unsigned int combine_swizzles(unsigned int src, unsigned int swz)
|
||||
{
|
||||
GLuint ret = 0;
|
||||
unsigned int ret = 0;
|
||||
|
||||
ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_X));
|
||||
ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Y)) << 3;
|
||||
ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Z)) << 6;
|
||||
ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_W)) << 9;
|
||||
ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_X));
|
||||
ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Y)) << 3;
|
||||
ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Z)) << 6;
|
||||
ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_W)) << 9;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static INLINE void reset_srcreg(struct prog_src_register* reg)
|
||||
struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg);
|
||||
|
||||
static inline void reset_srcreg(struct rc_src_register* reg)
|
||||
{
|
||||
_mesa_bzero(reg, sizeof(*reg));
|
||||
reg->Swizzle = SWIZZLE_NOOP;
|
||||
memset(reg, 0, sizeof(reg));
|
||||
reg->Swizzle = RC_SWIZZLE_XYZW;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -92,13 +268,13 @@ static INLINE void reset_srcreg(struct prog_src_register* reg)
|
|||
*
|
||||
* The function will be called once for each instruction.
|
||||
* It has to either emit the appropriate transformed code for the instruction
|
||||
* and return GL_TRUE, or return GL_FALSE if it doesn't understand the
|
||||
* and return true, or return false if it doesn't understand the
|
||||
* instruction.
|
||||
*
|
||||
* The function gets passed the userData as last parameter.
|
||||
*/
|
||||
struct radeon_program_transformation {
|
||||
GLboolean (*function)(
|
||||
int (*function)(
|
||||
struct radeon_compiler*,
|
||||
struct rc_instruction*,
|
||||
void*);
|
||||
|
|
@ -110,7 +286,7 @@ void radeonLocalTransform(
|
|||
int num_transformations,
|
||||
struct radeon_program_transformation* transformations);
|
||||
|
||||
GLint rc_find_free_temporary(struct radeon_compiler * c);
|
||||
unsigned int rc_find_free_temporary(struct radeon_compiler * c);
|
||||
|
||||
struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
|
||||
struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
|
||||
static struct rc_instruction *emit1(
|
||||
struct radeon_compiler * c, struct rc_instruction * after,
|
||||
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg)
|
||||
rc_opcode Opcode, rc_saturate_mode Saturate, struct rc_dst_register DstReg,
|
||||
struct rc_src_register SrcReg)
|
||||
{
|
||||
struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
|
||||
|
||||
|
|
@ -54,8 +54,8 @@ static struct rc_instruction *emit1(
|
|||
|
||||
static struct rc_instruction *emit2(
|
||||
struct radeon_compiler * c, struct rc_instruction * after,
|
||||
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1)
|
||||
rc_opcode Opcode, rc_saturate_mode Saturate, struct rc_dst_register DstReg,
|
||||
struct rc_src_register SrcReg0, struct rc_src_register SrcReg1)
|
||||
{
|
||||
struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
|
||||
|
||||
|
|
@ -69,9 +69,9 @@ static struct rc_instruction *emit2(
|
|||
|
||||
static struct rc_instruction *emit3(
|
||||
struct radeon_compiler * c, struct rc_instruction * after,
|
||||
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
|
||||
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1,
|
||||
struct prog_src_register SrcReg2)
|
||||
rc_opcode Opcode, rc_saturate_mode Saturate, struct rc_dst_register DstReg,
|
||||
struct rc_src_register SrcReg0, struct rc_src_register SrcReg1,
|
||||
struct rc_src_register SrcReg2)
|
||||
{
|
||||
struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
|
||||
|
||||
|
|
@ -84,131 +84,120 @@ static struct rc_instruction *emit3(
|
|||
return fpi;
|
||||
}
|
||||
|
||||
static struct prog_dst_register dstreg(int file, int index)
|
||||
static struct rc_dst_register dstreg(int file, int index)
|
||||
{
|
||||
struct prog_dst_register dst;
|
||||
struct rc_dst_register dst;
|
||||
dst.File = file;
|
||||
dst.Index = index;
|
||||
dst.WriteMask = WRITEMASK_XYZW;
|
||||
dst.CondMask = COND_TR;
|
||||
dst.WriteMask = RC_MASK_XYZW;
|
||||
dst.RelAddr = 0;
|
||||
dst.CondSwizzle = SWIZZLE_NOOP;
|
||||
dst.CondSrc = 0;
|
||||
dst.pad = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static struct prog_dst_register dstregtmpmask(int index, int mask)
|
||||
static struct rc_dst_register dstregtmpmask(int index, int mask)
|
||||
{
|
||||
struct prog_dst_register dst = {0};
|
||||
dst.File = PROGRAM_TEMPORARY;
|
||||
struct rc_dst_register dst = {0};
|
||||
dst.File = RC_FILE_TEMPORARY;
|
||||
dst.Index = index;
|
||||
dst.WriteMask = mask;
|
||||
dst.RelAddr = 0;
|
||||
dst.CondMask = COND_TR;
|
||||
dst.CondSwizzle = SWIZZLE_NOOP;
|
||||
dst.CondSrc = 0;
|
||||
dst.pad = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static const struct prog_src_register builtin_zero = {
|
||||
.File = PROGRAM_BUILTIN,
|
||||
static const struct rc_src_register builtin_zero = {
|
||||
.File = RC_FILE_NONE,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_0000
|
||||
.Swizzle = RC_SWIZZLE_0000
|
||||
};
|
||||
static const struct prog_src_register builtin_one = {
|
||||
.File = PROGRAM_BUILTIN,
|
||||
static const struct rc_src_register builtin_one = {
|
||||
.File = RC_FILE_NONE,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_1111
|
||||
.Swizzle = RC_SWIZZLE_1111
|
||||
};
|
||||
static const struct prog_src_register srcreg_undefined = {
|
||||
.File = PROGRAM_UNDEFINED,
|
||||
static const struct rc_src_register srcreg_undefined = {
|
||||
.File = RC_FILE_NONE,
|
||||
.Index = 0,
|
||||
.Swizzle = SWIZZLE_NOOP
|
||||
.Swizzle = RC_SWIZZLE_XYZW
|
||||
};
|
||||
|
||||
static struct prog_src_register srcreg(int file, int index)
|
||||
static struct rc_src_register srcreg(int file, int index)
|
||||
{
|
||||
struct prog_src_register src = srcreg_undefined;
|
||||
struct rc_src_register src = srcreg_undefined;
|
||||
src.File = file;
|
||||
src.Index = index;
|
||||
return src;
|
||||
}
|
||||
|
||||
static struct prog_src_register srcregswz(int file, int index, int swz)
|
||||
static struct rc_src_register srcregswz(int file, int index, int swz)
|
||||
{
|
||||
struct prog_src_register src = srcreg_undefined;
|
||||
struct rc_src_register src = srcreg_undefined;
|
||||
src.File = file;
|
||||
src.Index = index;
|
||||
src.Swizzle = swz;
|
||||
return src;
|
||||
}
|
||||
|
||||
static struct prog_src_register absolute(struct prog_src_register reg)
|
||||
static struct rc_src_register absolute(struct rc_src_register reg)
|
||||
{
|
||||
struct prog_src_register newreg = reg;
|
||||
struct rc_src_register newreg = reg;
|
||||
newreg.Abs = 1;
|
||||
newreg.Negate = NEGATE_NONE;
|
||||
newreg.Negate = RC_MASK_NONE;
|
||||
return newreg;
|
||||
}
|
||||
|
||||
static struct prog_src_register negate(struct prog_src_register reg)
|
||||
static struct rc_src_register negate(struct rc_src_register reg)
|
||||
{
|
||||
struct prog_src_register newreg = reg;
|
||||
newreg.Negate = newreg.Negate ^ NEGATE_XYZW;
|
||||
struct rc_src_register newreg = reg;
|
||||
newreg.Negate = newreg.Negate ^ RC_MASK_XYZW;
|
||||
return newreg;
|
||||
}
|
||||
|
||||
static struct prog_src_register swizzle(struct prog_src_register reg, GLuint x, GLuint y, GLuint z, GLuint w)
|
||||
static struct rc_src_register swizzle(struct rc_src_register reg,
|
||||
rc_swizzle x, rc_swizzle y, rc_swizzle z, rc_swizzle w)
|
||||
{
|
||||
struct prog_src_register swizzled = reg;
|
||||
swizzled.Swizzle = MAKE_SWIZZLE4(
|
||||
x >= 4 ? x : GET_SWZ(reg.Swizzle, x),
|
||||
y >= 4 ? y : GET_SWZ(reg.Swizzle, y),
|
||||
z >= 4 ? z : GET_SWZ(reg.Swizzle, z),
|
||||
w >= 4 ? w : GET_SWZ(reg.Swizzle, w));
|
||||
struct rc_src_register swizzled = reg;
|
||||
swizzled.Swizzle = combine_swizzles4(reg.Swizzle, x, y, z, w);
|
||||
return swizzled;
|
||||
}
|
||||
|
||||
static struct prog_src_register scalar(struct prog_src_register reg)
|
||||
static struct rc_src_register scalar(struct rc_src_register reg)
|
||||
{
|
||||
return swizzle(reg, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
|
||||
return swizzle(reg, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X);
|
||||
}
|
||||
|
||||
static void transform_ABS(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
struct prog_src_register src = inst->I.SrcReg[0];
|
||||
struct rc_src_register src = inst->I.SrcReg[0];
|
||||
src.Abs = 1;
|
||||
src.Negate = NEGATE_NONE;
|
||||
emit1(c, inst->Prev, OPCODE_MOV, inst->I.SaturateMode, inst->I.DstReg, src);
|
||||
src.Negate = RC_MASK_NONE;
|
||||
emit1(c, inst->Prev, RC_OPCODE_MOV, inst->I.SaturateMode, inst->I.DstReg, src);
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
||||
static void transform_DP3(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
struct prog_src_register src0 = inst->I.SrcReg[0];
|
||||
struct prog_src_register src1 = inst->I.SrcReg[1];
|
||||
src0.Negate &= ~NEGATE_W;
|
||||
struct rc_src_register src0 = inst->I.SrcReg[0];
|
||||
struct rc_src_register src1 = inst->I.SrcReg[1];
|
||||
src0.Negate &= ~RC_MASK_W;
|
||||
src0.Swizzle &= ~(7 << (3 * 3));
|
||||
src0.Swizzle |= SWIZZLE_ZERO << (3 * 3);
|
||||
src1.Negate &= ~NEGATE_W;
|
||||
src0.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
|
||||
src1.Negate &= ~RC_MASK_W;
|
||||
src1.Swizzle &= ~(7 << (3 * 3));
|
||||
src1.Swizzle |= SWIZZLE_ZERO << (3 * 3);
|
||||
emit2(c, inst->Prev, OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, src1);
|
||||
src1.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
|
||||
emit2(c, inst->Prev, RC_OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, src1);
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
||||
static void transform_DPH(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
struct prog_src_register src0 = inst->I.SrcReg[0];
|
||||
src0.Negate &= ~NEGATE_W;
|
||||
struct rc_src_register src0 = inst->I.SrcReg[0];
|
||||
src0.Negate &= ~RC_MASK_W;
|
||||
src0.Swizzle &= ~(7 << (3 * 3));
|
||||
src0.Swizzle |= SWIZZLE_ONE << (3 * 3);
|
||||
emit2(c, inst->Prev, OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, inst->I.SrcReg[1]);
|
||||
src0.Swizzle |= RC_SWIZZLE_ONE << (3 * 3);
|
||||
emit2(c, inst->Prev, RC_OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, inst->I.SrcReg[1]);
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
||||
|
|
@ -219,9 +208,9 @@ static void transform_DPH(struct radeon_compiler* c,
|
|||
static void transform_DST(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
emit2(c, inst->Prev, OPCODE_MUL, inst->I.SaturateMode, inst->I.DstReg,
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE),
|
||||
swizzle(inst->I.SrcReg[1], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_W));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MUL, inst->I.SaturateMode, inst->I.DstReg,
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_ONE, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ONE),
|
||||
swizzle(inst->I.SrcReg[1], RC_SWIZZLE_ONE, RC_SWIZZLE_Y, RC_SWIZZLE_ONE, RC_SWIZZLE_W));
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
||||
|
|
@ -229,9 +218,9 @@ static void transform_FLR(struct radeon_compiler* c,
|
|||
struct rc_instruction* inst)
|
||||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
emit1(c, inst->Prev, OPCODE_FRC, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0]);
|
||||
emit2(c, inst->Prev, OPCODE_ADD, inst->I.SaturateMode, inst->I.DstReg,
|
||||
inst->I.SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
|
||||
emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->I.SrcReg[0]);
|
||||
emit2(c, inst->Prev, RC_OPCODE_ADD, inst->I.SaturateMode, inst->I.DstReg,
|
||||
inst->I.SrcReg[0], negate(srcreg(RC_FILE_TEMPORARY, tempreg)));
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
||||
|
|
@ -256,64 +245,64 @@ static void transform_FLR(struct radeon_compiler* c,
|
|||
static void transform_LIT(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
GLuint constant;
|
||||
GLuint constant_swizzle;
|
||||
GLuint temp;
|
||||
struct prog_src_register srctemp;
|
||||
unsigned int constant;
|
||||
unsigned int constant_swizzle;
|
||||
unsigned int temp;
|
||||
struct rc_src_register srctemp;
|
||||
|
||||
constant = rc_constants_add_immediate_scalar(&c->Program.Constants, -127.999999, &constant_swizzle);
|
||||
|
||||
if (inst->I.DstReg.WriteMask != WRITEMASK_XYZW || inst->I.DstReg.File != PROGRAM_TEMPORARY) {
|
||||
if (inst->I.DstReg.WriteMask != RC_MASK_XYZW || inst->I.DstReg.File != RC_FILE_TEMPORARY) {
|
||||
struct rc_instruction * inst_mov;
|
||||
|
||||
inst_mov = emit1(c, inst,
|
||||
OPCODE_MOV, 0, inst->I.DstReg,
|
||||
srcreg(PROGRAM_TEMPORARY, rc_find_free_temporary(c)));
|
||||
RC_OPCODE_MOV, 0, inst->I.DstReg,
|
||||
srcreg(RC_FILE_TEMPORARY, rc_find_free_temporary(c)));
|
||||
|
||||
inst->I.DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst->I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
|
||||
inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst->I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
temp = inst->I.DstReg.Index;
|
||||
srctemp = srcreg(PROGRAM_TEMPORARY, temp);
|
||||
srctemp = srcreg(RC_FILE_TEMPORARY, temp);
|
||||
|
||||
// tmp.x = max(0.0, Src.x);
|
||||
// tmp.y = max(0.0, Src.y);
|
||||
// tmp.w = clamp(Src.z, -128+eps, 128-eps);
|
||||
emit2(c, inst->Prev, OPCODE_MAX, 0,
|
||||
dstregtmpmask(temp, WRITEMASK_XYW),
|
||||
emit2(c, inst->Prev, RC_OPCODE_MAX, 0,
|
||||
dstregtmpmask(temp, RC_MASK_XYW),
|
||||
inst->I.SrcReg[0],
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constant),
|
||||
SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, constant_swizzle&3));
|
||||
emit2(c, inst->Prev, OPCODE_MIN, 0,
|
||||
dstregtmpmask(temp, WRITEMASK_Z),
|
||||
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
negate(srcregswz(PROGRAM_CONSTANT, constant, constant_swizzle)));
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constant),
|
||||
RC_SWIZZLE_ZERO, RC_SWIZZLE_ZERO, RC_SWIZZLE_ZERO, constant_swizzle&3));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MIN, 0,
|
||||
dstregtmpmask(temp, RC_MASK_Z),
|
||||
swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
negate(srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle)));
|
||||
|
||||
// tmp.w = Pow(tmp.y, tmp.w)
|
||||
emit1(c, inst->Prev, OPCODE_LG2, 0,
|
||||
dstregtmpmask(temp, WRITEMASK_W),
|
||||
swizzle(srctemp, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y));
|
||||
emit2(c, inst->Prev, OPCODE_MUL, 0,
|
||||
dstregtmpmask(temp, WRITEMASK_W),
|
||||
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srctemp, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z));
|
||||
emit1(c, inst->Prev, OPCODE_EX2, 0,
|
||||
dstregtmpmask(temp, WRITEMASK_W),
|
||||
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
|
||||
emit1(c, inst->Prev, RC_OPCODE_LG2, 0,
|
||||
dstregtmpmask(temp, RC_MASK_W),
|
||||
swizzle(srctemp, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MUL, 0,
|
||||
dstregtmpmask(temp, RC_MASK_W),
|
||||
swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
swizzle(srctemp, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z));
|
||||
emit1(c, inst->Prev, RC_OPCODE_EX2, 0,
|
||||
dstregtmpmask(temp, RC_MASK_W),
|
||||
swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W));
|
||||
|
||||
// tmp.z = (tmp.x > 0) ? tmp.w : 0.0
|
||||
emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode,
|
||||
dstregtmpmask(temp, WRITEMASK_Z),
|
||||
negate(swizzle(srctemp, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
|
||||
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
emit3(c, inst->Prev, RC_OPCODE_CMP, inst->I.SaturateMode,
|
||||
dstregtmpmask(temp, RC_MASK_Z),
|
||||
negate(swizzle(srctemp, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
|
||||
swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
builtin_zero);
|
||||
|
||||
// tmp.x, tmp.y, tmp.w = 1.0, tmp.x, 1.0
|
||||
emit1(c, inst->Prev, OPCODE_MOV, inst->I.SaturateMode,
|
||||
dstregtmpmask(temp, WRITEMASK_XYW),
|
||||
swizzle(srctemp, SWIZZLE_ONE, SWIZZLE_X, SWIZZLE_ONE, SWIZZLE_ONE));
|
||||
emit1(c, inst->Prev, RC_OPCODE_MOV, inst->I.SaturateMode,
|
||||
dstregtmpmask(temp, RC_MASK_XYW),
|
||||
swizzle(srctemp, RC_SWIZZLE_ONE, RC_SWIZZLE_X, RC_SWIZZLE_ONE, RC_SWIZZLE_ONE));
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -323,12 +312,12 @@ static void transform_LRP(struct radeon_compiler* c,
|
|||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
emit2(c, inst->Prev, OPCODE_ADD, 0,
|
||||
dstreg(PROGRAM_TEMPORARY, tempreg),
|
||||
emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
|
||||
dstreg(RC_FILE_TEMPORARY, tempreg),
|
||||
inst->I.SrcReg[1], negate(inst->I.SrcReg[2]));
|
||||
emit3(c, inst->Prev, OPCODE_MAD, inst->I.SaturateMode,
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, inst->I.SaturateMode,
|
||||
inst->I.DstReg,
|
||||
inst->I.SrcReg[0], srcreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[2]);
|
||||
inst->I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg), inst->I.SrcReg[2]);
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -337,14 +326,14 @@ static void transform_POW(struct radeon_compiler* c,
|
|||
struct rc_instruction* inst)
|
||||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
struct prog_dst_register tempdst = dstreg(PROGRAM_TEMPORARY, tempreg);
|
||||
struct prog_src_register tempsrc = srcreg(PROGRAM_TEMPORARY, tempreg);
|
||||
tempdst.WriteMask = WRITEMASK_W;
|
||||
tempsrc.Swizzle = SWIZZLE_WWWW;
|
||||
struct rc_dst_register tempdst = dstreg(RC_FILE_TEMPORARY, tempreg);
|
||||
struct rc_src_register tempsrc = srcreg(RC_FILE_TEMPORARY, tempreg);
|
||||
tempdst.WriteMask = RC_MASK_W;
|
||||
tempsrc.Swizzle = RC_SWIZZLE_WWWW;
|
||||
|
||||
emit1(c, inst->Prev, OPCODE_LG2, 0, tempdst, scalar(inst->I.SrcReg[0]));
|
||||
emit2(c, inst->Prev, OPCODE_MUL, 0, tempdst, tempsrc, scalar(inst->I.SrcReg[1]));
|
||||
emit1(c, inst->Prev, OPCODE_EX2, inst->I.SaturateMode, inst->I.DstReg, tempsrc);
|
||||
emit1(c, inst->Prev, RC_OPCODE_LG2, 0, tempdst, scalar(inst->I.SrcReg[0]));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MUL, 0, tempdst, tempsrc, scalar(inst->I.SrcReg[1]));
|
||||
emit1(c, inst->Prev, RC_OPCODE_EX2, inst->I.SaturateMode, inst->I.DstReg, tempsrc);
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -360,9 +349,9 @@ static void transform_SGE(struct radeon_compiler* c,
|
|||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
emit2(c, inst->Prev, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
|
||||
emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcreg(PROGRAM_TEMPORARY, tempreg), builtin_zero, builtin_one);
|
||||
emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
|
||||
emit3(c, inst->Prev, RC_OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcreg(RC_FILE_TEMPORARY, tempreg), builtin_zero, builtin_one);
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -372,9 +361,9 @@ static void transform_SLT(struct radeon_compiler* c,
|
|||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
emit2(c, inst->Prev, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
|
||||
emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcreg(PROGRAM_TEMPORARY, tempreg), builtin_one, builtin_zero);
|
||||
emit2(c, inst->Prev, RC_OPCODE_ADD, 0, dstreg(RC_FILE_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
|
||||
emit3(c, inst->Prev, RC_OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcreg(RC_FILE_TEMPORARY, tempreg), builtin_one, builtin_zero);
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -382,14 +371,14 @@ static void transform_SLT(struct radeon_compiler* c,
|
|||
static void transform_SUB(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
inst->I.Opcode = OPCODE_ADD;
|
||||
inst->I.Opcode = RC_OPCODE_ADD;
|
||||
inst->I.SrcReg[1] = negate(inst->I.SrcReg[1]);
|
||||
}
|
||||
|
||||
static void transform_SWZ(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst)
|
||||
{
|
||||
inst->I.Opcode = OPCODE_MOV;
|
||||
inst->I.Opcode = RC_OPCODE_MOV;
|
||||
}
|
||||
|
||||
static void transform_XPD(struct radeon_compiler* c,
|
||||
|
|
@ -397,13 +386,13 @@ static void transform_XPD(struct radeon_compiler* c,
|
|||
{
|
||||
int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
emit2(c, inst->Prev, OPCODE_MUL, 0, dstreg(PROGRAM_TEMPORARY, tempreg),
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
|
||||
swizzle(inst->I.SrcReg[1], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W));
|
||||
emit3(c, inst->Prev, OPCODE_MAD, inst->I.SaturateMode, inst->I.DstReg,
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W),
|
||||
swizzle(inst->I.SrcReg[1], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
|
||||
negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstreg(RC_FILE_TEMPORARY, tempreg),
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W),
|
||||
swizzle(inst->I.SrcReg[1], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, inst->I.SaturateMode, inst->I.DstReg,
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_W),
|
||||
swizzle(inst->I.SrcReg[1], RC_SWIZZLE_Z, RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_W),
|
||||
negate(srcreg(RC_FILE_TEMPORARY, tempreg)));
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
}
|
||||
|
|
@ -423,27 +412,27 @@ static void transform_XPD(struct radeon_compiler* c,
|
|||
*
|
||||
* @note should be applicable to R300 and R500 fragment programs.
|
||||
*/
|
||||
GLboolean radeonTransformALU(
|
||||
int radeonTransformALU(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
switch(inst->I.Opcode) {
|
||||
case OPCODE_ABS: transform_ABS(c, inst); return GL_TRUE;
|
||||
case OPCODE_DPH: transform_DPH(c, inst); return GL_TRUE;
|
||||
case OPCODE_DST: transform_DST(c, inst); return GL_TRUE;
|
||||
case OPCODE_FLR: transform_FLR(c, inst); return GL_TRUE;
|
||||
case OPCODE_LIT: transform_LIT(c, inst); return GL_TRUE;
|
||||
case OPCODE_LRP: transform_LRP(c, inst); return GL_TRUE;
|
||||
case OPCODE_POW: transform_POW(c, inst); return GL_TRUE;
|
||||
case OPCODE_RSQ: transform_RSQ(c, inst); return GL_TRUE;
|
||||
case OPCODE_SGE: transform_SGE(c, inst); return GL_TRUE;
|
||||
case OPCODE_SLT: transform_SLT(c, inst); return GL_TRUE;
|
||||
case OPCODE_SUB: transform_SUB(c, inst); return GL_TRUE;
|
||||
case OPCODE_SWZ: transform_SWZ(c, inst); return GL_TRUE;
|
||||
case OPCODE_XPD: transform_XPD(c, inst); return GL_TRUE;
|
||||
case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
|
||||
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
|
||||
case RC_OPCODE_DST: transform_DST(c, inst); return 1;
|
||||
case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
|
||||
case RC_OPCODE_LIT: transform_LIT(c, inst); return 1;
|
||||
case RC_OPCODE_LRP: transform_LRP(c, inst); return 1;
|
||||
case RC_OPCODE_POW: transform_POW(c, inst); return 1;
|
||||
case RC_OPCODE_RSQ: transform_RSQ(c, inst); return 1;
|
||||
case RC_OPCODE_SGE: transform_SGE(c, inst); return 1;
|
||||
case RC_OPCODE_SLT: transform_SLT(c, inst); return 1;
|
||||
case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
|
||||
case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
|
||||
case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -452,37 +441,37 @@ static void transform_r300_vertex_ABS(struct radeon_compiler* c,
|
|||
struct rc_instruction* inst)
|
||||
{
|
||||
/* Note: r500 can take absolute values, but r300 cannot. */
|
||||
inst->I.Opcode = OPCODE_MAX;
|
||||
inst->I.Opcode = RC_OPCODE_MAX;
|
||||
inst->I.SrcReg[1] = inst->I.SrcReg[0];
|
||||
inst->I.SrcReg[1].Negate ^= NEGATE_XYZW;
|
||||
inst->I.SrcReg[1].Negate ^= RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with radeonLocalTransform, this transforms non-native ALU
|
||||
* instructions of the r300 up to r500 vertex engine.
|
||||
*/
|
||||
GLboolean r300_transform_vertex_alu(
|
||||
int r300_transform_vertex_alu(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
switch(inst->I.Opcode) {
|
||||
case OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return GL_TRUE;
|
||||
case OPCODE_DP3: transform_DP3(c, inst); return GL_TRUE;
|
||||
case OPCODE_DPH: transform_DPH(c, inst); return GL_TRUE;
|
||||
case OPCODE_FLR: transform_FLR(c, inst); return GL_TRUE;
|
||||
case OPCODE_LRP: transform_LRP(c, inst); return GL_TRUE;
|
||||
case OPCODE_SUB: transform_SUB(c, inst); return GL_TRUE;
|
||||
case OPCODE_SWZ: transform_SWZ(c, inst); return GL_TRUE;
|
||||
case OPCODE_XPD: transform_XPD(c, inst); return GL_TRUE;
|
||||
case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
|
||||
case RC_OPCODE_DP3: transform_DP3(c, inst); return 1;
|
||||
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
|
||||
case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
|
||||
case RC_OPCODE_LRP: transform_LRP(c, inst); return 1;
|
||||
case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
|
||||
case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
|
||||
case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void sincos_constants(struct radeon_compiler* c, GLuint *constants)
|
||||
static void sincos_constants(struct radeon_compiler* c, unsigned int *constants)
|
||||
{
|
||||
static const GLfloat SinCosConsts[2][4] = {
|
||||
static const float SinCosConsts[2][4] = {
|
||||
{
|
||||
1.273239545, // 4/PI
|
||||
-0.405284735, // -4/(PI*PI)
|
||||
|
|
@ -512,25 +501,25 @@ static void sincos_constants(struct radeon_compiler* c, GLuint *constants)
|
|||
*/
|
||||
static void sin_approx(
|
||||
struct radeon_compiler* c, struct rc_instruction * after,
|
||||
struct prog_dst_register dst, struct prog_src_register src, const GLuint* constants)
|
||||
struct rc_dst_register dst, struct rc_src_register src, const unsigned int* constants)
|
||||
{
|
||||
GLuint tempreg = rc_find_free_temporary(c);
|
||||
unsigned int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
emit2(c, after->Prev, OPCODE_MUL, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
|
||||
swizzle(src, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
srcreg(PROGRAM_CONSTANT, constants[0]));
|
||||
emit3(c, after->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_X),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
|
||||
absolute(swizzle(src, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
|
||||
emit3(c, after->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_Y),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
absolute(swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
|
||||
negate(swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)));
|
||||
emit3(c, after->Prev, OPCODE_MAD, 0, dst,
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
|
||||
emit2(c, after->Prev, RC_OPCODE_MUL, 0, dstregtmpmask(tempreg, RC_MASK_XY),
|
||||
swizzle(src, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
srcreg(RC_FILE_CONSTANT, constants[0]));
|
||||
emit3(c, after->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_X),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y),
|
||||
absolute(swizzle(src, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X));
|
||||
emit3(c, after->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_Y),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
absolute(swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
|
||||
negate(swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)));
|
||||
emit3(c, after->Prev, RC_OPCODE_MAD, 0, dst,
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[0]), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -538,81 +527,81 @@ static void sin_approx(
|
|||
* using only the basic instructions
|
||||
* MOV, ADD, MUL, MAD, FRC
|
||||
*/
|
||||
GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
|
||||
int radeonTransformTrigSimple(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
if (inst->I.Opcode != OPCODE_COS &&
|
||||
inst->I.Opcode != OPCODE_SIN &&
|
||||
inst->I.Opcode != OPCODE_SCS)
|
||||
return GL_FALSE;
|
||||
if (inst->I.Opcode != RC_OPCODE_COS &&
|
||||
inst->I.Opcode != RC_OPCODE_SIN &&
|
||||
inst->I.Opcode != RC_OPCODE_SCS)
|
||||
return 0;
|
||||
|
||||
GLuint constants[2];
|
||||
GLuint tempreg = rc_find_free_temporary(c);
|
||||
unsigned int constants[2];
|
||||
unsigned int tempreg = rc_find_free_temporary(c);
|
||||
|
||||
sincos_constants(c, constants);
|
||||
|
||||
if (inst->I.Opcode == OPCODE_COS) {
|
||||
if (inst->I.Opcode == RC_OPCODE_COS) {
|
||||
// MAD tmp.x, src, 1/(2*PI), 0.75
|
||||
// FRC tmp.x, tmp.x
|
||||
// MAD tmp.z, tmp.x, 2*PI, -PI
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
|
||||
emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
negate(swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X));
|
||||
emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
negate(swizzle(srcreg(RC_FILE_CONSTANT, constants[0]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z)));
|
||||
|
||||
sin_approx(c, inst->Prev, inst->I.DstReg,
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
constants);
|
||||
} else if (inst->I.Opcode == OPCODE_SIN) {
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y));
|
||||
emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
negate(swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)));
|
||||
} else if (inst->I.Opcode == RC_OPCODE_SIN) {
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y));
|
||||
emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
negate(swizzle(srcreg(RC_FILE_CONSTANT, constants[0]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z)));
|
||||
|
||||
sin_approx(c, inst->Prev, inst->I.DstReg,
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
constants);
|
||||
} else {
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W));
|
||||
emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
|
||||
srcreg(PROGRAM_TEMPORARY, tempreg));
|
||||
emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
|
||||
srcreg(PROGRAM_TEMPORARY, tempreg),
|
||||
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
|
||||
negate(swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_XY),
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_W));
|
||||
emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(tempreg, RC_MASK_XY),
|
||||
srcreg(RC_FILE_TEMPORARY, tempreg));
|
||||
emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_XY),
|
||||
srcreg(RC_FILE_TEMPORARY, tempreg),
|
||||
swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
|
||||
negate(swizzle(srcreg(RC_FILE_CONSTANT, constants[0]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z)));
|
||||
|
||||
struct prog_dst_register dst = inst->I.DstReg;
|
||||
struct rc_dst_register dst = inst->I.DstReg;
|
||||
|
||||
dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_X;
|
||||
dst.WriteMask = inst->I.DstReg.WriteMask & RC_MASK_X;
|
||||
sin_approx(c, inst->Prev, dst,
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
constants);
|
||||
|
||||
dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_Y;
|
||||
dst.WriteMask = inst->I.DstReg.WriteMask & RC_MASK_Y;
|
||||
sin_approx(c, inst->Prev, dst,
|
||||
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
|
||||
swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y),
|
||||
constants);
|
||||
}
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -624,53 +613,53 @@ GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
|
|||
*
|
||||
* @warning This transformation implicitly changes the semantics of SIN and COS!
|
||||
*/
|
||||
GLboolean radeonTransformTrigScale(struct radeon_compiler* c,
|
||||
int radeonTransformTrigScale(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
if (inst->I.Opcode != OPCODE_COS &&
|
||||
inst->I.Opcode != OPCODE_SIN &&
|
||||
inst->I.Opcode != OPCODE_SCS)
|
||||
return GL_FALSE;
|
||||
if (inst->I.Opcode != RC_OPCODE_COS &&
|
||||
inst->I.Opcode != RC_OPCODE_SIN &&
|
||||
inst->I.Opcode != RC_OPCODE_SCS)
|
||||
return 0;
|
||||
|
||||
static const GLfloat RCP_2PI = 0.15915494309189535;
|
||||
GLuint temp;
|
||||
GLuint constant;
|
||||
GLuint constant_swizzle;
|
||||
static const float RCP_2PI = 0.15915494309189535;
|
||||
unsigned int temp;
|
||||
unsigned int constant;
|
||||
unsigned int constant_swizzle;
|
||||
|
||||
temp = rc_find_free_temporary(c);
|
||||
constant = rc_constants_add_immediate_scalar(&c->Program.Constants, RCP_2PI, &constant_swizzle);
|
||||
|
||||
emit2(c, inst->Prev, OPCODE_MUL, 0, dstregtmpmask(temp, WRITEMASK_W),
|
||||
swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
srcregswz(PROGRAM_CONSTANT, constant, constant_swizzle));
|
||||
emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(temp, WRITEMASK_W),
|
||||
srcreg(PROGRAM_TEMPORARY, temp));
|
||||
emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstregtmpmask(temp, RC_MASK_W),
|
||||
swizzle(inst->I.SrcReg[0], RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
|
||||
srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle));
|
||||
emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstregtmpmask(temp, RC_MASK_W),
|
||||
srcreg(RC_FILE_TEMPORARY, temp));
|
||||
|
||||
if (inst->I.Opcode == OPCODE_COS) {
|
||||
emit1(c, inst->Prev, OPCODE_COS, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
|
||||
} else if (inst->I.Opcode == OPCODE_SIN) {
|
||||
emit1(c, inst->Prev, OPCODE_SIN, inst->I.SaturateMode,
|
||||
inst->I.DstReg, srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
|
||||
} else if (inst->I.Opcode == OPCODE_SCS) {
|
||||
struct prog_dst_register moddst = inst->I.DstReg;
|
||||
if (inst->I.Opcode == RC_OPCODE_COS) {
|
||||
emit1(c, inst->Prev, RC_OPCODE_COS, inst->I.SaturateMode, inst->I.DstReg,
|
||||
srcregswz(RC_FILE_TEMPORARY, temp, RC_SWIZZLE_WWWW));
|
||||
} else if (inst->I.Opcode == RC_OPCODE_SIN) {
|
||||
emit1(c, inst->Prev, RC_OPCODE_SIN, inst->I.SaturateMode,
|
||||
inst->I.DstReg, srcregswz(RC_FILE_TEMPORARY, temp, RC_SWIZZLE_WWWW));
|
||||
} else if (inst->I.Opcode == RC_OPCODE_SCS) {
|
||||
struct rc_dst_register moddst = inst->I.DstReg;
|
||||
|
||||
if (inst->I.DstReg.WriteMask & WRITEMASK_X) {
|
||||
moddst.WriteMask = WRITEMASK_X;
|
||||
emit1(c, inst->Prev, OPCODE_COS, inst->I.SaturateMode, moddst,
|
||||
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
|
||||
if (inst->I.DstReg.WriteMask & RC_MASK_X) {
|
||||
moddst.WriteMask = RC_MASK_X;
|
||||
emit1(c, inst->Prev, RC_OPCODE_COS, inst->I.SaturateMode, moddst,
|
||||
srcregswz(RC_FILE_TEMPORARY, temp, RC_SWIZZLE_WWWW));
|
||||
}
|
||||
if (inst->I.DstReg.WriteMask & WRITEMASK_Y) {
|
||||
moddst.WriteMask = WRITEMASK_Y;
|
||||
emit1(c, inst->Prev, OPCODE_SIN, inst->I.SaturateMode, moddst,
|
||||
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
|
||||
if (inst->I.DstReg.WriteMask & RC_MASK_Y) {
|
||||
moddst.WriteMask = RC_MASK_Y;
|
||||
emit1(c, inst->Prev, RC_OPCODE_SIN, inst->I.SaturateMode, moddst,
|
||||
srcregswz(RC_FILE_TEMPORARY, temp, RC_SWIZZLE_WWWW));
|
||||
}
|
||||
}
|
||||
|
||||
rc_remove_instruction(inst);
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -681,15 +670,15 @@ GLboolean radeonTransformTrigScale(struct radeon_compiler* c,
|
|||
* @warning This explicitly changes the form of DDX and DDY!
|
||||
*/
|
||||
|
||||
GLboolean radeonTransformDeriv(struct radeon_compiler* c,
|
||||
int radeonTransformDeriv(struct radeon_compiler* c,
|
||||
struct rc_instruction* inst,
|
||||
void* unused)
|
||||
{
|
||||
if (inst->I.Opcode != OPCODE_DDX && inst->I.Opcode != OPCODE_DDY)
|
||||
return GL_FALSE;
|
||||
if (inst->I.Opcode != RC_OPCODE_DDX && inst->I.Opcode != RC_OPCODE_DDY)
|
||||
return 0;
|
||||
|
||||
inst->I.SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
|
||||
inst->I.SrcReg[1].Negate = NEGATE_XYZW;
|
||||
inst->I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_ONE, RC_SWIZZLE_ONE, RC_SWIZZLE_ONE, RC_SWIZZLE_ONE);
|
||||
inst->I.SrcReg[1].Negate = RC_MASK_XYZW;
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,27 +30,27 @@
|
|||
|
||||
#include "radeon_program.h"
|
||||
|
||||
GLboolean radeonTransformALU(
|
||||
int radeonTransformALU(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void*);
|
||||
|
||||
GLboolean r300_transform_vertex_alu(
|
||||
int r300_transform_vertex_alu(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void*);
|
||||
|
||||
GLboolean radeonTransformTrigSimple(
|
||||
int radeonTransformTrigSimple(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void*);
|
||||
|
||||
GLboolean radeonTransformTrigScale(
|
||||
int radeonTransformTrigScale(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void*);
|
||||
|
||||
GLboolean radeonTransformDeriv(
|
||||
int radeonTransformDeriv(
|
||||
struct radeon_compiler * c,
|
||||
struct rc_instruction * inst,
|
||||
void*);
|
||||
|
|
|
|||
|
|
@ -35,9 +35,10 @@
|
|||
|
||||
#include "radeon_program_pair.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "memory_pool.h"
|
||||
#include "radeon_compiler.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
#define error(fmt, args...) do { \
|
||||
rc_error(&s->Compiler->Base, "%s::%s(): " fmt "\n", \
|
||||
|
|
@ -45,19 +46,19 @@
|
|||
} while(0)
|
||||
|
||||
struct pair_state_instruction {
|
||||
struct prog_instruction Instruction;
|
||||
GLuint IP; /**< Position of this instruction in original program */
|
||||
struct rc_sub_instruction Instruction;
|
||||
unsigned int IP; /**< Position of this instruction in original program */
|
||||
|
||||
GLuint IsTex:1; /**< Is a texture instruction */
|
||||
GLuint NeedRGB:1; /**< Needs the RGB ALU */
|
||||
GLuint NeedAlpha:1; /**< Needs the Alpha ALU */
|
||||
GLuint IsTranscendent:1; /**< Is a special transcendent instruction */
|
||||
unsigned int IsTex:1; /**< Is a texture instruction */
|
||||
unsigned int NeedRGB:1; /**< Needs the RGB ALU */
|
||||
unsigned int NeedAlpha:1; /**< Needs the Alpha ALU */
|
||||
unsigned int IsTranscendent:1; /**< Is a special transcendent instruction */
|
||||
|
||||
/**
|
||||
* Number of (read and write) dependencies that must be resolved before
|
||||
* this instruction can be scheduled.
|
||||
*/
|
||||
GLuint NumDependencies:5;
|
||||
unsigned int NumDependencies:5;
|
||||
|
||||
/**
|
||||
* Next instruction in the linked list of ready instructions.
|
||||
|
|
@ -81,11 +82,11 @@ struct reg_value_reader {
|
|||
|
||||
/**
|
||||
* Used to keep track which values are stored in each component of a
|
||||
* PROGRAM_TEMPORARY.
|
||||
* RC_FILE_TEMPORARY.
|
||||
*/
|
||||
struct reg_value {
|
||||
struct pair_state_instruction *Writer;
|
||||
struct reg_value *Next; /**< Pointer to the next value to be written to the same PROGRAM_TEMPORARY component */
|
||||
struct reg_value *Next; /**< Pointer to the next value to be written to the same RC_FILE_TEMPORARY component */
|
||||
|
||||
/**
|
||||
* Unordered linked list of instructions that read from this value.
|
||||
|
|
@ -98,21 +99,21 @@ struct reg_value {
|
|||
* When this count reaches zero, the instruction that writes the @ref Next value
|
||||
* can be scheduled.
|
||||
*/
|
||||
GLuint NumReaders;
|
||||
unsigned int NumReaders;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to translate a PROGRAM_INPUT or PROGRAM_TEMPORARY Mesa register
|
||||
* Used to translate a RC_FILE_INPUT or RC_FILE_TEMPORARY Mesa register
|
||||
* to the proper hardware temporary.
|
||||
*/
|
||||
struct pair_register_translation {
|
||||
GLuint Allocated:1;
|
||||
GLuint HwIndex:8;
|
||||
GLuint RefCount:23; /**< # of times this occurs in an unscheduled instruction SrcReg or DstReg */
|
||||
unsigned int Allocated:1;
|
||||
unsigned int HwIndex:8;
|
||||
unsigned int RefCount:23; /**< # of times this occurs in an unscheduled instruction SrcReg or DstReg */
|
||||
|
||||
/**
|
||||
* Notes the value that is currently contained in each component
|
||||
* (only used for PROGRAM_TEMPORARY registers).
|
||||
* (only used for RC_FILE_TEMPORARY registers).
|
||||
*/
|
||||
struct reg_value *Value[4];
|
||||
};
|
||||
|
|
@ -120,17 +121,17 @@ struct pair_register_translation {
|
|||
struct pair_state {
|
||||
struct r300_fragment_program_compiler * Compiler;
|
||||
const struct radeon_pair_handler *Handler;
|
||||
GLboolean Verbose;
|
||||
unsigned int Verbose;
|
||||
void *UserData;
|
||||
|
||||
/**
|
||||
* Translate Mesa registers to hardware registers
|
||||
*/
|
||||
struct pair_register_translation Inputs[FRAG_ATTRIB_MAX];
|
||||
struct pair_register_translation Temps[MAX_PROGRAM_TEMPS];
|
||||
struct pair_register_translation Inputs[RC_REGISTER_MAX_INDEX];
|
||||
struct pair_register_translation Temps[RC_REGISTER_MAX_INDEX];
|
||||
|
||||
struct {
|
||||
GLuint RefCount; /**< # of times this occurs in an unscheduled SrcReg or DstReg */
|
||||
unsigned int RefCount; /**< # of times this occurs in an unscheduled SrcReg or DstReg */
|
||||
} HwTemps[128];
|
||||
|
||||
/**
|
||||
|
|
@ -144,28 +145,28 @@ struct pair_state {
|
|||
};
|
||||
|
||||
|
||||
static struct pair_register_translation *get_register(struct pair_state *s, GLuint file, GLuint index)
|
||||
static struct pair_register_translation *get_register(struct pair_state *s, rc_register_file file, unsigned int index)
|
||||
{
|
||||
switch(file) {
|
||||
case PROGRAM_TEMPORARY: return &s->Temps[index];
|
||||
case PROGRAM_INPUT: return &s->Inputs[index];
|
||||
case RC_FILE_TEMPORARY: return &s->Temps[index];
|
||||
case RC_FILE_INPUT: return &s->Inputs[index];
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void alloc_hw_reg(struct pair_state *s, GLuint file, GLuint index, GLuint hwindex)
|
||||
static void alloc_hw_reg(struct pair_state *s, rc_register_file file, unsigned int index, unsigned int hwindex)
|
||||
{
|
||||
struct pair_register_translation *t = get_register(s, file, index);
|
||||
ASSERT(!s->HwTemps[hwindex].RefCount);
|
||||
ASSERT(!t->Allocated);
|
||||
assert(!s->HwTemps[hwindex].RefCount);
|
||||
assert(!t->Allocated);
|
||||
s->HwTemps[hwindex].RefCount = t->RefCount;
|
||||
t->Allocated = 1;
|
||||
t->HwIndex = hwindex;
|
||||
}
|
||||
|
||||
static GLuint get_hw_reg(struct pair_state *s, GLuint file, GLuint index)
|
||||
static unsigned int get_hw_reg(struct pair_state *s, rc_register_file file, unsigned int index)
|
||||
{
|
||||
GLuint hwindex;
|
||||
unsigned int hwindex;
|
||||
|
||||
struct pair_register_translation *t = get_register(s, file, index);
|
||||
if (!t) {
|
||||
|
|
@ -190,7 +191,7 @@ static GLuint get_hw_reg(struct pair_state *s, GLuint file, GLuint index)
|
|||
}
|
||||
|
||||
|
||||
static void deref_hw_reg(struct pair_state *s, GLuint hwindex)
|
||||
static void deref_hw_reg(struct pair_state *s, unsigned int hwindex)
|
||||
{
|
||||
if (!s->HwTemps[hwindex].RefCount) {
|
||||
error("Hwindex %i refcount error", hwindex);
|
||||
|
|
@ -213,7 +214,7 @@ static void add_pairinst_to_list(struct pair_state_instruction **list, struct pa
|
|||
static void instruction_ready(struct pair_state *s, struct pair_state_instruction *pairinst)
|
||||
{
|
||||
if (s->Verbose)
|
||||
_mesa_printf("instruction_ready(%i)\n", pairinst->IP);
|
||||
fprintf(stderr, "instruction_ready(%i)\n", pairinst->IP);
|
||||
|
||||
if (pairinst->IsTex)
|
||||
add_pairinst_to_list(&s->ReadyTEX, pairinst);
|
||||
|
|
@ -230,24 +231,24 @@ static void instruction_ready(struct pair_state *s, struct pair_state_instructio
|
|||
* Finally rewrite ADD, MOV, MUL as the appropriate native instruction
|
||||
* and reverse the order of arguments for CMP.
|
||||
*/
|
||||
static void final_rewrite(struct pair_state *s, struct prog_instruction *inst)
|
||||
static void final_rewrite(struct pair_state *s, struct rc_sub_instruction *inst)
|
||||
{
|
||||
struct prog_src_register tmp;
|
||||
struct rc_src_register tmp;
|
||||
|
||||
switch(inst->Opcode) {
|
||||
case OPCODE_ADD:
|
||||
case RC_OPCODE_ADD:
|
||||
inst->SrcReg[2] = inst->SrcReg[1];
|
||||
inst->SrcReg[1].File = PROGRAM_BUILTIN;
|
||||
inst->SrcReg[1].Swizzle = SWIZZLE_1111;
|
||||
inst->SrcReg[1].Negate = NEGATE_NONE;
|
||||
inst->Opcode = OPCODE_MAD;
|
||||
inst->SrcReg[1].File = RC_FILE_NONE;
|
||||
inst->SrcReg[1].Swizzle = RC_SWIZZLE_1111;
|
||||
inst->SrcReg[1].Negate = RC_MASK_NONE;
|
||||
inst->Opcode = RC_OPCODE_MAD;
|
||||
break;
|
||||
case OPCODE_CMP:
|
||||
case RC_OPCODE_CMP:
|
||||
tmp = inst->SrcReg[2];
|
||||
inst->SrcReg[2] = inst->SrcReg[0];
|
||||
inst->SrcReg[0] = tmp;
|
||||
break;
|
||||
case OPCODE_MOV:
|
||||
case RC_OPCODE_MOV:
|
||||
/* AMD say we should use CMP.
|
||||
* However, when we transform
|
||||
* KIL -r0;
|
||||
|
|
@ -258,16 +259,16 @@ static void final_rewrite(struct pair_state *s, struct prog_instruction *inst)
|
|||
* It appears that the R500 KIL hardware treats -0.0 as less
|
||||
* than zero.
|
||||
*/
|
||||
inst->SrcReg[1].File = PROGRAM_BUILTIN;
|
||||
inst->SrcReg[1].Swizzle = SWIZZLE_1111;
|
||||
inst->SrcReg[2].File = PROGRAM_BUILTIN;
|
||||
inst->SrcReg[2].Swizzle = SWIZZLE_0000;
|
||||
inst->Opcode = OPCODE_MAD;
|
||||
inst->SrcReg[1].File = RC_FILE_NONE;
|
||||
inst->SrcReg[1].Swizzle = RC_SWIZZLE_1111;
|
||||
inst->SrcReg[2].File = RC_FILE_NONE;
|
||||
inst->SrcReg[2].Swizzle = RC_SWIZZLE_0000;
|
||||
inst->Opcode = RC_OPCODE_MAD;
|
||||
break;
|
||||
case OPCODE_MUL:
|
||||
inst->SrcReg[2].File = PROGRAM_BUILTIN;
|
||||
inst->SrcReg[2].Swizzle = SWIZZLE_0000;
|
||||
inst->Opcode = OPCODE_MAD;
|
||||
case RC_OPCODE_MUL:
|
||||
inst->SrcReg[2].File = RC_FILE_NONE;
|
||||
inst->SrcReg[2].Swizzle = RC_SWIZZLE_0000;
|
||||
inst->Opcode = RC_OPCODE_MAD;
|
||||
break;
|
||||
default:
|
||||
/* nothing to do */
|
||||
|
|
@ -282,41 +283,40 @@ static void final_rewrite(struct pair_state *s, struct prog_instruction *inst)
|
|||
static void classify_instruction(struct pair_state *s,
|
||||
struct pair_state_instruction *psi)
|
||||
{
|
||||
psi->NeedRGB = (psi->Instruction.DstReg.WriteMask & WRITEMASK_XYZ) ? 1 : 0;
|
||||
psi->NeedAlpha = (psi->Instruction.DstReg.WriteMask & WRITEMASK_W) ? 1 : 0;
|
||||
psi->NeedRGB = (psi->Instruction.DstReg.WriteMask & RC_MASK_XYZ) ? 1 : 0;
|
||||
psi->NeedAlpha = (psi->Instruction.DstReg.WriteMask & RC_MASK_W) ? 1 : 0;
|
||||
|
||||
switch(psi->Instruction.Opcode) {
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_DDX:
|
||||
case OPCODE_DDY:
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MAD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_MUL:
|
||||
case RC_OPCODE_ADD:
|
||||
case RC_OPCODE_CMP:
|
||||
case RC_OPCODE_DDX:
|
||||
case RC_OPCODE_DDY:
|
||||
case RC_OPCODE_FRC:
|
||||
case RC_OPCODE_MAD:
|
||||
case RC_OPCODE_MAX:
|
||||
case RC_OPCODE_MIN:
|
||||
case RC_OPCODE_MOV:
|
||||
case RC_OPCODE_MUL:
|
||||
break;
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case RC_OPCODE_COS:
|
||||
case RC_OPCODE_EX2:
|
||||
case RC_OPCODE_LG2:
|
||||
case RC_OPCODE_RCP:
|
||||
case RC_OPCODE_RSQ:
|
||||
case RC_OPCODE_SIN:
|
||||
psi->IsTranscendent = 1;
|
||||
psi->NeedAlpha = 1;
|
||||
break;
|
||||
case OPCODE_DP4:
|
||||
case RC_OPCODE_DP4:
|
||||
psi->NeedAlpha = 1;
|
||||
/* fall through */
|
||||
case OPCODE_DP3:
|
||||
case RC_OPCODE_DP3:
|
||||
psi->NeedRGB = 1;
|
||||
break;
|
||||
case OPCODE_KIL:
|
||||
case OPCODE_TEX:
|
||||
case OPCODE_TXB:
|
||||
case OPCODE_TXP:
|
||||
case OPCODE_END:
|
||||
case RC_OPCODE_KIL:
|
||||
case RC_OPCODE_TEX:
|
||||
case RC_OPCODE_TXB:
|
||||
case RC_OPCODE_TXP:
|
||||
psi->IsTex = 1;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -333,7 +333,7 @@ static void classify_instruction(struct pair_state *s,
|
|||
static void scan_instructions(struct pair_state *s)
|
||||
{
|
||||
struct rc_instruction *source;
|
||||
GLuint ip;
|
||||
unsigned int ip;
|
||||
|
||||
for(source = s->Compiler->Base.Program.Instructions.Next, ip = 0;
|
||||
source != &s->Compiler->Base.Program.Instructions;
|
||||
|
|
@ -346,9 +346,9 @@ static void scan_instructions(struct pair_state *s)
|
|||
final_rewrite(s, &pairinst->Instruction);
|
||||
classify_instruction(s, pairinst);
|
||||
|
||||
int nsrc = _mesa_num_inst_src_regs(pairinst->Instruction.Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(pairinst->Instruction.Opcode);
|
||||
int j;
|
||||
for(j = 0; j < nsrc; j++) {
|
||||
for(j = 0; j < opcode->NumSrcRegs; j++) {
|
||||
struct pair_register_translation *t =
|
||||
get_register(s, pairinst->Instruction.SrcReg[j].File, pairinst->Instruction.SrcReg[j].Index);
|
||||
if (!t)
|
||||
|
|
@ -356,10 +356,10 @@ static void scan_instructions(struct pair_state *s)
|
|||
|
||||
t->RefCount++;
|
||||
|
||||
if (pairinst->Instruction.SrcReg[j].File == PROGRAM_TEMPORARY) {
|
||||
if (pairinst->Instruction.SrcReg[j].File == RC_FILE_TEMPORARY) {
|
||||
int i;
|
||||
for(i = 0; i < 4; ++i) {
|
||||
GLuint swz = GET_SWZ(pairinst->Instruction.SrcReg[j].Swizzle, i);
|
||||
unsigned int swz = GET_SWZ(pairinst->Instruction.SrcReg[j].Swizzle, i);
|
||||
if (swz >= 4)
|
||||
continue; /* constant or NIL swizzle */
|
||||
if (!t->Value[swz])
|
||||
|
|
@ -369,7 +369,7 @@ static void scan_instructions(struct pair_state *s)
|
|||
* also rewrites the value. The code below adds
|
||||
* a dependency for the DstReg, which is a superset
|
||||
* of the SrcReg dependency. */
|
||||
if (pairinst->Instruction.DstReg.File == PROGRAM_TEMPORARY &&
|
||||
if (pairinst->Instruction.DstReg.File == RC_FILE_TEMPORARY &&
|
||||
pairinst->Instruction.DstReg.Index == pairinst->Instruction.SrcReg[j].Index &&
|
||||
GET_BIT(pairinst->Instruction.DstReg.WriteMask, swz))
|
||||
continue;
|
||||
|
|
@ -384,14 +384,13 @@ static void scan_instructions(struct pair_state *s)
|
|||
}
|
||||
}
|
||||
|
||||
int ndst = _mesa_num_inst_dst_regs(pairinst->Instruction.Opcode);
|
||||
if (ndst) {
|
||||
if (opcode->HasDstReg) {
|
||||
struct pair_register_translation *t =
|
||||
get_register(s, pairinst->Instruction.DstReg.File, pairinst->Instruction.DstReg.Index);
|
||||
if (t) {
|
||||
t->RefCount++;
|
||||
|
||||
if (pairinst->Instruction.DstReg.File == PROGRAM_TEMPORARY) {
|
||||
if (pairinst->Instruction.DstReg.File == RC_FILE_TEMPORARY) {
|
||||
int j;
|
||||
for(j = 0; j < 4; ++j) {
|
||||
if (!GET_BIT(pairinst->Instruction.DstReg.WriteMask, j))
|
||||
|
|
@ -412,15 +411,15 @@ static void scan_instructions(struct pair_state *s)
|
|||
}
|
||||
|
||||
if (s->Verbose)
|
||||
_mesa_printf("scan(%i): NumDeps = %i\n", ip, pairinst->NumDependencies);
|
||||
fprintf(stderr, "scan(%i): NumDeps = %i\n", ip, pairinst->NumDependencies);
|
||||
|
||||
if (!pairinst->NumDependencies)
|
||||
instruction_ready(s, pairinst);
|
||||
}
|
||||
|
||||
/* Clear the PROGRAM_TEMPORARY state */
|
||||
/* Clear the RC_FILE_TEMPORARY state */
|
||||
int i, j;
|
||||
for(i = 0; i < MAX_PROGRAM_TEMPS; ++i) {
|
||||
for(i = 0; i < RC_REGISTER_MAX_INDEX; ++i) {
|
||||
for(j = 0; j < 4; ++j)
|
||||
s->Temps[i].Value[j] = 0;
|
||||
}
|
||||
|
|
@ -429,7 +428,7 @@ static void scan_instructions(struct pair_state *s)
|
|||
|
||||
static void decrement_dependencies(struct pair_state *s, struct pair_state_instruction *pairinst)
|
||||
{
|
||||
ASSERT(pairinst->NumDependencies > 0);
|
||||
assert(pairinst->NumDependencies > 0);
|
||||
if (!--pairinst->NumDependencies)
|
||||
instruction_ready(s, pairinst);
|
||||
}
|
||||
|
|
@ -440,12 +439,12 @@ static void decrement_dependencies(struct pair_state *s, struct pair_state_instr
|
|||
*/
|
||||
static void commit_instruction(struct pair_state *s, struct pair_state_instruction *pairinst)
|
||||
{
|
||||
struct prog_instruction *inst = &pairinst->Instruction;
|
||||
struct rc_sub_instruction *inst = &pairinst->Instruction;
|
||||
|
||||
if (s->Verbose)
|
||||
_mesa_printf("commit_instruction(%i)\n", pairinst->IP);
|
||||
fprintf(stderr, "commit_instruction(%i)\n", pairinst->IP);
|
||||
|
||||
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
|
||||
if (inst->DstReg.File == RC_FILE_TEMPORARY) {
|
||||
struct pair_register_translation *t = &s->Temps[inst->DstReg.Index];
|
||||
deref_hw_reg(s, t->HwIndex);
|
||||
|
||||
|
|
@ -467,21 +466,21 @@ static void commit_instruction(struct pair_state *s, struct pair_state_instructi
|
|||
}
|
||||
}
|
||||
|
||||
int nsrc = _mesa_num_inst_src_regs(inst->Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
|
||||
int i;
|
||||
for(i = 0; i < nsrc; i++) {
|
||||
for(i = 0; i < opcode->NumSrcRegs; i++) {
|
||||
struct pair_register_translation *t = get_register(s, inst->SrcReg[i].File, inst->SrcReg[i].Index);
|
||||
if (!t)
|
||||
continue;
|
||||
|
||||
deref_hw_reg(s, get_hw_reg(s, inst->SrcReg[i].File, inst->SrcReg[i].Index));
|
||||
|
||||
if (inst->SrcReg[i].File != PROGRAM_TEMPORARY)
|
||||
if (inst->SrcReg[i].File != RC_FILE_TEMPORARY)
|
||||
continue;
|
||||
|
||||
int j;
|
||||
for(j = 0; j < 4; ++j) {
|
||||
GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, j);
|
||||
unsigned int swz = GET_SWZ(inst->SrcReg[i].Swizzle, j);
|
||||
if (swz >= 4)
|
||||
continue;
|
||||
if (!t->Value[swz])
|
||||
|
|
@ -489,7 +488,7 @@ static void commit_instruction(struct pair_state *s, struct pair_state_instructi
|
|||
|
||||
/* Do not free a dependency if this instruction
|
||||
* also rewrites the value. See scan_instructions. */
|
||||
if (inst->DstReg.File == PROGRAM_TEMPORARY &&
|
||||
if (inst->DstReg.File == RC_FILE_TEMPORARY &&
|
||||
inst->DstReg.Index == inst->SrcReg[i].Index &&
|
||||
GET_BIT(inst->DstReg.WriteMask, swz))
|
||||
continue;
|
||||
|
|
@ -519,7 +518,7 @@ static void emit_all_tex(struct pair_state *s)
|
|||
struct pair_state_instruction *readytex;
|
||||
struct pair_state_instruction *pairinst;
|
||||
|
||||
ASSERT(s->ReadyTEX);
|
||||
assert(s->ReadyTEX);
|
||||
|
||||
// Don't let the ready list change under us!
|
||||
readytex = s->ReadyTEX;
|
||||
|
|
@ -527,39 +526,37 @@ static void emit_all_tex(struct pair_state *s)
|
|||
|
||||
// Allocate destination hardware registers in one block to avoid conflicts.
|
||||
for(pairinst = readytex; pairinst; pairinst = pairinst->NextReady) {
|
||||
struct prog_instruction *inst = &pairinst->Instruction;
|
||||
if (inst->Opcode != OPCODE_KIL)
|
||||
struct rc_sub_instruction *inst = &pairinst->Instruction;
|
||||
if (inst->Opcode != RC_OPCODE_KIL)
|
||||
get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
|
||||
}
|
||||
|
||||
if (s->Compiler->Base.Debug)
|
||||
_mesa_printf(" BEGIN_TEX\n");
|
||||
fprintf(stderr, " BEGIN_TEX\n");
|
||||
|
||||
if (s->Handler->BeginTexBlock)
|
||||
s->Compiler->Base.Error = s->Compiler->Base.Error || !s->Handler->BeginTexBlock(s->UserData);
|
||||
|
||||
for(pairinst = readytex; pairinst; pairinst = pairinst->NextReady) {
|
||||
struct prog_instruction *inst = &pairinst->Instruction;
|
||||
struct rc_sub_instruction *inst = &pairinst->Instruction;
|
||||
commit_instruction(s, pairinst);
|
||||
|
||||
if (inst->Opcode != OPCODE_KIL)
|
||||
if (inst->Opcode != RC_OPCODE_KIL)
|
||||
inst->DstReg.Index = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
|
||||
inst->SrcReg[0].Index = get_hw_reg(s, inst->SrcReg[0].File, inst->SrcReg[0].Index);
|
||||
|
||||
if (s->Compiler->Base.Debug) {
|
||||
_mesa_printf(" ");
|
||||
_mesa_print_instruction(inst);
|
||||
fflush(stderr);
|
||||
/* Should print the TEX instruction here */
|
||||
}
|
||||
|
||||
struct radeon_pair_texture_instruction rpti;
|
||||
|
||||
switch(inst->Opcode) {
|
||||
case OPCODE_TEX: rpti.Opcode = RADEON_OPCODE_TEX; break;
|
||||
case OPCODE_TXB: rpti.Opcode = RADEON_OPCODE_TXB; break;
|
||||
case OPCODE_TXP: rpti.Opcode = RADEON_OPCODE_TXP; break;
|
||||
case RC_OPCODE_TEX: rpti.Opcode = RADEON_OPCODE_TEX; break;
|
||||
case RC_OPCODE_TXB: rpti.Opcode = RADEON_OPCODE_TXB; break;
|
||||
case RC_OPCODE_TXP: rpti.Opcode = RADEON_OPCODE_TXP; break;
|
||||
default:
|
||||
case OPCODE_KIL: rpti.Opcode = RADEON_OPCODE_KIL; break;
|
||||
case RC_OPCODE_KIL: rpti.Opcode = RADEON_OPCODE_KIL; break;
|
||||
}
|
||||
|
||||
rpti.DestIndex = inst->DstReg.Index;
|
||||
|
|
@ -573,12 +570,12 @@ static void emit_all_tex(struct pair_state *s)
|
|||
}
|
||||
|
||||
if (s->Compiler->Base.Debug)
|
||||
_mesa_printf(" END_TEX\n");
|
||||
fprintf(stderr, " END_TEX\n");
|
||||
}
|
||||
|
||||
|
||||
static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instruction *pair,
|
||||
struct prog_src_register src, GLboolean rgb, GLboolean alpha)
|
||||
struct rc_src_register src, unsigned int rgb, unsigned int alpha)
|
||||
{
|
||||
int candidate = -1;
|
||||
int candidate_quality = -1;
|
||||
|
|
@ -587,10 +584,10 @@ static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instructio
|
|||
if (!rgb && !alpha)
|
||||
return 0;
|
||||
|
||||
GLuint constant;
|
||||
GLuint index;
|
||||
unsigned int constant;
|
||||
unsigned int index;
|
||||
|
||||
if (src.File == PROGRAM_TEMPORARY || src.File == PROGRAM_INPUT) {
|
||||
if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) {
|
||||
constant = 0;
|
||||
index = get_hw_reg(s, src.File, src.Index);
|
||||
} else {
|
||||
|
|
@ -642,37 +639,38 @@ static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instructio
|
|||
* Fill the given ALU instruction's opcodes and source operands into the given pair,
|
||||
* if possible.
|
||||
*/
|
||||
static GLboolean fill_instruction_into_pair(
|
||||
static int fill_instruction_into_pair(
|
||||
struct pair_state *s,
|
||||
struct radeon_pair_instruction *pair,
|
||||
struct pair_state_instruction *pairinst)
|
||||
{
|
||||
struct prog_instruction *inst = &pairinst->Instruction;
|
||||
struct rc_sub_instruction *inst = &pairinst->Instruction;
|
||||
|
||||
ASSERT(!pairinst->NeedRGB || pair->RGB.Opcode == OPCODE_NOP);
|
||||
ASSERT(!pairinst->NeedAlpha || pair->Alpha.Opcode == OPCODE_NOP);
|
||||
assert(!pairinst->NeedRGB || pair->RGB.Opcode == RC_OPCODE_NOP);
|
||||
assert(!pairinst->NeedAlpha || pair->Alpha.Opcode == RC_OPCODE_NOP);
|
||||
|
||||
if (pairinst->NeedRGB) {
|
||||
if (pairinst->IsTranscendent)
|
||||
pair->RGB.Opcode = OPCODE_REPL_ALPHA;
|
||||
pair->RGB.Opcode = RC_OPCODE_REPL_ALPHA;
|
||||
else
|
||||
pair->RGB.Opcode = inst->Opcode;
|
||||
if (inst->SaturateMode == SATURATE_ZERO_ONE)
|
||||
if (inst->SaturateMode == RC_SATURATE_ZERO_ONE)
|
||||
pair->RGB.Saturate = 1;
|
||||
}
|
||||
if (pairinst->NeedAlpha) {
|
||||
pair->Alpha.Opcode = inst->Opcode;
|
||||
if (inst->SaturateMode == SATURATE_ZERO_ONE)
|
||||
if (inst->SaturateMode == RC_SATURATE_ZERO_ONE)
|
||||
pair->Alpha.Saturate = 1;
|
||||
}
|
||||
|
||||
int nargs = _mesa_num_inst_src_regs(inst->Opcode);
|
||||
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
|
||||
int nargs = opcode->NumSrcRegs;
|
||||
int i;
|
||||
|
||||
/* Special case for DDX/DDY (MDH/MDV). */
|
||||
if (inst->Opcode == OPCODE_DDX || inst->Opcode == OPCODE_DDY) {
|
||||
if (inst->Opcode == RC_OPCODE_DDX || inst->Opcode == RC_OPCODE_DDY) {
|
||||
if (pair->RGB.Src[0].Used || pair->Alpha.Src[0].Used)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
else
|
||||
nargs++;
|
||||
}
|
||||
|
|
@ -680,43 +678,43 @@ static GLboolean fill_instruction_into_pair(
|
|||
for(i = 0; i < nargs; ++i) {
|
||||
int source;
|
||||
if (pairinst->NeedRGB && !pairinst->IsTranscendent) {
|
||||
GLboolean srcrgb = GL_FALSE;
|
||||
GLboolean srcalpha = GL_FALSE;
|
||||
unsigned int srcrgb = 0;
|
||||
unsigned int srcalpha = 0;
|
||||
int j;
|
||||
for(j = 0; j < 3; ++j) {
|
||||
GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, j);
|
||||
unsigned int swz = GET_SWZ(inst->SrcReg[i].Swizzle, j);
|
||||
if (swz < 3)
|
||||
srcrgb = GL_TRUE;
|
||||
srcrgb = 1;
|
||||
else if (swz < 4)
|
||||
srcalpha = GL_TRUE;
|
||||
srcalpha = 1;
|
||||
}
|
||||
source = alloc_pair_source(s, pair, inst->SrcReg[i], srcrgb, srcalpha);
|
||||
if (source < 0)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
pair->RGB.Arg[i].Source = source;
|
||||
pair->RGB.Arg[i].Swizzle = inst->SrcReg[i].Swizzle & 0x1ff;
|
||||
pair->RGB.Arg[i].Abs = inst->SrcReg[i].Abs;
|
||||
pair->RGB.Arg[i].Negate = !!(inst->SrcReg[i].Negate & (NEGATE_X | NEGATE_Y | NEGATE_Z));
|
||||
pair->RGB.Arg[i].Negate = !!(inst->SrcReg[i].Negate & (RC_MASK_X | RC_MASK_Y | RC_MASK_Z));
|
||||
}
|
||||
if (pairinst->NeedAlpha) {
|
||||
GLboolean srcrgb = GL_FALSE;
|
||||
GLboolean srcalpha = GL_FALSE;
|
||||
GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, pairinst->IsTranscendent ? 0 : 3);
|
||||
unsigned int srcrgb = 0;
|
||||
unsigned int srcalpha = 0;
|
||||
unsigned int swz = GET_SWZ(inst->SrcReg[i].Swizzle, pairinst->IsTranscendent ? 0 : 3);
|
||||
if (swz < 3)
|
||||
srcrgb = GL_TRUE;
|
||||
srcrgb = 1;
|
||||
else if (swz < 4)
|
||||
srcalpha = GL_TRUE;
|
||||
srcalpha = 1;
|
||||
source = alloc_pair_source(s, pair, inst->SrcReg[i], srcrgb, srcalpha);
|
||||
if (source < 0)
|
||||
return GL_FALSE;
|
||||
return 0;
|
||||
pair->Alpha.Arg[i].Source = source;
|
||||
pair->Alpha.Arg[i].Swizzle = swz;
|
||||
pair->Alpha.Arg[i].Abs = inst->SrcReg[i].Abs;
|
||||
pair->Alpha.Arg[i].Negate = !!(inst->SrcReg[i].Negate & NEGATE_W);
|
||||
pair->Alpha.Arg[i].Negate = !!(inst->SrcReg[i].Negate & RC_MASK_W);
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -733,20 +731,20 @@ static void fill_dest_into_pair(
|
|||
struct radeon_pair_instruction *pair,
|
||||
struct pair_state_instruction *pairinst)
|
||||
{
|
||||
struct prog_instruction *inst = &pairinst->Instruction;
|
||||
struct rc_sub_instruction *inst = &pairinst->Instruction;
|
||||
|
||||
if (inst->DstReg.File == PROGRAM_OUTPUT) {
|
||||
if (inst->DstReg.File == RC_FILE_OUTPUT) {
|
||||
if (inst->DstReg.Index == s->Compiler->OutputColor) {
|
||||
pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & WRITEMASK_XYZ;
|
||||
pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ;
|
||||
pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
|
||||
} else if (inst->DstReg.Index == s->Compiler->OutputDepth) {
|
||||
pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
|
||||
}
|
||||
} else {
|
||||
GLuint hwindex = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
|
||||
unsigned int hwindex = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
|
||||
if (pairinst->NeedRGB) {
|
||||
pair->RGB.DestIndex = hwindex;
|
||||
pair->RGB.WriteMask |= inst->DstReg.WriteMask & WRITEMASK_XYZ;
|
||||
pair->RGB.WriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ;
|
||||
}
|
||||
if (pairinst->NeedAlpha) {
|
||||
pair->Alpha.DestIndex = hwindex;
|
||||
|
|
@ -780,7 +778,7 @@ static void emit_alu(struct pair_state *s)
|
|||
s->ReadyAlpha = s->ReadyAlpha->NextReady;
|
||||
}
|
||||
|
||||
_mesa_bzero(&pair, sizeof(pair));
|
||||
memset(&pair, 0, sizeof(pair));
|
||||
fill_instruction_into_pair(s, &pair, psi);
|
||||
fill_dest_into_pair(s, &pair, psi);
|
||||
commit_instruction(s, psi);
|
||||
|
|
@ -794,7 +792,7 @@ static void emit_alu(struct pair_state *s)
|
|||
for(palpha = &s->ReadyAlpha; *palpha; palpha = &(*palpha)->NextReady) {
|
||||
struct pair_state_instruction * psirgb = *prgb;
|
||||
struct pair_state_instruction * psialpha = *palpha;
|
||||
_mesa_bzero(&pair, sizeof(pair));
|
||||
memset(&pair, 0, sizeof(pair));
|
||||
fill_instruction_into_pair(s, &pair, psirgb);
|
||||
if (!fill_instruction_into_pair(s, &pair, psialpha))
|
||||
continue;
|
||||
|
|
@ -812,7 +810,7 @@ static void emit_alu(struct pair_state *s)
|
|||
psi = s->ReadyRGB;
|
||||
s->ReadyRGB = s->ReadyRGB->NextReady;
|
||||
|
||||
_mesa_bzero(&pair, sizeof(pair));
|
||||
memset(&pair, 0, sizeof(pair));
|
||||
fill_instruction_into_pair(s, &pair, psi);
|
||||
fill_dest_into_pair(s, &pair, psi);
|
||||
commit_instruction(s, psi);
|
||||
|
|
@ -829,7 +827,7 @@ static void emit_alu(struct pair_state *s)
|
|||
static void alloc_helper(void * data, unsigned input, unsigned hwreg)
|
||||
{
|
||||
struct pair_state * s = data;
|
||||
alloc_hw_reg(s, PROGRAM_INPUT, input, hwreg);
|
||||
alloc_hw_reg(s, RC_FILE_INPUT, input, hwreg);
|
||||
}
|
||||
|
||||
void radeonPairProgram(
|
||||
|
|
@ -838,14 +836,14 @@ void radeonPairProgram(
|
|||
{
|
||||
struct pair_state s;
|
||||
|
||||
_mesa_bzero(&s, sizeof(s));
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.Compiler = compiler;
|
||||
s.Handler = handler;
|
||||
s.UserData = userdata;
|
||||
s.Verbose = GL_FALSE && s.Compiler->Base.Debug;
|
||||
s.Verbose = 0 && s.Compiler->Base.Debug;
|
||||
|
||||
if (s.Compiler->Base.Debug)
|
||||
_mesa_printf("Emit paired program\n");
|
||||
fprintf(stderr, "Emit paired program\n");
|
||||
|
||||
scan_instructions(&s);
|
||||
s.Compiler->AllocateHwInputs(s.Compiler, &alloc_helper, &s);
|
||||
|
|
@ -860,41 +858,36 @@ void radeonPairProgram(
|
|||
}
|
||||
|
||||
if (s.Compiler->Base.Debug)
|
||||
_mesa_printf(" END\n");
|
||||
fprintf(stderr, " END\n");
|
||||
}
|
||||
|
||||
|
||||
static void print_pair_src(int i, struct radeon_pair_instruction_source* src)
|
||||
{
|
||||
_mesa_printf(" Src%i = %s[%i]", i, src->Constant ? "CNST" : "TEMP", src->Index);
|
||||
fprintf(stderr, " Src%i = %s[%i]", i, src->Constant ? "CNST" : "TEMP", src->Index);
|
||||
}
|
||||
|
||||
static const char* opcode_string(GLuint opcode)
|
||||
static const char* opcode_string(rc_opcode opcode)
|
||||
{
|
||||
if (opcode == OPCODE_REPL_ALPHA)
|
||||
return "SOP";
|
||||
else
|
||||
return _mesa_opcode_string(opcode);
|
||||
return rc_get_opcode_info(opcode)->Name;
|
||||
}
|
||||
|
||||
static int num_pairinst_args(GLuint opcode)
|
||||
static int num_pairinst_args(rc_opcode opcode)
|
||||
{
|
||||
if (opcode == OPCODE_REPL_ALPHA)
|
||||
return 0;
|
||||
else
|
||||
return _mesa_num_inst_src_regs(opcode);
|
||||
return rc_get_opcode_info(opcode)->NumSrcRegs;
|
||||
}
|
||||
|
||||
static char swizzle_char(GLuint swz)
|
||||
static char swizzle_char(rc_swizzle swz)
|
||||
{
|
||||
switch(swz) {
|
||||
case SWIZZLE_X: return 'x';
|
||||
case SWIZZLE_Y: return 'y';
|
||||
case SWIZZLE_Z: return 'z';
|
||||
case SWIZZLE_W: return 'w';
|
||||
case SWIZZLE_ZERO: return '0';
|
||||
case SWIZZLE_ONE: return '1';
|
||||
case SWIZZLE_NIL: return '_';
|
||||
case RC_SWIZZLE_X: return 'x';
|
||||
case RC_SWIZZLE_Y: return 'y';
|
||||
case RC_SWIZZLE_Z: return 'z';
|
||||
case RC_SWIZZLE_W: return 'w';
|
||||
case RC_SWIZZLE_ZERO: return '0';
|
||||
case RC_SWIZZLE_ONE: return '1';
|
||||
case RC_SWIZZLE_HALF: return 'H';
|
||||
case RC_SWIZZLE_UNUSED: return '_';
|
||||
default: return '?';
|
||||
}
|
||||
}
|
||||
|
|
@ -904,27 +897,27 @@ void radeonPrintPairInstruction(struct radeon_pair_instruction *inst)
|
|||
int nargs;
|
||||
int i;
|
||||
|
||||
_mesa_printf(" RGB: ");
|
||||
fprintf(stderr, " RGB: ");
|
||||
for(i = 0; i < 3; ++i) {
|
||||
if (inst->RGB.Src[i].Used)
|
||||
print_pair_src(i, inst->RGB.Src + i);
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
_mesa_printf(" Alpha:");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " Alpha:");
|
||||
for(i = 0; i < 3; ++i) {
|
||||
if (inst->Alpha.Src[i].Used)
|
||||
print_pair_src(i, inst->Alpha.Src + i);
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
_mesa_printf(" %s%s", opcode_string(inst->RGB.Opcode), inst->RGB.Saturate ? "_SAT" : "");
|
||||
fprintf(stderr, " %s%s", opcode_string(inst->RGB.Opcode), inst->RGB.Saturate ? "_SAT" : "");
|
||||
if (inst->RGB.WriteMask)
|
||||
_mesa_printf(" TEMP[%i].%s%s%s", inst->RGB.DestIndex,
|
||||
fprintf(stderr, " TEMP[%i].%s%s%s", inst->RGB.DestIndex,
|
||||
(inst->RGB.WriteMask & 1) ? "x" : "",
|
||||
(inst->RGB.WriteMask & 2) ? "y" : "",
|
||||
(inst->RGB.WriteMask & 4) ? "z" : "");
|
||||
if (inst->RGB.OutputWriteMask)
|
||||
_mesa_printf(" COLOR.%s%s%s",
|
||||
fprintf(stderr, " COLOR.%s%s%s",
|
||||
(inst->RGB.OutputWriteMask & 1) ? "x" : "",
|
||||
(inst->RGB.OutputWriteMask & 2) ? "y" : "",
|
||||
(inst->RGB.OutputWriteMask & 4) ? "z" : "");
|
||||
|
|
@ -932,27 +925,27 @@ void radeonPrintPairInstruction(struct radeon_pair_instruction *inst)
|
|||
for(i = 0; i < nargs; ++i) {
|
||||
const char* abs = inst->RGB.Arg[i].Abs ? "|" : "";
|
||||
const char* neg = inst->RGB.Arg[i].Negate ? "-" : "";
|
||||
_mesa_printf(", %s%sSrc%i.%c%c%c%s", neg, abs, inst->RGB.Arg[i].Source,
|
||||
fprintf(stderr, ", %s%sSrc%i.%c%c%c%s", neg, abs, inst->RGB.Arg[i].Source,
|
||||
swizzle_char(GET_SWZ(inst->RGB.Arg[i].Swizzle, 0)),
|
||||
swizzle_char(GET_SWZ(inst->RGB.Arg[i].Swizzle, 1)),
|
||||
swizzle_char(GET_SWZ(inst->RGB.Arg[i].Swizzle, 2)),
|
||||
abs);
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
_mesa_printf(" %s%s", opcode_string(inst->Alpha.Opcode), inst->Alpha.Saturate ? "_SAT" : "");
|
||||
fprintf(stderr, " %s%s", opcode_string(inst->Alpha.Opcode), inst->Alpha.Saturate ? "_SAT" : "");
|
||||
if (inst->Alpha.WriteMask)
|
||||
_mesa_printf(" TEMP[%i].w", inst->Alpha.DestIndex);
|
||||
fprintf(stderr, " TEMP[%i].w", inst->Alpha.DestIndex);
|
||||
if (inst->Alpha.OutputWriteMask)
|
||||
_mesa_printf(" COLOR.w");
|
||||
fprintf(stderr, " COLOR.w");
|
||||
if (inst->Alpha.DepthWriteMask)
|
||||
_mesa_printf(" DEPTH.w");
|
||||
fprintf(stderr, " DEPTH.w");
|
||||
nargs = num_pairinst_args(inst->Alpha.Opcode);
|
||||
for(i = 0; i < nargs; ++i) {
|
||||
const char* abs = inst->Alpha.Arg[i].Abs ? "|" : "";
|
||||
const char* neg = inst->Alpha.Arg[i].Negate ? "-" : "";
|
||||
_mesa_printf(", %s%sSrc%i.%c%s", neg, abs, inst->Alpha.Arg[i].Source,
|
||||
fprintf(stderr, ", %s%sSrc%i.%c%s", neg, abs, inst->Alpha.Arg[i].Source,
|
||||
swizzle_char(inst->Alpha.Arg[i].Swizzle), abs);
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,43 +38,43 @@ struct r300_fragment_program_compiler;
|
|||
* fragment programs.
|
||||
*/
|
||||
struct radeon_pair_instruction_source {
|
||||
GLuint Index:8;
|
||||
GLuint Constant:1;
|
||||
GLuint Used:1;
|
||||
unsigned int Index:8;
|
||||
unsigned int Constant:1;
|
||||
unsigned int Used:1;
|
||||
};
|
||||
|
||||
struct radeon_pair_instruction_rgb {
|
||||
GLuint Opcode:8;
|
||||
GLuint DestIndex:8;
|
||||
GLuint WriteMask:3;
|
||||
GLuint OutputWriteMask:3;
|
||||
GLuint Saturate:1;
|
||||
unsigned int Opcode:8;
|
||||
unsigned int DestIndex:8;
|
||||
unsigned int WriteMask:3;
|
||||
unsigned int OutputWriteMask:3;
|
||||
unsigned int Saturate:1;
|
||||
|
||||
struct radeon_pair_instruction_source Src[3];
|
||||
|
||||
struct {
|
||||
GLuint Source:2;
|
||||
GLuint Swizzle:9;
|
||||
GLuint Abs:1;
|
||||
GLuint Negate:1;
|
||||
unsigned int Source:2;
|
||||
unsigned int Swizzle:9;
|
||||
unsigned int Abs:1;
|
||||
unsigned int Negate:1;
|
||||
} Arg[3];
|
||||
};
|
||||
|
||||
struct radeon_pair_instruction_alpha {
|
||||
GLuint Opcode:8;
|
||||
GLuint DestIndex:8;
|
||||
GLuint WriteMask:1;
|
||||
GLuint OutputWriteMask:1;
|
||||
GLuint DepthWriteMask:1;
|
||||
GLuint Saturate:1;
|
||||
unsigned int Opcode:8;
|
||||
unsigned int DestIndex:8;
|
||||
unsigned int WriteMask:1;
|
||||
unsigned int OutputWriteMask:1;
|
||||
unsigned int DepthWriteMask:1;
|
||||
unsigned int Saturate:1;
|
||||
|
||||
struct radeon_pair_instruction_source Src[3];
|
||||
|
||||
struct {
|
||||
GLuint Source:2;
|
||||
GLuint Swizzle:3;
|
||||
GLuint Abs:1;
|
||||
GLuint Negate:1;
|
||||
unsigned int Source:2;
|
||||
unsigned int Swizzle:3;
|
||||
unsigned int Abs:1;
|
||||
unsigned int Negate:1;
|
||||
} Arg[3];
|
||||
};
|
||||
|
||||
|
|
@ -92,16 +92,16 @@ enum {
|
|||
};
|
||||
|
||||
struct radeon_pair_texture_instruction {
|
||||
GLuint Opcode:2; /**< one of RADEON_OPCODE_xxx */
|
||||
unsigned int Opcode:2; /**< one of RADEON_OPCODE_xxx */
|
||||
|
||||
GLuint DestIndex:8;
|
||||
GLuint WriteMask:4;
|
||||
unsigned int DestIndex:8;
|
||||
unsigned int WriteMask:4;
|
||||
|
||||
GLuint TexSrcUnit:5;
|
||||
GLuint TexSrcTarget:3;
|
||||
unsigned int TexSrcUnit:5;
|
||||
unsigned int TexSrcTarget:3;
|
||||
|
||||
GLuint SrcIndex:8;
|
||||
GLuint SrcSwizzle:12;
|
||||
unsigned int SrcIndex:8;
|
||||
unsigned int SrcSwizzle:12;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -112,24 +112,24 @@ struct radeon_pair_handler {
|
|||
/**
|
||||
* Write a paired instruction to the hardware.
|
||||
*
|
||||
* @return GL_FALSE on error.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
GLboolean (*EmitPaired)(void*, struct radeon_pair_instruction*);
|
||||
int (*EmitPaired)(void*, struct radeon_pair_instruction*);
|
||||
|
||||
/**
|
||||
* Write a texture instruction to the hardware.
|
||||
* Register indices have already been rewritten to the allocated
|
||||
* hardware register numbers.
|
||||
*
|
||||
* @return GL_FALSE on error.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
GLboolean (*EmitTex)(void*, struct radeon_pair_texture_instruction*);
|
||||
int (*EmitTex)(void*, struct radeon_pair_texture_instruction*);
|
||||
|
||||
/**
|
||||
* Called before a block of contiguous, independent texture
|
||||
* instructions is emitted.
|
||||
*/
|
||||
GLboolean (*BeginTexBlock)(void*);
|
||||
int (*BeginTexBlock)(void*);
|
||||
|
||||
unsigned MaxHwTemps;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler,
|
|||
*/
|
||||
static void rewriteFog(struct r300_fragment_program_compiler *compiler, struct r300_fragment_program * fp)
|
||||
{
|
||||
struct prog_src_register src;
|
||||
struct rc_src_register src;
|
||||
int i;
|
||||
|
||||
if (!(compiler->Base.Program.InputsRead & FRAG_BIT_FOGC)) {
|
||||
|
|
@ -142,7 +142,7 @@ static void rewriteFog(struct r300_fragment_program_compiler *compiler, struct r
|
|||
}
|
||||
|
||||
memset(&src, 0, sizeof(src));
|
||||
src.File = PROGRAM_INPUT;
|
||||
src.File = RC_FILE_INPUT;
|
||||
src.Index = fp->fog_attr;
|
||||
src.Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
|
||||
rc_move_input(&compiler->Base, FRAG_ATTRIB_FOGC, src);
|
||||
|
|
|
|||
|
|
@ -28,12 +28,153 @@
|
|||
#include "radeon_mesa_to_rc.h"
|
||||
|
||||
#include "main/mtypes.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
|
||||
#include "compiler/radeon_compiler.h"
|
||||
#include "compiler/radeon_program.h"
|
||||
|
||||
|
||||
static rc_opcode translate_opcode(gl_inst_opcode opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case OPCODE_NOP: return RC_OPCODE_NOP;
|
||||
case OPCODE_ABS: return RC_OPCODE_ABS;
|
||||
case OPCODE_ADD: return RC_OPCODE_ADD;
|
||||
case OPCODE_ARL: return RC_OPCODE_ARL;
|
||||
case OPCODE_CMP: return RC_OPCODE_CMP;
|
||||
case OPCODE_COS: return RC_OPCODE_COS;
|
||||
case OPCODE_DDX: return RC_OPCODE_DDX;
|
||||
case OPCODE_DDY: return RC_OPCODE_DDY;
|
||||
case OPCODE_DP3: return RC_OPCODE_DP3;
|
||||
case OPCODE_DP4: return RC_OPCODE_DP4;
|
||||
case OPCODE_DPH: return RC_OPCODE_DPH;
|
||||
case OPCODE_DST: return RC_OPCODE_DST;
|
||||
case OPCODE_EX2: return RC_OPCODE_EX2;
|
||||
case OPCODE_EXP: return RC_OPCODE_EXP;
|
||||
case OPCODE_FLR: return RC_OPCODE_FLR;
|
||||
case OPCODE_FRC: return RC_OPCODE_FRC;
|
||||
case OPCODE_KIL: return RC_OPCODE_KIL;
|
||||
case OPCODE_LG2: return RC_OPCODE_LG2;
|
||||
case OPCODE_LIT: return RC_OPCODE_LIT;
|
||||
case OPCODE_LOG: return RC_OPCODE_LOG;
|
||||
case OPCODE_LRP: return RC_OPCODE_LRP;
|
||||
case OPCODE_MAD: return RC_OPCODE_MAD;
|
||||
case OPCODE_MAX: return RC_OPCODE_MAX;
|
||||
case OPCODE_MIN: return RC_OPCODE_MIN;
|
||||
case OPCODE_MOV: return RC_OPCODE_MOV;
|
||||
case OPCODE_MUL: return RC_OPCODE_MUL;
|
||||
case OPCODE_POW: return RC_OPCODE_POW;
|
||||
case OPCODE_RCP: return RC_OPCODE_RCP;
|
||||
case OPCODE_RSQ: return RC_OPCODE_RSQ;
|
||||
case OPCODE_SCS: return RC_OPCODE_SCS;
|
||||
case OPCODE_SEQ: return RC_OPCODE_SEQ;
|
||||
case OPCODE_SFL: return RC_OPCODE_SFL;
|
||||
case OPCODE_SGE: return RC_OPCODE_SGE;
|
||||
case OPCODE_SGT: return RC_OPCODE_SGT;
|
||||
case OPCODE_SIN: return RC_OPCODE_SIN;
|
||||
case OPCODE_SLE: return RC_OPCODE_SLE;
|
||||
case OPCODE_SLT: return RC_OPCODE_SLT;
|
||||
case OPCODE_SNE: return RC_OPCODE_SNE;
|
||||
case OPCODE_SUB: return RC_OPCODE_SUB;
|
||||
case OPCODE_SWZ: return RC_OPCODE_SWZ;
|
||||
case OPCODE_TEX: return RC_OPCODE_TEX;
|
||||
case OPCODE_TXB: return RC_OPCODE_TXB;
|
||||
case OPCODE_TXD: return RC_OPCODE_TXD;
|
||||
case OPCODE_TXL: return RC_OPCODE_TXL;
|
||||
case OPCODE_TXP: return RC_OPCODE_TXP;
|
||||
case OPCODE_XPD: return RC_OPCODE_XPD;
|
||||
default: return RC_OPCODE_ILLEGAL_OPCODE;
|
||||
}
|
||||
}
|
||||
|
||||
static rc_saturate_mode translate_saturate(unsigned int saturate)
|
||||
{
|
||||
switch(saturate) {
|
||||
default:
|
||||
case SATURATE_OFF: return RC_SATURATE_NONE;
|
||||
case SATURATE_ZERO_ONE: return RC_SATURATE_ZERO_ONE;
|
||||
case SATURATE_PLUS_MINUS_ONE: return RC_SATURATE_MINUS_PLUS_ONE;
|
||||
}
|
||||
}
|
||||
|
||||
static rc_register_file translate_register_file(unsigned int file)
|
||||
{
|
||||
switch(file) {
|
||||
case PROGRAM_TEMPORARY: return RC_FILE_TEMPORARY;
|
||||
case PROGRAM_INPUT: return RC_FILE_INPUT;
|
||||
case PROGRAM_OUTPUT: return RC_FILE_OUTPUT;
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
case PROGRAM_ENV_PARAM:
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
case PROGRAM_UNIFORM: return RC_FILE_CONSTANT;
|
||||
case PROGRAM_ADDRESS: return RC_FILE_ADDRESS;
|
||||
default: return RC_FILE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void translate_srcreg(struct rc_src_register * dest, struct prog_src_register * src)
|
||||
{
|
||||
dest->File = translate_register_file(src->File);
|
||||
dest->Index = src->Index;
|
||||
dest->RelAddr = src->RelAddr;
|
||||
dest->Swizzle = src->Swizzle;
|
||||
dest->Abs = src->Abs;
|
||||
dest->Negate = src->Negate;
|
||||
}
|
||||
|
||||
static void translate_dstreg(struct rc_dst_register * dest, struct prog_dst_register * src)
|
||||
{
|
||||
dest->File = translate_register_file(src->File);
|
||||
dest->Index = src->Index;
|
||||
dest->RelAddr = src->RelAddr;
|
||||
dest->WriteMask = src->WriteMask;
|
||||
}
|
||||
|
||||
static rc_texture_target translate_tex_target(gl_texture_index target)
|
||||
{
|
||||
switch(target) {
|
||||
case TEXTURE_2D_ARRAY_INDEX: return RC_TEXTURE_2D_ARRAY;
|
||||
case TEXTURE_1D_ARRAY_INDEX: return RC_TEXTURE_1D_ARRAY;
|
||||
case TEXTURE_CUBE_INDEX: return RC_TEXTURE_CUBE;
|
||||
case TEXTURE_3D_INDEX: return RC_TEXTURE_3D;
|
||||
case TEXTURE_RECT_INDEX: return RC_TEXTURE_RECT;
|
||||
default:
|
||||
case TEXTURE_2D_INDEX: return RC_TEXTURE_2D;
|
||||
case TEXTURE_1D_INDEX: return RC_TEXTURE_1D;
|
||||
}
|
||||
}
|
||||
|
||||
static void translate_instruction(struct radeon_compiler * c,
|
||||
struct rc_instruction * dest, struct prog_instruction * src)
|
||||
{
|
||||
const struct rc_opcode_info * opcode;
|
||||
unsigned int i;
|
||||
|
||||
dest->I.Opcode = translate_opcode(src->Opcode);
|
||||
if (dest->I.Opcode == RC_OPCODE_ILLEGAL_OPCODE) {
|
||||
rc_error(c, "Unsupported opcode %i\n", src->Opcode);
|
||||
return;
|
||||
}
|
||||
dest->I.SaturateMode = translate_saturate(src->SaturateMode);
|
||||
|
||||
opcode = rc_get_opcode_info(dest->I.Opcode);
|
||||
|
||||
for(i = 0; i < opcode->NumSrcRegs; ++i)
|
||||
translate_srcreg(&dest->I.SrcReg[i], &src->SrcReg[i]);
|
||||
|
||||
if (opcode->HasDstReg)
|
||||
translate_dstreg(&dest->I.DstReg, &src->DstReg);
|
||||
|
||||
if (opcode->HasTexture) {
|
||||
dest->I.TexSrcUnit = src->TexSrcUnit;
|
||||
dest->I.TexSrcTarget = translate_tex_target(src->TexSrcTarget);
|
||||
dest->I.TexShadow = src->TexShadow;
|
||||
}
|
||||
}
|
||||
|
||||
void radeon_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program)
|
||||
{
|
||||
struct prog_instruction *source;
|
||||
|
|
@ -41,7 +182,7 @@ void radeon_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * p
|
|||
|
||||
for(source = program->Instructions; source->Opcode != OPCODE_END; ++source) {
|
||||
struct rc_instruction * dest = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
|
||||
dest->I = *source;
|
||||
translate_instruction(c, dest, source);
|
||||
}
|
||||
|
||||
c->Program.ShadowSamplers = program->ShadowSamplers;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue