111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (c) 2016 Google Inc. 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Permission is hereby granted, free of charge, to any person obtaining a 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// copy of this software and/or associated documentation files (the 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// "Materials"), to deal in the Materials without restriction, including 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// without limitation the rights to use, copy, modify, merge, publish, 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// distribute, sublicense, and/or sell copies of the Materials, and to 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permit persons to whom the Materials are furnished to do so, subject to 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the following conditions: 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The above copyright notice and this permission notice shall be included 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// in all copies or substantial portions of the Materials. 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// https://www.khronos.org/registry/ 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "libspirv.hpp" 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "ir_loader.h" 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace spvtools { 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace { 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Sets the module header. Meets the interface requirement of spvBinaryParse(). 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertspv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic, 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t version, uint32_t generator, 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t id_bound, uint32_t reserved) { 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<ir::IrLoader*>(builder)->SetModuleHeader( 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert magic, version, generator, id_bound, reserved); 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return SPV_SUCCESS; 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Processes a parsed instruction. Meets the interface requirement of 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// spvBinaryParse(). 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertspv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) { 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst); 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return SPV_SUCCESS; 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // annoymous namespace 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertspv_result_t SpvTools::Assemble(const std::string& text, 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::vector<uint32_t>* binary) { 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_binary spvbinary = nullptr; 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_diagnostic diagnostic = nullptr; 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_result_t status = spvTextToBinary(context_, text.data(), text.size(), 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert &spvbinary, &diagnostic); 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (status == SPV_SUCCESS) { 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert binary->assign(spvbinary->code, spvbinary->code + spvbinary->wordCount); 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvDiagnosticDestroy(diagnostic); 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvBinaryDestroy(spvbinary); 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return status; 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertspv_result_t SpvTools::Disassemble(const std::vector<uint32_t>& binary, 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::string* text) { 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_text spvtext = nullptr; 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_diagnostic diagnostic = nullptr; 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_result_t status = spvBinaryToText(context_, binary.data(), binary.size(), 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert &spvtext, &diagnostic); 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (status == SPV_SUCCESS) { 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert text->assign(spvtext->str, spvtext->str + spvtext->length); 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvDiagnosticDestroy(diagnostic); 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvTextDestroy(spvtext); 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return status; 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::unique_ptr<ir::Module> SpvTools::BuildModule( 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const std::vector<uint32_t>& binary) { 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_diagnostic diagnostic = nullptr; 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_ptr<ir::Module> module(new ir::Module); 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ir::IrLoader loader(module.get()); 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spv_result_t status = 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvBinaryParse(context_, &loader, binary.data(), binary.size(), 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SetSpvHeader, SetSpvInst, &diagnostic); 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert spvDiagnosticDestroy(diagnostic); 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loader.EndModule(); 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (status == SPV_SUCCESS) return module; 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::unique_ptr<ir::Module> SpvTools::BuildModule(const std::string& text) { 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::vector<uint32_t> binary; 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (Assemble(text, &binary) != SPV_SUCCESS) return nullptr; 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return BuildModule(binary); 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace spvtools 114