Home | History | Annotate | Download | only in source
      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