Shader libraries cached in MVKPipelineCache instead of MVKShaderModule.
This commit is contained in:
parent
fd7521dc7b
commit
c45b47183e
@ -105,9 +105,11 @@ typedef struct {
|
||||
|
||||
/** MoltenVK performance of shader compilation events for a VkDevice. */
|
||||
typedef struct {
|
||||
MVKShaderCompilationEventPerformance hashShaderCode; /** Create a hash from the incoming shader code. */
|
||||
MVKShaderCompilationEventPerformance spirvToMSL; /** Convert SPIR-V to MSL source code. */
|
||||
MVKShaderCompilationEventPerformance mslCompile; /** Compile MSL source code into a MTLLibrary. */
|
||||
MVKShaderCompilationEventPerformance mslLoad; /** Load pre-compiled MSL code into a MTLLibrary. */
|
||||
MVKShaderCompilationEventPerformance shaderLibraryFromCache; /** Retrieve a shader library from the cache, lazily creating it if needed. */
|
||||
MVKShaderCompilationEventPerformance functionRetrieval; /** Retrieve a MTLFunction from a MTLLibrary. */
|
||||
MVKShaderCompilationEventPerformance functionSpecialization; /** Specialize a retrieved MTLFunction. */
|
||||
MVKShaderCompilationEventPerformance pipelineCompile; /** Compile MTLFunctions into a pipeline. */
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "MVKCmdQueries.h"
|
||||
#include "MVKMTLBufferAllocation.h"
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
|
||||
|
@ -221,7 +221,7 @@ public:
|
||||
return (MVKPhysicalDevice*)getDispatchableObject(vkPhysicalDevice);
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
friend class MVKDevice;
|
||||
|
||||
MTLFeatureSet getMaximalMTLFeatureSet();
|
||||
|
@ -1325,10 +1325,10 @@ void MVKDevice::addShaderCompilationEventPerformanceImpl(MVKShaderCompilationEve
|
||||
double currInterval = mvkGetElapsedMilliseconds(startTime, endTime);
|
||||
shaderCompilationEvent.minimumDuration = min(currInterval, shaderCompilationEvent.minimumDuration);
|
||||
shaderCompilationEvent.maximumDuration = max(currInterval, shaderCompilationEvent.maximumDuration);
|
||||
double totalInverval = (shaderCompilationEvent.averageDuration * shaderCompilationEvent.count++) + currInterval;
|
||||
shaderCompilationEvent.averageDuration = totalInverval / shaderCompilationEvent.count;
|
||||
double totalInterval = (shaderCompilationEvent.averageDuration * shaderCompilationEvent.count++) + currInterval;
|
||||
shaderCompilationEvent.averageDuration = totalInterval / shaderCompilationEvent.count;
|
||||
|
||||
MVKLogInfo("%s performance curr: %.3f ms, avg: %.3f ms, min: %.3f ms, max: %.3f ms, count: %d",
|
||||
MVKLogDebug("%s performance curr: %.3f ms, avg: %.3f ms, min: %.3f ms, max: %.3f ms, count: %d",
|
||||
getShaderCompilationEventName(shaderCompilationEvent),
|
||||
currInterval,
|
||||
shaderCompilationEvent.averageDuration,
|
||||
@ -1338,9 +1338,11 @@ void MVKDevice::addShaderCompilationEventPerformanceImpl(MVKShaderCompilationEve
|
||||
}
|
||||
|
||||
const char* MVKDevice::getShaderCompilationEventName(MVKShaderCompilationEventPerformance& shaderCompilationEvent) {
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.hashShaderCode) { return "Hash shader code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.spirvToMSL) { return "Convert SPIR-V to MSL source code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslCompile) { return "Compile MSL source code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslLoad) { return "Load pre-compiled MSL code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.shaderLibraryFromCache) { return "Retrieve shader library from the cache."; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionRetrieval) { return "Retrieve a MTLFunction from a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionSpecialization) { return "Specialize a retrieved MTLFunction"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.pipelineCompile) { return "Compile MTLFunctions into a pipeline"; }
|
||||
@ -1464,9 +1466,11 @@ void MVKDevice::initPerformanceTracking() {
|
||||
initPerf.minimumDuration = numeric_limits<double>::max();
|
||||
initPerf.maximumDuration = 0.0;
|
||||
|
||||
_shaderCompilationPerformance.hashShaderCode = initPerf;
|
||||
_shaderCompilationPerformance.spirvToMSL = initPerf;
|
||||
_shaderCompilationPerformance.mslCompile = initPerf;
|
||||
_shaderCompilationPerformance.mslLoad = initPerf;
|
||||
_shaderCompilationPerformance.shaderLibraryFromCache = initPerf;
|
||||
_shaderCompilationPerformance.functionRetrieval = initPerf;
|
||||
_shaderCompilationPerformance.functionSpecialization = initPerf;
|
||||
_shaderCompilationPerformance.pipelineCompile = initPerf;
|
||||
|
@ -71,7 +71,12 @@ public:
|
||||
virtual void encode(MVKCommandEncoder* cmdEncoder) = 0;
|
||||
|
||||
/** Constructs an instance for the device. layout, and parent (which may be NULL). */
|
||||
MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent) : MVKBaseDeviceObject(device) {}
|
||||
MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipeline* parent) : MVKBaseDeviceObject(device),
|
||||
_pipelineCache(pipelineCache) {}
|
||||
|
||||
protected:
|
||||
MVKPipelineCache* _pipelineCache;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -168,6 +173,9 @@ public:
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule);
|
||||
|
||||
/** Merges the contents of the specified number of pipeline caches into this cache. */
|
||||
inline VkResult mergePipelineCaches(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches) { return VK_SUCCESS; }
|
||||
|
||||
@ -176,4 +184,10 @@ public:
|
||||
/** Constructs an instance for the specified device. */
|
||||
MVKPipelineCache(MVKDevice* device, const VkPipelineCacheCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {}
|
||||
|
||||
~MVKPipelineCache() override;
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::size_t, MVKShaderLibraryCache*> _shaderCacheByModuleHash;
|
||||
std::mutex _shaderCacheLock;
|
||||
|
||||
};
|
||||
|
@ -271,13 +271,13 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
|
||||
// Vertex shader
|
||||
if (mvkAreFlagsEnabled(pSS->stage, VK_SHADER_STAGE_VERTEX_BIT)) {
|
||||
shaderContext.options.entryPointStage = spv::ExecutionModelVertex;
|
||||
plDesc.vertexFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo).mtlFunction;
|
||||
plDesc.vertexFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache).mtlFunction;
|
||||
}
|
||||
|
||||
// Fragment shader
|
||||
if (mvkAreFlagsEnabled(pSS->stage, VK_SHADER_STAGE_FRAGMENT_BIT)) {
|
||||
shaderContext.options.entryPointStage = spv::ExecutionModelFragment;
|
||||
plDesc.fragmentFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo).mtlFunction;
|
||||
plDesc.fragmentFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache).mtlFunction;
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,10 +437,36 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
|
||||
layout->populateShaderConverterContext(shaderContext);
|
||||
|
||||
MVKShaderModule* mvkShdrMod = (MVKShaderModule*)pSS->module;
|
||||
return mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo);
|
||||
return mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache);
|
||||
}
|
||||
|
||||
|
||||
MVKComputePipeline::~MVKComputePipeline() {
|
||||
[_mtlPipelineState release];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKPipelineCache
|
||||
|
||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
||||
MVKShaderLibrary* MVKPipelineCache::getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule) {
|
||||
lock_guard<mutex> lock(_shaderCacheLock);
|
||||
|
||||
size_t smKey = shaderModule->getKey();
|
||||
MVKShaderLibraryCache* slCache = _shaderCacheByModuleHash[smKey];
|
||||
if ( !slCache ) {
|
||||
slCache = new MVKShaderLibraryCache(_device);
|
||||
_shaderCacheByModuleHash[smKey] = slCache;
|
||||
}
|
||||
|
||||
return slCache->getShaderLibrary(pContext, shaderModule);
|
||||
}
|
||||
|
||||
|
||||
MVKPipelineCache::~MVKPipelineCache() {
|
||||
for (auto& pair : _shaderCacheByModuleHash) { delete pair.second; }
|
||||
_shaderCacheByModuleHash.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
class MVKPipelineCache;
|
||||
|
||||
using namespace mvk;
|
||||
|
||||
|
||||
@ -47,8 +49,8 @@ public:
|
||||
/** Returns the Metal shader function, possibly specialized. */
|
||||
MVKMTLFunction getMTLFunction(const VkSpecializationInfo* pSpecializationInfo);
|
||||
|
||||
/** Constructs an instance from the MSL source code in the specified SPIRVToMSLConverter. */
|
||||
MVKShaderLibrary(MVKDevice* device, SPIRVToMSLConverter& mslConverter);
|
||||
/** Constructs an instance from the specified MSL source code. */
|
||||
MVKShaderLibrary(MVKDevice* device, const char* mslSourceCode, const SPIRVEntryPoint& entryPoint);
|
||||
|
||||
/** Constructs an instance from the specified compiled MSL code data. */
|
||||
MVKShaderLibrary(MVKDevice* device,
|
||||
@ -66,6 +68,33 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKShaderLibraryCache
|
||||
|
||||
/** Represents a cache of shader libraries for one shader module. */
|
||||
class MVKShaderLibraryCache : public MVKBaseDeviceObject {
|
||||
|
||||
public:
|
||||
|
||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule);
|
||||
|
||||
MVKShaderLibraryCache(MVKDevice* device) : MVKBaseDeviceObject(device) {};
|
||||
|
||||
~MVKShaderLibraryCache() override;
|
||||
|
||||
protected:
|
||||
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConverterContext* pContext);
|
||||
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
const char* mslSourceCode,
|
||||
const SPIRVEntryPoint& entryPoint);
|
||||
|
||||
std::mutex _accessLock;
|
||||
std::size_t _shaderModuleHash;
|
||||
std::vector<std::pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>> _shaderLibraries;
|
||||
};
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKShaderModule
|
||||
|
||||
@ -75,19 +104,32 @@ class MVKShaderModule : public MVKBaseDeviceObject {
|
||||
public:
|
||||
/** Returns the Metal shader function, possibly specialized. */
|
||||
MVKMTLFunction getMTLFunction(SPIRVToMSLConverterContext* pContext,
|
||||
const VkSpecializationInfo* pSpecializationInfo);
|
||||
const VkSpecializationInfo* pSpecializationInfo,
|
||||
MVKPipelineCache* pipelineCache);
|
||||
|
||||
/** Convert the SPIR-V to MSL, using the specified shader conversion context. */
|
||||
bool convert(SPIRVToMSLConverterContext* pContext);
|
||||
|
||||
/**
|
||||
* Returns the Metal Shading Language source code most recently converted
|
||||
* by the convert() function, or set directly using the setMSL() function.
|
||||
*/
|
||||
inline const std::string& getMSL() { return _converter.getMSL(); }
|
||||
|
||||
/** Returns information about the shader entry point. */
|
||||
inline const SPIRVEntryPoint& getEntryPoint() { return _converter.getEntryPoint(); }
|
||||
|
||||
/** Returns a key as a means of identifying this shader module in a pipeline cache. */
|
||||
inline std::size_t getKey() { return _key; }
|
||||
|
||||
MVKShaderModule(MVKDevice* device, const VkShaderModuleCreateInfo* pCreateInfo);
|
||||
|
||||
~MVKShaderModule() override;
|
||||
|
||||
protected:
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext);
|
||||
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConverterContext* pContext);
|
||||
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConverterContext* pContext);
|
||||
|
||||
MVKShaderLibraryCache _shaderLibraryCache;
|
||||
SPIRVToMSLConverter _converter;
|
||||
MVKShaderLibrary* _defaultLibrary;
|
||||
std::vector<std::pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>> _shaderLibraries;
|
||||
std::size_t _key;
|
||||
std::mutex _accessLock;
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "MVKShaderModule.h"
|
||||
#include "MVKPipeline.h"
|
||||
#include "MVKFoundation.h"
|
||||
#include "vk_mvk_moltenvk.h"
|
||||
#include <string>
|
||||
@ -119,19 +120,19 @@ MTLFunctionConstant* MVKShaderLibrary::getFunctionConstant(NSArray<MTLFunctionCo
|
||||
return nil;
|
||||
}
|
||||
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device, SPIRVToMSLConverter& mslConverter) : MVKBaseDeviceObject(device) {
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device, const char* mslSourceCode, const SPIRVEntryPoint& entryPoint) : MVKBaseDeviceObject(device) {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
@autoreleasepool {
|
||||
MTLCompileOptions* options = [[MTLCompileOptions new] autorelease]; // TODO: what compile options apply?
|
||||
NSError* err = nil;
|
||||
_mtlLibrary = [getMTLDevice() newLibraryWithSource: @(mslConverter.getMSL().data())
|
||||
_mtlLibrary = [getMTLDevice() newLibraryWithSource: @(mslSourceCode)
|
||||
options: options
|
||||
error: &err]; // retained
|
||||
handleCompilationError(err, "Shader module compilation");
|
||||
}
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.mslCompile, startTime);
|
||||
|
||||
_entryPoint = mslConverter.getEntryPoint();
|
||||
_entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device,
|
||||
@ -174,27 +175,22 @@ MVKShaderLibrary::~MVKShaderLibrary() {
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKShaderModule
|
||||
|
||||
MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConverterContext* pContext,
|
||||
const VkSpecializationInfo* pSpecializationInfo) {
|
||||
lock_guard<mutex> lock(_accessLock);
|
||||
MVKShaderLibrary* mvkLib = getShaderLibrary(pContext);
|
||||
return mvkLib ? mvkLib->getMTLFunction(pSpecializationInfo) : MVKMTLFunctionNull;
|
||||
}
|
||||
|
||||
MVKShaderLibrary* MVKShaderModule::getShaderLibrary(SPIRVToMSLConverterContext* pContext) {
|
||||
if (_defaultLibrary) { return _defaultLibrary; }
|
||||
#pragma mark MVKShaderLibraryCache
|
||||
|
||||
MVKShaderLibrary* MVKShaderLibraryCache::getShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
MVKShaderModule* shaderModule) {
|
||||
MVKShaderLibrary* shLib = findShaderLibrary(pContext);
|
||||
if ( !shLib ) { shLib = addShaderLibrary(pContext); }
|
||||
// else { MVKLogDebug("Shader Module %p reusing library.", this); }
|
||||
if ( !shLib ) {
|
||||
if (shaderModule->convert(pContext)) {
|
||||
shLib = addShaderLibrary(pContext, shaderModule->getMSL().c_str(), shaderModule->getEntryPoint());
|
||||
}
|
||||
}
|
||||
return shLib;
|
||||
}
|
||||
|
||||
// Finds and returns a shader library matching the specified context, or returns nullptr if it doesn't exist.
|
||||
// If a match is found, the usage of the specified context is aligned with the context of the matching library.
|
||||
MVKShaderLibrary* MVKShaderModule::findShaderLibrary(SPIRVToMSLConverterContext* pContext) {
|
||||
MVKShaderLibrary* MVKShaderLibraryCache::findShaderLibrary(SPIRVToMSLConverterContext* pContext) {
|
||||
for (auto& slPair : _shaderLibraries) {
|
||||
if (slPair.first.matches(*pContext)) {
|
||||
pContext->alignUsageWith(slPair.first);
|
||||
@ -205,9 +201,42 @@ MVKShaderLibrary* MVKShaderModule::findShaderLibrary(SPIRVToMSLConverterContext*
|
||||
}
|
||||
|
||||
/** Adds and returns a new shader library configured from the specified context. */
|
||||
MVKShaderLibrary* MVKShaderModule::addShaderLibrary(SPIRVToMSLConverterContext* pContext) {
|
||||
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
const char* mslSourceCode,
|
||||
const SPIRVEntryPoint& entryPoint) {
|
||||
MVKShaderLibrary* shLib = new MVKShaderLibrary(_device, mslSourceCode, entryPoint);
|
||||
_shaderLibraries.push_back(pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>(*pContext, shLib));
|
||||
return shLib;
|
||||
}
|
||||
|
||||
MVKShaderLibrary* shLib = nullptr;
|
||||
MVKShaderLibraryCache::~MVKShaderLibraryCache() {
|
||||
for (auto& slPair : _shaderLibraries) { delete slPair.second; }
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKShaderModule
|
||||
|
||||
MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConverterContext* pContext,
|
||||
const VkSpecializationInfo* pSpecializationInfo,
|
||||
MVKPipelineCache* pipelineCache) {
|
||||
lock_guard<mutex> lock(_accessLock);
|
||||
MVKShaderLibrary* mvkLib = _defaultLibrary;
|
||||
if ( !mvkLib ) {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
if (pipelineCache) {
|
||||
MVKLogDebug("Retrieving shader from pipeline cache.");
|
||||
mvkLib = pipelineCache->getShaderLibrary(pContext, this);
|
||||
} else {
|
||||
MVKLogDebug("Retrieving shader from shader module.");
|
||||
mvkLib = _shaderLibraryCache.getShaderLibrary(pContext, this);
|
||||
}
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.shaderLibraryFromCache, startTime);
|
||||
}
|
||||
return mvkLib ? mvkLib->getMTLFunction(pSpecializationInfo) : MVKMTLFunctionNull;
|
||||
}
|
||||
|
||||
bool MVKShaderModule::convert(SPIRVToMSLConverterContext* pContext) {
|
||||
bool shouldLogCode = _device->_mvkConfig.debugMode;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
@ -216,55 +245,80 @@ MVKShaderLibrary* MVKShaderModule::addShaderLibrary(SPIRVToMSLConverterContext*
|
||||
|
||||
if (wasConverted) {
|
||||
if (shouldLogCode) { MVKLogInfo("%s", _converter.getResultLog().data()); }
|
||||
shLib = new MVKShaderLibrary(_device, _converter);
|
||||
_shaderLibraries.push_back(pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>(*pContext, shLib));
|
||||
// MVKLogDebug("Shader Module %p compiled %d libraries.", this, _shaderLibraries.size());
|
||||
} else {
|
||||
mvkNotifyErrorWithText(VK_ERROR_FORMAT_NOT_SUPPORTED, "Unable to convert SPIR-V to MSL:\n%s", _converter.getResultLog().data());
|
||||
}
|
||||
return shLib;
|
||||
return wasConverted;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
const VkShaderModuleCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
|
||||
const VkShaderModuleCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device),
|
||||
_shaderLibraryCache(device) {
|
||||
_defaultLibrary = nullptr;
|
||||
|
||||
size_t codeSize = pCreateInfo->codeSize;
|
||||
|
||||
// Ensure something is there.
|
||||
if ( (pCreateInfo->pCode != VK_NULL_HANDLE) && (pCreateInfo->codeSize >= 4) ) {
|
||||
if ( (pCreateInfo->pCode == VK_NULL_HANDLE) || (codeSize < 4) ) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_INCOMPLETE, "Shader module contains no SPIR-V code."));
|
||||
return;
|
||||
}
|
||||
|
||||
_key = mvkHash(&pCreateInfo->codeSize, 1);
|
||||
|
||||
// Retrieve the magic number to determine what type of shader code has been loaded.
|
||||
uint32_t magicNum = *pCreateInfo->pCode;
|
||||
switch (magicNum) {
|
||||
case kMVKMagicNumberSPIRVCode: { // SPIR-V code
|
||||
size_t spvCount = (pCreateInfo->codeSize + 3) >> 2; // Round up if byte length not exactly on uint32_t boundary
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(pCreateInfo->pCode, spvCount, _key);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_converter.setSPIRV(pCreateInfo->pCode, spvCount);
|
||||
|
||||
break;
|
||||
}
|
||||
case kMVKMagicNumberMSLSourceCode: { // MSL source code
|
||||
uintptr_t pMSLCode = uintptr_t(pCreateInfo->pCode) + sizeof(MVKMSLSPIRVHeader);
|
||||
_converter.setMSL((char*)pMSLCode, nullptr);
|
||||
_defaultLibrary = new MVKShaderLibrary(_device, _converter);
|
||||
size_t hdrSize = sizeof(MVKMSLSPIRVHeader);
|
||||
char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize);
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(&magicNum, 1, _key);
|
||||
_key = mvkHash(pMSLCode, mslCodeLen, _key);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_converter.setMSL(pMSLCode, nullptr);
|
||||
_defaultLibrary = new MVKShaderLibrary(_device, _converter.getMSL().c_str(), _converter.getEntryPoint());
|
||||
|
||||
break;
|
||||
}
|
||||
case kMVKMagicNumberMSLCompiledCode: { // MSL compiled binary code
|
||||
uintptr_t pMSLCode = uintptr_t(pCreateInfo->pCode) + sizeof(MVKMSLSPIRVHeader);
|
||||
_defaultLibrary = new MVKShaderLibrary(_device, (void*)(pMSLCode), (pCreateInfo->codeSize - sizeof(MVKMSLSPIRVHeader)));
|
||||
size_t hdrSize = sizeof(MVKMSLSPIRVHeader);
|
||||
char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize);
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(&magicNum, 1, _key);
|
||||
_key = mvkHash(pMSLCode, mslCodeLen, _key);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_defaultLibrary = new MVKShaderLibrary(_device, (void*)(pMSLCode), mslCodeLen);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FORMAT_NOT_SUPPORTED, "SPIR-V contains invalid magic number %x.", magicNum));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_INCOMPLETE, "Shader module contains no SPIR-V code."));
|
||||
}
|
||||
}
|
||||
|
||||
MVKShaderModule::~MVKShaderModule() {
|
||||
if (_defaultLibrary) { delete _defaultLibrary; }
|
||||
for (auto& slPair : _shaderLibraries) { delete slPair.second; }
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,8 @@
|
||||
#include "MVKFoundation.h"
|
||||
|
||||
#include <vector>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#if MVK_MACOS
|
||||
#import <CoreFoundation/CFData.h>
|
||||
|
@ -207,9 +207,6 @@ namespace mvk {
|
||||
/** Returns information about the shader entry point. */
|
||||
const SPIRVEntryPoint& getEntryPoint() { return _entryPoint; }
|
||||
|
||||
/** Returns a mapping of entry point info, indexed by SPIR-V entry point name. */
|
||||
// const SPIRVEntryPointsByName& getEntryPoints() { return _entryPoints; }
|
||||
|
||||
/**
|
||||
* Returns whether the most recent conversion was successful.
|
||||
*
|
||||
@ -228,10 +225,6 @@ namespace mvk {
|
||||
_msl = msl;
|
||||
if (pEntryPoint) { _entryPoint = *pEntryPoint; }
|
||||
}
|
||||
// void setMSL(const std::string& msl, const SPIRVEntryPointsByName& entryPoints) {
|
||||
// _msl = msl;
|
||||
// _entryPoints = entryPoints;
|
||||
// }
|
||||
|
||||
protected:
|
||||
void logMsg(const char* logMsg);
|
||||
@ -245,7 +238,6 @@ namespace mvk {
|
||||
std::string _msl;
|
||||
std::string _resultLog;
|
||||
SPIRVEntryPoint _entryPoint;
|
||||
// SPIRVEntryPointsByName _entryPoints;
|
||||
bool _wasConverted = false;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user