1 /*------------------------------------------------------------------------- 2 * Vulkan CTS Framework 3 * -------------------- 4 * 5 * Copyright (c) 2015 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief SPIR-V assembly to binary. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vkSpirVAsm.hpp" 25 #include "vkSpirVProgram.hpp" 26 #include "deClock.h" 27 28 #include <algorithm> 29 30 #if defined(DEQP_HAVE_SPIRV_TOOLS) 31 # include "spirv-tools/libspirv.h" 32 #endif 33 34 namespace vk 35 { 36 37 using std::string; 38 using std::vector; 39 40 #if defined(DEQP_HAVE_SPIRV_TOOLS) 41 42 bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo) 43 { 44 const spv_context context = spvContextCreate(); 45 spv_binary binary = DE_NULL; 46 spv_diagnostic diagnostic = DE_NULL; 47 48 if (!context) 49 throw std::bad_alloc(); 50 51 try 52 { 53 const std::string& spvSource = program->source; 54 const deUint64 compileStartTime = deGetMicroseconds(); 55 const spv_result_t compileOk = spvTextToBinary(context, spvSource.c_str(), spvSource.size(), &binary, &diagnostic); 56 57 buildInfo->source = spvSource; 58 buildInfo->infoLog = diagnostic? diagnostic->error : ""; // \todo [2015-07-13 pyry] Include debug log? 59 buildInfo->compileTimeUs = deGetMicroseconds() - compileStartTime; 60 buildInfo->compileOk = (compileOk == SPV_SUCCESS); 61 62 dst->resize(binary->wordCount); 63 std::copy(&binary->code[0], &binary->code[0] + binary->wordCount, dst->begin()); 64 65 spvBinaryDestroy(binary); 66 spvDiagnosticDestroy(diagnostic); 67 spvContextDestroy(context); 68 69 return compileOk == SPV_SUCCESS; 70 } 71 catch (...) 72 { 73 spvBinaryDestroy(binary); 74 spvDiagnosticDestroy(diagnostic); 75 spvContextDestroy(context); 76 77 throw; 78 } 79 } 80 81 void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst) 82 { 83 const spv_context context = spvContextCreate(); 84 spv_text text = DE_NULL; 85 spv_diagnostic diagnostic = DE_NULL; 86 87 if (!context) 88 throw std::bad_alloc(); 89 90 try 91 { 92 const spv_result_t result = spvBinaryToText(context, binary, binarySizeInWords, 0, &text, &diagnostic); 93 94 if (result != SPV_SUCCESS) 95 TCU_THROW(InternalError, "Disassembling SPIR-V failed"); 96 97 *dst << text->str; 98 99 spvTextDestroy(text); 100 spvDiagnosticDestroy(diagnostic); 101 spvContextDestroy(context); 102 } 103 catch (...) 104 { 105 spvTextDestroy(text); 106 spvDiagnosticDestroy(diagnostic); 107 spvContextDestroy(context); 108 109 throw; 110 } 111 } 112 113 bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog) 114 { 115 const spv_context context = spvContextCreate(); 116 spv_diagnostic diagnostic = DE_NULL; 117 118 try 119 { 120 spv_const_binary_t cbinary = { binary, binarySizeInWords }; 121 const spv_result_t valid = spvValidate(context, &cbinary, &diagnostic); 122 123 if (diagnostic) 124 *infoLog << diagnostic->error; 125 126 spvDiagnosticDestroy(diagnostic); 127 spvContextDestroy(context); 128 129 return valid == SPV_SUCCESS; 130 } 131 catch (...) 132 { 133 spvDiagnosticDestroy(diagnostic); 134 spvContextDestroy(context); 135 136 throw; 137 } 138 } 139 140 #else // defined(DEQP_HAVE_SPIRV_TOOLS) 141 142 bool assembleSpirV (const SpirVAsmSource*, std::vector<deUint32>*, SpirVProgramInfo*) 143 { 144 TCU_THROW(NotSupportedError, "SPIR-V assembly not supported (DEQP_HAVE_SPIRV_TOOLS not defined)"); 145 } 146 147 void disassembleSpirV (size_t, const deUint32*, std::ostream*) 148 { 149 TCU_THROW(NotSupportedError, "SPIR-V disassembling not supported (DEQP_HAVE_SPIRV_TOOLS not defined)"); 150 } 151 152 bool validateSpirV (size_t, const deUint32*, std::ostream*) 153 { 154 TCU_THROW(NotSupportedError, "SPIR-V validation not supported (DEQP_HAVE_SPIRV_TOOLS not defined)"); 155 } 156 157 #endif 158 159 } // vk 160