| 31 | } // namespace |
| 32 | |
| 33 | Pass::Status EliminateDeadIOComponentsPass::Process() { |
| 34 | // Only process input and output variables |
| 35 | if (elim_sclass_ != spv::StorageClass::Input && |
| 36 | elim_sclass_ != spv::StorageClass::Output) { |
| 37 | if (consumer()) { |
| 38 | std::string message = |
| 39 | "EliminateDeadIOComponentsPass only valid for input and output " |
| 40 | "variables."; |
| 41 | consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); |
| 42 | } |
| 43 | return Status::Failure; |
| 44 | } |
| 45 | // If safe mode, only process Input variables in vertex shader |
| 46 | const auto stage = context()->GetStage(); |
| 47 | if (safe_mode_ && !(stage == spv::ExecutionModel::Vertex && |
| 48 | elim_sclass_ == spv::StorageClass::Input)) |
| 49 | return Status::SuccessWithoutChange; |
| 50 | // Current functionality assumes shader capability. |
| 51 | if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) |
| 52 | return Status::SuccessWithoutChange; |
| 53 | // Current functionality assumes vert, frag, tesc, tese or geom shader. |
| 54 | // TODO(issue #4988): Add GLCompute. |
| 55 | if (stage != spv::ExecutionModel::Vertex && |
| 56 | stage != spv::ExecutionModel::Fragment && |
| 57 | stage != spv::ExecutionModel::TessellationControl && |
| 58 | stage != spv::ExecutionModel::TessellationEvaluation && |
| 59 | stage != spv::ExecutionModel::Geometry) |
| 60 | return Status::SuccessWithoutChange; |
| 61 | analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); |
| 62 | analysis::TypeManager* type_mgr = context()->get_type_mgr(); |
| 63 | bool modified = false; |
| 64 | std::vector<Instruction*> vars_to_move; |
| 65 | for (auto& var : context()->types_values()) { |
| 66 | if (var.opcode() != spv::Op::OpVariable) { |
| 67 | continue; |
| 68 | } |
| 69 | analysis::Type* var_type = type_mgr->GetType(var.type_id()); |
| 70 | analysis::Pointer* ptr_type = var_type->AsPointer(); |
| 71 | if (ptr_type == nullptr) { |
| 72 | continue; |
| 73 | } |
| 74 | const auto sclass = ptr_type->storage_class(); |
| 75 | if (sclass != elim_sclass_) { |
| 76 | continue; |
| 77 | } |
| 78 | // For tesc, or input variables in tese or geom shaders, |
| 79 | // there is a outer per-vertex-array that must be ignored |
| 80 | // for the purposes of this analysis/optimization. Do the |
| 81 | // analysis on the inner type in these cases. |
| 82 | bool skip_first_index = false; |
| 83 | auto core_type = ptr_type->pointee_type(); |
| 84 | if (stage == spv::ExecutionModel::TessellationControl || |
| 85 | (sclass == spv::StorageClass::Input && |
| 86 | (stage == spv::ExecutionModel::TessellationEvaluation || |
| 87 | stage == spv::ExecutionModel::Geometry))) { |
| 88 | auto arr_type = core_type->AsArray(); |
| 89 | if (!arr_type) continue; |
| 90 | core_type = arr_type->element_type(); |
nothing calls this directly
no test coverage detected