X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fir_set_program_inouts.cpp;h=a3cb19479b8a2c7985f261c11eabda1ec59bc1a7;hb=1b1b436fa7cf92cce23018ea923597c4d7290d57;hp=df06923b870f5b85122a6d7561d5117f9cde96cb;hpb=741744f691d6ef63e9f9a4c03136f969f2ffb0bf;p=mesa.git diff --git a/src/compiler/glsl/ir_set_program_inouts.cpp b/src/compiler/glsl/ir_set_program_inouts.cpp index df06923b870..a3cb19479b8 100644 --- a/src/compiler/glsl/ir_set_program_inouts.cpp +++ b/src/compiler/glsl/ir_set_program_inouts.cpp @@ -24,23 +24,20 @@ /** * \file ir_set_program_inouts.cpp * - * Sets the InputsRead and OutputsWritten of Mesa programs. - * - * Additionally, for fragment shaders, sets the InterpQualifier array, the - * IsCentroid and IsSample bitfields, and the UsesDFdy flag. + * Sets the inputs_read and outputs_written of Mesa programs. * * Mesa programs (gl_program, not gl_shader_program) have a set of * flags indicating which varyings are read and written. Computing * which are actually read from some sort of backend code can be * tricky when variable array indexing involved. So this pass - * provides support for setting InputsRead and OutputsWritten right + * provides support for setting inputs_read and outputs_written right * from the GLSL IR. */ -#include "main/core.h" /* for struct gl_program */ #include "ir.h" #include "ir_visitor.h" #include "compiler/glsl_types.h" +#include "main/mtypes.h" namespace { @@ -58,7 +55,6 @@ public: virtual ir_visitor_status visit_enter(ir_dereference_array *); virtual ir_visitor_status visit_enter(ir_function_signature *); - virtual ir_visitor_status visit_enter(ir_expression *); virtual ir_visitor_status visit_enter(ir_discard *); virtual ir_visitor_status visit_enter(ir_texture *); virtual ir_visitor_status visit(ir_dereference_variable *); @@ -87,17 +83,21 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, { /* As of GLSL 1.20, varyings can only be floats, floating-point * vectors or matrices, or arrays of them. For Mesa programs using - * InputsRead/OutputsWritten, everything but matrices uses one + * inputs_read/outputs_written, everything but matrices uses one * slot, while matrices use a slot per column. Presumably * something doing a more clever packing would use something other - * than InputsRead/OutputsWritten. + * than inputs_read/outputs_written. */ for (int i = 0; i < len; i++) { - int idx = var->data.location + var->data.index + offset + i; + assert(var->data.location != -1); + + int idx = var->data.location + offset + i; bool is_patch_generic = var->data.patch && idx != VARYING_SLOT_TESS_LEVEL_INNER && - idx != VARYING_SLOT_TESS_LEVEL_OUTER; + idx != VARYING_SLOT_TESS_LEVEL_OUTER && + idx != VARYING_SLOT_BOUNDING_BOX0 && + idx != VARYING_SLOT_BOUNDING_BOX1; GLbitfield64 bitfield; if (is_patch_generic) { @@ -111,32 +111,32 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, if (var->data.mode == ir_var_shader_in) { if (is_patch_generic) - prog->PatchInputsRead |= bitfield; + prog->info.patch_inputs_read |= bitfield; else - prog->InputsRead |= bitfield; + prog->info.inputs_read |= bitfield; /* double inputs read is only for vertex inputs */ if (stage == MESA_SHADER_VERTEX && - var->type->without_array()->is_dual_slot_double()) - prog->DoubleInputsRead |= bitfield; + var->type->without_array()->is_dual_slot()) + prog->DualSlotInputs |= bitfield; if (stage == MESA_SHADER_FRAGMENT) { - gl_fragment_program *fprog = (gl_fragment_program *) prog; - fprog->InterpQualifier[idx] = - (glsl_interp_qualifier) var->data.interpolation; - if (var->data.centroid) - fprog->IsCentroid |= bitfield; - if (var->data.sample) - fprog->IsSample |= bitfield; + prog->info.fs.uses_sample_qualifier |= var->data.sample; } } else if (var->data.mode == ir_var_system_value) { - prog->SystemValuesRead |= bitfield; + prog->info.system_values_read |= bitfield; } else { assert(var->data.mode == ir_var_shader_out); - if (is_patch_generic) - prog->PatchOutputsWritten |= bitfield; - else - prog->OutputsWritten |= bitfield; + if (is_patch_generic) { + prog->info.patch_outputs_written |= bitfield; + } else if (!var->data.read_only) { + prog->info.outputs_written |= bitfield; + if (var->data.index > 0) + prog->SecondaryOutputsWritten |= bitfield; + } + + if (var->data.fb_fetch_output) + prog->info.outputs_read |= bitfield; } } } @@ -149,7 +149,7 @@ void ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var) { const glsl_type *type = var->type; - bool vertex_input = false; + bool is_vertex_input = false; if (this->shader_stage == MESA_SHADER_GEOMETRY && var->data.mode == ir_var_shader_in && type->is_array()) { type = type->fields.array; @@ -175,9 +175,9 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var) if (this->shader_stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_in) - vertex_input = true; + is_vertex_input = true; - mark(this->prog, var, 0, type->count_attribute_slots(vertex_input), + mark(this->prog, var, 0, type->count_attribute_slots(is_vertex_input), this->shader_stage); } @@ -258,15 +258,19 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, * lowering passes (do_vec_index_to_swizzle() gets rid of indexing into * vectors, and lower_packed_varyings() gets rid of structs that occur in * varyings). + * + * However, we don't use varying packing in all cases - tessellation + * shaders bypass it. This means we'll see varying structs and arrays + * of structs here. For now, we just give up so the caller marks the + * entire variable as used. */ if (!(type->is_matrix() || (type->is_array() && (type->fields.array->is_numeric() || type->fields.array->is_boolean())))) { - assert(!"Unexpected indexing in ir_set_program_inouts"); - /* For safety in release builds, in case we ever encounter unexpected - * indexing, give up and let the caller mark the whole variable as used. + /* If we don't know how to handle this case, give up and let the + * caller mark the whole variable as used. */ return false; } @@ -304,7 +308,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, /* double element width for double types that takes two slots */ if (this->shader_stage != MESA_SHADER_VERTEX || var->data.mode != ir_var_shader_in) { - if (type->without_array()->is_dual_slot_double()) + if (type->without_array()->is_dual_slot()) elem_width *= 2; } @@ -397,27 +401,13 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir) return visit_continue_with_parent; } -ir_visitor_status -ir_set_program_inouts_visitor::visit_enter(ir_expression *ir) -{ - if (this->shader_stage == MESA_SHADER_FRAGMENT && - (ir->operation == ir_unop_dFdy || - ir->operation == ir_unop_dFdy_coarse || - ir->operation == ir_unop_dFdy_fine)) { - gl_fragment_program *fprog = (gl_fragment_program *) prog; - fprog->UsesDFdy = true; - } - return visit_continue; -} - ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_discard *) { /* discards are only allowed in fragment shaders. */ assert(this->shader_stage == MESA_SHADER_FRAGMENT); - gl_fragment_program *fprog = (gl_fragment_program *) prog; - fprog->UsesKill = true; + prog->info.fs.uses_discard = true; return visit_continue; } @@ -426,7 +416,7 @@ ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_texture *ir) { if (ir->op == ir_tg4) - prog->UsesGather = true; + prog->info.uses_texture_gather = true; return visit_continue; } @@ -436,18 +426,16 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog, { ir_set_program_inouts_visitor v(prog, shader_stage); - prog->InputsRead = 0; - prog->OutputsWritten = 0; - prog->PatchInputsRead = 0; - prog->PatchOutputsWritten = 0; - prog->SystemValuesRead = 0; + prog->info.inputs_read = 0; + prog->info.outputs_written = 0; + prog->SecondaryOutputsWritten = 0; + prog->info.outputs_read = 0; + prog->info.patch_inputs_read = 0; + prog->info.patch_outputs_written = 0; + prog->info.system_values_read = 0; if (shader_stage == MESA_SHADER_FRAGMENT) { - gl_fragment_program *fprog = (gl_fragment_program *) prog; - memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier)); - fprog->IsCentroid = 0; - fprog->IsSample = 0; - fprog->UsesDFdy = false; - fprog->UsesKill = false; + prog->info.fs.uses_sample_qualifier = false; + prog->info.fs.uses_discard = false; } visit_list_elements(&v, instructions); }