freedreno/a3xx: fix const/rel/const-rel encoding
The encoding of constant, relative, and relative-const src registers is
a bit more complex than originally thought, which gives an extra bit to
encode const reg # at expense of taking a bit from relative offset.
In most cases a3xx seems to actually use a scheme whereby it can encode
an extra bit for const register. You have three possible encodings in
thirteen bits:
register: (11 bits for N.c)
00........... rN.c
relative: (10 bits for N)
010.......... r<a0.x + N>
011.......... c<a0.x + N>
const: (12 bits for N.c)
1............ cN.c
Which means we can deal w/ more consts than previously thought.
Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
@@ -111,7 +111,7 @@ static void print_reg(reg_t reg, bool full, bool r, bool c, bool im,
|
||||
* write-after-read (output.. but not 100%)..
|
||||
*/
|
||||
|
||||
#define MAX_REG 128
|
||||
#define MAX_REG 4096
|
||||
|
||||
typedef struct {
|
||||
uint8_t full[MAX_REG/8];
|
||||
@@ -317,8 +317,7 @@ static void print_instr_cat1(instr_t *instr)
|
||||
{
|
||||
instr_cat1_t *cat1 = &instr->cat1;
|
||||
|
||||
// XXX maybe a bug in libllvm disassembler?
|
||||
if (cat1->src_rel)
|
||||
if (cat1->ul)
|
||||
printf("(ul)");
|
||||
|
||||
if (cat1->src_type == cat1->dst_type) {
|
||||
@@ -355,10 +354,11 @@ static void print_instr_cat1(instr_t *instr)
|
||||
/* I would just use %+d but trying to make it diff'able with
|
||||
* libllvm-a3xx...
|
||||
*/
|
||||
char type = cat1->src_rel_c ? 'c' : 'r';
|
||||
if (cat1->off < 0)
|
||||
printf("c<a0.x - %d>", -cat1->off);
|
||||
printf("%c<a0.x - %d>", type, -cat1->off);
|
||||
else if (cat1->off > 0)
|
||||
printf("c<a0.x + %d>", cat1->off);
|
||||
printf("%c<a0.x + %d>", type, cat1->off);
|
||||
else
|
||||
printf("c<a0.x>");
|
||||
} else {
|
||||
@@ -399,9 +399,21 @@ static void print_instr_cat2(instr_t *instr)
|
||||
printf("(ei)");
|
||||
print_reg_dst((reg_t)(cat2->dst), cat2->full ^ cat2->dst_half, false);
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)(cat2->src1), cat2->full, cat2->src1_r,
|
||||
cat2->src1_c, cat2->src1_im, cat2->src1_neg,
|
||||
cat2->src1_abs, cat2->src1_rel);
|
||||
|
||||
if (cat2->c1.src1_c) {
|
||||
print_reg_src((reg_t)(cat2->c1.src1), cat2->full, cat2->src1_r,
|
||||
cat2->c1.src1_c, cat2->src1_im, cat2->src1_neg,
|
||||
cat2->src1_abs, false);
|
||||
} else if (cat2->rel1.src1_rel) {
|
||||
print_reg_src((reg_t)(cat2->rel1.src1), cat2->full, cat2->src1_r,
|
||||
cat2->rel1.src1_c, cat2->src1_im, cat2->src1_neg,
|
||||
cat2->src1_abs, cat2->rel1.src1_rel);
|
||||
} else {
|
||||
print_reg_src((reg_t)(cat2->src1), cat2->full, cat2->src1_r,
|
||||
false, cat2->src1_im, cat2->src1_neg,
|
||||
cat2->src1_abs, false);
|
||||
}
|
||||
|
||||
switch (cat2->opc) {
|
||||
case OPC_ABSNEG_F:
|
||||
case OPC_ABSNEG_S:
|
||||
@@ -421,9 +433,19 @@ static void print_instr_cat2(instr_t *instr)
|
||||
break;
|
||||
default:
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)(cat2->src2), cat2->full, cat2->src2_r,
|
||||
cat2->src2_c, cat2->src2_im, cat2->src2_neg,
|
||||
cat2->src2_abs, cat2->src2_rel);
|
||||
if (cat2->c2.src2_c) {
|
||||
print_reg_src((reg_t)(cat2->c2.src2), cat2->full, cat2->src2_r,
|
||||
cat2->c2.src2_c, cat2->src2_im, cat2->src2_neg,
|
||||
cat2->src2_abs, false);
|
||||
} else if (cat2->rel2.src2_rel) {
|
||||
print_reg_src((reg_t)(cat2->rel2.src2), cat2->full, cat2->src2_r,
|
||||
cat2->rel2.src2_c, cat2->src2_im, cat2->src2_neg,
|
||||
cat2->src2_abs, cat2->rel2.src2_rel);
|
||||
} else {
|
||||
print_reg_src((reg_t)(cat2->src2), cat2->full, cat2->src2_r,
|
||||
false, cat2->src2_im, cat2->src2_neg,
|
||||
cat2->src2_abs, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -450,17 +472,37 @@ static void print_instr_cat3(instr_t *instr)
|
||||
printf(" ");
|
||||
print_reg_dst((reg_t)(cat3->dst), full ^ cat3->dst_half, false);
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)(cat3->src1), full,
|
||||
cat3->src1_r, cat3->src1_c, false, cat3->src1_neg,
|
||||
false, cat3->src1_rel);
|
||||
if (cat3->c1.src1_c) {
|
||||
print_reg_src((reg_t)(cat3->c1.src1), full,
|
||||
cat3->src1_r, cat3->c1.src1_c, false, cat3->src1_neg,
|
||||
false, false);
|
||||
} else if (cat3->rel1.src1_rel) {
|
||||
print_reg_src((reg_t)(cat3->rel1.src1), full,
|
||||
cat3->src1_r, cat3->rel1.src1_c, false, cat3->src1_neg,
|
||||
false, cat3->rel1.src1_rel);
|
||||
} else {
|
||||
print_reg_src((reg_t)(cat3->src1), full,
|
||||
cat3->src1_r, false, false, cat3->src1_neg,
|
||||
false, false);
|
||||
}
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)cat3->src2, full,
|
||||
cat3->src2_r, cat3->src2_c, false, cat3->src2_neg,
|
||||
false, false);
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)(cat3->src3), full,
|
||||
cat3->src3_r, cat3->src3_c, false, cat3->src3_neg,
|
||||
false, cat3->src3_rel);
|
||||
if (cat3->c2.src3_c) {
|
||||
print_reg_src((reg_t)(cat3->c2.src3), full,
|
||||
cat3->src3_r, cat3->c2.src3_c, false, cat3->src3_neg,
|
||||
false, false);
|
||||
} else if (cat3->rel2.src3_rel) {
|
||||
print_reg_src((reg_t)(cat3->rel2.src3), full,
|
||||
cat3->src3_r, cat3->rel2.src3_c, false, cat3->src3_neg,
|
||||
false, cat3->rel2.src3_rel);
|
||||
} else {
|
||||
print_reg_src((reg_t)(cat3->src3), full,
|
||||
cat3->src3_r, false, false, cat3->src3_neg,
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_instr_cat4(instr_t *instr)
|
||||
@@ -470,9 +512,20 @@ static void print_instr_cat4(instr_t *instr)
|
||||
printf(" ");
|
||||
print_reg_dst((reg_t)(cat4->dst), cat4->full ^ cat4->dst_half, false);
|
||||
printf(", ");
|
||||
print_reg_src((reg_t)(cat4->src), cat4->full,
|
||||
cat4->src_r, cat4->src_c, cat4->src_im,
|
||||
cat4->src_neg, cat4->src_abs, cat4->src_rel);
|
||||
|
||||
if (cat4->c.src_c) {
|
||||
print_reg_src((reg_t)(cat4->c.src), cat4->full,
|
||||
cat4->src_r, cat4->c.src_c, cat4->src_im,
|
||||
cat4->src_neg, cat4->src_abs, false);
|
||||
} else if (cat4->rel.src_rel) {
|
||||
print_reg_src((reg_t)(cat4->rel.src), cat4->full,
|
||||
cat4->src_r, cat4->rel.src_c, cat4->src_im,
|
||||
cat4->src_neg, cat4->src_abs, cat4->rel.src_rel);
|
||||
} else {
|
||||
print_reg_src((reg_t)(cat4->src), cat4->full,
|
||||
cat4->src_r, false, cat4->src_im,
|
||||
cat4->src_neg, cat4->src_abs, false);
|
||||
}
|
||||
|
||||
if ((debug & PRINT_VERBOSE) && (cat4->dummy1|cat4->dummy2))
|
||||
printf("\t{4: %x,%x}", cat4->dummy1, cat4->dummy2);
|
||||
|
||||
@@ -232,13 +232,16 @@ typedef union PACKED {
|
||||
/* normal gpr or const src register: */
|
||||
struct PACKED {
|
||||
uint32_t comp : 2;
|
||||
uint32_t num : 9;
|
||||
uint32_t num : 10;
|
||||
};
|
||||
/* for immediate val: */
|
||||
int32_t iim_val : 11;
|
||||
/* to make compiler happy: */
|
||||
uint32_t dummy32;
|
||||
uint32_t dummy10 : 10;
|
||||
uint32_t dummy11 : 11;
|
||||
uint32_t dummy12 : 12;
|
||||
uint32_t dummy13 : 13;
|
||||
uint32_t dummy8 : 8;
|
||||
} reg_t;
|
||||
|
||||
@@ -276,12 +279,16 @@ typedef struct PACKED {
|
||||
/* for normal src register: */
|
||||
struct PACKED {
|
||||
uint32_t src : 11;
|
||||
/* at least low bit of pad must be zero or it will
|
||||
* look like a address relative src
|
||||
*/
|
||||
uint32_t pad : 21;
|
||||
};
|
||||
/* for address relative: */
|
||||
struct PACKED {
|
||||
int32_t off : 10;
|
||||
uint32_t must_be_3 : 2;
|
||||
uint32_t src_rel_c : 1;
|
||||
uint32_t src_rel : 1;
|
||||
uint32_t unknown : 20;
|
||||
};
|
||||
/* for immediate: */
|
||||
@@ -294,7 +301,7 @@ typedef struct PACKED {
|
||||
uint32_t repeat : 3;
|
||||
uint32_t src_r : 1;
|
||||
uint32_t ss : 1;
|
||||
uint32_t src_rel : 1;
|
||||
uint32_t ul : 1;
|
||||
uint32_t dst_type : 3;
|
||||
uint32_t dst_rel : 1;
|
||||
uint32_t src_type : 3;
|
||||
@@ -310,19 +317,49 @@ typedef struct PACKED {
|
||||
|
||||
typedef struct PACKED {
|
||||
/* dword0: */
|
||||
uint32_t src1 : 11;
|
||||
uint32_t src1_rel : 1; /* relative address */
|
||||
uint32_t src1_c : 1; /* const */
|
||||
uint32_t src1_im : 1; /* immediate */
|
||||
uint32_t src1_neg : 1; /* negate */
|
||||
uint32_t src1_abs : 1; /* absolute value */
|
||||
union PACKED {
|
||||
struct PACKED {
|
||||
uint32_t src1 : 11;
|
||||
uint32_t must_be_zero1: 2;
|
||||
uint32_t src1_im : 1; /* immediate */
|
||||
uint32_t src1_neg : 1; /* negate */
|
||||
uint32_t src1_abs : 1; /* absolute value */
|
||||
};
|
||||
struct PACKED {
|
||||
uint32_t src1 : 10;
|
||||
uint32_t src1_c : 1; /* relative-const */
|
||||
uint32_t src1_rel : 1; /* relative address */
|
||||
uint32_t must_be_zero : 1;
|
||||
uint32_t dummy : 3;
|
||||
} rel1;
|
||||
struct PACKED {
|
||||
uint32_t src1 : 12;
|
||||
uint32_t src1_c : 1; /* const */
|
||||
uint32_t dummy : 3;
|
||||
} c1;
|
||||
};
|
||||
|
||||
uint32_t src2 : 11;
|
||||
uint32_t src2_rel : 1; /* relative address */
|
||||
uint32_t src2_c : 1; /* const */
|
||||
uint32_t src2_im : 1; /* immediate */
|
||||
uint32_t src2_neg : 1; /* negate */
|
||||
uint32_t src2_abs : 1; /* absolute value */
|
||||
union PACKED {
|
||||
struct PACKED {
|
||||
uint32_t src2 : 11;
|
||||
uint32_t must_be_zero2: 2;
|
||||
uint32_t src2_im : 1; /* immediate */
|
||||
uint32_t src2_neg : 1; /* negate */
|
||||
uint32_t src2_abs : 1; /* absolute value */
|
||||
};
|
||||
struct PACKED {
|
||||
uint32_t src2 : 10;
|
||||
uint32_t src2_c : 1; /* relative-const */
|
||||
uint32_t src2_rel : 1; /* relative address */
|
||||
uint32_t must_be_zero : 1;
|
||||
uint32_t dummy : 3;
|
||||
} rel2;
|
||||
struct PACKED {
|
||||
uint32_t src2 : 12;
|
||||
uint32_t src2_c : 1; /* const */
|
||||
uint32_t dummy : 3;
|
||||
} c2;
|
||||
};
|
||||
|
||||
/* dword1: */
|
||||
uint32_t dst : 8;
|
||||
@@ -343,18 +380,49 @@ typedef struct PACKED {
|
||||
|
||||
typedef struct PACKED {
|
||||
/* dword0: */
|
||||
uint32_t src1 : 11;
|
||||
uint32_t src1_rel : 1;
|
||||
uint32_t src1_c : 1;
|
||||
uint32_t src2_c : 1;
|
||||
uint32_t src1_neg : 1;
|
||||
uint32_t src2_r : 1;
|
||||
uint32_t src3 : 11;
|
||||
uint32_t src3_rel : 1;
|
||||
uint32_t src3_c : 1;
|
||||
uint32_t src3_r : 1;
|
||||
uint32_t src2_neg : 1;
|
||||
uint32_t src3_neg : 1;
|
||||
union PACKED {
|
||||
struct PACKED {
|
||||
uint32_t src1 : 11;
|
||||
uint32_t must_be_zero1: 2;
|
||||
uint32_t src2_c : 1;
|
||||
uint32_t src1_neg : 1;
|
||||
uint32_t src2_r : 1;
|
||||
};
|
||||
struct PACKED {
|
||||
uint32_t src1 : 10;
|
||||
uint32_t src1_c : 1;
|
||||
uint32_t src1_rel : 1;
|
||||
uint32_t must_be_zero : 1;
|
||||
uint32_t dummy : 3;
|
||||
} rel1;
|
||||
struct PACKED {
|
||||
uint32_t src1 : 12;
|
||||
uint32_t src1_c : 1;
|
||||
uint32_t dummy : 3;
|
||||
} c1;
|
||||
};
|
||||
|
||||
union PACKED {
|
||||
struct PACKED {
|
||||
uint32_t src3 : 11;
|
||||
uint32_t must_be_zero2: 2;
|
||||
uint32_t src3_r : 1;
|
||||
uint32_t src2_neg : 1;
|
||||
uint32_t src3_neg : 1;
|
||||
};
|
||||
struct PACKED {
|
||||
uint32_t src3 : 10;
|
||||
uint32_t src3_c : 1;
|
||||
uint32_t src3_rel : 1;
|
||||
uint32_t must_be_zero : 1;
|
||||
uint32_t dummy : 3;
|
||||
} rel2;
|
||||
struct PACKED {
|
||||
uint32_t src3 : 12;
|
||||
uint32_t src3_c : 1;
|
||||
uint32_t dummy : 3;
|
||||
} c2;
|
||||
};
|
||||
|
||||
/* dword1: */
|
||||
uint32_t dst : 8;
|
||||
@@ -372,12 +440,27 @@ typedef struct PACKED {
|
||||
|
||||
typedef struct PACKED {
|
||||
/* dword0: */
|
||||
uint32_t src : 11;
|
||||
uint32_t src_rel : 1;
|
||||
uint32_t src_c : 1;
|
||||
uint32_t src_im : 1;
|
||||
uint32_t src_neg : 1;
|
||||
uint32_t src_abs : 1;
|
||||
union PACKED {
|
||||
struct PACKED {
|
||||
uint32_t src : 11;
|
||||
uint32_t must_be_zero1: 2;
|
||||
uint32_t src_im : 1; /* immediate */
|
||||
uint32_t src_neg : 1; /* negate */
|
||||
uint32_t src_abs : 1; /* absolute value */
|
||||
};
|
||||
struct PACKED {
|
||||
uint32_t src : 10;
|
||||
uint32_t src_c : 1; /* relative-const */
|
||||
uint32_t src_rel : 1; /* relative address */
|
||||
uint32_t must_be_zero : 1;
|
||||
uint32_t dummy : 3;
|
||||
} rel;
|
||||
struct PACKED {
|
||||
uint32_t src : 12;
|
||||
uint32_t src_c : 1; /* const */
|
||||
uint32_t dummy : 3;
|
||||
} c;
|
||||
};
|
||||
uint32_t dummy1 : 16; /* seem to be ignored */
|
||||
|
||||
/* dword1: */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Rob Clark <robdclark@gmail.com>
|
||||
* Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -132,11 +132,12 @@ static int emit_cat1(struct ir3_instruction *instr, void *ptr,
|
||||
} else if (src->flags & IR3_REG_RELATIV) {
|
||||
cat1->off = src->offset;
|
||||
cat1->src_rel = 1;
|
||||
cat1->must_be_3 = 3;
|
||||
cat1->src_rel_c = !!(src->flags & IR3_REG_CONST);
|
||||
} else {
|
||||
cat1->src = reg(src, info, instr->repeat,
|
||||
IR3_REG_IMMED | IR3_REG_RELATIV |
|
||||
IR3_REG_R | IR3_REG_CONST | IR3_REG_HALF);
|
||||
IR3_REG_IMMED | IR3_REG_R |
|
||||
IR3_REG_CONST | IR3_REG_HALF);
|
||||
cat1->src_c = !!(src->flags & IR3_REG_CONST);
|
||||
}
|
||||
|
||||
cat1->dst = reg(dst, info, instr->repeat,
|
||||
@@ -145,10 +146,10 @@ static int emit_cat1(struct ir3_instruction *instr, void *ptr,
|
||||
cat1->repeat = instr->repeat;
|
||||
cat1->src_r = !!(src->flags & IR3_REG_R);
|
||||
cat1->ss = !!(instr->flags & IR3_INSTR_SS);
|
||||
cat1->ul = !!(instr->flags & IR3_INSTR_UL);
|
||||
cat1->dst_type = instr->cat1.dst_type;
|
||||
cat1->dst_rel = !!(dst->flags & IR3_REG_RELATIV);
|
||||
cat1->src_type = instr->cat1.src_type;
|
||||
cat1->src_c = !!(src->flags & IR3_REG_CONST);
|
||||
cat1->even = !!(dst->flags & IR3_REG_EVEN);
|
||||
cat1->pos_inf = !!(dst->flags & IR3_REG_POS_INF);
|
||||
cat1->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
|
||||
@@ -168,11 +169,25 @@ static int emit_cat2(struct ir3_instruction *instr, void *ptr,
|
||||
|
||||
iassert((instr->regs_count == 2) || (instr->regs_count == 3));
|
||||
|
||||
cat2->src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
|
||||
IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->src1_rel = !!(src1->flags & IR3_REG_RELATIV);
|
||||
cat2->src1_c = !!(src1->flags & IR3_REG_CONST);
|
||||
if (src1->flags & IR3_REG_RELATIV) {
|
||||
iassert(src1->num < (1 << 10));
|
||||
cat2->rel1.src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_NEGATE |
|
||||
IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->rel1.src1_c = !!(src1->flags & IR3_REG_CONST);
|
||||
cat2->rel1.src1_rel = 1;
|
||||
} else if (src1->flags & IR3_REG_CONST) {
|
||||
iassert(src1->num < (1 << 12));
|
||||
cat2->c1.src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_CONST | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->c1.src1_c = 1;
|
||||
} else {
|
||||
iassert(src1->num < (1 << 11));
|
||||
cat2->src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_IMMED | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
}
|
||||
cat2->src1_im = !!(src1->flags & IR3_REG_IMMED);
|
||||
cat2->src1_neg = !!(src1->flags & IR3_REG_NEGATE);
|
||||
cat2->src1_abs = !!(src1->flags & IR3_REG_ABS);
|
||||
@@ -181,11 +196,27 @@ static int emit_cat2(struct ir3_instruction *instr, void *ptr,
|
||||
if (src2) {
|
||||
iassert((src2->flags & IR3_REG_IMMED) ||
|
||||
!((src1->flags ^ src2->flags) & IR3_REG_HALF));
|
||||
cat2->src2 = reg(src2, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
|
||||
IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->src2_rel = !!(src2->flags & IR3_REG_RELATIV);
|
||||
cat2->src2_c = !!(src2->flags & IR3_REG_CONST);
|
||||
|
||||
if (src2->flags & IR3_REG_RELATIV) {
|
||||
iassert(src2->num < (1 << 10));
|
||||
cat2->rel2.src2 = reg(src2, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_NEGATE |
|
||||
IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->rel2.src2_c = !!(src2->flags & IR3_REG_CONST);
|
||||
cat2->rel2.src2_rel = 1;
|
||||
} else if (src2->flags & IR3_REG_CONST) {
|
||||
iassert(src2->num < (1 << 12));
|
||||
cat2->c2.src2 = reg(src2, info, instr->repeat,
|
||||
IR3_REG_CONST | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
cat2->c2.src2_c = 1;
|
||||
} else {
|
||||
iassert(src2->num < (1 << 11));
|
||||
cat2->src2 = reg(src2, info, instr->repeat,
|
||||
IR3_REG_IMMED | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
}
|
||||
|
||||
cat2->src2_im = !!(src2->flags & IR3_REG_IMMED);
|
||||
cat2->src2_neg = !!(src2->flags & IR3_REG_NEGATE);
|
||||
cat2->src2_abs = !!(src2->flags & IR3_REG_ABS);
|
||||
@@ -239,11 +270,25 @@ static int emit_cat3(struct ir3_instruction *instr, void *ptr,
|
||||
iassert(!((src2->flags ^ src_flags) & IR3_REG_HALF));
|
||||
iassert(!((src3->flags ^ src_flags) & IR3_REG_HALF));
|
||||
|
||||
cat3->src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST |
|
||||
IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
|
||||
cat3->src1_rel = !!(src1->flags & IR3_REG_RELATIV);
|
||||
cat3->src1_c = !!(src1->flags & IR3_REG_CONST);
|
||||
if (src1->flags & IR3_REG_RELATIV) {
|
||||
iassert(src1->num < (1 << 10));
|
||||
cat3->rel1.src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_NEGATE |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
cat3->rel1.src1_c = !!(src1->flags & IR3_REG_CONST);
|
||||
cat3->rel1.src1_rel = 1;
|
||||
} else if (src1->flags & IR3_REG_CONST) {
|
||||
iassert(src1->num < (1 << 12));
|
||||
cat3->c1.src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_CONST | IR3_REG_NEGATE | IR3_REG_R |
|
||||
IR3_REG_HALF);
|
||||
cat3->c1.src1_c = 1;
|
||||
} else {
|
||||
iassert(src1->num < (1 << 11));
|
||||
cat3->src1 = reg(src1, info, instr->repeat,
|
||||
IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
|
||||
}
|
||||
|
||||
cat3->src1_neg = !!(src1->flags & IR3_REG_NEGATE);
|
||||
cat3->src1_r = !!(src1->flags & IR3_REG_R);
|
||||
|
||||
@@ -254,11 +299,26 @@ static int emit_cat3(struct ir3_instruction *instr, void *ptr,
|
||||
cat3->src2_neg = !!(src2->flags & IR3_REG_NEGATE);
|
||||
cat3->src2_r = !!(src2->flags & IR3_REG_R);
|
||||
|
||||
cat3->src3 = reg(src3, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST |
|
||||
IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
|
||||
cat3->src3_rel = !!(src3->flags & IR3_REG_RELATIV);
|
||||
cat3->src3_c = !!(src3->flags & IR3_REG_CONST);
|
||||
|
||||
if (src3->flags & IR3_REG_RELATIV) {
|
||||
iassert(src3->num < (1 << 10));
|
||||
cat3->rel2.src3 = reg(src3, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_NEGATE |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
cat3->rel2.src3_c = !!(src3->flags & IR3_REG_CONST);
|
||||
cat3->rel2.src3_rel = 1;
|
||||
} else if (src3->flags & IR3_REG_CONST) {
|
||||
iassert(src3->num < (1 << 12));
|
||||
cat3->c2.src3 = reg(src3, info, instr->repeat,
|
||||
IR3_REG_CONST | IR3_REG_NEGATE | IR3_REG_R |
|
||||
IR3_REG_HALF);
|
||||
cat3->c2.src3_c = 1;
|
||||
} else {
|
||||
iassert(src3->num < (1 << 11));
|
||||
cat3->src3 = reg(src3, info, instr->repeat,
|
||||
IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
|
||||
}
|
||||
|
||||
cat3->src3_neg = !!(src3->flags & IR3_REG_NEGATE);
|
||||
cat3->src3_r = !!(src3->flags & IR3_REG_R);
|
||||
|
||||
@@ -284,12 +344,26 @@ static int emit_cat4(struct ir3_instruction *instr, void *ptr,
|
||||
|
||||
iassert(instr->regs_count == 2);
|
||||
|
||||
cat4->src = reg(src, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
|
||||
IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R |
|
||||
IR3_REG_HALF);
|
||||
cat4->src_rel = !!(src->flags & IR3_REG_RELATIV);
|
||||
cat4->src_c = !!(src->flags & IR3_REG_CONST);
|
||||
if (src->flags & IR3_REG_RELATIV) {
|
||||
iassert(src->num < (1 << 10));
|
||||
cat4->rel.src = reg(src, info, instr->repeat,
|
||||
IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_NEGATE |
|
||||
IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
|
||||
cat4->rel.src_c = !!(src->flags & IR3_REG_CONST);
|
||||
cat4->rel.src_rel = 1;
|
||||
} else if (src->flags & IR3_REG_CONST) {
|
||||
iassert(src->num < (1 << 12));
|
||||
cat4->c.src = reg(src, info, instr->repeat,
|
||||
IR3_REG_CONST | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
cat4->c.src_c = 1;
|
||||
} else {
|
||||
iassert(src->num < (1 << 11));
|
||||
cat4->src = reg(src, info, instr->repeat,
|
||||
IR3_REG_IMMED | IR3_REG_NEGATE | IR3_REG_ABS |
|
||||
IR3_REG_R | IR3_REG_HALF);
|
||||
}
|
||||
|
||||
cat4->src_im = !!(src->flags & IR3_REG_IMMED);
|
||||
cat4->src_neg = !!(src->flags & IR3_REG_NEGATE);
|
||||
cat4->src_abs = !!(src->flags & IR3_REG_ABS);
|
||||
|
||||
@@ -267,6 +267,8 @@ static int
|
||||
fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
enum pipe_shader_cap param)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
|
||||
switch(shader)
|
||||
{
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
@@ -293,13 +295,13 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
case PIPE_SHADER_CAP_MAX_INPUTS:
|
||||
return 32;
|
||||
case PIPE_SHADER_CAP_MAX_TEMPS:
|
||||
return 256; /* Max native temporaries. */
|
||||
return 64; /* Max native temporaries. */
|
||||
case PIPE_SHADER_CAP_MAX_ADDRS:
|
||||
/* XXX Isn't this equal to TEMPS? */
|
||||
return 1; /* Max native address registers */
|
||||
case PIPE_SHADER_CAP_MAX_CONSTS:
|
||||
return (screen->gpu_id >= 300) ? 1024 : 64;
|
||||
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
|
||||
return 64;
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_MAX_PREDS:
|
||||
return 0; /* nothing uses this */
|
||||
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
|
||||
|
||||
Reference in New Issue
Block a user