From: Kenneth Graunke Date: Tue, 27 Nov 2012 06:53:10 +0000 (-0800) Subject: i965/vs: Split final assembly code generation out of vec4_visitor. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eda9726ef51dcfd3895924eb0f74df8e67aa9c3a;p=mesa.git i965/vs: Split final assembly code generation out of vec4_visitor. 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.) Reviewed-by: Eric Anholt Reviewed-by: Anuj Phogat --- diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index d5f1abe3270..d705235ab33 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 3d9d0dc504f..d0609414253 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 a2a5975c6b2..c033804f438 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 4579e0c45e7..aaf932fa02d 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;