|
|
|
@@ -46,10 +46,11 @@ namespace {
|
|
|
|
|
|
|
|
|
|
class ir_set_program_inouts_visitor : public ir_hierarchical_visitor {
|
|
|
|
|
public:
|
|
|
|
|
ir_set_program_inouts_visitor(struct gl_program *prog, GLenum shader_type)
|
|
|
|
|
ir_set_program_inouts_visitor(struct gl_program *prog,
|
|
|
|
|
gl_shader_stage shader_stage)
|
|
|
|
|
{
|
|
|
|
|
this->prog = prog;
|
|
|
|
|
this->shader_type = shader_type;
|
|
|
|
|
this->shader_stage = shader_stage;
|
|
|
|
|
}
|
|
|
|
|
~ir_set_program_inouts_visitor()
|
|
|
|
|
{
|
|
|
|
@@ -67,7 +68,7 @@ private:
|
|
|
|
|
bool try_mark_partial_variable(ir_variable *var, ir_rvalue *index);
|
|
|
|
|
|
|
|
|
|
struct gl_program *prog;
|
|
|
|
|
GLenum shader_type;
|
|
|
|
|
gl_shader_stage shader_stage;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} /* anonymous namespace */
|
|
|
|
@@ -124,13 +125,13 @@ void
|
|
|
|
|
ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
|
|
|
|
|
{
|
|
|
|
|
const glsl_type *type = var->type;
|
|
|
|
|
if (this->shader_type == GL_GEOMETRY_SHADER &&
|
|
|
|
|
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
|
|
|
|
var->data.mode == ir_var_shader_in && type->is_array()) {
|
|
|
|
|
type = type->fields.array;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mark(this->prog, var, 0, type->count_attribute_slots(),
|
|
|
|
|
this->shader_type == GL_FRAGMENT_SHADER);
|
|
|
|
|
this->shader_stage == MESA_SHADER_FRAGMENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Default handler: Mark all the locations in the variable as used. */
|
|
|
|
@@ -163,7 +164,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
|
|
|
|
|
{
|
|
|
|
|
const glsl_type *type = var->type;
|
|
|
|
|
|
|
|
|
|
if (this->shader_type == GL_GEOMETRY_SHADER &&
|
|
|
|
|
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
|
|
|
|
var->data.mode == ir_var_shader_in) {
|
|
|
|
|
/* The only geometry shader input that is not an array is
|
|
|
|
|
* gl_PrimitiveIDIn, and in that case, this code will never be reached,
|
|
|
|
@@ -227,7 +228,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mark(this->prog, var, index_as_constant->value.u[0] * elem_width,
|
|
|
|
|
elem_width, this->shader_type == GL_FRAGMENT_SHADER);
|
|
|
|
|
elem_width, this->shader_stage == MESA_SHADER_FRAGMENT);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -245,7 +246,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
|
|
|
|
*/
|
|
|
|
|
if (ir_dereference_variable * const deref_var =
|
|
|
|
|
inner_array->array->as_dereference_variable()) {
|
|
|
|
|
if (this->shader_type == GL_GEOMETRY_SHADER &&
|
|
|
|
|
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
|
|
|
|
deref_var->var->data.mode == ir_var_shader_in) {
|
|
|
|
|
/* foo is a geometry shader input, so i is the vertex, and j the
|
|
|
|
|
* part of the input we're accessing.
|
|
|
|
@@ -264,7 +265,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
|
|
|
|
} else if (ir_dereference_variable * const deref_var =
|
|
|
|
|
ir->array->as_dereference_variable()) {
|
|
|
|
|
/* ir => foo[i], where foo is a variable. */
|
|
|
|
|
if (this->shader_type == GL_GEOMETRY_SHADER &&
|
|
|
|
|
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
|
|
|
|
deref_var->var->data.mode == ir_var_shader_in) {
|
|
|
|
|
/* foo is a geometry shader input, so i is the vertex, and we're
|
|
|
|
|
* accessing the entire input.
|
|
|
|
@@ -304,7 +305,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir)
|
|
|
|
|
ir_visitor_status
|
|
|
|
|
ir_set_program_inouts_visitor::visit_enter(ir_expression *ir)
|
|
|
|
|
{
|
|
|
|
|
if (this->shader_type == GL_FRAGMENT_SHADER &&
|
|
|
|
|
if (this->shader_stage == MESA_SHADER_FRAGMENT &&
|
|
|
|
|
ir->operation == ir_unop_dFdy) {
|
|
|
|
|
gl_fragment_program *fprog = (gl_fragment_program *) prog;
|
|
|
|
|
fprog->UsesDFdy = true;
|
|
|
|
@@ -316,7 +317,7 @@ ir_visitor_status
|
|
|
|
|
ir_set_program_inouts_visitor::visit_enter(ir_discard *)
|
|
|
|
|
{
|
|
|
|
|
/* discards are only allowed in fragment shaders. */
|
|
|
|
|
assert(this->shader_type == GL_FRAGMENT_SHADER);
|
|
|
|
|
assert(this->shader_stage == MESA_SHADER_FRAGMENT);
|
|
|
|
|
|
|
|
|
|
gl_fragment_program *fprog = (gl_fragment_program *) prog;
|
|
|
|
|
fprog->UsesKill = true;
|
|
|
|
@@ -334,14 +335,14 @@ ir_set_program_inouts_visitor::visit_enter(ir_texture *ir)
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
|
|
|
|
|
GLenum shader_type)
|
|
|
|
|
gl_shader_stage shader_stage)
|
|
|
|
|
{
|
|
|
|
|
ir_set_program_inouts_visitor v(prog, shader_type);
|
|
|
|
|
ir_set_program_inouts_visitor v(prog, shader_stage);
|
|
|
|
|
|
|
|
|
|
prog->InputsRead = 0;
|
|
|
|
|
prog->OutputsWritten = 0;
|
|
|
|
|
prog->SystemValuesRead = 0;
|
|
|
|
|
if (shader_type == GL_FRAGMENT_SHADER) {
|
|
|
|
|
if (shader_stage == MESA_SHADER_FRAGMENT) {
|
|
|
|
|
gl_fragment_program *fprog = (gl_fragment_program *) prog;
|
|
|
|
|
memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
|
|
|
|
|
fprog->IsCentroid = 0;
|
|
|
|
|