Skip to content

Commit

Permalink
Merge pull request #108 from billhollings/master
Browse files Browse the repository at this point in the history
SPIRV entry points, streamline integration with V-LVL & v1.0.1.
  • Loading branch information
billhollings authored Mar 19, 2018
2 parents 2a6a186 + 8fbbaba commit 18fa813
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 165 deletions.
17 changes: 9 additions & 8 deletions External/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ if you encounter any linking errors, may need to re-add the *SPIRV-Cross* librar
2. In the *Finder*, right-click your `MoltenVKShaderConverter.xcodeproj` file and select
**_Show Package Contents_**.
3. Open the `project.pbxproj` file in a text editor.
4. Replace all occurrences of the `path-to-SPIRV-Cross-repo-folder` with simply
`SPIRV-Cross`.
4. Remove all occurrences of `path-to-SPIRV-Cross-repo-folder` from the paths to the files added above.


### Regression Testing Your Changes to *SPIRV-Cross*
Expand Down Expand Up @@ -174,10 +173,10 @@ if you encounter any linking errors, may need to re-add the *SPIRV-Tools* librar
*Build Settings* tab. Locate the build setting entry **Header Search Paths**
(`HEADER_SEARCH_PATHS`) and add the following paths:

"$(SRCROOT)/MoltenVKSPIRVToMSLConverter/SPIRV-Tools/include"
"$(SRCROOT)/MoltenVKSPIRVToMSLConverter/SPIRV-Tools/source"
"$(SRCROOT)/MoltenVKSPIRVToMSLConverter/SPIRV-Tools/build"
"$(SRCROOT)/MoltenVKSPIRVToMSLConverter/SPIRV-Headers/include"
"$(SRCROOT)/../External/glslang/External/spirv-tools/include"
"$(SRCROOT)/../External/glslang/External/spirv-tools/source"
"$(SRCROOT)/../External/glslang/External/spirv-tools/external/spirv-headers/include"
"$(SRCROOT)/../External/glslang/build/External/spirv-tools"

5. ***(Optional)*** To simplify the paths used within *Xcode* to reference the added files,
perform the following steps:
Expand All @@ -186,7 +185,8 @@ if you encounter any linking errors, may need to re-add the *SPIRV-Tools* librar
2. In the *Finder*, right-click your `MoltenVKShaderConverter.xcodeproj` file and select
**_Show Package Contents_**.
3. Open the `project.pbxproj` file in a text editor.
4. Replace all occurrences of the `path-to-SPIRV-Tools-repo-folder/source` with simply `source`.
4. Remove all occurrences of `path-to-SPIRV-Tools-repo-folder` from the paths to the
`source` directory added above.



Expand Down Expand Up @@ -225,6 +225,7 @@ if you encounter any linking errors, may need to re-add the *glslang* library to
2. In the *Finder*, right-click your `MoltenVKShaderConverter.xcodeproj` file and select
**_Show Package Contents_**.
3. Open the `project.pbxproj` file in a text editor.
4. Replace all occurrences of the `path-to-glslang-repo-folder` with simply `glslang `.
4. Remove all occurrences of `path-to-glslang-repo-folder` from the paths to the
`glslang`, `OGLCompilersDLL`, and `SPIRV` directories added above.


2 changes: 1 addition & 1 deletion External/SPIRV-Cross_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0f9cb0da0d5ab91b21a42ffc0062840fc76e81e3
5161d5ed3b5a788c2469bb548fbb6001f98c03fa
2 changes: 1 addition & 1 deletion External/Vulkan-LoaderAndValidationLayers_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6d3938172cba2d9235f258efa1db1c16443c66c6
78ae9ec027bfad5d2ace2fce7d82c4e364c6b22c
17 changes: 0 additions & 17 deletions External/fetchDependencies
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ echo

V_LVL_NAME=Vulkan-LoaderAndValidationLayers
GLSLANG_NAME=glslang
SPIRV_TOOLS_NAME=SPIRV-Tools

# ----------------- SPIRV-Cross -------------------

Expand All @@ -67,20 +66,6 @@ REPO_REV=$(cat "./${REPO_NAME}_repo_revision")
clone_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}


# ----------------- SPIRV-Tools -------------------

REPO_NAME=${SPIRV_TOOLS_NAME}
rm -rf ${REPO_NAME}
ln -sfn ${GLSLANG_NAME}/External/spirv-tools ${REPO_NAME}


# ----------------- SPIRV-Headers -------------------

REPO_NAME=SPIRV-Headers
rm -rf ${REPO_NAME}
ln -sfn ${SPIRV_TOOLS_NAME}/external/spirv-headers ${REPO_NAME}


# ----------------- Vulkan-LoaderAndValidationLayers, glslang, SPIRV-Tools & SPIRV-Headers -------------------

# When MoltenVK is loaded as a dependency of the LunarG SDK, the LunarG SDK already
Expand Down Expand Up @@ -120,7 +105,5 @@ else

build_repo ${GLSLANG_NAME}

build_repo ${SPIRV_TOOLS_NAME}

fi

2 changes: 1 addition & 1 deletion MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extern "C" {
*/
#define MVK_VERSION_MAJOR 1
#define MVK_VERSION_MINOR 0
#define MVK_VERSION_PATCH 0
#define MVK_VERSION_PATCH 1

#define MVK_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch))
#define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
Expand Down
11 changes: 8 additions & 3 deletions MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,20 @@
// Add shader stages
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
const VkPipelineShaderStageCreateInfo* pSS = &pCreateInfo->pStages[i];
shaderContext.options.entryPointName = pSS->pName;

MVKShaderModule* mvkShdrMod = (MVKShaderModule*)pSS->module;

// Vertex shader
if (mvkAreFlagsEnabled(pSS->stage, VK_SHADER_STAGE_VERTEX_BIT)) {
plDesc.vertexFunction = mvkShdrMod->getMTLFunction(pSS, &shaderContext).mtlFunction;
shaderContext.options.entryPointStage = spv::ExecutionModelVertex;
plDesc.vertexFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo).mtlFunction;
}

// Fragment shader
if (mvkAreFlagsEnabled(pSS->stage, VK_SHADER_STAGE_FRAGMENT_BIT)) {
plDesc.fragmentFunction = mvkShdrMod->getMTLFunction(pSS, &shaderContext).mtlFunction;
shaderContext.options.entryPointStage = spv::ExecutionModelFragment;
plDesc.fragmentFunction = mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo).mtlFunction;
}
}

Expand Down Expand Up @@ -426,13 +429,15 @@
if ( !mvkAreFlagsEnabled(pSS->stage, VK_SHADER_STAGE_COMPUTE_BIT) ) { return MVKMTLFunctionNull; }

SPIRVToMSLConverterContext shaderContext;
shaderContext.options.entryPointName = pCreateInfo->stage.pName;
shaderContext.options.entryPointStage = spv::ExecutionModelGLCompute;
shaderContext.options.mslVersion = _device->_pMetalFeatures->mslVersion;

MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
layout->populateShaderConverterContext(shaderContext);

MVKShaderModule* mvkShdrMod = (MVKShaderModule*)pSS->module;
return mvkShdrMod->getMTLFunction(pSS, &shaderContext);
return mvkShdrMod->getMTLFunction(&shaderContext, pSS->pSpecializationInfo);
}


Expand Down
12 changes: 6 additions & 6 deletions MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ extern const MVKMTLFunction MVKMTLFunctionNull;
class MVKShaderLibrary : public MVKBaseDeviceObject {

public:
/** Returns the Metal shader function used by the specified shader state. */
MVKMTLFunction getMTLFunction(const VkPipelineShaderStageCreateInfo* pShaderStage);
/** 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);
Expand All @@ -62,7 +62,7 @@ class MVKShaderLibrary : public MVKBaseDeviceObject {
MTLFunctionConstant* getFunctionConstant(NSArray<MTLFunctionConstant*>* mtlFCs, NSUInteger mtlFCID);

id<MTLLibrary> _mtlLibrary;
SPIRVEntryPointsByName _entryPoints;
SPIRVEntryPoint _entryPoint;
};


Expand All @@ -73,9 +73,9 @@ class MVKShaderLibrary : public MVKBaseDeviceObject {
class MVKShaderModule : public MVKBaseDeviceObject {

public:
/** Returns the Metal shader function used by the specified shader state, or nil if it doesn't exist. */
MVKMTLFunction getMTLFunction(const VkPipelineShaderStageCreateInfo* pShaderStage,
SPIRVToMSLConverterContext* pContext);
/** Returns the Metal shader function, possibly specialized. */
MVKMTLFunction getMTLFunction(SPIRVToMSLConverterContext* pContext,
const VkSpecializationInfo* pSpecializationInfo);

MVKShaderModule(MVKDevice* device, const VkShaderModuleCreateInfo* pCreateInfo);

Expand Down
52 changes: 24 additions & 28 deletions MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
return -1;
}

MVKMTLFunction MVKShaderLibrary::getMTLFunction(const VkPipelineShaderStageCreateInfo* pShaderStage) {
MVKMTLFunction MVKShaderLibrary::getMTLFunction(const VkSpecializationInfo* pSpecializationInfo) {

if ( !_mtlLibrary ) { return MVKMTLFunctionNull; }

// Ensure the function name is compatible with Metal (Metal does not allow main()
// as a function name), and retrieve the unspecialized Metal function with that name.
SPIRVEntryPoint& ep = _entryPoints[pShaderStage->pName];
NSString* mtlFuncName = @(ep.mtlFunctionName.c_str());
NSString* mtlFuncName = @(_entryPoint.mtlFunctionName.c_str());

uint64_t startTime = _device->getPerformanceTimestamp();
id<MTLFunction> mtlFunc = [[_mtlLibrary newFunctionWithName: mtlFuncName] autorelease];
Expand All @@ -64,16 +63,15 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
// The Metal shader contains function constants and expects to be specialized
// Populate the Metal function constant values from the Vulkan specialization info.
MTLFunctionConstantValues* mtlFCVals = [[MTLFunctionConstantValues new] autorelease];
const VkSpecializationInfo* pSpecInfo = pShaderStage->pSpecializationInfo;
if (pSpecInfo) {
if (pSpecializationInfo) {
// Iterate through the provided Vulkan specialization entries, and populate the
// Metal function constant value that matches the Vulkan specialization constantID.
for (uint32_t specIdx = 0; specIdx < pSpecInfo->mapEntryCount; specIdx++) {
const VkSpecializationMapEntry* pMapEntry = &pSpecInfo->pMapEntries[specIdx];
for (uint32_t specIdx = 0; specIdx < pSpecializationInfo->mapEntryCount; specIdx++) {
const VkSpecializationMapEntry* pMapEntry = &pSpecializationInfo->pMapEntries[specIdx];
NSUInteger mtlFCIndex = pMapEntry->constantID;
MTLFunctionConstant* mtlFC = getFunctionConstant(mtlFCs, mtlFCIndex);
if (mtlFC) {
[mtlFCVals setConstantValue: &(((char*)pSpecInfo->pData)[pMapEntry->offset])
[mtlFCVals setConstantValue: &(((char*)pSpecializationInfo->pData)[pMapEntry->offset])
type: mtlFC.type
atIndex: mtlFCIndex];
}
Expand All @@ -90,29 +88,28 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
} else {
mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Shader module does not contain an entry point named '%s'.", mtlFuncName.UTF8String);
}

const VkSpecializationInfo* pSpecInfo = pShaderStage->pSpecializationInfo;
if (pSpecInfo) {

if (pSpecializationInfo) {
// Get the specialization constant values for the work group size
if (ep.workgroupSizeId.constant != 0) {
uint32_t widthOffset = getOffsetForConstantId(pSpecInfo, ep.workgroupSizeId.width);
if (_entryPoint.workgroupSizeId.constant != 0) {
uint32_t widthOffset = getOffsetForConstantId(pSpecializationInfo, _entryPoint.workgroupSizeId.width);
if (widthOffset != -1) {
ep.workgroupSize.width = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecInfo->pData + widthOffset);
_entryPoint.workgroupSize.width = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecializationInfo->pData + widthOffset);
}
uint32_t heightOffset = getOffsetForConstantId(pSpecInfo, ep.workgroupSizeId.height);

uint32_t heightOffset = getOffsetForConstantId(pSpecializationInfo, _entryPoint.workgroupSizeId.height);
if (heightOffset != -1) {
ep.workgroupSize.height = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecInfo->pData + heightOffset);
_entryPoint.workgroupSize.height = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecializationInfo->pData + heightOffset);
}
uint32_t depthOffset = getOffsetForConstantId(pSpecInfo, ep.workgroupSizeId.depth);

uint32_t depthOffset = getOffsetForConstantId(pSpecializationInfo, _entryPoint.workgroupSizeId.depth);
if (depthOffset != -1) {
ep.workgroupSize.depth = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecInfo->pData + depthOffset);
_entryPoint.workgroupSize.depth = *reinterpret_cast<uint32_t*>((uint8_t*)pSpecializationInfo->pData + depthOffset);
}
}
}

return { mtlFunc, MTLSizeMake(ep.workgroupSize.width, ep.workgroupSize.height, ep.workgroupSize.depth) };
return { mtlFunc, MTLSizeMake(_entryPoint.workgroupSize.width, _entryPoint.workgroupSize.height, _entryPoint.workgroupSize.depth) };
}

// Returns the MTLFunctionConstant with the specified ID from the specified array of function constants.
Expand All @@ -134,7 +131,7 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
}
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.mslCompile, startTime);

_entryPoints = mslConverter.getEntryPoints();
_entryPoint = mslConverter.getEntryPoint();
}

MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device,
Expand Down Expand Up @@ -179,11 +176,11 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
#pragma mark -
#pragma mark MVKShaderModule

MVKMTLFunction MVKShaderModule::getMTLFunction(const VkPipelineShaderStageCreateInfo* pShaderStage,
SPIRVToMSLConverterContext* pContext) {
MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConverterContext* pContext,
const VkSpecializationInfo* pSpecializationInfo) {
lock_guard<mutex> lock(_accessLock);
MVKShaderLibrary* mvkLib = getShaderLibrary(pContext);
return mvkLib ? mvkLib->getMTLFunction(pShaderStage) : MVKMTLFunctionNull;
return mvkLib ? mvkLib->getMTLFunction(pSpecializationInfo) : MVKMTLFunctionNull;
}

MVKShaderLibrary* MVKShaderModule::getShaderLibrary(SPIRVToMSLConverterContext* pContext) {
Expand All @@ -200,7 +197,7 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
MVKShaderLibrary* MVKShaderModule::findShaderLibrary(SPIRVToMSLConverterContext* pContext) {
for (auto& slPair : _shaderLibraries) {
if (slPair.first.matches(*pContext)) {
(*pContext).alignUsageWith(slPair.first);
pContext->alignUsageWith(slPair.first);
return slPair.second;
}
}
Expand Down Expand Up @@ -248,8 +245,7 @@ static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, ui
}
case kMVKMagicNumberMSLSourceCode: { // MSL source code
uintptr_t pMSLCode = uintptr_t(pCreateInfo->pCode) + sizeof(MVKMSLSPIRVHeader);
SPIRVEntryPointsByName entryPoints;
_converter.setMSL((char*)pMSLCode, entryPoints);
_converter.setMSL((char*)pMSLCode, nullptr);
_defaultLibrary = new MVKShaderLibrary(_device, _converter);
break;
}
Expand Down
26 changes: 15 additions & 11 deletions MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,22 @@
_performanceStatistics.averageFrameInterval += _averageFrameIntervalFilterAlpha * (_performanceStatistics.lastFrameInterval - _performanceStatistics.averageFrameInterval);
_performanceStatistics.averageFramesPerSecond = 1000.0 / _performanceStatistics.averageFrameInterval;

// Uncomment for per-frame logging.
// MVKLogDebug("Frame interval: %.2f ms. Avg frame interval: %.2f ms. Frame number: %d.",
// _performanceStatistics.lastFrameInterval,
// _performanceStatistics.averageFrameInterval,
// _currentPerfLogFrameCount + 1);

uint32_t perfLogCntLimit = _device->_mvkConfig.performanceLoggingFrameCount;
if (perfLogCntLimit > 0) {
_currentPerfLogFrameCount++;
if (_currentPerfLogFrameCount >= perfLogCntLimit) {
MVKLogInfo("Frame interval: %.2f ms. Avg frame interval: %.2f ms. FPS: %.2f. Elapsed time: %.3f seconds.",
_performanceStatistics.lastFrameInterval,
_performanceStatistics.averageFrameInterval,
_performanceStatistics.averageFramesPerSecond,
mvkGetElapsedMilliseconds() / 1000.0);
_currentPerfLogFrameCount = 0;
}
}
if ((perfLogCntLimit > 0) && (++_currentPerfLogFrameCount >= perfLogCntLimit)) {
_currentPerfLogFrameCount = 0;
MVKLogInfo("Frame interval: %.2f ms. Avg frame interval: %.2f ms. Avg FPS: %.2f. Reporting every: %d frames. Elapsed time: %.3f seconds.",
_performanceStatistics.lastFrameInterval,
_performanceStatistics.averageFrameInterval,
_performanceStatistics.averageFramesPerSecond,
perfLogCntLimit,
mvkGetElapsedMilliseconds() / 1000.0);
}
}

void MVKSwapchain::getPerformanceStatistics(MVKSwapchainPerformance* pSwapchainPerf) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "SPIRVToMSLConverter.h"
#include "MVKStrings.h"
#include "GlslangToSpv.h"
#include "glslang/SPIRV/disassemble.h"
#include "../../External/glslang/SPIRV/disassemble.h"
#include "doc.h"
#include <sstream>

Expand All @@ -43,8 +43,8 @@ MVK_PUBLIC_SYMBOL void GLSLToSPIRVConverter::setGLSL(const string& glslSrc) { _g
MVK_PUBLIC_SYMBOL const string& GLSLToSPIRVConverter::getGLSL() { return _glsl; }

MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKShaderStage shaderStage,
bool shouldLogGLSL,
bool shouldLogSPIRV) {
bool shouldLogGLSL,
bool shouldLogSPIRV) {
_wasConverted = true;
_resultLog.clear();
_spirv.clear();
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 18fa813

Please sign in to comment.