[Mesa-dev] [RFC PATCH 01/17] etnaviv: add basic block based backend ir: eir
Christian Gmeiner
christian.gmeiner at gmail.com
Fri May 10 09:08:59 UTC 2019
Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
src/etnaviv/compiler/eir.c | 239 ++++++++++
src/etnaviv/compiler/eir.h | 499 ++++++++++++++++++++
src/etnaviv/compiler/eir_uniform.c | 108 +++++
src/etnaviv/compiler/meson.build | 38 ++
src/etnaviv/compiler/tests/eir_assemble.cpp | 114 +++++
src/etnaviv/compiler/tests/eir_uniform.cpp | 324 +++++++++++++
src/etnaviv/compiler/tests/meson.build | 44 ++
src/etnaviv/meson.build | 1 +
8 files changed, 1367 insertions(+)
create mode 100644 src/etnaviv/compiler/eir.c
create mode 100644 src/etnaviv/compiler/eir.h
create mode 100644 src/etnaviv/compiler/eir_uniform.c
create mode 100644 src/etnaviv/compiler/meson.build
create mode 100644 src/etnaviv/compiler/tests/eir_assemble.cpp
create mode 100644 src/etnaviv/compiler/tests/eir_uniform.cpp
create mode 100644 src/etnaviv/compiler/tests/meson.build
diff --git a/src/etnaviv/compiler/eir.c b/src/etnaviv/compiler/eir.c
new file mode 100644
index 00000000000..398ae7443c5
--- /dev/null
+++ b/src/etnaviv/compiler/eir.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2018 Etnaviv Project
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner at gmail.com>
+ */
+
+#include "eir.h"
+#include <stdlib.h>
+#include <string.h>
+#include "util/ralloc.h"
+
+struct eir *
+eir_create(void)
+{
+ struct eir *ir = rzalloc(NULL, struct eir);
+
+ list_inithead(&ir->block_list);
+ util_dynarray_init(&ir->reg_alloc, ir);
+ util_dynarray_init(&ir->uniform_alloc, ir);
+
+ return ir;
+}
+
+void
+eir_destroy(struct eir *ir)
+{
+ assert(ir);
+ util_dynarray_fini(&ir->reg_alloc);
+ util_dynarray_fini(&ir->uniform_alloc);
+ ralloc_free(ir);
+}
+
+struct eir_block *
+eir_block_create(struct eir *ir)
+{
+ assert(ir);
+ struct eir_block *block = rzalloc(ir, struct eir_block);
+
+ block->ir = ir;
+ block->num = ir->blocks++;
+ list_inithead(&block->node);
+ list_inithead(&block->instr_list);
+
+ list_addtail(&block->node, &ir->block_list);
+
+ return block;
+}
+
+struct eir_instruction *
+eir_instruction_create(struct eir_block *block, enum gc_op opc)
+{
+ assert(block);
+ struct eir_instruction *instr = rzalloc(block, struct eir_instruction);
+
+ instr->block = block;
+ list_addtail(&instr->node, &block->instr_list);
+
+ instr->gc.opcode = opc;
+
+ return instr;
+}
+
+struct eir_register
+eir_temp_register(struct eir *ir, unsigned num_components)
+{
+ assert(num_components >= 1 && num_components <= 4);
+
+ struct eir_register reg = {
+ .type = EIR_REG_TEMP,
+ .index = util_dynarray_num_elements(&ir->reg_alloc, unsigned),
+ };
+
+ util_dynarray_append(&ir->reg_alloc, unsigned, num_components);
+
+ return reg;
+}
+
+void
+eir_link_blocks(struct eir_block *predecessor, struct eir_block *successor)
+{
+ assert(predecessor);
+ assert(successor);
+
+ if (predecessor->successors[0]) {
+ assert(!predecessor->successors[1]);
+ predecessor->successors[1] = successor;
+ } else {
+ predecessor->successors[0] = successor;
+ }
+}
+
+static void
+convert_sampler(const struct eir_register *eir, struct gc_instr_sampler *sampler)
+{
+ assert(eir->type == EIR_REG_SAMPLER);
+
+ sampler->id = eir->index;
+ sampler->swiz = eir->swizzle;
+ sampler->amode = GC_ADDRESSING_MODE_DIRECT;
+}
+
+static void
+convert_src(const struct eir_register *eir, struct gc_instr_src *gc)
+{
+ assert(!gc->use);
+ assert(eir->type != EIR_REG_UNDEF);
+ assert(eir->type != EIR_REG_SAMPLER);
+
+ gc->use = true;
+ gc->reg = eir->index;
+ gc->abs = eir->abs;
+ gc->neg = eir->neg;
+ gc->swiz = eir->swizzle;
+
+ switch (eir->type) {
+ case EIR_REG_TEMP:
+ gc->rgroup = GC_REGISTER_GROUP_TEMP;
+ break;
+
+ case EIR_REG_UNIFORM:
+ gc->rgroup = GC_REGISTER_GROUP_UNIFORM;
+ break;
+
+ default:
+ unreachable("unhandled type");
+ }
+}
+
+static void
+convert_dst(const struct eir_register *eir, struct gc_instr_dst *gc)
+{
+ assert(!gc->comps);
+
+ gc->reg = eir->index;
+ gc->comps = eir->writemask;
+}
+
+static void
+eir_to_gc(struct eir_instruction *instr)
+{
+ struct gc_instr *gc = &instr->gc;
+
+ if (gc_op_num_src(gc->opcode)) {
+ const unsigned swizzle = gc_op_src_swizzle(gc->opcode);
+
+ /* src swizzle */
+ for (int i = 0; i < gc_op_num_src(gc->opcode); i++) {
+ const unsigned shift = i * 2;
+ const unsigned mask = 0x3 << shift;
+ const unsigned index = (swizzle & mask) >> shift;
+
+ if (index == 0x3)
+ continue;
+
+ if (instr->src[i].type == EIR_REG_UNDEF)
+ continue;
+
+ switch (gc->type) {
+ case GC_OP_TYPE_ALU:
+ convert_src(&instr->src[i], &gc->alu.src[index]);
+ break;
+
+ case GC_OP_TYPE_BRANCH:
+ convert_src(&instr->src[i], &gc->branch.src[index]);
+ break;
+
+ case GC_OP_TYPE_SAMPLER:
+ if (i == 0)
+ convert_sampler(&instr->src[0], &gc->sampler);
+ else if (i == 1)
+ convert_src(&instr->src[1], &gc->sampler.src);
+ else
+ unreachable("unkown sampler index");
+
+ break;
+ }
+ }
+
+ /* special handling for src replication */
+ if (gc->type == GC_OP_TYPE_ALU && swizzle & SWIZ_REP_SRC0_TO_SRC2) {
+ assert(gc->type == GC_OP_TYPE_ALU);
+ convert_src(&instr->src[0], &gc->alu.src[2]);
+ }
+ }
+
+ if (gc_op_has_dst(gc->opcode))
+ convert_dst(&instr->dst, &gc->dst);
+}
+
+uint32_t *
+eir_assemble(const struct eir *ir, struct eir_info *info)
+{
+ assert(ir);
+ assert(info);
+ uint32_t *ptr, *dwords;
+
+ memset(info, 0, sizeof(*info));
+
+ eir_for_each_block(block, ir) {
+ eir_for_each_inst(instr, block) {
+ info->sizedwords += 4;
+ }
+ }
+
+ ptr = dwords = calloc(4, info->sizedwords);
+ if (!ptr)
+ return NULL;
+
+ eir_for_each_block(block, ir) {
+ eir_for_each_inst(instr, block) {
+ eir_to_gc(instr);
+ gc_pack_instr(&instr->gc, dwords);
+ dwords += 4;
+ }
+ }
+
+ return ptr;
+}
diff --git a/src/etnaviv/compiler/eir.h b/src/etnaviv/compiler/eir.h
new file mode 100644
index 00000000000..e2185b004f1
--- /dev/null
+++ b/src/etnaviv/compiler/eir.h
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2018 Etnaviv Project
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner at gmail.com>
+ */
+
+#ifndef H_EIR
+#define H_EIR
+
+#include <assert.h>
+#include "util/list.h"
+#include "util/u_dynarray.h"
+#include "util/u_math.h"
+#include "etnaviv/gc/gc_instr.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+struct eir;
+struct eir_block;
+
+struct eir_register
+{
+ enum {
+ EIR_REG_UNDEF = 0,
+ EIR_REG_TEMP,
+ EIR_REG_UNIFORM,
+ EIR_REG_SAMPLER,
+ } type;
+
+ unsigned index;
+
+ /* dst only: */
+ unsigned writemask:4;
+ /* src only: */
+ unsigned swizzle:8;
+ unsigned abs:1;
+ unsigned neg:1;
+};
+
+struct eir_instruction
+{
+ struct eir_block *block;
+ struct list_head node; /* entry in eir_block's instruction list */
+
+ /* Pre-register-allocation references to src/dst registers */
+ struct eir_register dst;
+ struct eir_register src[3];
+
+ struct gc_instr gc; /* instruction being wrapped. */
+};
+
+struct eir_block
+{
+ struct eir *ir;
+ struct list_head node; /* entry in eir's block list */
+ struct list_head instr_list;
+
+ unsigned num;
+
+ struct eir_block *successors[2];
+
+ /* per-pass extra block data */
+ void *data;
+};
+
+enum eir_uniform_contents
+{
+ EIR_UNIFORM_UNUSED,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_IMAGE_WIDTH,
+ EIR_UNIFORM_IMAGE_HEIGHT,
+ EIR_UNIFORM_IMAGE_DEPTH,
+};
+
+static inline const char *
+eir_uniform_content(enum eir_uniform_contents content)
+{
+ switch(content) {
+ case EIR_UNIFORM_UNUSED:
+ return "unused";
+ case EIR_UNIFORM_CONSTANT:
+ return "constant";
+ case EIR_UNIFORM_IMAGE_WIDTH:
+ return "image width";
+ case EIR_UNIFORM_IMAGE_HEIGHT:
+ return "image height";
+ case EIR_UNIFORM_IMAGE_DEPTH:
+ return "image depth";
+ default:
+ unreachable("unhandled content type");
+ break;
+ }
+
+ return NULL;
+}
+
+struct eir_uniform_data
+{
+ enum eir_uniform_contents content;
+ uint32_t data;
+};
+
+struct eir
+{
+ struct list_head block_list;
+ unsigned blocks;
+
+ /* attributes/varyings: */
+ unsigned num_inputs;
+ struct {
+ unsigned slot;
+ unsigned reg;
+ unsigned ncomp;
+ } inputs[16];
+
+ /* varyings/outputs: */
+ unsigned num_outputs;
+ struct {
+ unsigned slot;
+ unsigned reg;
+ unsigned ncomp;
+ } outputs[16];
+
+ /* keep track of numer of allocated registers
+ * and the used components per register */
+ struct util_dynarray reg_alloc;
+
+ /* keep track of number of allocated uniforms */
+ struct util_dynarray uniform_alloc;
+ unsigned uniform_offset;
+};
+
+struct eir_info {
+ uint16_t sizedwords;
+};
+
+struct eir *
+eir_create(void);
+
+void
+eir_destroy(struct eir *ir);
+
+struct eir_block *
+eir_block_create(struct eir *ir);
+
+struct eir_instruction *
+eir_instruction_create(struct eir_block *block, enum gc_op opc);
+
+struct eir_register
+eir_temp_register(struct eir *ir, unsigned num_components);
+
+struct eir_register
+eir_uniform_register_vec4(struct eir *ir,
+ const unsigned ncomp,
+ const enum eir_uniform_contents *contents,
+ const uint32_t *values);
+
+static inline struct eir_register
+eir_uniform_register(struct eir *ir, const enum eir_uniform_contents content, uint32_t value)
+{
+ const enum eir_uniform_contents contents[] = {
+ content
+ };
+
+ const uint32_t values[] = {
+ value
+ };
+
+ return eir_uniform_register_vec4(ir, 1, contents, values);
+}
+
+static inline struct eir_register
+eir_uniform_register_ui(struct eir *ir, uint32_t value)
+{
+ static const enum eir_uniform_contents contents[] = {
+ EIR_UNIFORM_CONSTANT
+ };
+
+ uint32_t values[] = {
+ value
+ };
+
+ return eir_uniform_register_vec4(ir, 1, contents, values);
+}
+
+static inline struct eir_register
+eir_uniform_register_f(struct eir *ir, float value)
+{
+ static const enum eir_uniform_contents contents[] = {
+ EIR_UNIFORM_CONSTANT
+ };
+
+ uint32_t values[] = {
+ fui(value)
+ };
+
+ return eir_uniform_register_vec4(ir, 1, contents, values);
+}
+
+static inline struct eir_register
+eir_uniform_register_vec4_ui(struct eir *ir, const unsigned ncomp, const uint32_t *values)
+{
+ static const enum eir_uniform_contents contents[] =
+ {
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ };
+
+ return eir_uniform_register_vec4(ir, ncomp, contents, values);
+}
+
+static inline struct eir_register
+eir_uniform_register_vec4_f(struct eir *ir, const unsigned ncomp, float *values)
+{
+ static const enum eir_uniform_contents contents[] =
+ {
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ };
+
+ uint32_t val[4];
+
+ for (unsigned i = 0; i < ncomp; i++)
+ val[i] = fui(values[i]);
+
+ return eir_uniform_register_vec4(ir, ncomp, contents, val);
+}
+
+void
+eir_link_blocks(struct eir_block *predecessor, struct eir_block *successor);
+
+static inline void
+eir_assign_input(struct eir *ir, unsigned idx, unsigned slot, unsigned ncomp)
+{
+ assert(ir);
+ assert(idx < ARRAY_SIZE(ir->inputs));
+
+ ir->inputs[idx].reg = idx;
+ ir->inputs[idx].slot = slot;
+ ir->inputs[idx].ncomp = ncomp;
+
+ ir->num_inputs = MAX2(ir->num_inputs, idx + 1);
+}
+
+static inline void
+eir_assign_output(struct eir *ir, unsigned idx, unsigned slot, unsigned ncomp)
+{
+ assert(ir);
+ assert(idx < ARRAY_SIZE(ir->outputs));
+
+ ir->outputs[idx].reg = idx;
+ ir->outputs[idx].slot = slot;
+ ir->outputs[idx].ncomp = ncomp;
+
+ ir->num_outputs = MAX2(ir->num_outputs, idx + 1);
+}
+
+void
+eir_calculate_live_intervals(struct eir *ir);
+
+int
+eir_temp_range_start(const struct eir* ir, unsigned n);
+
+int
+eir_temp_range_end(const struct eir* ir, unsigned n);
+
+uint32_t *
+eir_assemble(const struct eir *ir, struct eir_info *info);
+
+static inline struct eir_instruction *
+eir_SET(struct eir_block *block, struct eir_register *dst,
+ struct eir_register *src0, enum gc_cond condition,
+ struct eir_register *src1)
+{
+ struct eir_instruction *instr;
+
+ assert(gc_op_has_dst(GC_SET));
+ assert(gc_op_num_src(GC_SET) == 2);
+
+ instr = eir_instruction_create(block, GC_SET);
+ instr->gc.type = GC_OP_TYPE_ALU;
+ instr->gc.condition = condition;
+ instr->dst = *dst;
+ instr->src[0] = *src0;
+ instr->src[1] = *src1;
+
+ return instr;
+}
+
+static inline struct eir_instruction *
+eir_BRANCH(struct eir_block *block, struct eir_register *src0,
+ struct eir_register *src1)
+{
+ struct eir_instruction *instr;
+
+ assert(!gc_op_has_dst(GC_BRANCH));
+ assert(gc_op_num_src(GC_BRANCH) == 2);
+
+ instr = eir_instruction_create(block, GC_BRANCH);
+ instr->gc.type = GC_OP_TYPE_BRANCH;
+ instr->gc.branch.imm = ~0;
+ instr->src[0] = *src0;
+ instr->src[1] = *src1;
+
+ return instr;
+}
+
+static inline struct eir_instruction *
+eir_TEXKILL_IF(struct eir_block *block, struct eir_register *src0,
+ enum gc_cond condition, struct eir_register *src1)
+{
+ struct eir_instruction *instr;
+
+ assert(!gc_op_has_dst(GC_TEXKILL_IF));
+ assert(gc_op_num_src(GC_TEXKILL_IF) == 2);
+
+ instr = eir_instruction_create(block, GC_TEXKILL_IF);
+ instr->gc.type = GC_OP_TYPE_ALU;
+ instr->gc.condition = condition;
+ instr->src[0] = *src0;
+ instr->src[1] = *src1;
+
+ return instr;
+}
+
+#define ALU0(opc) \
+static inline struct eir_instruction * \
+eir_##opc(struct eir_block *block) \
+{ \
+ struct eir_instruction *instr; \
+ \
+ assert(!gc_op_has_dst(GC_##opc));\
+ assert(gc_op_num_src(GC_##opc) == 0);\
+ \
+ instr = eir_instruction_create(block, GC_##opc); \
+ instr->gc.type = GC_OP_TYPE_ALU; \
+ \
+ return instr; \
+}
+
+#define ALU1(opc) \
+static inline struct eir_instruction * \
+eir_##opc(struct eir_block *block, struct eir_register *dst, \
+ struct eir_register *src0) \
+{ \
+ struct eir_instruction *instr; \
+ \
+ assert(gc_op_has_dst(GC_##opc));\
+ assert(gc_op_num_src(GC_##opc) >= 1);\
+ \
+ instr = eir_instruction_create(block, GC_##opc); \
+ instr->gc.type = GC_OP_TYPE_ALU; \
+ instr->dst = *dst; \
+ instr->src[0] = *src0; \
+ \
+ return instr; \
+}
+
+#define ALU2(opc) \
+static inline struct eir_instruction * \
+eir_##opc(struct eir_block *block, struct eir_register *dst, \
+ struct eir_register *src0, struct eir_register *src1) \
+{ \
+ struct eir_instruction *instr; \
+ \
+ assert(gc_op_has_dst(GC_##opc));\
+ assert(gc_op_num_src(GC_##opc) == 2);\
+ \
+ instr = eir_instruction_create(block, GC_##opc); \
+ instr->gc.type = GC_OP_TYPE_ALU; \
+ instr->dst = *dst; \
+ instr->src[0] = *src0; \
+ instr->src[1] = *src1; \
+ \
+ return instr; \
+}
+
+#define ALU3(opc) \
+static inline struct eir_instruction * \
+eir_##opc(struct eir_block *block, struct eir_register *dst, \
+ struct eir_register *src0, struct eir_register *src1, \
+ struct eir_register *src2) \
+{ \
+ struct eir_instruction *instr; \
+ \
+ assert(gc_op_has_dst(GC_##opc));\
+ assert(gc_op_num_src(GC_##opc) == 3);\
+ \
+ instr = eir_instruction_create(block, GC_##opc); \
+ instr->gc.type = GC_OP_TYPE_ALU; \
+ instr->dst = *dst; \
+ instr->src[0] = *src0; \
+ instr->src[1] = *src1; \
+ instr->src[2] = *src2; \
+ \
+ return instr; \
+}
+
+#define TEX(opc) \
+static inline struct eir_instruction * \
+eir_##opc(struct eir_block *block, struct eir_register *dst, \
+ struct eir_register *sampler, struct eir_register *src) \
+{ \
+ struct eir_instruction *instr; \
+ \
+ assert(gc_op_has_dst(GC_##opc));\
+ assert(gc_op_num_src(GC_##opc) == 2); \
+ \
+ instr = eir_instruction_create(block, GC_##opc); \
+ instr->gc.type = GC_OP_TYPE_SAMPLER; \
+ instr->dst = *dst; \
+ instr->src[0] = *sampler; \
+ instr->src[1] = *src; \
+ \
+ return instr; \
+}
+
+ALU0(NOP);
+ALU0(TEXKILL);
+
+ALU1(MOV);
+ALU1(MOVAR);
+ALU1(RCP);
+ALU1(RSQ);
+ALU1(CEIL);
+ALU1(FLOOR);
+ALU1(FRC);
+ALU1(LOG);
+ALU1(SQRT);
+ALU1(SIN);
+ALU1(COS);
+ALU1(EXP);
+ALU1(DSX);
+ALU1(DSY);
+
+ALU2(ADD);
+ALU2(MUL);
+ALU2(DP2);
+ALU2(DP3);
+ALU2(DP4);
+
+ALU3(MAD);
+ALU3(SELECT);
+
+TEX(TEXLD);
+TEX(TEXLDB);
+TEX(TEXLDL);
+
+#define eir_for_each_block(block, ir) \
+ list_for_each_entry(struct eir_block, block, &ir->block_list, node)
+
+#define eir_for_each_block_rev(block, ir) \
+ list_for_each_entry_rev(struct eir_block, block, &ir->block_list, node)
+
+/* Loop over the non-NULL members of the successors array. */
+#define eir_for_each_successor(succ, block) \
+ for (struct eir_block *succ = block->successors[0]; \
+ succ != NULL; \
+ succ = (succ == block->successors[1] ? NULL : \
+ block->successors[1]))
+
+#define eir_for_each_inst(inst, block) \
+ list_for_each_entry(struct eir_instruction, inst, &block->instr_list, node)
+
+#define eir_for_each_inst_safe(inst, block) \
+ list_for_each_entry_safe(struct eir_instruction, inst, &block->instr_list, node)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // H_EIR
diff --git a/src/etnaviv/compiler/eir_uniform.c b/src/etnaviv/compiler/eir_uniform.c
new file mode 100644
index 00000000000..7f75215e480
--- /dev/null
+++ b/src/etnaviv/compiler/eir_uniform.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2018 Etnaviv Project
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner at gmail.com>
+ */
+
+#include "eir.h"
+
+static inline void
+append_uniform(struct eir *ir, enum eir_uniform_contents content, uint32_t value)
+{
+ struct eir_uniform_data d = {
+ .content = content,
+ .data = value
+ };
+
+ util_dynarray_append(&ir->uniform_alloc, struct eir_uniform_data, d);
+}
+
+struct eir_register
+eir_uniform_register_vec4(struct eir *ir,
+ const unsigned ncomp,
+ const enum eir_uniform_contents *contents,
+ const uint32_t *values)
+{
+ const unsigned size = util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data);
+ unsigned idx, i;
+
+ /* is there already something useful to reuse? */
+ for (idx = 0; idx < size; idx++) {
+ const struct eir_uniform_data *data;
+
+ for (i = 0; i < ncomp; i++) {
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, idx + i);
+
+ if (data->content == EIR_UNIFORM_UNUSED)
+ continue;
+
+ if (data->content != contents[i] || data->data != values[i])
+ break;
+ }
+
+ /* matched all components */
+ if (i == ncomp)
+ break;
+ }
+
+ /* do we need to update unused items? */
+ if (idx != size) {
+ struct eir_uniform_data *data;
+
+ for (i = 0; i < ncomp; i++) {
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, idx + i);
+
+ data->content = contents[i];
+ data->data = values[i];
+ }
+ }
+
+ /* need to allocate new immediate */
+ if (idx == size) {
+ /* pad out current uniform vector - if needed */
+ if (size % 4)
+ for (i = size % 4; i < ncomp; i++)
+ append_uniform(ir, EIR_UNIFORM_UNUSED, 0);
+
+ for (i = 0; i < ncomp; i++)
+ append_uniform(ir, contents[i], values[i]);
+
+ idx = util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data);
+ idx -= ncomp;
+ }
+
+ idx += ir->uniform_offset;
+
+ struct eir_register reg = {
+ .type = EIR_REG_UNIFORM,
+ .index = idx / 4,
+ };
+
+ if (ncomp == 4)
+ reg.swizzle = INST_SWIZ_IDENTITY;
+ else
+ reg.swizzle = INST_SWIZ_BROADCAST(idx & 3);
+
+ return reg;
+}
diff --git a/src/etnaviv/compiler/meson.build b/src/etnaviv/compiler/meson.build
new file mode 100644
index 00000000000..8affe6ebd48
--- /dev/null
+++ b/src/etnaviv/compiler/meson.build
@@ -0,0 +1,38 @@
+# Copyright (c) 2018 Etnaviv Project
+# Copyright (C) 2018 Zodiac Inflight Innovations
+#
+# 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, sub license,
+# 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS 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.
+
+libetnaviv_compiler_files = files(
+ 'eir.c',
+ 'eir.h',
+ 'eir_uniform.c',
+)
+
+libetnaviv_compiler = static_library(
+ ['etnaviv_compiler'],
+ libetnaviv_compiler_files,
+ include_directories : [inc_common, inc_etnaviv],
+ c_args : [c_vis_args, no_override_init_args],
+ dependencies : [dep_libdrm, dep_valgrind, idep_nir],
+ build_by_default : true,
+)
+
+subdir('tests')
diff --git a/src/etnaviv/compiler/tests/eir_assemble.cpp b/src/etnaviv/compiler/tests/eir_assemble.cpp
new file mode 100644
index 00000000000..63535908a32
--- /dev/null
+++ b/src/etnaviv/compiler/tests/eir_assemble.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 Etnaviv Project
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner at gmail.com>
+ */
+
+#include <gtest/gtest.h>
+#include "etnaviv/compiler/eir.h"
+
+TEST (AssembleTest, NopAssembleDisassemble)
+{
+ struct eir *ir = eir_create();
+ struct eir_block *block = eir_block_create(ir);
+
+ eir_NOP(block);
+
+ struct eir_info info;
+ void *bin = eir_assemble(ir, &info);
+ ASSERT_TRUE(bin);
+
+ eir_destroy(ir);
+
+ struct gc_instr instr;
+ gc_unpack_instr((uint32_t* )bin, &instr);
+
+ ASSERT_EQ(instr.type, GC_OP_TYPE_ALU);
+ ASSERT_EQ(instr.opcode, GC_NOP);
+
+ ASSERT_EQ(info.sizedwords, 4);
+
+ free(bin);
+}
+
+TEST (AssembleTest, Swizzle)
+{
+ struct eir *ir = eir_create();
+ struct eir_block *block = eir_block_create(ir);
+
+ struct eir_register d = eir_temp_register(ir, 4);
+ struct eir_register s0 = eir_temp_register(ir, 4);
+ struct eir_register s1 = eir_temp_register(ir, 4);
+
+ eir_ADD(block, &d, &s0, &s1);
+
+ struct eir_info info;
+ void *bin = eir_assemble(ir, &info);
+ ASSERT_TRUE(bin);
+
+ eir_destroy(ir);
+
+ struct gc_instr instr;
+ gc_unpack_instr((uint32_t* )bin, &instr);
+
+ ASSERT_EQ(instr.type, GC_OP_TYPE_ALU);
+ ASSERT_EQ(instr.opcode, GC_ADD);
+ ASSERT_TRUE(instr.alu.src[0].use);
+ ASSERT_FALSE(instr.alu.src[1].use);
+ ASSERT_TRUE(instr.alu.src[2].use);
+ ASSERT_EQ(instr.alu.src[0].reg, 1);
+ ASSERT_EQ(instr.alu.src[2].reg, 2);
+ ASSERT_EQ(instr.dst.reg, 0);
+
+ free(bin);
+}
+
+TEST (AssembleTest, SwizzleReplicate)
+{
+ struct eir *ir = eir_create();
+ struct eir_block *block = eir_block_create(ir);
+
+ struct eir_register d = eir_temp_register(ir, 4);
+ struct eir_register s = eir_temp_register(ir, 4);
+ eir_DSX(block, &d, &s);
+
+ struct eir_info info;
+ void *bin = eir_assemble(ir, &info);
+ ASSERT_TRUE(bin);
+
+ eir_destroy(ir);
+
+ struct gc_instr instr;
+ gc_unpack_instr((uint32_t* )bin, &instr);
+
+ ASSERT_EQ(instr.type, GC_OP_TYPE_ALU);
+ ASSERT_EQ(instr.opcode, GC_DSX);
+ ASSERT_TRUE(instr.alu.src[0].use);
+ ASSERT_FALSE(instr.alu.src[1].use);
+ ASSERT_TRUE(instr.alu.src[2].use);
+ ASSERT_EQ(instr.alu.src[0].reg, 1);
+ ASSERT_EQ(instr.alu.src[2].reg, 1);
+
+ free(bin);
+}
diff --git a/src/etnaviv/compiler/tests/eir_uniform.cpp b/src/etnaviv/compiler/tests/eir_uniform.cpp
new file mode 100644
index 00000000000..867e51ab384
--- /dev/null
+++ b/src/etnaviv/compiler/tests/eir_uniform.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2018 Etnaviv Project
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Christian Gmeiner <christian.gmeiner at gmail.com>
+ */
+
+#include <gtest/gtest.h>
+#include "etnaviv/compiler/eir.h"
+
+TEST (UniformTest, Basic)
+{
+ struct eir *ir = eir_create();
+ struct eir_register u;
+ const struct eir_uniform_data *data;
+
+ u = eir_uniform_register_ui(ir, 1);
+
+ ASSERT_EQ(u.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u.index, 0);
+ ASSERT_EQ(u.swizzle, INST_SWIZ_BROADCAST(0));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 0);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 1);
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, ReuseUnused)
+{
+ struct eir *ir = eir_create();
+ struct eir_register u1, u2;
+
+ eir_uniform_register(ir, EIR_UNIFORM_UNUSED, 0);
+
+ ASSERT_EQ(util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data), 1);
+
+ u1 = eir_uniform_register_ui(ir, 1);
+ u2 = eir_uniform_register_ui(ir, 1);
+
+ ASSERT_EQ(util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data), 1);
+
+ ASSERT_EQ(u1.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u1.index, 0);
+ ASSERT_EQ(u1.swizzle, INST_SWIZ_BROADCAST(0));
+
+ ASSERT_EQ(u2.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u2.index, 0);
+ ASSERT_EQ(u2.swizzle, INST_SWIZ_BROADCAST(0));
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, ReuseUnusedCausedByVec4)
+{
+ struct eir *ir = eir_create();
+ struct eir_register u1, u2, u3;
+
+ u1 = eir_uniform_register_ui(ir, 0);
+
+ ASSERT_EQ(util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data), 1);
+
+ uint32_t v[] = {
+ 10,
+ 11,
+ 12,
+ 13,
+ };
+
+ u2 = eir_uniform_register_vec4_ui(ir, 4, v);
+
+ ASSERT_EQ(util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data), 8);
+
+ u3 = eir_uniform_register_ui(ir, 1);
+
+ ASSERT_EQ(util_dynarray_num_elements(&ir->uniform_alloc, struct eir_uniform_data), 8);
+
+ ASSERT_EQ(u1.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u1.index, 0);
+ ASSERT_EQ(u1.swizzle, INST_SWIZ_BROADCAST(0));
+
+ ASSERT_EQ(u2.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u2.index, 1);
+ ASSERT_EQ(u2.swizzle, INST_SWIZ_IDENTITY);
+
+ ASSERT_EQ(u3.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u3.index, 0);
+ ASSERT_EQ(u3.swizzle, INST_SWIZ_BROADCAST(1));
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, EqualUniforms)
+{
+ struct eir *ir = eir_create();
+ struct eir_register u1, u2;
+
+ u1 = eir_uniform_register_ui(ir, 1);
+ u2 = eir_uniform_register_ui(ir, 1);
+
+ ASSERT_EQ(u1.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u1.index, 0);
+ ASSERT_EQ(u1.swizzle, INST_SWIZ_BROADCAST(0));
+
+ ASSERT_EQ(u2.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u2.index, 0);
+ ASSERT_EQ(u2.swizzle, INST_SWIZ_BROADCAST(0));
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, MultipeSwizzles)
+{
+ struct eir *ir = eir_create();
+ struct eir_register u1, u2, u3, u4, u5;
+ const struct eir_uniform_data *data;
+
+ u1 = eir_uniform_register_ui(ir, 0);
+ u2 = eir_uniform_register_ui(ir, 1);
+ u3 = eir_uniform_register_ui(ir, 2);
+ u4 = eir_uniform_register_ui(ir, 3);
+ u5 = eir_uniform_register_ui(ir, 4);
+
+ ASSERT_EQ(u1.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u1.index, 0);
+ ASSERT_EQ(u1.swizzle, INST_SWIZ_BROADCAST(0));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 0);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 0);
+
+
+ ASSERT_EQ(u2.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u2.index, 0);
+ ASSERT_EQ(u2.swizzle, INST_SWIZ_BROADCAST(1));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 1);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 1);
+
+
+ ASSERT_EQ(u3.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u3.index, 0);
+ ASSERT_EQ(u3.swizzle, INST_SWIZ_BROADCAST(2));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 2);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 2);
+
+ ASSERT_EQ(u4.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u4.index, 0);
+ ASSERT_EQ(u4.swizzle, INST_SWIZ_BROADCAST(3));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 3);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 3);
+
+
+ ASSERT_EQ(u5.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u5.index, 1);
+ ASSERT_EQ(u5.swizzle, INST_SWIZ_BROADCAST(0));
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 4);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 4);
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, BasicVec4)
+{
+ static const uint32_t values[4] = { 1, 2, 3, 4 };
+ struct eir *ir = eir_create();
+ struct eir_register u;
+ struct eir_uniform_data *data;
+
+ u = eir_uniform_register_vec4_ui(ir, 4, values);
+
+ ASSERT_EQ(u.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u.index, 0);
+ ASSERT_EQ(u.swizzle, INST_SWIZ_IDENTITY);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 0);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 1);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 1);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 2);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 2);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 3);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 3);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 4);
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, EqualUnfiormsVec4)
+{
+ static const uint32_t values[4] = { 1, 2, 3, 4 };
+ struct eir *ir = eir_create();
+ struct eir_register u1, u2;
+ struct eir_uniform_data *data;
+
+ u1 = eir_uniform_register_vec4_ui(ir, 4, values);
+ u2 = eir_uniform_register_vec4_ui(ir, 4, values);
+
+ ASSERT_EQ(u1.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u1.index, 0);
+ ASSERT_EQ(u1.swizzle, INST_SWIZ_IDENTITY);
+
+ ASSERT_EQ(u2.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u2.index, 0);
+ ASSERT_EQ(u2.swizzle, INST_SWIZ_IDENTITY);
+
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 0);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 1);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 1);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 2);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 2);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 3);
+
+ data = util_dynarray_element(&ir->uniform_alloc, struct eir_uniform_data, 3);
+ ASSERT_EQ(data->content, EIR_UNIFORM_CONSTANT);
+ ASSERT_EQ(data->data, 4);
+
+ eir_destroy(ir);
+}
+
+TEST (UniformTest, ncomp1)
+{
+ struct eir *ir = eir_create();
+
+ static const eir_uniform_contents contents[4] = {
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_UNUSED,
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ };
+
+ static const uint32_t values[4] = {
+ 1,
+ 2,
+ 3,
+ 4,
+ };
+
+ eir_uniform_register_vec4(ir, 4, contents, values);
+
+ struct eir_register u = eir_uniform_register_ui(ir, 2);
+
+ ASSERT_EQ(u.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u.index, 0);
+ ASSERT_EQ(u.swizzle, INST_SWIZ_BROADCAST(1));
+}
+
+TEST (UniformTest, ncomp2)
+{
+ struct eir *ir = eir_create();
+
+ static const eir_uniform_contents contents[] = {
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_UNUSED,
+ EIR_UNIFORM_UNUSED,
+ EIR_UNIFORM_CONSTANT,
+ };
+
+ static const uint32_t values[] = {
+ 1,
+ 2,
+ 3,
+ 4,
+ };
+
+ eir_uniform_register_vec4(ir, 4, contents, values);
+
+
+ static const eir_uniform_contents c[] = {
+ EIR_UNIFORM_CONSTANT,
+ EIR_UNIFORM_CONSTANT,
+ };
+
+ static const uint32_t v[] = {
+ 10,
+ 10,
+ };
+
+ struct eir_register u = eir_uniform_register_vec4(ir, 2, c, v);
+
+ ASSERT_EQ(u.type, eir_register::EIR_REG_UNIFORM);
+ ASSERT_EQ(u.index, 0);
+ ASSERT_EQ(u.swizzle, INST_SWIZ_BROADCAST(1));
+}
diff --git a/src/etnaviv/compiler/tests/meson.build b/src/etnaviv/compiler/tests/meson.build
new file mode 100644
index 00000000000..c7506f04ed5
--- /dev/null
+++ b/src/etnaviv/compiler/tests/meson.build
@@ -0,0 +1,44 @@
+# Copyright (c) 2018 Etnaviv Project
+# Copyright (C) 2018 Zodiac Inflight Innovations
+#
+# 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, sub license,
+# 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS 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.
+
+test(
+ 'eir_assemble',
+ executable(
+ 'eir_assemble', 'eir_assemble.cpp',
+ cpp_args : [cpp_vis_args, cpp_msvc_compat_args],
+ link_with: [libetnaviv_gc, libetnaviv_compiler, libmesa_util],
+ include_directories: [inc_common, inc_etnaviv],
+ dependencies : [dep_clock, dep_thread, idep_gtest],
+ )
+)
+
+test(
+ 'eir_uniform',
+ executable(
+ 'eir_uniform', 'eir_uniform.cpp',
+ cpp_args : [cpp_vis_args, cpp_msvc_compat_args],
+ link_with: [libetnaviv_gc, libetnaviv_compiler, libmesa_util],
+ include_directories: [inc_common, inc_etnaviv],
+ dependencies : [dep_clock, dep_thread, idep_gtest],
+ )
+)
+
diff --git a/src/etnaviv/meson.build b/src/etnaviv/meson.build
index a706feafe86..e2a6408d7c3 100644
--- a/src/etnaviv/meson.build
+++ b/src/etnaviv/meson.build
@@ -23,3 +23,4 @@
inc_etnaviv = include_directories('.')
subdir('gc')
+subdir('compiler')
--
2.21.0
More information about the mesa-dev
mailing list