summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Marek <jonathan@marek.ca>2019-06-27 21:52:22 -0400
committerJonathan Marek <jonathan@marek.ca>2019-08-06 10:33:17 -0400
commite9a5181ad604d3f0eb9285a84bf2fe64667f3cab (patch)
treec233a5e798aa71b63fed87e9e53a5716fdf59692
parent98e59f0a0add4c042cd4f3c7b62b1436065471ee (diff)
etnaviv: asm: new features
* Dual16 bits * Halti5 disable multiple uniform src * write_mask compose * Halti2+ immediates Signed-off-by: Jonathan Marek <jonathan@marek.ca> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_asm.c10
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_asm.h50
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_compiler.c4
3 files changed, 53 insertions, 11 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_asm.c b/src/gallium/drivers/etnaviv/etnaviv_asm.c
index 8ef4dc9f719..ab6bb4c616e 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_asm.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_asm.c
@@ -65,7 +65,7 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
if (inst->imm && inst->src[2].use)
return 1;
- if (!check_uniforms(inst))
+ if (!inst->halti5 && !check_uniforms(inst))
BUG("error: generating instruction that accesses two different uniforms");
assert(!(inst->opcode&~0x7f));
@@ -76,7 +76,7 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
COND(inst->dst.use, VIV_ISA_WORD_0_DST_USE) |
VIV_ISA_WORD_0_DST_AMODE(inst->dst.amode) |
VIV_ISA_WORD_0_DST_REG(inst->dst.reg) |
- VIV_ISA_WORD_0_DST_COMPS(inst->dst.comps) |
+ VIV_ISA_WORD_0_DST_COMPS(inst->dst.write_mask) |
VIV_ISA_WORD_0_TEX_ID(inst->tex.id);
out[1] = VIV_ISA_WORD_1_TEX_AMODE(inst->tex.amode) |
VIV_ISA_WORD_1_TEX_SWIZ(inst->tex.swiz) |
@@ -103,7 +103,11 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
COND(inst->src[2].neg, VIV_ISA_WORD_3_SRC2_NEG) |
COND(inst->src[2].abs, VIV_ISA_WORD_3_SRC2_ABS) |
VIV_ISA_WORD_3_SRC2_AMODE(inst->src[2].amode) |
- VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup);
+ VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup) |
+ COND(inst->sel_bit0, VIV_ISA_WORD_3_SEL_BIT0) |
+ COND(inst->sel_bit1, VIV_ISA_WORD_3_SEL_BIT1) |
+ COND(inst->dst_full, VIV_ISA_WORD_3_DST_FULL);
+
out[3] |= VIV_ISA_WORD_3_SRC2_IMM(inst->imm);
return 0;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_asm.h b/src/gallium/drivers/etnaviv/etnaviv_asm.h
index 2fe23df8d4a..e91e08a2064 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_asm.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_asm.h
@@ -28,6 +28,7 @@
#define H_ETNAVIV_ASM
#include <stdint.h>
+#include <stdbool.h>
#include "hw/isa.xml.h"
/* Size of an instruction in 32-bit words */
@@ -57,7 +58,7 @@ struct etna_inst_dst {
unsigned use:1; /* 0: not in use, 1: in use */
unsigned amode:3; /* INST_AMODE_* */
unsigned reg:7; /* register number 0..127 */
- unsigned comps:4; /* INST_COMPS_* */
+ unsigned write_mask:4; /* INST_COMPS_* */
};
/* texture operand */
@@ -70,12 +71,20 @@ struct etna_inst_tex {
/* source operand */
struct etna_inst_src {
unsigned use:1; /* 0: not in use, 1: in use */
- unsigned reg:9; /* register or uniform number 0..511 */
- unsigned swiz:8; /* INST_SWIZ */
- unsigned neg:1; /* negate (flip sign) if set */
- unsigned abs:1; /* absolute (remove sign) if set */
- unsigned amode:3; /* INST_AMODE_* */
unsigned rgroup:3; /* INST_RGROUP_* */
+ union {
+ struct __attribute__((__packed__)) {
+ unsigned reg:9; /* register or uniform number 0..511 */
+ unsigned swiz:8; /* INST_SWIZ */
+ unsigned neg:1; /* negate (flip sign) if set */
+ unsigned abs:1; /* absolute (remove sign) if set */
+ unsigned amode:3; /* INST_AMODE_* */
+ };
+ struct __attribute__((__packed__)) {
+ unsigned imm_val : 20;
+ unsigned imm_type : 2;
+ };
+ };
};
/*** instruction ***/
@@ -84,6 +93,10 @@ struct etna_inst {
uint8_t type; /* INST_TYPE_* */
unsigned cond:5; /* INST_CONDITION_* */
unsigned sat:1; /* saturate result between 0..1 */
+ unsigned sel_bit0:1; /* select low half mediump */
+ unsigned sel_bit1:1; /* select high half mediump */
+ unsigned dst_full:1; /* write to highp register */
+ unsigned halti5:1; /* allow multiple different uniform sources */
struct etna_inst_dst dst; /* destination operand */
struct etna_inst_tex tex; /* texture operand */
struct etna_inst_src src[ETNA_NUM_SRC]; /* source operand */
@@ -99,6 +112,20 @@ static inline uint32_t inst_swiz_compose(uint32_t swz1, uint32_t swz2)
INST_SWIZ_W((swz1 >> (((swz2 >> 6)&3)*2))&3);
};
+/* Compose two write_masks (computes wm1.wm2) */
+static inline uint32_t inst_write_mask_compose(uint32_t wm1, uint32_t wm2)
+{
+ unsigned wm = 0;
+ for (unsigned i = 0, j = 0; i < 4; i++) {
+ if (wm2 & (1 << i)) {
+ if (wm1 & (1 << j))
+ wm |= (1 << i);
+ j++;
+ }
+ }
+ return wm;
+};
+
/* Return whether the rgroup is one of the uniforms */
static inline int
etna_rgroup_is_uniform(unsigned rgroup)
@@ -107,6 +134,17 @@ etna_rgroup_is_uniform(unsigned rgroup)
rgroup == INST_RGROUP_UNIFORM_1;
}
+static inline struct etna_inst_src
+etna_immediate_src(unsigned type, uint32_t bits)
+{
+ return (struct etna_inst_src) {
+ .use = 1,
+ .rgroup = INST_RGROUP_IMMEDIATE,
+ .imm_val = bits,
+ .imm_type = type
+ };
+}
+
/**
* Build vivante instruction from structure with
* opcode, cond, sat, dst_use, dst_amode,
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
index 0150002c06d..f89c46eff66 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
@@ -763,7 +763,7 @@ etna_native_to_dst(struct etna_native_reg native, unsigned comps)
assert(native.valid && !native.is_tex && native.rgroup == INST_RGROUP_TEMP);
struct etna_inst_dst rv = {
- .comps = comps,
+ .write_mask = comps,
.use = 1,
.reg = native.id,
};
@@ -892,7 +892,7 @@ convert_dst(struct etna_compile *c, const struct tgsi_full_dst_register *in)
{
struct etna_inst_dst rv = {
/// XXX .amode
- .comps = in->Register.WriteMask,
+ .write_mask = in->Register.WriteMask,
};
if (in->Register.File == TGSI_FILE_ADDRESS) {