1 // Copyright (c) 2015-2016 The Khronos Group Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "ext_inst.h" 16 17 #include <cassert> 18 #include <cstring> 19 20 #include "spirv/1.0/GLSL.std.450.h" 21 #include "spirv/1.0/OpenCL.std.h" 22 #include "spirv_definition.h" 23 24 #include "macro.h" 25 26 static const spv_ext_inst_desc_t glslStd450Entries_1_0[] = { 27 #include "glsl.std.450.insts-1.0.inc" 28 }; 29 30 static const spv_ext_inst_desc_t openclEntries_1_0[] = { 31 #include "opencl.std.insts-1.0.inc" 32 }; 33 34 static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = { 35 #include "spv-amd-shader-explicit-vertex-parameter.insts.inc" 36 }; 37 38 static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = { 39 #include "spv-amd-shader-trinary-minmax.insts.inc" 40 }; 41 42 static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = { 43 #include "spv-amd-gcn-shader.insts.inc" 44 }; 45 46 static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = { 47 #include "spv-amd-shader-ballot.insts.inc" 48 }; 49 50 spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable, 51 spv_target_env env) { 52 if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER; 53 54 static const spv_ext_inst_group_t groups_1_0[] = { 55 {SPV_EXT_INST_TYPE_GLSL_STD_450, ARRAY_SIZE(glslStd450Entries_1_0), 56 glslStd450Entries_1_0}, 57 {SPV_EXT_INST_TYPE_OPENCL_STD, ARRAY_SIZE(openclEntries_1_0), 58 openclEntries_1_0}, 59 {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER, 60 ARRAY_SIZE(spv_amd_shader_explicit_vertex_parameter_entries), spv_amd_shader_explicit_vertex_parameter_entries}, 61 {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX, 62 ARRAY_SIZE(spv_amd_shader_trinary_minmax_entries), spv_amd_shader_trinary_minmax_entries}, 63 {SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER, 64 ARRAY_SIZE(spv_amd_gcn_shader_entries), spv_amd_gcn_shader_entries}, 65 {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT, 66 ARRAY_SIZE(spv_amd_shader_ballot_entries), spv_amd_shader_ballot_entries}, 67 }; 68 69 static const spv_ext_inst_table_t table_1_0 = {ARRAY_SIZE(groups_1_0), 70 groups_1_0}; 71 72 switch (env) { 73 // The extended instruction sets are all version 1.0 so far. 74 case SPV_ENV_UNIVERSAL_1_0: 75 case SPV_ENV_VULKAN_1_0: 76 case SPV_ENV_UNIVERSAL_1_1: 77 case SPV_ENV_UNIVERSAL_1_2: 78 case SPV_ENV_OPENCL_2_1: 79 case SPV_ENV_OPENCL_2_2: 80 case SPV_ENV_OPENGL_4_0: 81 case SPV_ENV_OPENGL_4_1: 82 case SPV_ENV_OPENGL_4_2: 83 case SPV_ENV_OPENGL_4_3: 84 case SPV_ENV_OPENGL_4_5: 85 *pExtInstTable = &table_1_0; 86 return SPV_SUCCESS; 87 default: 88 assert(0 && "Unknown spv_target_env in spvExtInstTableGet()"); 89 return SPV_ERROR_INVALID_TABLE; 90 } 91 } 92 93 spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) { 94 // The names are specified by the respective extension instruction 95 // specifications. 96 if (!strcmp("GLSL.std.450", name)) { 97 return SPV_EXT_INST_TYPE_GLSL_STD_450; 98 } 99 if (!strcmp("OpenCL.std", name)) { 100 return SPV_EXT_INST_TYPE_OPENCL_STD; 101 } 102 if (!strcmp("SPV_AMD_shader_explicit_vertex_parameter", name)) { 103 return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER; 104 } 105 if (!strcmp("SPV_AMD_shader_trinary_minmax", name)) { 106 return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX; 107 } 108 if (!strcmp("SPV_AMD_gcn_shader", name)) { 109 return SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER; 110 } 111 if (!strcmp("SPV_AMD_shader_ballot", name)) { 112 return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT; 113 } 114 return SPV_EXT_INST_TYPE_NONE; 115 } 116 117 spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table, 118 const spv_ext_inst_type_t type, 119 const char* name, 120 spv_ext_inst_desc* pEntry) { 121 if (!table) return SPV_ERROR_INVALID_TABLE; 122 if (!pEntry) return SPV_ERROR_INVALID_POINTER; 123 124 for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { 125 const auto& group = table->groups[groupIndex]; 126 if (type != group.type) continue; 127 for (uint32_t index = 0; index < group.count; index++) { 128 const auto& entry = group.entries[index]; 129 if (!strcmp(name, entry.name)) { 130 *pEntry = &entry; 131 return SPV_SUCCESS; 132 } 133 } 134 } 135 136 return SPV_ERROR_INVALID_LOOKUP; 137 } 138 139 spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table, 140 const spv_ext_inst_type_t type, 141 const uint32_t value, 142 spv_ext_inst_desc* pEntry) { 143 if (!table) return SPV_ERROR_INVALID_TABLE; 144 if (!pEntry) return SPV_ERROR_INVALID_POINTER; 145 146 for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { 147 const auto& group = table->groups[groupIndex]; 148 if (type != group.type) continue; 149 for (uint32_t index = 0; index < group.count; index++) { 150 const auto& entry = group.entries[index]; 151 if (value == entry.ext_inst) { 152 *pEntry = &entry; 153 return SPV_SUCCESS; 154 } 155 } 156 } 157 158 return SPV_ERROR_INVALID_LOOKUP; 159 } 160