[Mesa-dev] [PATCH 7/8] i965/vs: Split final assembly code generation out of vec4_visitor.
Kenneth Graunke
kenneth at whitecape.org
Tue Nov 27 00:42:32 PST 2012
Compiling shaders requires several main steps:
1. Generating VS IR from either GLSL IR or Mesa IR
2. Optimizing the IR
3. Register allocation
4. Generating assembly code
This patch splits out step 4 into a separate class named "vec4_generator."
There are several reasons for doing so:
1. Future hardware has a different instruction encoding. Splitting
this out will allow us to replace vec4_generator (which relies
heavily on the brw_eu_emit.c code and struct brw_instruction) with
a new code generator that writes the new format.
2. It reduces the size of the vec4_visitor monolith. (Arguably, a lot
more should be split out, but that's left for "future work.")
3. Separate namespaces allow us to make helper functions for
generating instructions in both classes: ADD() can exist in
vec4_visitor and create IR, while ADD() in vec4_generator() can
create brw_instructions. (Patches for this upcoming.)
---
src/mesa/drivers/dri/i965/brw_vec4.cpp | 10 +--
src/mesa/drivers/dri/i965/brw_vec4.h | 44 ++++++++++-
src/mesa/drivers/dri/i965/brw_vec4_emit.cpp | 104 +++++++++++++++----------
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 1 -
4 files changed, 106 insertions(+), 53 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index d5f1abe..d705235 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1113,13 +1113,6 @@ vec4_visitor::run()
break;
}
- if (failed)
- return false;
-
- brw_set_access_mode(p, BRW_ALIGN_16);
-
- generate_code();
-
return !failed;
}
@@ -1185,7 +1178,8 @@ brw_vs_emit(struct brw_context *brw,
return NULL;
}
- return brw_get_program(&c->func, final_assembly_size);
+ vec4_generator g(brw, c, prog, mem_ctx);
+ return g.generate_assembly(&v.instructions, final_assembly_size);
}
} /* extern "C" */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 3d9d0dc..d060941 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -195,6 +195,12 @@ public:
bool is_math();
};
+/**
+ * The vertex shader front-end.
+ *
+ * Translates either GLSL IR or Mesa IR (for ARB_vertex_program and
+ * fixed-function) into VS IR.
+ */
class vec4_visitor : public backend_visitor
{
public:
@@ -218,7 +224,6 @@ public:
const struct gl_vertex_program *vp;
struct brw_vs_compile *c;
struct brw_vs_prog_data *prog_data;
- struct brw_compile *p;
char *fail_msg;
bool failed;
@@ -448,7 +453,28 @@ public:
bool process_move_condition(ir_rvalue *ir);
- void generate_code();
+ void dump_instruction(vec4_instruction *inst);
+ void dump_instructions();
+};
+
+/**
+ * The vertex shader code generator.
+ *
+ * Translates VS IR to actual i965 assembly code.
+ */
+class vec4_generator
+{
+public:
+ vec4_generator(struct brw_context *brw,
+ struct brw_vs_compile *c,
+ struct gl_shader_program *prog,
+ void *mem_ctx);
+ ~vec4_generator();
+
+ const unsigned *generate_assembly(exec_list *insts, unsigned *asm_size);
+
+private:
+ void generate_code(exec_list *instructions);
void generate_vs_instruction(vec4_instruction *inst,
struct brw_reg dst,
struct brw_reg *src);
@@ -491,8 +517,18 @@ public:
struct brw_reg index,
struct brw_reg offset);
- void dump_instruction(vec4_instruction *inst);
- void dump_instructions();
+ struct brw_context *brw;
+ struct intel_context *intel;
+ struct gl_context *ctx;
+
+ struct brw_compile *p;
+ struct brw_vs_compile *c;
+
+ struct gl_shader_program *prog;
+ struct gl_shader *shader;
+ const struct gl_vertex_program *vp;
+
+ void *mem_ctx;
};
} /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index a2a5975..c033804 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -132,10 +132,25 @@ vec4_instruction::get_src(int i)
return brw_reg;
}
+vec4_generator::vec4_generator(struct brw_context *brw,
+ struct brw_vs_compile *c,
+ struct gl_shader_program *prog,
+ void *mem_ctx)
+ : brw(brw), c(c), prog(prog), mem_ctx(mem_ctx)
+{
+ intel = &brw->intel;
+ vp = &c->vp->program;
+ p = &c->func;
+}
+
+vec4_generator::~vec4_generator()
+{
+}
+
void
-vec4_visitor::generate_math1_gen4(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src)
+vec4_generator::generate_math1_gen4(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src)
{
brw_math(p,
dst,
@@ -156,9 +171,9 @@ check_gen6_math_src_arg(struct brw_reg src)
}
void
-vec4_visitor::generate_math1_gen6(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src)
+vec4_generator::generate_math1_gen6(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src)
{
/* Can't do writemask because math can't be align16. */
assert(dst.dw1.bits.writemask == WRITEMASK_XYZW);
@@ -176,10 +191,10 @@ vec4_visitor::generate_math1_gen6(vec4_instruction *inst,
}
void
-vec4_visitor::generate_math2_gen7(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src0,
- struct brw_reg src1)
+vec4_generator::generate_math2_gen7(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src0,
+ struct brw_reg src1)
{
brw_math2(p,
dst,
@@ -188,10 +203,10 @@ vec4_visitor::generate_math2_gen7(vec4_instruction *inst,
}
void
-vec4_visitor::generate_math2_gen6(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src0,
- struct brw_reg src1)
+vec4_generator::generate_math2_gen6(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src0,
+ struct brw_reg src1)
{
/* Can't do writemask because math can't be align16. */
assert(dst.dw1.bits.writemask == WRITEMASK_XYZW);
@@ -208,10 +223,10 @@ vec4_visitor::generate_math2_gen6(vec4_instruction *inst,
}
void
-vec4_visitor::generate_math2_gen4(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src0,
- struct brw_reg src1)
+vec4_generator::generate_math2_gen4(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src0,
+ struct brw_reg src1)
{
/* From the Ironlake PRM, Volume 4, Part 1, Section 6.1.13
* "Message Payload":
@@ -242,9 +257,9 @@ vec4_visitor::generate_math2_gen4(vec4_instruction *inst,
}
void
-vec4_visitor::generate_tex(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src)
+vec4_generator::generate_tex(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src)
{
int msg_type = -1;
@@ -356,7 +371,7 @@ vec4_visitor::generate_tex(vec4_instruction *inst,
}
void
-vec4_visitor::generate_urb_write(vec4_instruction *inst)
+vec4_generator::generate_urb_write(vec4_instruction *inst)
{
brw_urb_WRITE(p,
brw_null_reg(), /* dest */
@@ -373,8 +388,8 @@ vec4_visitor::generate_urb_write(vec4_instruction *inst)
}
void
-vec4_visitor::generate_oword_dual_block_offsets(struct brw_reg m1,
- struct brw_reg index)
+vec4_generator::generate_oword_dual_block_offsets(struct brw_reg m1,
+ struct brw_reg index)
{
int second_vertex_offset;
@@ -410,9 +425,9 @@ vec4_visitor::generate_oword_dual_block_offsets(struct brw_reg m1,
}
void
-vec4_visitor::generate_scratch_read(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg index)
+vec4_generator::generate_scratch_read(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg index)
{
struct brw_reg header = brw_vec8_grf(0, 0);
@@ -448,10 +463,10 @@ vec4_visitor::generate_scratch_read(vec4_instruction *inst,
}
void
-vec4_visitor::generate_scratch_write(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg src,
- struct brw_reg index)
+vec4_generator::generate_scratch_write(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg src,
+ struct brw_reg index)
{
struct brw_reg header = brw_vec8_grf(0, 0);
bool write_commit;
@@ -521,10 +536,10 @@ vec4_visitor::generate_scratch_write(vec4_instruction *inst,
}
void
-vec4_visitor::generate_pull_constant_load(vec4_instruction *inst,
- struct brw_reg dst,
- struct brw_reg index,
- struct brw_reg offset)
+vec4_generator::generate_pull_constant_load(vec4_instruction *inst,
+ struct brw_reg dst,
+ struct brw_reg index,
+ struct brw_reg offset)
{
assert(index.file == BRW_IMMEDIATE_VALUE &&
index.type == BRW_REGISTER_TYPE_UD);
@@ -581,9 +596,9 @@ vec4_visitor::generate_pull_constant_load(vec4_instruction *inst,
}
void
-vec4_visitor::generate_vs_instruction(vec4_instruction *instruction,
- struct brw_reg dst,
- struct brw_reg *src)
+vec4_generator::generate_vs_instruction(vec4_instruction *instruction,
+ struct brw_reg dst,
+ struct brw_reg *src)
{
vec4_instruction *inst = (vec4_instruction *)instruction;
@@ -651,7 +666,7 @@ vec4_visitor::generate_vs_instruction(vec4_instruction *instruction,
}
void
-vec4_visitor::generate_code()
+vec4_generator::generate_code(exec_list *instructions)
{
int last_native_insn_offset = 0;
const char *last_annotation_string = NULL;
@@ -665,7 +680,7 @@ vec4_visitor::generate_code()
}
}
- foreach_list(node, &this->instructions) {
+ foreach_list(node, instructions) {
vec4_instruction *inst = (vec4_instruction *)node;
struct brw_reg src[3], dst;
@@ -845,4 +860,13 @@ vec4_visitor::generate_code()
}
}
+const unsigned *
+vec4_generator::generate_assembly(exec_list *instructions,
+ unsigned *assembly_size)
+{
+ brw_set_access_mode(p, BRW_ALIGN_16);
+ generate_code(instructions);
+ return brw_get_program(p, assembly_size);
+}
+
} /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 4579e0c..aaf932f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -2813,7 +2813,6 @@ vec4_visitor::vec4_visitor(struct brw_context *brw,
void *mem_ctx)
{
this->c = c;
- this->p = &c->func;
this->brw = brw;
this->intel = &brw->intel;
this->ctx = &intel->ctx;
--
1.8.0
More information about the mesa-dev
mailing list