Bill Hollings fbf2af58a0 Fixes and consolidation of external library header references.
All external library header references consistently include framework references.
Cleanup references to external library headers that are no longer required.
Simplify and consolidate external library header paths in Xcode projects.
Add MVK_EXCLUDE_SPIRV_TOOLS build option to avoid use of SPIRV-Tools library.
Remove all other references to headers within SPIRV-Tools library.
2019-05-28 17:19:43 -04:00

90 lines
2.8 KiB
C++

/*
* SPIRVSupport.cpp
*
* Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SPIRVSupport.h"
#include <SPIRV-Cross/spirv.hpp>
#import <CoreFoundation/CFByteOrder.h>
using namespace mvk;
using namespace std;
void mvk::spirvToBytes(const vector<uint32_t>& spv, vector<char>& bytes) {
// Assumes desired endianness.
size_t byteCnt = spv.size() * sizeof(uint32_t);
char* cBytes = (char*)spv.data();
bytes.clear();
bytes.insert(bytes.end(), cBytes, cBytes + byteCnt);
}
void mvk::bytesToSPIRV(const vector<char>& bytes, vector<uint32_t>& spv) {
size_t spvCnt = bytes.size() / sizeof(uint32_t);
uint32_t* cSPV = (uint32_t*)bytes.data();
spv.clear();
spv.insert(spv.end(), cSPV, cSPV + spvCnt);
ensureSPIRVEndianness(spv);
}
bool mvk::ensureSPIRVEndianness(vector<uint32_t>& spv) {
if (spv.empty()) { return false; } // Nothing to convert
uint32_t magNum = spv.front();
if (magNum == spv::MagicNumber) { return false; } // No need to convert
if (CFSwapInt32(magNum) == spv::MagicNumber) { // Yep, it's SPIR-V, but wrong endianness
for (auto& elem : spv) { elem = CFSwapInt32(elem); }
return true;
}
return false; // Not SPIR-V, so don't convert
}
// Optionally exclude including SPIRV-Tools components.
#ifdef MVK_EXCLUDE_SPIRV_TOOLS
void mvk::logSPIRV(vector<uint32_t>& /*spirv*/, string& spvLog) {
spvLog.append("\n");
spvLog.append("Decompiled SPIR-V is unavailable. To log decompiled SPIR-V code,\n");
spvLog.append("build MoltenVK without the MVK_EXCLUDE_SPIRV_TOOLS build setting.");
spvLog.append("\n");
}
#else
#include <spirv-tools/libspirv.h>
void mvk::logSPIRV(vector<uint32_t>& spirv, string& spvLog) {
if ( !((spirv.size() > 4) &&
(spirv[0] == spv::MagicNumber) &&
(spirv[4] == 0)) ) { return; }
uint32_t options = (SPV_BINARY_TO_TEXT_OPTION_INDENT);
spv_text text;
spv_diagnostic diagnostic = nullptr;
spv_context context = spvContextCreate(SPV_ENV_VULKAN_1_0);
spv_result_t error = spvBinaryToText(context, spirv.data(), spirv.size(), options, &text, &diagnostic);
spvContextDestroy(context);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
return;
}
spvLog.append(text->str, text->length);
spvTextDestroy(text);
}
#endif