From: Bryan Cain <bryanca...@gmail.com> These correspond to the EmitVertex and EndPrimitive functions in GLSL.
v2 (Paul Berry <stereotype...@gmail.com>): Add stub implementations of new pure visitor functions to i965's vec4_visitor and fs_visitor classes. --- src/glsl/ir.h | 51 ++++++++++++++++++++++++++ src/glsl/ir_hierarchical_visitor.cpp | 18 +++++++++ src/glsl/ir_hierarchical_visitor.h | 2 + src/glsl/ir_hv_accept.cpp | 13 +++++++ src/glsl/ir_print_visitor.cpp | 12 ++++++ src/glsl/ir_print_visitor.h | 2 + src/glsl/ir_reader.cpp | 30 +++++++++++++++ src/glsl/ir_visitor.h | 4 ++ src/glsl/lower_output_reads.cpp | 13 ++++++- src/glsl/opt_dead_code_local.cpp | 17 +++++++++ src/mesa/drivers/dri/i965/brw_fs.h | 2 + src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 12 ++++++ src/mesa/drivers/dri/i965/brw_vec4.h | 2 + src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 12 ++++++ src/mesa/program/ir_to_mesa.cpp | 14 +++++++ src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 14 +++++++ 16 files changed, 217 insertions(+), 1 deletion(-) diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 7ac291c..ae79a39 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -81,6 +81,8 @@ enum ir_node_type { ir_type_return, ir_type_swizzle, ir_type_texture, + ir_type_emitvertex, + ir_type_endprim, ir_type_max /**< maximum ir_type enum number, for validation */ }; @@ -519,6 +521,8 @@ public: * * - Vertex shader input: one of the values from \c gl_vert_attrib. * - Vertex shader output: one of the values from \c gl_varying_slot. + * - Geometry shader input: one of the values from \c gl_varying_slot. + * - Geometry shader output: one of the values from \c gl_varying_slot. * - Fragment shader input: one of the values from \c gl_varying_slot. * - Fragment shader output: one of the values from \c gl_frag_result. * - Uniforms: Per-stage uniform slot number for default uniform block. @@ -1992,6 +1996,53 @@ private: /*@}*/ /** + * IR instruction to emit a vertex in a geometry shader. + */ +class ir_emitvertex : public ir_instruction { +public: + ir_emitvertex() + { + ir_type = ir_type_emitvertex; + } + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + virtual ir_emitvertex *clone(void *mem_ctx, struct hash_table *) const + { + return new(mem_ctx) ir_emitvertex(); + } + + virtual ir_visitor_status accept(ir_hierarchical_visitor *); +}; + +/** + * IR instruction to complete the current primitive and start a new one in a + * geometry shader. + */ +class ir_endprim : public ir_instruction { +public: + ir_endprim() + { + ir_type = ir_type_endprim; + } + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + virtual ir_endprim *clone(void *mem_ctx, struct hash_table *) const + { + return new(mem_ctx) ir_endprim(); + } + + virtual ir_visitor_status accept(ir_hierarchical_visitor *); +}; + +/** * Apply a visitor to each IR node in a list */ void diff --git a/src/glsl/ir_hierarchical_visitor.cpp b/src/glsl/ir_hierarchical_visitor.cpp index f244140..9600211 100644 --- a/src/glsl/ir_hierarchical_visitor.cpp +++ b/src/glsl/ir_hierarchical_visitor.cpp @@ -69,6 +69,24 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir) } ir_visitor_status +ir_hierarchical_visitor::visit(ir_emitvertex *ir) +{ + if (this->callback != NULL) + this->callback(ir, this->data); + + return visit_continue; +} + +ir_visitor_status +ir_hierarchical_visitor::visit(ir_endprim *ir) +{ + if (this->callback != NULL) + this->callback(ir, this->data); + + return visit_continue; +} + +ir_visitor_status ir_hierarchical_visitor::visit(ir_dereference_variable *ir) { if (this->callback != NULL) diff --git a/src/glsl/ir_hierarchical_visitor.h b/src/glsl/ir_hierarchical_visitor.h index 1988ad0..6245f80 100644 --- a/src/glsl/ir_hierarchical_visitor.h +++ b/src/glsl/ir_hierarchical_visitor.h @@ -87,6 +87,8 @@ public: virtual ir_visitor_status visit(class ir_variable *); virtual ir_visitor_status visit(class ir_constant *); virtual ir_visitor_status visit(class ir_loop_jump *); + virtual ir_visitor_status visit(class ir_emitvertex *); + virtual ir_visitor_status visit(class ir_endprim *); /** * ir_dereference_variable isn't technically a leaf, but it is treated as a diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp index 559b71a..ec9a8b6 100644 --- a/src/glsl/ir_hv_accept.cpp +++ b/src/glsl/ir_hv_accept.cpp @@ -415,3 +415,16 @@ ir_if::accept(ir_hierarchical_visitor *v) return v->visit_leave(this); } + +ir_visitor_status +ir_emitvertex::accept(ir_hierarchical_visitor *v) +{ + return v->visit(this); +} + + +ir_visitor_status +ir_endprim::accept(ir_hierarchical_visitor *v) +{ + return v->visit(this); +} diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index ca973a5..44c4933 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -539,3 +539,15 @@ ir_print_visitor::visit(ir_loop_jump *ir) { printf("%s", ir->is_break() ? "break" : "continue"); } + +void +ir_print_visitor::visit(ir_emitvertex *ir) +{ + printf("(emitvertex)"); +} + +void +ir_print_visitor::visit(ir_endprim *ir) +{ + printf("(endprim)"); +} diff --git a/src/glsl/ir_print_visitor.h b/src/glsl/ir_print_visitor.h index a84056d..38db6a1 100644 --- a/src/glsl/ir_print_visitor.h +++ b/src/glsl/ir_print_visitor.h @@ -69,6 +69,8 @@ public: virtual void visit(ir_if *); virtual void visit(ir_loop *); virtual void visit(ir_loop_jump *); + virtual void visit(ir_emitvertex *); + virtual void visit(ir_endprim *); /*@}*/ private: diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 51534ca..f8fb52d 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -59,6 +59,8 @@ private: ir_swizzle *read_swizzle(s_expression *); ir_constant *read_constant(s_expression *); ir_texture *read_texture(s_expression *); + ir_emitvertex *read_emitvertex(s_expression *); + ir_endprim *read_endprim(s_expression *); ir_dereference *read_dereference(s_expression *); ir_dereference_variable *read_var_ref(s_expression *); @@ -355,6 +357,10 @@ ir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx) inst = read_return(list); } else if (strcmp(tag->value(), "function") == 0) { inst = read_function(list, false); + } else if (strcmp(tag->value(), "emitvertex") == 0) { + inst = read_emitvertex(list); + } else if (strcmp(tag->value(), "endprim") == 0) { + inst = read_endprim(list); } else { inst = read_rvalue(list); if (inst == NULL) @@ -1065,3 +1071,27 @@ ir_reader::read_texture(s_expression *expr) }; return tex; } + +ir_emitvertex * +ir_reader::read_emitvertex(s_expression *expr) +{ + s_pattern pat[] = { "emitvertex" }; + + if (MATCH(expr, pat)) { + return new(mem_ctx) ir_emitvertex(); + } + ir_read_error(NULL, "when reading emitvertex"); + return NULL; +} + +ir_endprim * +ir_reader::read_endprim(s_expression *expr) +{ + s_pattern pat[] = { "endprim" }; + + if (MATCH(expr, pat)) { + return new(mem_ctx) ir_endprim(); + } + ir_read_error(NULL, "when reading emitvertex"); + return NULL; +} diff --git a/src/glsl/ir_visitor.h b/src/glsl/ir_visitor.h index bd47ef7..af0f986 100644 --- a/src/glsl/ir_visitor.h +++ b/src/glsl/ir_visitor.h @@ -63,6 +63,8 @@ public: virtual void visit(class ir_if *) = 0; virtual void visit(class ir_loop *) = 0; virtual void visit(class ir_loop_jump *) = 0; + virtual void visit(class ir_emitvertex *) = 0; + virtual void visit(class ir_endprim *) = 0; /*@}*/ }; @@ -81,6 +83,8 @@ public: virtual void visit(class ir_assignment *) {} virtual void visit(class ir_constant *) {} virtual void visit(class ir_call *) {} + virtual void visit(class ir_emitvertex *) {} + virtual void visit(class ir_endprim *) {} }; #endif /* __cplusplus */ diff --git a/src/glsl/lower_output_reads.cpp b/src/glsl/lower_output_reads.cpp index b93e254..bc633ba 100644 --- a/src/glsl/lower_output_reads.cpp +++ b/src/glsl/lower_output_reads.cpp @@ -50,6 +50,7 @@ public: output_read_remover(); ~output_read_remover(); virtual ir_visitor_status visit(class ir_dereference_variable *); + virtual ir_visitor_status visit(class ir_emitvertex *); virtual ir_visitor_status visit_leave(class ir_return *); virtual ir_visitor_status visit_leave(class ir_function_signature *); }; @@ -117,7 +118,9 @@ copy(void *ctx, ir_variable *output, ir_variable *temp) return new(ctx) ir_assignment(lhs, rhs); } -/** Insert a copy-back assignment before a "return" statement */ +/** Insert a copy-back assignment before a "return" statement or a call to + * EmitVertex(). + */ static void emit_return_copy(const void *key, void *data, void *closure) { @@ -141,6 +144,14 @@ output_read_remover::visit_leave(ir_return *ir) } ir_visitor_status +output_read_remover::visit(ir_emitvertex *ir) +{ + hash_table_call_foreach(replacements, emit_return_copy, ir); + hash_table_clear(replacements); + return visit_continue; +} + +ir_visitor_status output_read_remover::visit_leave(ir_function_signature *sig) { if (strcmp(sig->function_name(), "main") != 0) diff --git a/src/glsl/opt_dead_code_local.cpp b/src/glsl/opt_dead_code_local.cpp index 8c31802..72a4b38 100644 --- a/src/glsl/opt_dead_code_local.cpp +++ b/src/glsl/opt_dead_code_local.cpp @@ -114,6 +114,23 @@ public: return visit_continue_with_parent; } + virtual ir_visitor_status visit(ir_emitvertex *ir) + { + /* For the purpose of dead code elimination, emitting a vertex counts as + * "reading" all of the currently assigned output variables. + */ + foreach_iter(exec_list_iterator, iter, *this->assignments) { + assignment_entry *entry = (assignment_entry *)iter.get(); + if (entry->lhs->mode == ir_var_shader_out) { + if (debug) + printf("kill %s\n", entry->lhs->name); + entry->remove(); + } + } + + return visit_continue; + } + private: exec_list *assignments; }; diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 0645fb7..8170e7c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -238,6 +238,8 @@ public: void visit(ir_call *ir); void visit(ir_function *ir); void visit(ir_function_signature *ir); + void visit(ir_emitvertex *); + void visit(ir_endprim *); void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 15d1c6a..ac9ff0f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1991,6 +1991,18 @@ fs_visitor::visit(ir_function_signature *ir) (void)ir; } +void +fs_visitor::visit(ir_emitvertex *) +{ + assert(!"not reached"); +} + +void +fs_visitor::visit(ir_endprim *) +{ + assert(!"not reached"); +} + fs_inst * fs_visitor::emit(fs_inst inst) { diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 407d8b6..46210be 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -283,6 +283,8 @@ public: virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); + virtual void visit(ir_emitvertex *); + virtual void visit(ir_endprim *); /*@}*/ src_reg result; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 1d86b33..1c162ef 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -2582,6 +2582,18 @@ vec4_visitor::visit(ir_if *ir) } void +vec4_visitor::visit(ir_emitvertex *) +{ + assert(!"not reached"); +} + +void +vec4_visitor::visit(ir_endprim *) +{ + assert(!"not reached"); +} + +void vec4_visitor::emit_ndc_computation() { /* Get the position */ diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index f0fc1b9..e526582 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -265,6 +265,8 @@ public: virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); + virtual void visit(ir_emitvertex *); + virtual void visit(ir_endprim *); /*@}*/ src_reg result; @@ -2252,6 +2254,18 @@ ir_to_mesa_visitor::visit(ir_if *ir) if_inst = emit(ir->condition, OPCODE_ENDIF); } +void +ir_to_mesa_visitor::visit(ir_emitvertex *ir) +{ + assert(!"Geometry shaders not supported."); +} + +void +ir_to_mesa_visitor::visit(ir_endprim *ir) +{ + assert(!"Geometry shaders not supported."); +} + ir_to_mesa_visitor::ir_to_mesa_visitor() { result.file = PROGRAM_UNDEFINED; diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 69c1b41..77623f9 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -369,6 +369,8 @@ public: virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); + virtual void visit(ir_emitvertex *); + virtual void visit(ir_endprim *); /*@}*/ st_src_reg result; @@ -3008,6 +3010,18 @@ glsl_to_tgsi_visitor::visit(ir_if *ir) if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); } +void +glsl_to_tgsi_visitor::visit(ir_emitvertex *ir) +{ + assert(!"Geometry shaders not supported."); +} + +void +glsl_to_tgsi_visitor::visit(ir_endprim *ir) +{ + assert(!"Geometry shaders not supported."); +} + glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() { result.file = PROGRAM_UNDEFINED; -- 1.8.3.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev