glsl: add ir_emit_vertex and ir_end_primitive instruction types
These correspond to the EmitVertex and EndPrimitive functions in GLSL. v2 (Paul Berry <stereotype441@gmail.com>): Add stub implementations of new pure visitor functions to i965's vec4_visitor and fs_visitor classes. v3 (Paul Berry <stereotype441@gmail.com>): Rename classes to be more consistent with the names used in the GL spec. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -81,6 +81,8 @@ enum ir_node_type {
|
|||||||
ir_type_return,
|
ir_type_return,
|
||||||
ir_type_swizzle,
|
ir_type_swizzle,
|
||||||
ir_type_texture,
|
ir_type_texture,
|
||||||
|
ir_type_emit_vertex,
|
||||||
|
ir_type_end_primitive,
|
||||||
ir_type_max /**< maximum ir_type enum number, for validation */
|
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 input: one of the values from \c gl_vert_attrib.
|
||||||
* - Vertex shader output: one of the values from \c gl_varying_slot.
|
* - 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 input: one of the values from \c gl_varying_slot.
|
||||||
* - Fragment shader output: one of the values from \c gl_frag_result.
|
* - Fragment shader output: one of the values from \c gl_frag_result.
|
||||||
* - Uniforms: Per-stage uniform slot number for default uniform block.
|
* - Uniforms: Per-stage uniform slot number for default uniform block.
|
||||||
@@ -1991,6 +1995,53 @@ private:
|
|||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IR instruction to emit a vertex in a geometry shader.
|
||||||
|
*/
|
||||||
|
class ir_emit_vertex : public ir_instruction {
|
||||||
|
public:
|
||||||
|
ir_emit_vertex()
|
||||||
|
{
|
||||||
|
ir_type = ir_type_emit_vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void accept(ir_visitor *v)
|
||||||
|
{
|
||||||
|
v->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *) const
|
||||||
|
{
|
||||||
|
return new(mem_ctx) ir_emit_vertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_end_primitive : public ir_instruction {
|
||||||
|
public:
|
||||||
|
ir_end_primitive()
|
||||||
|
{
|
||||||
|
ir_type = ir_type_end_primitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void accept(ir_visitor *v)
|
||||||
|
{
|
||||||
|
v->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *) const
|
||||||
|
{
|
||||||
|
return new(mem_ctx) ir_end_primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a visitor to each IR node in a list
|
* Apply a visitor to each IR node in a list
|
||||||
*/
|
*/
|
||||||
|
@@ -68,6 +68,24 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
|
|||||||
return visit_continue;
|
return visit_continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
ir_hierarchical_visitor::visit(ir_emit_vertex *ir)
|
||||||
|
{
|
||||||
|
if (this->callback != NULL)
|
||||||
|
this->callback(ir, this->data);
|
||||||
|
|
||||||
|
return visit_continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
ir_hierarchical_visitor::visit(ir_end_primitive *ir)
|
||||||
|
{
|
||||||
|
if (this->callback != NULL)
|
||||||
|
this->callback(ir, this->data);
|
||||||
|
|
||||||
|
return visit_continue;
|
||||||
|
}
|
||||||
|
|
||||||
ir_visitor_status
|
ir_visitor_status
|
||||||
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
|
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
|
||||||
{
|
{
|
||||||
|
@@ -87,6 +87,8 @@ public:
|
|||||||
virtual ir_visitor_status visit(class ir_variable *);
|
virtual ir_visitor_status visit(class ir_variable *);
|
||||||
virtual ir_visitor_status visit(class ir_constant *);
|
virtual ir_visitor_status visit(class ir_constant *);
|
||||||
virtual ir_visitor_status visit(class ir_loop_jump *);
|
virtual ir_visitor_status visit(class ir_loop_jump *);
|
||||||
|
virtual ir_visitor_status visit(class ir_emit_vertex *);
|
||||||
|
virtual ir_visitor_status visit(class ir_end_primitive *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ir_dereference_variable isn't technically a leaf, but it is treated as a
|
* ir_dereference_variable isn't technically a leaf, but it is treated as a
|
||||||
|
@@ -415,3 +415,16 @@ ir_if::accept(ir_hierarchical_visitor *v)
|
|||||||
|
|
||||||
return v->visit_leave(this);
|
return v->visit_leave(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
ir_emit_vertex::accept(ir_hierarchical_visitor *v)
|
||||||
|
{
|
||||||
|
return v->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
ir_end_primitive::accept(ir_hierarchical_visitor *v)
|
||||||
|
{
|
||||||
|
return v->visit(this);
|
||||||
|
}
|
||||||
|
@@ -539,3 +539,15 @@ ir_print_visitor::visit(ir_loop_jump *ir)
|
|||||||
{
|
{
|
||||||
printf("%s", ir->is_break() ? "break" : "continue");
|
printf("%s", ir->is_break() ? "break" : "continue");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir_print_visitor::visit(ir_emit_vertex *ir)
|
||||||
|
{
|
||||||
|
printf("(emit-vertex)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir_print_visitor::visit(ir_end_primitive *ir)
|
||||||
|
{
|
||||||
|
printf("(end-primitive)");
|
||||||
|
}
|
||||||
|
@@ -69,6 +69,8 @@ public:
|
|||||||
virtual void visit(ir_if *);
|
virtual void visit(ir_if *);
|
||||||
virtual void visit(ir_loop *);
|
virtual void visit(ir_loop *);
|
||||||
virtual void visit(ir_loop_jump *);
|
virtual void visit(ir_loop_jump *);
|
||||||
|
virtual void visit(ir_emit_vertex *);
|
||||||
|
virtual void visit(ir_end_primitive *);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -59,6 +59,8 @@ private:
|
|||||||
ir_swizzle *read_swizzle(s_expression *);
|
ir_swizzle *read_swizzle(s_expression *);
|
||||||
ir_constant *read_constant(s_expression *);
|
ir_constant *read_constant(s_expression *);
|
||||||
ir_texture *read_texture(s_expression *);
|
ir_texture *read_texture(s_expression *);
|
||||||
|
ir_emit_vertex *read_emit_vertex(s_expression *);
|
||||||
|
ir_end_primitive *read_end_primitive(s_expression *);
|
||||||
|
|
||||||
ir_dereference *read_dereference(s_expression *);
|
ir_dereference *read_dereference(s_expression *);
|
||||||
ir_dereference_variable *read_var_ref(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);
|
inst = read_return(list);
|
||||||
} else if (strcmp(tag->value(), "function") == 0) {
|
} else if (strcmp(tag->value(), "function") == 0) {
|
||||||
inst = read_function(list, false);
|
inst = read_function(list, false);
|
||||||
|
} else if (strcmp(tag->value(), "emit-vertex") == 0) {
|
||||||
|
inst = read_emit_vertex(list);
|
||||||
|
} else if (strcmp(tag->value(), "end-primitive") == 0) {
|
||||||
|
inst = read_end_primitive(list);
|
||||||
} else {
|
} else {
|
||||||
inst = read_rvalue(list);
|
inst = read_rvalue(list);
|
||||||
if (inst == NULL)
|
if (inst == NULL)
|
||||||
@@ -1065,3 +1071,27 @@ ir_reader::read_texture(s_expression *expr)
|
|||||||
};
|
};
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_emit_vertex *
|
||||||
|
ir_reader::read_emit_vertex(s_expression *expr)
|
||||||
|
{
|
||||||
|
s_pattern pat[] = { "emit-vertex" };
|
||||||
|
|
||||||
|
if (MATCH(expr, pat)) {
|
||||||
|
return new(mem_ctx) ir_emit_vertex();
|
||||||
|
}
|
||||||
|
ir_read_error(NULL, "when reading emit-vertex");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_end_primitive *
|
||||||
|
ir_reader::read_end_primitive(s_expression *expr)
|
||||||
|
{
|
||||||
|
s_pattern pat[] = { "end-primitive" };
|
||||||
|
|
||||||
|
if (MATCH(expr, pat)) {
|
||||||
|
return new(mem_ctx) ir_end_primitive();
|
||||||
|
}
|
||||||
|
ir_read_error(NULL, "when reading end-primitive");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -63,6 +63,8 @@ public:
|
|||||||
virtual void visit(class ir_if *) = 0;
|
virtual void visit(class ir_if *) = 0;
|
||||||
virtual void visit(class ir_loop *) = 0;
|
virtual void visit(class ir_loop *) = 0;
|
||||||
virtual void visit(class ir_loop_jump *) = 0;
|
virtual void visit(class ir_loop_jump *) = 0;
|
||||||
|
virtual void visit(class ir_emit_vertex *) = 0;
|
||||||
|
virtual void visit(class ir_end_primitive *) = 0;
|
||||||
/*@}*/
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,6 +83,8 @@ public:
|
|||||||
virtual void visit(class ir_assignment *) {}
|
virtual void visit(class ir_assignment *) {}
|
||||||
virtual void visit(class ir_constant *) {}
|
virtual void visit(class ir_constant *) {}
|
||||||
virtual void visit(class ir_call *) {}
|
virtual void visit(class ir_call *) {}
|
||||||
|
virtual void visit(class ir_emit_vertex *) {}
|
||||||
|
virtual void visit(class ir_end_primitive *) {}
|
||||||
};
|
};
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
@@ -50,6 +50,7 @@ public:
|
|||||||
output_read_remover();
|
output_read_remover();
|
||||||
~output_read_remover();
|
~output_read_remover();
|
||||||
virtual ir_visitor_status visit(class ir_dereference_variable *);
|
virtual ir_visitor_status visit(class ir_dereference_variable *);
|
||||||
|
virtual ir_visitor_status visit(class ir_emit_vertex *);
|
||||||
virtual ir_visitor_status visit_leave(class ir_return *);
|
virtual ir_visitor_status visit_leave(class ir_return *);
|
||||||
virtual ir_visitor_status visit_leave(class ir_function_signature *);
|
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);
|
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
|
static void
|
||||||
emit_return_copy(const void *key, void *data, void *closure)
|
emit_return_copy(const void *key, void *data, void *closure)
|
||||||
{
|
{
|
||||||
@@ -140,6 +143,14 @@ output_read_remover::visit_leave(ir_return *ir)
|
|||||||
return visit_continue;
|
return visit_continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
output_read_remover::visit(ir_emit_vertex *ir)
|
||||||
|
{
|
||||||
|
hash_table_call_foreach(replacements, emit_return_copy, ir);
|
||||||
|
hash_table_clear(replacements);
|
||||||
|
return visit_continue;
|
||||||
|
}
|
||||||
|
|
||||||
ir_visitor_status
|
ir_visitor_status
|
||||||
output_read_remover::visit_leave(ir_function_signature *sig)
|
output_read_remover::visit_leave(ir_function_signature *sig)
|
||||||
{
|
{
|
||||||
|
@@ -114,6 +114,23 @@ public:
|
|||||||
return visit_continue_with_parent;
|
return visit_continue_with_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ir_visitor_status visit(ir_emit_vertex *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:
|
private:
|
||||||
exec_list *assignments;
|
exec_list *assignments;
|
||||||
};
|
};
|
||||||
|
@@ -238,6 +238,8 @@ public:
|
|||||||
void visit(ir_call *ir);
|
void visit(ir_call *ir);
|
||||||
void visit(ir_function *ir);
|
void visit(ir_function *ir);
|
||||||
void visit(ir_function_signature *ir);
|
void visit(ir_function_signature *ir);
|
||||||
|
void visit(ir_emit_vertex *);
|
||||||
|
void visit(ir_end_primitive *);
|
||||||
|
|
||||||
void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler);
|
void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler);
|
||||||
|
|
||||||
|
@@ -1991,6 +1991,18 @@ fs_visitor::visit(ir_function_signature *ir)
|
|||||||
(void)ir;
|
(void)ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fs_visitor::visit(ir_emit_vertex *)
|
||||||
|
{
|
||||||
|
assert(!"not reached");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fs_visitor::visit(ir_end_primitive *)
|
||||||
|
{
|
||||||
|
assert(!"not reached");
|
||||||
|
}
|
||||||
|
|
||||||
fs_inst *
|
fs_inst *
|
||||||
fs_visitor::emit(fs_inst inst)
|
fs_visitor::emit(fs_inst inst)
|
||||||
{
|
{
|
||||||
|
@@ -283,6 +283,8 @@ public:
|
|||||||
virtual void visit(ir_discard *);
|
virtual void visit(ir_discard *);
|
||||||
virtual void visit(ir_texture *);
|
virtual void visit(ir_texture *);
|
||||||
virtual void visit(ir_if *);
|
virtual void visit(ir_if *);
|
||||||
|
virtual void visit(ir_emit_vertex *);
|
||||||
|
virtual void visit(ir_end_primitive *);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
src_reg result;
|
src_reg result;
|
||||||
|
@@ -2581,6 +2581,18 @@ vec4_visitor::visit(ir_if *ir)
|
|||||||
emit(BRW_OPCODE_ENDIF);
|
emit(BRW_OPCODE_ENDIF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vec4_visitor::visit(ir_emit_vertex *)
|
||||||
|
{
|
||||||
|
assert(!"not reached");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vec4_visitor::visit(ir_end_primitive *)
|
||||||
|
{
|
||||||
|
assert(!"not reached");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
vec4_visitor::emit_ndc_computation()
|
vec4_visitor::emit_ndc_computation()
|
||||||
{
|
{
|
||||||
|
@@ -265,6 +265,8 @@ public:
|
|||||||
virtual void visit(ir_discard *);
|
virtual void visit(ir_discard *);
|
||||||
virtual void visit(ir_texture *);
|
virtual void visit(ir_texture *);
|
||||||
virtual void visit(ir_if *);
|
virtual void visit(ir_if *);
|
||||||
|
virtual void visit(ir_emit_vertex *);
|
||||||
|
virtual void visit(ir_end_primitive *);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
src_reg result;
|
src_reg result;
|
||||||
@@ -2252,6 +2254,18 @@ ir_to_mesa_visitor::visit(ir_if *ir)
|
|||||||
if_inst = emit(ir->condition, OPCODE_ENDIF);
|
if_inst = emit(ir->condition, OPCODE_ENDIF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir_to_mesa_visitor::visit(ir_emit_vertex *ir)
|
||||||
|
{
|
||||||
|
assert(!"Geometry shaders not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ir_to_mesa_visitor::visit(ir_end_primitive *ir)
|
||||||
|
{
|
||||||
|
assert(!"Geometry shaders not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
ir_to_mesa_visitor::ir_to_mesa_visitor()
|
ir_to_mesa_visitor::ir_to_mesa_visitor()
|
||||||
{
|
{
|
||||||
result.file = PROGRAM_UNDEFINED;
|
result.file = PROGRAM_UNDEFINED;
|
||||||
|
@@ -369,6 +369,8 @@ public:
|
|||||||
virtual void visit(ir_discard *);
|
virtual void visit(ir_discard *);
|
||||||
virtual void visit(ir_texture *);
|
virtual void visit(ir_texture *);
|
||||||
virtual void visit(ir_if *);
|
virtual void visit(ir_if *);
|
||||||
|
virtual void visit(ir_emit_vertex *);
|
||||||
|
virtual void visit(ir_end_primitive *);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
st_src_reg result;
|
st_src_reg result;
|
||||||
@@ -3015,6 +3017,18 @@ glsl_to_tgsi_visitor::visit(ir_if *ir)
|
|||||||
if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
|
if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
|
||||||
|
{
|
||||||
|
assert(!"Geometry shaders not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
|
||||||
|
{
|
||||||
|
assert(!"Geometry shaders not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
|
glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
|
||||||
{
|
{
|
||||||
result.file = PROGRAM_UNDEFINED;
|
result.file = PROGRAM_UNDEFINED;
|
||||||
|
Reference in New Issue
Block a user