This commit is contained in:
Bill Hollings 2018-09-10 16:15:15 -04:00
commit c7219636ac
46 changed files with 2205 additions and 326 deletions

View File

@ -1,8 +1,8 @@
language: objective-c
# macOS and Xcode Version
# Xcode 9.2 running on macOS 10.12
osx_image: xcode9.2
# Xcode 9.4 running on macOS 10.13
osx_image: xcode9.4
# Build dependencies
install:
@ -15,6 +15,6 @@ cache:
- External
script:
- xcodebuild -scheme "MoltenVK (Debug)"
- xcodebuild -workspace Demos/Demos.xcworkspace -scheme "API-Samples-macOS"
- xcodebuild -scheme "MoltenVK Package (Release)"
- xcodebuild -workspace Demos/Demos.xcworkspace -scheme "Cube-macOS"

View File

@ -12,6 +12,41 @@ Copyright (c) 2014-2018 [The Brenwill Workshop Ltd.](http://www.brenwill.com)
For best results, use a Markdown reader.*
MoltenVK 1.0.21
---------------
Released 2018/09/08
- Add support for extensions:
- VK_KHR_descriptor_update_template
- Create 3D MTLTextureViews for 2D image views of 3D textures.
- Allow building and packaging MoltenVK for of only iOS or only macOS.
- Move packaging scripts out of Xcode projects and into script files.
- vkUpdateDescriptorSet: Handle copies of uninitialized descriptors.
- vkCmdFillBuffer & vkCmdCopyBuffers: Use dispatch call that supports older OS versions.
- Update to latest SPIRV-Cross version:
- MSL: Emit F{Min,Max,Clamp} as fast:: and N{Min,Max,Clamp} as precise
- MSL: Implement multisampled array textures.
- MSL: Emit spvTexelBufferCoord() on ImageWrite to a Buffer.
- MSL: Handle interpolation qualifiers.
- MSL: Account for components when assigning locations to varyings.
- MSL: Do not emit function constants for version < 1.2.
MoltenVK 1.0.20
---------------
Released 2018/09/01
- Add support for extensions:
- VK_KHR_maintenance1
- VK_KHR_shader_draw_parameters
- VK_KHR_get_physical_device_properties2
- VK_KHR_push_descriptor
- Add ability to track and access supported and enabled extensions.
- Update to latest SPIRV-Cross version.
MoltenVK 1.0.19
---------------

View File

@ -1 +1 @@
6480db7352b154f7decf8df9eb38b4c3c1ec530b
9ffd4172b46408ab6b03625b0f4f9cfafa5aaa71

View File

@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
A909F65F213B190700FCD6BE /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; };
A909F660213B190700FCD6BE /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; };
A909F661213B190700FCD6BE /* MVKExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A909F65E213B190700FCD6BE /* MVKExtensions.cpp */; };
A909F662213B190700FCD6BE /* MVKExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A909F65E213B190700FCD6BE /* MVKExtensions.cpp */; };
A90C8DEA1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */; };
A90C8DEB1F45354D009CB32C /* MVKCommandEncodingPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */; };
A90C8DEC1F45354D009CB32C /* MVKCommandEncodingPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A90C8DE91F45354D009CB32C /* MVKCommandEncodingPool.mm */; };
@ -147,8 +151,8 @@
A98149521FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */; };
A98149531FB6A3F7005F00B4 /* MVKFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149441FB6A3F7005F00B4 /* MVKFoundation.h */; };
A98149541FB6A3F7005F00B4 /* MVKFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149441FB6A3F7005F00B4 /* MVKFoundation.h */; };
A98149551FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */; };
A98149561FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */; };
A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */; };
A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */; };
A98149571FB6A3F7005F00B4 /* MVKObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */; };
A98149581FB6A3F7005F00B4 /* MVKObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */; };
A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
@ -256,6 +260,8 @@
/* Begin PBXFileReference section */
A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdDispatch.h; sourceTree = "<group>"; };
A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDispatch.mm; sourceTree = "<group>"; };
A909F65A213B190600FCD6BE /* MVKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKExtensions.h; sourceTree = "<group>"; };
A909F65E213B190700FCD6BE /* MVKExtensions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKExtensions.cpp; sourceTree = "<group>"; };
A90C8DE81F45354D009CB32C /* MVKCommandEncodingPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommandEncodingPool.h; sourceTree = "<group>"; };
A90C8DE91F45354D009CB32C /* MVKCommandEncodingPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCommandEncodingPool.mm; sourceTree = "<group>"; };
A93E832E2121C5D3001FEBD4 /* MVKGPUCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKGPUCapture.h; sourceTree = "<group>"; };
@ -325,7 +331,7 @@
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKBaseObject.h; sourceTree = "<group>"; };
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKEnvironment.h; sourceTree = "<group>"; };
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKFoundation.h; sourceTree = "<group>"; };
A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKFoundation.mm; sourceTree = "<group>"; };
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKFoundation.cpp; sourceTree = "<group>"; };
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKObjectPool.h; sourceTree = "<group>"; };
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKWatermark.h; sourceTree = "<group>"; };
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKWatermark.mm; sourceTree = "<group>"; };
@ -365,7 +371,7 @@
A94FB7651C7DFB4800632CA3 /* API */,
A94FB76B1C7DFB4800632CA3 /* Commands */,
A94FB77E1C7DFB4800632CA3 /* GPUObjects */,
A94FB79F1C7DFB4800632CA3 /* Loader */,
A94FB79F1C7DFB4800632CA3 /* Layers */,
A9E53DCC2100B197002781DD /* OS */,
A98149401FB6A3F7005F00B4 /* Utility */,
A94FB7A81C7DFB4800632CA3 /* Vulkan */,
@ -457,13 +463,15 @@
path = GPUObjects;
sourceTree = "<group>";
};
A94FB79F1C7DFB4800632CA3 /* Loader */ = {
A94FB79F1C7DFB4800632CA3 /* Layers */ = {
isa = PBXGroup;
children = (
A909F65A213B190600FCD6BE /* MVKExtensions.h */,
A909F65E213B190700FCD6BE /* MVKExtensions.cpp */,
A94FB7A01C7DFB4800632CA3 /* MVKLayers.h */,
A94FB7A11C7DFB4800632CA3 /* MVKLayers.mm */,
);
path = Loader;
path = Layers;
sourceTree = "<group>";
};
A94FB7A81C7DFB4800632CA3 /* Vulkan */ = {
@ -483,7 +491,7 @@
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
A98149451FB6A3F7005F00B4 /* MVKFoundation.mm */,
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
A98149491FB6A3F7005F00B4 /* MVKWatermark.h */,
A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */,
@ -576,6 +584,7 @@
buildActionMask = 2147483647;
files = (
A94FB7B41C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
A909F65F213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B01C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A98149511FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
A948BB7F1E51642700DE59F2 /* mvk_vulkan.h in Headers */,
@ -635,6 +644,7 @@
buildActionMask = 2147483647;
files = (
A94FB7B51C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
A909F660213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B11C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A98149521FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
A948BB801E51642700DE59F2 /* mvk_vulkan.h in Headers */,
@ -821,7 +831,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_SYS_FWK_DIR=\"${SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${SDK_DIR}/usr/lib\"\n\nclang \\\n-dynamiclib \\\n-arch x86_64 \\\n-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal -framework IOSurface -framework IOKit -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
shellScript = "${SRCROOT}/scripts/create_dylib_macos.sh";
};
A9731FAD1EDDAE39006B7298 /* Create Dynamic Library */ = {
isa = PBXShellScriptBuildPhase;
@ -835,7 +845,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_SYS_FWK_DIR=\"${SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${SDK_DIR}/usr/lib\"\n\n# Do not link to IOSurface if deploying to iOS versions below 11.0, doing so will\n# link IOSurface as a private framework, which will trigger App Store rejection.\nif [ $(echo \"${IPHONEOS_DEPLOYMENT_TARGET} >= 11.0\" | bc) -eq 1 ]\nthen\n export MVK_IOSURFACE_FWK=\"-framework IOSurface\"\nelse\n export MVK_IOSURFACE_FWK=\"\"\nfi\n\nclang \\\n-dynamiclib \\\n-arch arm64 \\\n-mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET} \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal ${MVK_IOSURFACE_FWK} -framework UIKit -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
shellScript = "${SRCROOT}/scripts/create_dylib_ios.sh";
};
/* End PBXShellScriptBuildPhase section */
@ -866,7 +876,8 @@
A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
A94FB82A1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
A98149551FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */,
A909F661213B190700FCD6BE /* MVKExtensions.cpp in Sources */,
A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A94FB7FA1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,
@ -917,7 +928,8 @@
A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
A94FB7DF1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
A94FB82B1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
A98149561FB6A3F7005F00B4 /* MVKFoundation.mm in Sources */,
A909F662213B190700FCD6BE /* MVKExtensions.cpp in Sources */,
A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */,
A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */,
A9E53DF62100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */,
A94FB7FB1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */,

View File

@ -31,7 +31,7 @@
extern "C" {
#endif // __cplusplus
#include <vulkan/vulkan.h>
#include <MoltenVK/mvk_vulkan.h>
#import <Metal/Metal.h>
#import <CoreGraphics/CoreGraphics.h>

View File

@ -26,7 +26,7 @@
extern "C" {
#endif // __cplusplus
#include <vulkan/vulkan.h>
#include <MoltenVK/mvk_vulkan.h>
#ifdef __OBJC__
#import <Metal/Metal.h>
@ -48,7 +48,7 @@ extern "C" {
*/
#define MVK_VERSION_MAJOR 1
#define MVK_VERSION_MINOR 0
#define MVK_VERSION_PATCH 19
#define MVK_VERSION_PATCH 21
#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)

View File

@ -25,6 +25,7 @@ class MVKCommandBuffer;
class MVKPipeline;
class MVKPipelineLayout;
class MVKDescriptorSet;
class MVKDescriptorUpdateTemplate;
#pragma mark -
@ -131,6 +132,61 @@ private:
};
#pragma mark -
#pragma mark MVKCmdPushDescriptorSet
/** Vulkan command to update a descriptor set. */
class MVKCmdPushDescriptorSet : public MVKCommand {
public:
void setContent(VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites);
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdPushDescriptorSet(MVKCommandTypePool<MVKCmdPushDescriptorSet>* pool);
~MVKCmdPushDescriptorSet() override;
private:
void clearDescriptorWrites();
VkPipelineBindPoint _pipelineBindPoint;
MVKPipelineLayout* _pipelineLayout;
std::vector<VkWriteDescriptorSet> _descriptorWrites;
uint32_t _set;
};
#pragma mark -
#pragma mark MVKCmdPushDescriptorSetWithTemplate
/** Vulkan command to update a descriptor set from a template. */
class MVKCmdPushDescriptorSetWithTemplate : public MVKCommand {
public:
void setContent(VkDescriptorUpdateTemplateKHR descUpdateTemplate,
VkPipelineLayout layout,
uint32_t set,
const void* pData);
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdPushDescriptorSetWithTemplate(MVKCommandTypePool<MVKCmdPushDescriptorSetWithTemplate>* pool);
~MVKCmdPushDescriptorSetWithTemplate() override;
private:
MVKDescriptorUpdateTemplate* _descUpdateTemplate;
MVKPipelineLayout* _pipelineLayout;
uint32_t _set;
void* _pData;
};
#pragma mark -
#pragma mark Command creation functions
@ -168,3 +224,18 @@ void mvkCmdPushConstants(MVKCommandBuffer* cmdBuff,
uint32_t offset,
uint32_t size,
const void* pValues);
/** Adds commands to the specified command buffer that update the specified descriptor set. */
void mvkCmdPushDescriptorSet(MVKCommandBuffer* cmdBuff,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites);
/** Adds commands to the specified command buffer that update the specified descriptor set from the given template. */
void mvkCmdPushDescriptorSetWithTemplate(MVKCommandBuffer* cmdBuff,
VkDescriptorUpdateTemplateKHR descUpdateTemplate,
VkPipelineLayout layout,
uint32_t set,
const void* pData);

View File

@ -179,6 +179,125 @@ MVKCmdPushConstants::MVKCmdPushConstants(MVKCommandTypePool<MVKCmdPushConstants>
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
#pragma mark -
#pragma mark MVKCmdPushDescriptorSet
void MVKCmdPushDescriptorSet::setContent(VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites) {
_pipelineBindPoint = pipelineBindPoint;
_pipelineLayout = (MVKPipelineLayout*)layout;
_set = set;
// Add the descriptor writes
clearDescriptorWrites(); // Clear for reuse
_descriptorWrites.reserve(descriptorWriteCount);
for (uint32_t dwIdx = 0; dwIdx < descriptorWriteCount; dwIdx++) {
_descriptorWrites.push_back(pDescriptorWrites[dwIdx]);
VkWriteDescriptorSet& descWrite = _descriptorWrites.back();
// Make a copy of the associated data.
if (descWrite.pImageInfo) {
auto* pNewImageInfo = new VkDescriptorImageInfo[descWrite.descriptorCount];
std::copy_n(descWrite.pImageInfo, descWrite.descriptorCount, pNewImageInfo);
descWrite.pImageInfo = pNewImageInfo;
}
if (descWrite.pBufferInfo) {
auto* pNewBufferInfo = new VkDescriptorBufferInfo[descWrite.descriptorCount];
std::copy_n(descWrite.pBufferInfo, descWrite.descriptorCount, pNewBufferInfo);
descWrite.pBufferInfo = pNewBufferInfo;
}
if (descWrite.pTexelBufferView) {
auto* pNewTexelBufferView = new VkBufferView[descWrite.descriptorCount];
std::copy_n(descWrite.pTexelBufferView, descWrite.descriptorCount, pNewTexelBufferView);
descWrite.pTexelBufferView = pNewTexelBufferView;
}
}
}
void MVKCmdPushDescriptorSet::encode(MVKCommandEncoder* cmdEncoder) {
_pipelineLayout->pushDescriptorSet(cmdEncoder, _descriptorWrites, _set);
}
MVKCmdPushDescriptorSet::MVKCmdPushDescriptorSet(MVKCommandTypePool<MVKCmdPushDescriptorSet>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
MVKCmdPushDescriptorSet::~MVKCmdPushDescriptorSet() {
clearDescriptorWrites();
}
void MVKCmdPushDescriptorSet::clearDescriptorWrites() {
for (VkWriteDescriptorSet &descWrite : _descriptorWrites) {
if (descWrite.pImageInfo) delete[] descWrite.pImageInfo;
if (descWrite.pBufferInfo) delete[] descWrite.pBufferInfo;
if (descWrite.pTexelBufferView) delete[] descWrite.pTexelBufferView;
}
_descriptorWrites.clear();
}
#pragma mark -
#pragma mark MVKCmdPushDescriptorSetWithTemplate
void MVKCmdPushDescriptorSetWithTemplate::setContent(VkDescriptorUpdateTemplateKHR descUpdateTemplate,
VkPipelineLayout layout,
uint32_t set,
const void* pData) {
_descUpdateTemplate = (MVKDescriptorUpdateTemplate*)descUpdateTemplate;
_pipelineLayout = (MVKPipelineLayout*)layout;
_set = set;
if (_pData) delete[] (char*)_pData;
// Work out how big the memory block in pData is.
const VkDescriptorUpdateTemplateEntryKHR* pEntry =
_descUpdateTemplate->getEntry(_descUpdateTemplate->getNumberOfEntries()-1);
size_t size = pEntry->offset;
// If we were given a stride, use that; otherwise, assume only one info
// struct of the appropriate type.
if (pEntry->stride)
size += pEntry->stride * pEntry->descriptorCount;
else switch (pEntry->descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
size += sizeof(VkDescriptorBufferInfo);
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
size += sizeof(VkDescriptorImageInfo);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
size += sizeof(VkBufferView);
break;
default:
break;
}
_pData = new char[size];
memcpy(_pData, pData, size);
}
void MVKCmdPushDescriptorSetWithTemplate::encode(MVKCommandEncoder* cmdEncoder) {
_pipelineLayout->pushDescriptorSet(cmdEncoder, _descUpdateTemplate, _set, _pData);
}
MVKCmdPushDescriptorSetWithTemplate::MVKCmdPushDescriptorSetWithTemplate(
MVKCommandTypePool<MVKCmdPushDescriptorSetWithTemplate>* pool)
: MVKCommand::MVKCommand((MVKCommandTypePool<MVKCommand>*)pool) {}
MVKCmdPushDescriptorSetWithTemplate::~MVKCmdPushDescriptorSetWithTemplate() {
if (_pData) delete[] (char*)_pData;
}
#pragma mark -
#pragma mark Command creation functions
@ -232,3 +351,23 @@ void mvkCmdPushConstants(MVKCommandBuffer* cmdBuff,
cmdBuff->addCommand(cmd);
}
void mvkCmdPushDescriptorSet(MVKCommandBuffer* cmdBuff,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites) {
MVKCmdPushDescriptorSet* cmd = cmdBuff->_commandPool->_cmdPushDescriptorSetPool.acquireObject();
cmd->setContent(pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
cmdBuff->addCommand(cmd);
}
void mvkCmdPushDescriptorSetWithTemplate(MVKCommandBuffer* cmdBuff,
VkDescriptorUpdateTemplateKHR descUpdateTemplate,
VkPipelineLayout layout,
uint32_t set,
const void* pData) {
MVKCmdPushDescriptorSetWithTemplate* cmd = cmdBuff->_commandPool->_cmdPushSetWithTemplatePool.acquireObject();
cmd->setContent(descUpdateTemplate, layout, set, pData);
cmdBuff->addCommand(cmd);
}

View File

@ -62,6 +62,9 @@ void MVKCmdCopyImage::setContent(VkImage srcImage,
if (_srcImage->getMTLPixelFormat() != _dstImage->getMTLPixelFormat()) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdCopyImage(): The source and destination images must have the same format."));
}
if ((_srcImage->getMTLTextureType() == MTLTextureType3D) || (_dstImage->getMTLTextureType() == MTLTextureType3D)) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdCopyImage(): Metal does not support copying to or from slices of a 3D texture."));
}
}
// Adds a Metal copy region structure for each layer in the specified copy region.
@ -591,7 +594,7 @@ void MVKCmdCopyBuffer::encode(MVKCommandEncoder* cmdEncoder) {
[mtlComputeEnc setBuffer:srcMTLBuff offset: srcMTLBuffOffset atIndex: 0];
[mtlComputeEnc setBuffer:dstMTLBuff offset: dstMTLBuffOffset atIndex: 1];
[mtlComputeEnc setBytes: &copyInfo length: sizeof(copyInfo) atIndex: 2];
[mtlComputeEnc dispatchThreads: MTLSizeMake(1, 1, 1) threadsPerThreadgroup: MTLSizeMake(1, 1, 1)];
[mtlComputeEnc dispatchThreadgroups: MTLSizeMake(1, 1, 1) threadsPerThreadgroup: MTLSizeMake(1, 1, 1)];
[mtlComputeEnc popDebugGroup];
} else {
id<MTLBlitCommandEncoder> mtlBlitEnc = cmdEncoder->getMTLBlitEncoder(kMVKCommandUseCopyBuffer);
@ -975,7 +978,6 @@ void MVKCmdClearImage::encode(MVKCommandEncoder* cmdEncoder) {
// Matches shader struct
typedef struct {
uint32_t dstOffset;
uint32_t size;
uint32_t data;
} MVKCmdFillBufferInfo;
@ -996,20 +998,19 @@ void MVKCmdFillBuffer::encode(MVKCommandEncoder* cmdEncoder) {
VkDeviceSize byteCnt = (_size == VK_WHOLE_SIZE) ? (_dstBuffer->getByteCount() - (dstMTLBuffOffset + _dstOffset)) : _size;
VkDeviceSize wordCnt = byteCnt >> 2;
MVKAssert(mvkFits<uint32_t>(_dstOffset) && mvkFits<uint32_t>(wordCnt),
"Buffer fill offset and size must each fit into a 32-bit unsigned integer.");
MVKAssert(mvkFits<uint32_t>(wordCnt),
"Buffer fill size must fit into a 32-bit unsigned integer.");
MVKCmdFillBufferInfo fillInfo;
fillInfo.dstOffset = (uint32_t)_dstOffset;
fillInfo.size = (uint32_t)wordCnt;
fillInfo.data = _dataValue;
id<MTLComputeCommandEncoder> mtlComputeEnc = cmdEncoder->getMTLComputeEncoder(kMVKCommandUseCopyBuffer);
[mtlComputeEnc pushDebugGroup: @"vkCmdFillBuffer"];
[mtlComputeEnc setComputePipelineState: cmdEncoder->getCommandEncodingPool()->getCmdFillBufferMTLComputePipelineState()];
[mtlComputeEnc setBuffer: dstMTLBuff offset: dstMTLBuffOffset atIndex: 0];
[mtlComputeEnc setBuffer: dstMTLBuff offset: dstMTLBuffOffset+_dstOffset atIndex: 0];
[mtlComputeEnc setBytes: &fillInfo length: sizeof(fillInfo) atIndex: 1];
[mtlComputeEnc dispatchThreads: MTLSizeMake(1, 1, 1) threadsPerThreadgroup: MTLSizeMake(1, 1, 1)];
[mtlComputeEnc dispatchThreadgroups: MTLSizeMake(1, 1, 1) threadsPerThreadgroup: MTLSizeMake(1, 1, 1)];
[mtlComputeEnc popDebugGroup];
}

View File

@ -80,7 +80,6 @@ kernel void cmdCopyBufferBytes(device uint8_t* src [[ buffer(0) ]],
}; \n\
\n\
typedef struct { \n\
uint32_t dstOffset; \n\
uint32_t size; \n\
uint32_t data; \n\
} FillInfo; \n\
@ -88,7 +87,7 @@ typedef struct {
kernel void cmdFillBuffer(device uint32_t* dst [[ buffer(0) ]], \n\
constant FillInfo& info [[ buffer(1) ]]) { \n\
for (uint32_t i = 0; i < info.size; i++) { \n\
dst[i + info.dstOffset] = info.data; \n\
dst[i] = info.data; \n\
} \n\
}; \n\
\n\

View File

@ -131,6 +131,10 @@ public:
MVKCommandTypePool<MVKCmdDispatchIndirect> _cmdDispatchIndirectPool;
MVKCommandTypePool<MVKCmdPushDescriptorSet> _cmdPushDescriptorSetPool;
MVKCommandTypePool<MVKCmdPushDescriptorSetWithTemplate> _cmdPushSetWithTemplatePool;
#pragma mark Command resources
@ -142,6 +146,9 @@ public:
void freeCommandBuffers(uint32_t commandBufferCount,
const VkCommandBuffer* pCommandBuffers);
/** Release any held but unused memory back to the system. */
void trimCommandPool();
#pragma mark Construction

View File

@ -63,6 +63,10 @@ void MVKCommandPool::freeCommandBuffers(uint32_t commandBufferCount,
}
}
void MVKCommandPool::trimCommandPool() {
// TODO: Implement.
}
void MVKCommandPool::addCommandBuffer(MVKCommandBuffer* cmdBuffer) {
_commandBuffers.insert(cmdBuffer);
}
@ -114,7 +118,9 @@ MVKCommandPool::MVKCommandPool(MVKDevice* device,
_cmdCopyQueryPoolResultsPool(this, true),
_cmdPushConstantsPool(this, true),
_cmdDispatchPool(this, true),
_cmdDispatchIndirectPool(this, true)
_cmdDispatchIndirectPool(this, true),
_cmdPushDescriptorSetPool(this, true),
_cmdPushSetWithTemplatePool(this, true)
{}
// TODO: Destroying a command pool implicitly destroys all command buffers and commands created from it.

View File

@ -78,6 +78,16 @@ public:
std::vector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex);
/** Encodes this binding layout and the specified descriptor binding on the specified command encoder immediately. */
void push(MVKCommandEncoder* cmdEncoder,
uint32_t& dstArrayElement,
uint32_t& descriptorCount,
uint32_t& descriptorsPushed,
VkDescriptorType descriptorType,
size_t stride,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets);
/** Populates the specified shader converter context, at the specified descriptor set binding. */
void populateShaderConverterContext(SPIRVToMSLConverterContext& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
@ -119,11 +129,27 @@ public:
uint32_t* pDynamicOffsetIndex);
/** Encodes this descriptor set layout and the specified descriptor updates on the specified command encoder immediately. */
void pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
std::vector<VkWriteDescriptorSet>& descriptorWrites,
MVKShaderResourceBinding& dslMTLRezIdxOffsets);
/** Encodes this descriptor set layout and the updates from the given template on the specified command encoder immediately. */
void pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
MVKDescriptorUpdateTemplate* descUpdateTemplates,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets);
/** Populates the specified shader converter context, at the specified DSL index. */
void populateShaderConverterContext(SPIRVToMSLConverterContext& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
uint32_t dslIndex);
/** Returns true if this layout is for push descriptors only. */
bool isPushDescriptorLayout() const { return _isPushDescriptorLayout; }
/** Constructs an instance for the specified device. */
MVKDescriptorSetLayout(MVKDevice* device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
@ -135,6 +161,7 @@ protected:
std::vector<MVKDescriptorSetLayoutBinding> _bindings;
MVKShaderResourceBinding _mtlResourceCounts;
bool _isPushDescriptorLayout : 1;
};
@ -169,9 +196,8 @@ public:
uint32_t writeBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView);
size_t stride,
const void* pData);
/**
* Updates the specified content arrays from the internal element bindings.
@ -196,6 +222,7 @@ public:
uint32_t readBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView);
@ -234,15 +261,15 @@ public:
/** Updates the resource bindings in this instance from the specified content. */
template<typename DescriptorAction>
void writeDescriptorSets(const DescriptorAction* pDescriptorAction,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView);
size_t stride,
const void* pData);
/**
* Reads the resource bindings defined in the specified content
* from this instance into the specified collection of bindings.
*/
void readDescriptorSets(const VkCopyDescriptorSet* pDescriptorCopies,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView);
@ -291,6 +318,34 @@ protected:
};
#pragma mark -
#pragma mark MVKDescriptorUpdateTemplate
/** Represents a Vulkan descriptor update template. */
class MVKDescriptorUpdateTemplate : public MVKConfigurableObject {
public:
/** Get the nth update template entry. */
const VkDescriptorUpdateTemplateEntryKHR* getEntry(uint32_t n) const;
/** Get the total number of entries. */
uint32_t getNumberOfEntries() const;
/** Get the type of this template. */
VkDescriptorUpdateTemplateTypeKHR getType() const;
/** Constructs an instance for the specified device. */
MVKDescriptorUpdateTemplate(MVKDevice* device, const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo);
/** Destructor. */
~MVKDescriptorUpdateTemplate() override = default;
private:
VkDescriptorUpdateTemplateTypeKHR _type;
std::vector<VkDescriptorUpdateTemplateEntryKHR> _entries;
};
#pragma mark -
#pragma mark Support functions
@ -300,6 +355,11 @@ void mvkUpdateDescriptorSets(uint32_t writeCount,
uint32_t copyCount,
const VkCopyDescriptorSet* pDescriptorCopies);
/** Updates the resource bindings in the given descriptor set from the specified template. */
void mvkUpdateDescriptorSetWithTemplate(VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplateKHR updateTemplate,
const void* pData);
/**
* If the shader stage binding has a binding defined for the specified stage, populates
* the context at the descriptor set binding from the shader stage resource binding.

View File

@ -173,6 +173,173 @@ void MVKDescriptorSetLayoutBinding::bind(MVKCommandEncoder* cmdEncoder,
}
}
template<typename T>
static const T& get(const void* pData, size_t stride, uint32_t index) {
return *(T*)((const char*)pData + stride * index);
}
void MVKDescriptorSetLayoutBinding::push(MVKCommandEncoder* cmdEncoder,
uint32_t& dstArrayElement,
uint32_t& descriptorCount,
uint32_t& descriptorsPushed,
VkDescriptorType descriptorType,
size_t stride,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets) {
MVKMTLBufferBinding bb;
MVKMTLTextureBinding tb;
MVKMTLSamplerStateBinding sb;
if (dstArrayElement >= _info.descriptorCount) {
dstArrayElement -= _info.descriptorCount;
return;
}
if (descriptorType != _info.descriptorType) {
dstArrayElement = 0;
if (_info.descriptorCount > descriptorCount)
descriptorCount = 0;
else {
descriptorCount -= _info.descriptorCount;
descriptorsPushed = _info.descriptorCount;
}
return;
}
// Establish the resource indices to use, by combining the offsets of the DSL and this DSL binding.
MVKShaderResourceBinding mtlIdxs = _mtlResourceIndexOffsets + dslMTLRezIdxOffsets;
for (uint32_t rezIdx = dstArrayElement;
rezIdx < _info.descriptorCount && rezIdx - dstArrayElement < descriptorCount;
rezIdx++) {
switch (_info.descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
const auto& bufferInfo = get<VkDescriptorBufferInfo>(pData, stride, rezIdx - dstArrayElement);
MVKBuffer* buffer = (MVKBuffer*)bufferInfo.buffer;
bb.mtlBuffer = buffer->getMTLBuffer();
bb.offset = bufferInfo.offset;
if (_applyToVertexStage) {
bb.index = mtlIdxs.vertexStage.bufferIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexBuffer(bb);
}
if (_applyToFragmentStage) {
bb.index = mtlIdxs.fragmentStage.bufferIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentBuffer(bb);
}
if (_applyToComputeStage) {
bb.index = mtlIdxs.computeStage.bufferIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindBuffer(bb);
}
break;
}
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
const auto& imageInfo = get<VkDescriptorImageInfo>(pData, stride, rezIdx - dstArrayElement);
MVKImageView* imageView = (MVKImageView*)imageInfo.imageView;
tb.mtlTexture = imageView->getMTLTexture();
if (_applyToVertexStage) {
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
}
if (_applyToFragmentStage) {
tb.index = mtlIdxs.fragmentStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentTexture(tb);
}
if (_applyToComputeStage) {
tb.index = mtlIdxs.computeStage.textureIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindTexture(tb);
}
break;
}
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
auto* bufferView = get<MVKBufferView*>(pData, stride, rezIdx - dstArrayElement);
tb.mtlTexture = bufferView->getMTLTexture();
if (_applyToVertexStage) {
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
}
if (_applyToFragmentStage) {
tb.index = mtlIdxs.fragmentStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentTexture(tb);
}
if (_applyToComputeStage) {
tb.index = mtlIdxs.computeStage.textureIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindTexture(tb);
}
break;
}
case VK_DESCRIPTOR_TYPE_SAMPLER: {
MVKSampler* sampler;
if (_immutableSamplers.empty())
sampler = (MVKSampler*)get<VkDescriptorImageInfo>(pData, stride, rezIdx - dstArrayElement).sampler;
else
sampler = _immutableSamplers[rezIdx];
sb.mtlSamplerState = sampler->getMTLSamplerState();
if (_applyToVertexStage) {
sb.index = mtlIdxs.vertexStage.samplerIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexSamplerState(sb);
}
if (_applyToFragmentStage) {
sb.index = mtlIdxs.fragmentStage.samplerIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentSamplerState(sb);
}
if (_applyToComputeStage) {
sb.index = mtlIdxs.computeStage.samplerIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindSamplerState(sb);
}
break;
}
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
const auto& imageInfo = get<VkDescriptorImageInfo>(pData, stride, rezIdx - dstArrayElement);
MVKImageView* imageView = (MVKImageView*)imageInfo.imageView;
MVKSampler* sampler = _immutableSamplers.empty() ? (MVKSampler*)imageInfo.sampler : _immutableSamplers[rezIdx];
tb.mtlTexture = imageView->getMTLTexture();
sb.mtlSamplerState = sampler->getMTLSamplerState();
if (_applyToVertexStage) {
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
sb.index = mtlIdxs.vertexStage.samplerIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindVertexSamplerState(sb);
}
if (_applyToFragmentStage) {
tb.index = mtlIdxs.fragmentStage.textureIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentTexture(tb);
sb.index = mtlIdxs.fragmentStage.samplerIndex + rezIdx;
cmdEncoder->_graphicsResourcesState.bindFragmentSamplerState(sb);
}
if (_applyToComputeStage) {
tb.index = mtlIdxs.computeStage.textureIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindTexture(tb);
sb.index = mtlIdxs.computeStage.samplerIndex + rezIdx;
cmdEncoder->_computeResourcesState.bindSamplerState(sb);
}
break;
}
default:
break;
}
}
dstArrayElement = 0;
if (_info.descriptorCount > descriptorCount)
descriptorCount = 0;
else {
descriptorCount -= _info.descriptorCount;
descriptorsPushed = _info.descriptorCount;
}
}
void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(SPIRVToMSLConverterContext& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
uint32_t dslIndex) {
@ -300,6 +467,7 @@ void MVKDescriptorSetLayout::bindDescriptorSet(MVKCommandEncoder* cmdEncoder,
vector<uint32_t>& dynamicOffsets,
uint32_t* pDynamicOffsetIndex) {
if (_isPushDescriptorLayout) return;
uint32_t bindCnt = (uint32_t)_bindings.size();
for (uint32_t bindIdx = 0; bindIdx < bindCnt; bindIdx++) {
_bindings[bindIdx].bind(cmdEncoder, descSet->_bindings[bindIdx],
@ -308,6 +476,96 @@ void MVKDescriptorSetLayout::bindDescriptorSet(MVKCommandEncoder* cmdEncoder,
}
}
static const void* getWriteParameters(VkDescriptorType type, const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo, const VkBufferView* pTexelBufferView,
size_t& stride) {
const void* pData;
switch (type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
pData = pBufferInfo;
stride = sizeof(VkDescriptorBufferInfo);
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
pData = pImageInfo;
stride = sizeof(VkDescriptorImageInfo);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
pData = pTexelBufferView;
stride = sizeof(MVKBufferView*);
break;
default:
pData = nullptr;
stride = 0;
}
return pData;
}
void MVKDescriptorSetLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
vector<VkWriteDescriptorSet>& descriptorWrites,
MVKShaderResourceBinding& dslMTLRezIdxOffsets) {
if (!_isPushDescriptorLayout) return;
for (const VkWriteDescriptorSet& descWrite : descriptorWrites) {
uint32_t bindIdx = descWrite.dstBinding;
uint32_t dstArrayElement = descWrite.dstArrayElement;
uint32_t descriptorCount = descWrite.descriptorCount;
const VkDescriptorImageInfo* pImageInfo = descWrite.pImageInfo;
const VkDescriptorBufferInfo* pBufferInfo = descWrite.pBufferInfo;
const VkBufferView* pTexelBufferView = descWrite.pTexelBufferView;
// Note: This will result in us walking off the end of the array
// in case there are too many updates... but that's ill-defined anyway.
for (; descriptorCount; bindIdx++) {
size_t stride;
const void* pData = getWriteParameters(descWrite.descriptorType, pImageInfo,
pBufferInfo, pTexelBufferView, stride);
uint32_t descriptorsPushed = 0;
_bindings[bindIdx].push(cmdEncoder, dstArrayElement, descriptorCount,
descriptorsPushed, descWrite.descriptorType,
stride, pData, dslMTLRezIdxOffsets);
pBufferInfo += descriptorsPushed;
pImageInfo += descriptorsPushed;
pTexelBufferView += descriptorsPushed;
}
}
}
void MVKDescriptorSetLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
MVKDescriptorUpdateTemplate* descUpdateTemplate,
const void* pData,
MVKShaderResourceBinding& dslMTLRezIdxOffsets) {
if (!_isPushDescriptorLayout ||
descUpdateTemplate->getType() != VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR)
return;
for (uint32_t i = 0; i < descUpdateTemplate->getNumberOfEntries(); i++) {
const VkDescriptorUpdateTemplateEntryKHR* pEntry = descUpdateTemplate->getEntry(i);
uint32_t bindIdx = pEntry->dstBinding;
uint32_t dstArrayElement = pEntry->dstArrayElement;
uint32_t descriptorCount = pEntry->descriptorCount;
const void* pCurData = (const char*)pData + pEntry->offset;
// Note: This will result in us walking off the end of the array
// in case there are too many updates... but that's ill-defined anyway.
for (; descriptorCount; bindIdx++) {
uint32_t descriptorsPushed = 0;
_bindings[bindIdx].push(cmdEncoder, dstArrayElement, descriptorCount,
descriptorsPushed, pEntry->descriptorType,
pEntry->stride, pCurData, dslMTLRezIdxOffsets);
pCurData = (const char*)pCurData + pEntry->stride * descriptorsPushed;
}
}
}
void MVKDescriptorSetLayout::populateShaderConverterContext(SPIRVToMSLConverterContext& context,
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
uint32_t dslIndex) {
@ -319,6 +577,7 @@ void MVKDescriptorSetLayout::populateShaderConverterContext(SPIRVToMSLConverterC
MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
_isPushDescriptorLayout = (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) != 0;
// Create the descriptor bindings
_bindings.reserve(pCreateInfo->bindingCount);
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
@ -334,9 +593,8 @@ MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView) {
size_t stride,
const void* pData) {
uint32_t dstCnt = MIN(count, _pBindingLayout->_info.descriptorCount - dstStartIndex);
@ -344,10 +602,10 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
case VK_DESCRIPTOR_TYPE_SAMPLER:
for (uint32_t i = 0; i < dstCnt; i++) {
uint32_t dstIdx = dstStartIndex + i;
const VkDescriptorImageInfo* pImgInfo = &pImageInfo[srcStartIndex + i];
const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcStartIndex + i);
_imageBindings[dstIdx] = *pImgInfo;
if (_hasDynamicSamplers) {
_mtlSamplers[dstIdx] = ((MVKSampler*)pImgInfo->sampler)->getMTLSamplerState();
_mtlSamplers[dstIdx] = pImgInfo->sampler ? ((MVKSampler*)pImgInfo->sampler)->getMTLSamplerState() : nil;
}
}
break;
@ -355,11 +613,11 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
for (uint32_t i = 0; i < dstCnt; i++) {
uint32_t dstIdx = dstStartIndex + i;
const VkDescriptorImageInfo* pImgInfo = &pImageInfo[srcStartIndex + i];
const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcStartIndex + i);
_imageBindings[dstIdx] = *pImgInfo;
_mtlTextures[dstIdx] = ((MVKImageView*)pImgInfo->imageView)->getMTLTexture();
_mtlTextures[dstIdx] = pImgInfo->imageView ? ((MVKImageView*)pImgInfo->imageView)->getMTLTexture() : nil;
if (_hasDynamicSamplers) {
_mtlSamplers[dstIdx] = ((MVKSampler*)pImgInfo->sampler)->getMTLSamplerState();
_mtlSamplers[dstIdx] = pImgInfo->sampler ? ((MVKSampler*)pImgInfo->sampler)->getMTLSamplerState() : nil;
}
}
break;
@ -369,9 +627,9 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t i = 0; i < dstCnt; i++) {
uint32_t dstIdx = dstStartIndex + i;
const VkDescriptorImageInfo* pImgInfo = &pImageInfo[srcStartIndex + i];
const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcStartIndex + i);
_imageBindings[dstIdx] = *pImgInfo;
_mtlTextures[dstIdx] = ((MVKImageView*)pImgInfo->imageView)->getMTLTexture();
_mtlTextures[dstIdx] = pImgInfo->imageView ? ((MVKImageView*)pImgInfo->imageView)->getMTLTexture() : nil;
}
break;
@ -381,11 +639,11 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
for (uint32_t i = 0; i < dstCnt; i++) {
uint32_t dstIdx = dstStartIndex + i;
const VkDescriptorBufferInfo* pBuffInfo = &pBufferInfo[srcStartIndex + i];
const auto* pBuffInfo = &get<VkDescriptorBufferInfo>(pData, stride, srcStartIndex + i);
_bufferBindings[dstIdx] = *pBuffInfo;
MVKBuffer* mtlBuff = (MVKBuffer*)pBuffInfo->buffer;
_mtlBuffers[dstIdx] = mtlBuff->getMTLBuffer();
_mtlBufferOffsets[dstIdx] = mtlBuff->getMTLBufferOffset() + pBuffInfo->offset;
_mtlBuffers[dstIdx] = mtlBuff ? mtlBuff->getMTLBuffer() : nil;
_mtlBufferOffsets[dstIdx] = mtlBuff ? (mtlBuff->getMTLBufferOffset() + pBuffInfo->offset) : 0;
}
break;
@ -393,9 +651,9 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
for (uint32_t i = 0; i < dstCnt; i++) {
uint32_t dstIdx = dstStartIndex + i;
const VkBufferView* pBuffView = &pTexelBufferView[srcStartIndex + i];
const auto* pBuffView = &get<VkBufferView>(pData, stride, srcStartIndex + i);
_texelBufferBindings[dstIdx] = *pBuffView;
_mtlTextures[dstIdx] = ((MVKBufferView*)*pBuffView)->getMTLTexture();
_mtlTextures[dstIdx] = *pBuffView ? ((MVKBufferView*)*pBuffView)->getMTLTexture() : nil;
}
break;
default:
@ -408,12 +666,14 @@ uint32_t MVKDescriptorBinding::writeBindings(uint32_t srcStartIndex,
uint32_t MVKDescriptorBinding::readBindings(uint32_t srcStartIndex,
uint32_t dstStartIndex,
uint32_t count,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView) {
uint32_t srcCnt = MIN(count, _pBindingLayout->_info.descriptorCount - srcStartIndex);
descType = _pBindingLayout->_info.descriptorType;
switch (_pBindingLayout->_info.descriptorType) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
@ -524,9 +784,7 @@ void MVKDescriptorBinding::initMTLSamplers(MVKDescriptorSetLayoutBinding* pBindi
template<typename DescriptorAction>
void MVKDescriptorSet::writeDescriptorSets(const DescriptorAction* pDescriptorAction,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView) {
size_t stride, const void* pData) {
uint32_t dstStartIdx = pDescriptorAction->dstArrayElement;
uint32_t binding = pDescriptorAction->dstBinding;
uint32_t origCnt = pDescriptorAction->descriptorCount;
@ -541,7 +799,7 @@ void MVKDescriptorSet::writeDescriptorSets(const DescriptorAction* pDescriptorAc
uint32_t srcStartIdx = origCnt - remainCnt;
remainCnt = mvkDescBind->writeBindings(srcStartIdx, dstStartIdx, remainCnt,
pImageInfo, pBufferInfo, pTexelBufferView);
stride, pData);
binding++; // If not consumed, move to next consecutive binding point
mvkDescBind = getBinding(binding);
@ -549,17 +807,17 @@ void MVKDescriptorSet::writeDescriptorSets(const DescriptorAction* pDescriptorAc
}
}
// Create concrete implementations of the two variations of the writeDescriptorSets() function.
// Create concrete implementations of the three variations of the writeDescriptorSets() function.
template void MVKDescriptorSet::writeDescriptorSets<VkWriteDescriptorSet>(const VkWriteDescriptorSet* pDescriptorAction,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView);
size_t stride, const void *pData);
template void MVKDescriptorSet::writeDescriptorSets<VkCopyDescriptorSet>(const VkCopyDescriptorSet* pDescriptorAction,
const VkDescriptorImageInfo* pImageInfo,
const VkDescriptorBufferInfo* pBufferInfo,
const VkBufferView* pTexelBufferView);
size_t stride, const void *pData);
template void MVKDescriptorSet::writeDescriptorSets<VkDescriptorUpdateTemplateEntryKHR>(
const VkDescriptorUpdateTemplateEntryKHR* pDescriptorAction,
size_t stride, const void *pData);
void MVKDescriptorSet::readDescriptorSets(const VkCopyDescriptorSet* pDescriptorCopy,
VkDescriptorType& descType,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView) {
@ -576,7 +834,7 @@ void MVKDescriptorSet::readDescriptorSets(const VkCopyDescriptorSet* pDescriptor
// MVKLogDebug("Reading MVKDescriptorBinding with binding point %d.", binding);
uint32_t dstStartIdx = origCnt - remainCnt;
remainCnt = mvkDescBind->readBindings(srcStartIdx, dstStartIdx, remainCnt,
remainCnt = mvkDescBind->readBindings(srcStartIdx, dstStartIdx, remainCnt, descType,
pImageInfo, pBufferInfo, pTexelBufferView);
binding++; // If not consumed, move to next consecutive binding point
@ -611,11 +869,16 @@ VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
const VkDescriptorSetLayout* pSetLayouts,
VkDescriptorSet* pDescriptorSets) {
if (_allocatedSetCount + count > _maxSets) {
return mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "The maximum number of descriptor sets that can be allocated by this descriptor pool is %d.", _maxSets);
if (_device->_enabledExtensions.vk_KHR_maintenance1.enabled) {
return VK_ERROR_OUT_OF_POOL_MEMORY; // Failure is an acceptable test...don't log as error.
} else {
return mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "The maximum number of descriptor sets that can be allocated by this descriptor pool is %d.", _maxSets);
}
}
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
MVKDescriptorSetLayout* mvkDSL = (MVKDescriptorSetLayout*)pSetLayouts[dsIdx];
if (mvkDSL->isPushDescriptorLayout()) continue;
MVKDescriptorSet* mvkDescSet = new MVKDescriptorSet(_device, mvkDSL);
_allocatedSets.push_front(mvkDescSet);
pDescriptorSets[dsIdx] = (VkDescriptorSet)mvkDescSet;
@ -656,6 +919,29 @@ MVKDescriptorPool::~MVKDescriptorPool() {
}
#pragma mark -
#pragma mark MVKDescriptorUpdateTemplate
const VkDescriptorUpdateTemplateEntryKHR* MVKDescriptorUpdateTemplate::getEntry(uint32_t n) const {
return &_entries[n];
}
uint32_t MVKDescriptorUpdateTemplate::getNumberOfEntries() const {
return (uint32_t)_entries.size();
}
VkDescriptorUpdateTemplateTypeKHR MVKDescriptorUpdateTemplate::getType() const {
return _type;
}
MVKDescriptorUpdateTemplate::MVKDescriptorUpdateTemplate(MVKDevice* device, const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo) :
MVKConfigurableObject(), _type(pCreateInfo->templateType) {
for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; i++)
_entries.push_back(pCreateInfo->pDescriptorUpdateEntries[i]);
}
#pragma mark -
#pragma mark Support functions
@ -668,11 +954,12 @@ void mvkUpdateDescriptorSets(uint32_t writeCount,
// Perform the write updates
for (uint32_t i = 0; i < writeCount; i++) {
const VkWriteDescriptorSet* pDescWrite = &pDescriptorWrites[i];
size_t stride;
const void* pData = getWriteParameters(pDescWrite->descriptorType, pDescWrite->pImageInfo,
pDescWrite->pBufferInfo, pDescWrite->pTexelBufferView,
stride);
MVKDescriptorSet* dstSet = (MVKDescriptorSet*)pDescWrite->dstSet;
dstSet->writeDescriptorSets(pDescWrite,
pDescWrite->pImageInfo,
pDescWrite->pBufferInfo,
pDescWrite->pTexelBufferView);
dstSet->writeDescriptorSets(pDescWrite, stride, pData);
}
// Perform the copy updates by reading bindings from one set and writing to other set.
@ -680,15 +967,37 @@ void mvkUpdateDescriptorSets(uint32_t writeCount,
const VkCopyDescriptorSet* pDescCopy = &pDescriptorCopies[i];
uint32_t descCnt = pDescCopy->descriptorCount;
VkDescriptorType descType;
VkDescriptorImageInfo imgInfos[descCnt];
VkDescriptorBufferInfo buffInfos[descCnt];
VkBufferView texelBuffInfos[descCnt];
MVKDescriptorSet* srcSet = (MVKDescriptorSet*)pDescCopy->srcSet;
srcSet->readDescriptorSets(pDescCopy, imgInfos, buffInfos, texelBuffInfos);
srcSet->readDescriptorSets(pDescCopy, descType, imgInfos, buffInfos, texelBuffInfos);
MVKDescriptorSet* dstSet = (MVKDescriptorSet*)pDescCopy->dstSet;
dstSet->writeDescriptorSets(pDescCopy, imgInfos, buffInfos, texelBuffInfos);
size_t stride;
const void* pData = getWriteParameters(descType, imgInfos, buffInfos, texelBuffInfos, stride);
dstSet->writeDescriptorSets(pDescCopy, stride, pData);
}
}
/** Updates the resource bindings in the given descriptor set from the specified template. */
void mvkUpdateDescriptorSetWithTemplate(VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplateKHR updateTemplate,
const void* pData) {
MVKDescriptorSet* dstSet = (MVKDescriptorSet*)descriptorSet;
MVKDescriptorUpdateTemplate* pTemplate = (MVKDescriptorUpdateTemplate*)updateTemplate;
if (pTemplate->getType() != VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR)
return;
// Perform the updates
for (uint32_t i = 0; i < pTemplate->getNumberOfEntries(); i++) {
const VkDescriptorUpdateTemplateEntryKHR* pEntry = pTemplate->getEntry(i);
const void* pCurData = (const char*)pData + pEntry->offset;
dstSet->writeDescriptorSets(pEntry, pEntry->stride, pCurData);
}
}

View File

@ -53,6 +53,7 @@ class MVKPipeline;
class MVKSampler;
class MVKDescriptorSetLayout;
class MVKDescriptorPool;
class MVKDescriptorUpdateTemplate;
class MVKFramebuffer;
class MVKRenderPass;
class MVKCommandPool;
@ -75,18 +76,27 @@ public:
/** Populates the specified structure with the features of this device. */
void getFeatures(VkPhysicalDeviceFeatures* features);
/** Populates the specified structure with the features of this device. */
void getFeatures(VkPhysicalDeviceFeatures2KHR* features);
/** Populates the specified structure with the Metal-specific features of this device. */
void getMetalFeatures(MVKPhysicalDeviceMetalFeatures* mtlFeatures);
/** Populates the specified structure with the properties of this device. */
void getProperties(VkPhysicalDeviceProperties* properties);
/** Populates the specified structure with the properties of this device. */
void getProperties(VkPhysicalDeviceProperties2KHR* properties);
/** Returns whether the specified format is supported on this device. */
bool getFormatIsSupported(VkFormat format);
/** Populates the specified structure with the format properties of this device. */
void getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties);
/** Populates the specified structure with the format properties of this device. */
void getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties);
/**
* Populates the specified structure with the image format properties
* supported for the specified image characteristics on this device.
@ -98,6 +108,13 @@ public:
VkImageCreateFlags flags,
VkImageFormatProperties* pImageFormatProperties);
/**
* Populates the specified structure with the image format properties
* supported for the specified image characteristics on this device.
*/
VkResult getImageFormatProperties(const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo,
VkImageFormatProperties2KHR* pImageFormatProperties);
#pragma mark Surfaces
/**
@ -158,6 +175,20 @@ public:
*/
VkResult getQueueFamilyProperties(uint32_t* pCount, VkQueueFamilyProperties* properties);
/**
* If properties is null, the value of pCount is updated with the number of
* queue families supported by this instance.
*
* If properties is not null, then pCount queue family properties are copied into the
* array. If the number of available queue families is less than pCount, the value of
* pCount is updated to indicate the number of queue families actually returned in the array.
*
* Returns VK_SUCCESS if successful. Returns VK_INCOMPLETE if the number of queue families
* available in this instance is larger than the specified pCount. Returns other values if
* an error occurs.
*/
VkResult getQueueFamilyProperties(uint32_t* pCount, VkQueueFamilyProperties2KHR* properties);
/** Returns a pointer to the Vulkan instance. */
inline MVKInstance* getInstance() { return _mvkInstance; }
@ -173,6 +204,9 @@ public:
/** Populates the specified memory properties with the memory characteristics of this device. */
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties);
/** Populates the specified memory properties with the memory characteristics of this device. */
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
/**
* Returns a bit mask of all memory type indices.
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
@ -255,7 +289,7 @@ class MVKDevice : public MVKDispatchableObject {
public:
/** Returns a pointer to the Vulkan instance. */
inline MVKInstance* getInstance() { return _physicalDevice->getInstance(); }
inline MVKInstance* getInstance() { return _physicalDevice->_mvkInstance; }
/** Returns the physical device underlying this logical device. */
inline MVKPhysicalDevice* getPhysicalDevice() { return _physicalDevice; }
@ -364,6 +398,11 @@ public:
void destroyDescriptorPool(MVKDescriptorPool* mvkDP,
const VkAllocationCallbacks* pAllocator);
MVKDescriptorUpdateTemplate* createDescriptorUpdateTemplate(const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
void destroyDescriptorUpdateTemplate(MVKDescriptorUpdateTemplate* mvkDUT,
const VkAllocationCallbacks* pAllocator);
MVKFramebuffer* createFramebuffer(const VkFramebufferCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
void destroyFramebuffer(MVKFramebuffer* mvkFB,
@ -471,7 +510,7 @@ public:
#pragma mark Properties directly accessible
/** The MoltenVK configuration settings. */
/** Pointer to the MoltenVK configuration settings. */
const MVKConfiguration* _pMVKConfig;
/** Pointer to the feature set of the underlying physical device. */
@ -486,6 +525,9 @@ public:
/** Pointer to the memory properties of the underlying physical device. */
const VkPhysicalDeviceMemoryProperties* _pMemoryProperties;
/** The list of Vulkan extensions, indicating whether each has been enabled by the app for this device. */
const MVKExtensionList _enabledExtensions;
/** Performance statistics. */
MVKPerformanceStatistics _performanceStatistics;

View File

@ -58,6 +58,13 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures* features) {
if (features) { *features = _features; }
}
void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2KHR* features) {
if (features) {
features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
features->features = _features;
}
}
void MVKPhysicalDevice::getMetalFeatures(MVKPhysicalDeviceMetalFeatures* mtlFeatures) {
if (mtlFeatures) { *mtlFeatures = _metalFeatures; }
}
@ -66,6 +73,27 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties* properties) {
if (properties) { *properties = _properties; }
}
void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2KHR* properties) {
if (properties) {
properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
properties->properties = _properties;
auto* next = (VkStructureType*)properties->pNext;
while (next) {
switch (*next) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
auto* pushDescProps = (VkPhysicalDevicePushDescriptorPropertiesKHR*)next;
pushDescProps->maxPushDescriptors = _properties.limits.maxPerStageResources;
next = (VkStructureType*)pushDescProps->pNext;
break;
}
default:
next = (VkStructureType*)((VkPhysicalDeviceProperties2KHR*)next)->pNext;
break;
}
}
}
}
bool MVKPhysicalDevice::getFormatIsSupported(VkFormat format) {
if ( !mvkVkFormatIsSupported(format) ) { return false; }
@ -91,6 +119,15 @@ void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties*
}
}
void MVKPhysicalDevice::getFormatProperties(VkFormat format,
VkFormatProperties2KHR* pFormatProperties) {
static VkFormatProperties noFmtFeats = { 0, 0, 0 };
if (pFormatProperties) {
pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
pFormatProperties->formatProperties = getFormatIsSupported(format) ? mvkVkFormatProperties(format) : noFmtFeats;
}
}
VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
VkImageType type,
VkImageTiling tiling,
@ -148,6 +185,25 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
return VK_SUCCESS;
}
VkResult MVKPhysicalDevice::getImageFormatProperties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
VkImageFormatProperties2KHR* pImageFormatProperties) {
if ( !pImageFormatInfo || pImageFormatInfo->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR ) {
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
if ( !getFormatIsSupported(pImageFormatInfo->format) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
if ( !pImageFormatProperties ) {
return VK_SUCCESS;
}
pImageFormatProperties->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
return getImageFormatProperties(pImageFormatInfo->format, pImageFormatInfo->type,
pImageFormatInfo->tiling, pImageFormatInfo->usage,
pImageFormatInfo->flags,
&pImageFormatProperties->imageFormatProperties);
}
#pragma mark Surfaces
@ -293,6 +349,31 @@ VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
return (*pCount <= qfCnt) ? VK_SUCCESS : VK_INCOMPLETE;
}
VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
VkQueueFamilyProperties2KHR* queueProperties) {
uint32_t qfCnt = uint32_t(_queueFamilies.size());
// If properties aren't actually being requested yet, simply update the returned count
if ( !queueProperties ) {
*pCount = qfCnt;
return VK_SUCCESS;
}
// Determine how many families we'll return, and return that number
*pCount = min(*pCount, qfCnt);
// Now populate the queue families
if (queueProperties) {
for (uint32_t qfIdx = 0; qfIdx < *pCount; qfIdx++) {
queueProperties[qfIdx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR;
_queueFamilies[qfIdx]->getProperties(&queueProperties[qfIdx].queueFamilyProperties);
}
}
return (*pCount <= qfCnt) ? VK_SUCCESS : VK_INCOMPLETE;
}
#pragma mark Memory models
@ -302,6 +383,14 @@ VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMe
return VK_SUCCESS;
}
VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties) {
if (pMemoryProperties) {
pMemoryProperties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR;
pMemoryProperties->memoryProperties = _memoryProperties;
}
return VK_SUCCESS;
}
#pragma mark Construction
@ -929,39 +1018,39 @@ void MVKPhysicalDevice::logGPUInfo() {
break;
}
string fsMsg = "GPU device:";
fsMsg += "\n\t\tmodel: %s";
fsMsg += "\n\t\ttype: %s";
fsMsg += "\n\t\tvendorID: %#06x";
fsMsg += "\n\t\tdeviceID: %#06x";
fsMsg += "\n\t\tpipelineCacheUUID: %s";
fsMsg += "\n\tsupports the following Metal Feature Sets:";
string logMsg = "GPU device:";
logMsg += "\n\t\tmodel: %s";
logMsg += "\n\t\ttype: %s";
logMsg += "\n\t\tvendorID: %#06x";
logMsg += "\n\t\tdeviceID: %#06x";
logMsg += "\n\t\tpipelineCacheUUID: %s";
logMsg += "\n\tsupports the following Metal Feature Sets:";
#if MVK_IOS
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) { fsMsg += "\n\tviOS GPU Family 4 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) { logMsg += "\n\t\tiOS GPU Family 4 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v3] ) { fsMsg += "\n\t\tiOS GPU Family 3 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) { fsMsg += "\n\t\tiOS GPU Family 3 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1] ) { fsMsg += "\n\t\tiOS GPU Family 3 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v3] ) { logMsg += "\n\t\tiOS GPU Family 3 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v2] ) { logMsg += "\n\t\tiOS GPU Family 3 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1] ) { logMsg += "\n\t\tiOS GPU Family 3 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) { fsMsg += "\n\t\tiOS GPU Family 2 v4"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v3] ) { fsMsg += "\n\t\tiOS GPU Family 2 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v2] ) { fsMsg += "\n\t\tiOS GPU Family 2 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) { fsMsg += "\n\t\tiOS GPU Family 2 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) { logMsg += "\n\t\tiOS GPU Family 2 v4"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v3] ) { logMsg += "\n\t\tiOS GPU Family 2 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v2] ) { logMsg += "\n\t\tiOS GPU Family 2 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) { logMsg += "\n\t\tiOS GPU Family 2 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v4] ) { fsMsg += "\n\t\tiOS GPU Family 1 v4"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v3] ) { fsMsg += "\n\t\tiOS GPU Family 1 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v2] ) { fsMsg += "\n\t\tiOS GPU Family 1 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v1] ) { fsMsg += "\n\t\tiOS GPU Family 1 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v4] ) { logMsg += "\n\t\tiOS GPU Family 1 v4"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v3] ) { logMsg += "\n\t\tiOS GPU Family 1 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v2] ) { logMsg += "\n\t\tiOS GPU Family 1 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v1] ) { logMsg += "\n\t\tiOS GPU Family 1 v1"; }
#endif
#if MVK_MACOS
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v1] ) { fsMsg += "\n\t\tmacOS GPU Family 1 v1"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v3] ) { logMsg += "\n\t\tmacOS GPU Family 1 v3"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2] ) { logMsg += "\n\t\tmacOS GPU Family 1 v2"; }
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v1] ) { logMsg += "\n\t\tmacOS GPU Family 1 v1"; }
#endif
MVKLogInfo(fsMsg.c_str(), _properties.deviceName, devTypeStr.c_str(), _properties.vendorID, _properties.deviceID,
MVKLogInfo(logMsg.c_str(), _properties.deviceName, devTypeStr.c_str(), _properties.vendorID, _properties.deviceID,
[[[NSUUID alloc] initWithUUIDBytes: _properties.pipelineCacheUUID] autorelease].UUIDString.UTF8String);
}
@ -1272,6 +1361,17 @@ void MVKDevice::destroyDescriptorPool(MVKDescriptorPool* mvkDP,
mvkDP->destroy();
}
MVKDescriptorUpdateTemplate* MVKDevice::createDescriptorUpdateTemplate(
const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKDescriptorUpdateTemplate(this, pCreateInfo);
}
void MVKDevice::destroyDescriptorUpdateTemplate(MVKDescriptorUpdateTemplate* mvkDUT,
const VkAllocationCallbacks* pAllocator) {
mvkDUT->destroy();
}
MVKFramebuffer* MVKDevice::createFramebuffer(const VkFramebufferCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKFramebuffer(this, pCreateInfo);
@ -1433,7 +1533,7 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
initPerformanceTracking();
_physicalDevice = physicalDevice;
_pMVKConfig = &_physicalDevice->getInstance()->_mvkConfig;
_pMVKConfig = _physicalDevice->_mvkInstance->getMoltenVKConfiguration();
_pFeatures = &_physicalDevice->_features;
_pMetalFeatures = &_physicalDevice->_metalFeatures;
_pProperties = &_physicalDevice->_properties;
@ -1442,15 +1542,19 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
_globalVisibilityResultMTLBuffer = nil;
_globalVisibilityQueryCount = 0;
// Verify the requested extension names. Should be same as those requested from instance.
setConfigurationResult(_physicalDevice->_mvkInstance->verifyExtensions(pCreateInfo->enabledExtensionCount,
pCreateInfo->ppEnabledExtensionNames));
_commandResourceFactory = new MVKCommandResourceFactory(this);
_commandResourceFactory = new MVKCommandResourceFactory(this);
// Verify the requested extension names. Should be same as those requested from instance.
MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions;
setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
pCreateInfo->ppEnabledExtensionNames,
getInstance()->getDriverLayer()->getSupportedExtensions()));
initQueues(pCreateInfo);
MVKLogInfo("Created VkDevice to run on GPU %s", _pProperties->deviceName);
string logMsg = "Created VkDevice to run on GPU %s with the following Vulkan extensions enabled:";
logMsg += _enabledExtensions.enabledNamesString("\n\t\t", true);
MVKLogInfo(logMsg.c_str(), _pProperties->deviceName);
}
void MVKDevice::initPerformanceTracking() {

View File

@ -281,6 +281,7 @@ protected:
bool matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern);
const char* getSwizzleName(VkComponentSwizzle swizzle);
void setSwizzleFormatError(VkFormat format, VkComponentMapping components);
void validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo);
MVKImage* _image;
VkImageSubresourceRange _subresourceRange;

View File

@ -603,8 +603,13 @@ id<MTLTexture> MVKImageView::getMTLTexture() {
// Creates and returns a retained Metal texture as an
// overlay on the Metal texture of the underlying image.
id<MTLTexture> MVKImageView::newMTLTexture() {
MTLTextureType mtlTextureType = _mtlTextureType;
// Fake support for 2D views of 3D textures.
if (_image->getImageType() == VK_IMAGE_TYPE_3D &&
(mtlTextureType == MTLTextureType2D || mtlTextureType == MTLTextureType2DArray))
mtlTextureType = MTLTextureType3D;
return [_image->getMTLTexture() newTextureViewWithPixelFormat: _mtlPixelFormat
textureType: _mtlTextureType
textureType: mtlTextureType
levels: NSMakeRange(_subresourceRange.baseMipLevel, _subresourceRange.levelCount)
slices: NSMakeRange(_subresourceRange.baseArrayLayer, _subresourceRange.layerCount)]; // retained
}
@ -614,6 +619,8 @@ id<MTLTexture> MVKImageView::newMTLTexture() {
MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
validateImageViewConfig(pCreateInfo);
_image = (MVKImage*)pCreateInfo->image;
// Remember the subresource range, and determine the actual number of mip levels and texture slices
@ -631,6 +638,24 @@ MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCrea
initMTLTextureViewSupport();
}
// Validate whether the image view configuration can be supported
void MVKImageView::validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo) {
MVKImage* image = (MVKImage*)pCreateInfo->image;
VkImageType imgType = image->getImageType();
VkImageViewType viewType = pCreateInfo->viewType;
// VK_KHR_maintenance1 supports taking 2D image views of 3D slices. No dice in Metal.
if ((viewType == VK_IMAGE_VIEW_TYPE_2D || viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && (imgType == VK_IMAGE_TYPE_3D)) {
if (pCreateInfo->subresourceRange.layerCount != image->_extent.depth) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImageView(): Metal does not support views on a subset of a 3D texture."));
} else if (!(image->_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImageView(): 2D views on 3D images are only supported for color attachments."));
} else if (image->_usage & ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImageView(): 2D views on 3D images are only supported for color attachments.");
}
}
}
// Returns a MTLPixelFormat, based on the original MTLPixelFormat, as converted from the VkFormat,
// but possibly modified by the swizzles defined in the VkComponentMapping of the VkImageViewCreateInfo.
// Metal does not support general per-texture swizzles, and so this function relies on a few coincidental
@ -750,10 +775,12 @@ void MVKImageView::initMTLTextureViewSupport() {
_useMTLTextureView = _image->_canSupportMTLTextureView;
// If the view is identical to underlying image, don't bother using a Metal view
bool is3D = _image->_mtlTextureType == MTLTextureType3D;
if (_mtlPixelFormat == _image->_mtlPixelFormat &&
_mtlTextureType == _image->_mtlTextureType &&
(_mtlTextureType == _image->_mtlTextureType ||
((_mtlTextureType == MTLTextureType2D || _mtlTextureType == MTLTextureType2DArray) && is3D)) &&
_subresourceRange.levelCount == _image->_mipLevels &&
_subresourceRange.layerCount == _image->_arrayLayers) {
_subresourceRange.layerCount == (is3D ? _image->_extent.depth : _image->_arrayLayers)) {
_useMTLTextureView = false;
}
}

View File

@ -18,6 +18,7 @@
#pragma once
#include "MVKLayers.h"
#include "MVKSurface.h"
#include "MVKBaseObject.h"
#include "vk_mvk_moltenvk.h"
@ -53,17 +54,8 @@ public:
*/
VkResult getPhysicalDevices(uint32_t* pCount, VkPhysicalDevice* pPhysicalDevices);
/**
* Verifies that the list of layers are available,
* and returns VK_SUCCESS or VK_ERROR_LAYER_NOT_PRESENT.
*/
VkResult verifyLayers(uint32_t count, const char* const* names);
/**
* Verifies that the list of extensions are available,
* and returns VK_SUCCESS or VK_ERROR_EXTENSION_NOT_PRESENT.
*/
VkResult verifyExtensions(uint32_t count, const char* const* names);
/** Returns the driver layer. */
MVKLayer* getDriverLayer() { return MVKLayerManager::globalManager()->getDriverLayer(); }
/** Creates and returns a new object. */
MVKSurface* createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
@ -73,8 +65,14 @@ public:
void destroySurface(MVKSurface* mvkSrfc,
const VkAllocationCallbacks* pAllocator);
/** The MoltenVK configuration settings. */
MVKConfiguration _mvkConfig;
/** Returns the MoltenVK configuration settings. */
const MVKConfiguration* getMoltenVKConfiguration() { return &_mvkConfig; }
/** Returns the MoltenVK configuration settings. */
void setMoltenVKConfiguration(MVKConfiguration* mvkConfig) { _mvkConfig = *mvkConfig; }
/** The list of Vulkan extensions, indicating whether each has been enabled by the app. */
const MVKExtensionList _enabledExtensions;
#pragma mark Object Creation
@ -102,7 +100,9 @@ protected:
void initProcAddrs();
void initConfig();
void logVersions();
VkResult verifyLayers(uint32_t count, const char* const* names);
MVKConfiguration _mvkConfig;
VkApplicationInfo _appInfo;
std::vector<MVKPhysicalDevice*> _physicalDevices;
std::unordered_map<std::string, PFN_vkVoidFunction> _procAddrMap;

View File

@ -18,7 +18,6 @@
#include "MVKInstance.h"
#include "MVKLayers.h"
#include "MVKDevice.h"
#include "MVKFoundation.h"
#include "MVKEnvironment.h"
@ -53,27 +52,6 @@ VkResult MVKInstance::getPhysicalDevices(uint32_t* pCount, VkPhysicalDevice* pPh
return result;
}
VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < count; i++) {
if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
result = mvkNotifyErrorWithText(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
}
}
return result;
}
VkResult MVKInstance::verifyExtensions(uint32_t count, const char* const* names) {
VkResult result = VK_SUCCESS;
MVKLayer* driverLayer = MVKLayerManager::globalManager()->getDriverLayer();
for (uint32_t i = 0; i < count; i++) {
if (!driverLayer->hasExtensionNamed(names[i])) {
result = mvkNotifyErrorWithText(VK_ERROR_EXTENSION_NOT_PRESENT, "Vulkan extension %s is not supported.", names[i]);
}
}
return result;
}
MVKSurface* MVKInstance::createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKSurface(this, pCreateInfo, pAllocator);
@ -87,6 +65,74 @@ void MVKInstance::destroySurface(MVKSurface* mvkSrfc,
#pragma mark Object Creation
// Returns an autoreleased array containing the MTLDevices available on this system,
// sorted according to power, with higher power GPU's at the front of the array.
// This ensures that a lazy app that simply grabs the first GPU will get a high-power one by default.
// If the MVK_FORCE_LOW_POWER_GPU is defined, the returned array will only include low-power devices.
static NSArray<id<MTLDevice>>* getAvailableMTLDevices() {
#if MVK_MACOS
NSArray* mtlDevs = [MTLCopyAllDevices() autorelease];
#ifdef MVK_FORCE_LOW_POWER_GPU
NSMutableArray* lpDevs = [[NSMutableArray new] autorelease];
for (id<MTLDevice> md in mtlDevs) {
if (md.isLowPower) { [lpDevs addObject: md]; }
}
return lpDevs;
#else
return [mtlDevs sortedArrayUsingComparator: ^(id<MTLDevice> md1, id<MTLDevice> md2) {
BOOL md1IsLP = md1.isLowPower;
BOOL md2IsLP = md2.isLowPower;
if (md1IsLP == md2IsLP) {
// If one device is headless and the other one is not, select the
// one that is not headless first.
BOOL md1IsHeadless = md1.isHeadless;
BOOL md2IsHeadless = md2.isHeadless;
if (md1IsHeadless == md2IsHeadless ) {
return NSOrderedSame;
}
return md2IsHeadless ? NSOrderedAscending : NSOrderedDescending;
}
return md2IsLP ? NSOrderedAscending : NSOrderedDescending;
}];
#endif // MVK_MACOS
#endif
#if MVK_IOS
return [NSArray arrayWithObject: MTLCreateSystemDefaultDevice()];
#endif
}
MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) {
_appInfo.apiVersion = MVK_VULKAN_API_VERSION; // Default
mvkSetOrClear(&_appInfo, pCreateInfo->pApplicationInfo);
initProcAddrs(); // Init function pointers
initConfig();
setConfigurationResult(verifyLayers(pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames));
MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_enabledExtensions;
setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
pCreateInfo->ppEnabledExtensionNames,
getDriverLayer()->getSupportedExtensions()));
logVersions(); // Log the MoltenVK and Vulkan versions
if (MVK_VULKAN_API_VERSION_CONFORM(MVK_VULKAN_API_VERSION) <
MVK_VULKAN_API_VERSION_CONFORM(_appInfo.apiVersion)) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, "Request for driver version %x is not compatible with provided version %x.", _appInfo.apiVersion, MVK_VULKAN_API_VERSION));
}
// Populate the array of physical GPU devices
NSArray<id<MTLDevice>>* mtlDevices = getAvailableMTLDevices();
_physicalDevices.reserve(mtlDevices.count);
for (id<MTLDevice> mtlDev in mtlDevices) {
_physicalDevices.push_back(new MVKPhysicalDevice(this, mtlDev));
}
}
#define ADD_PROC_ADDR(entrypoint) _procAddrMap[""#entrypoint] = (PFN_vkVoidFunction)&entrypoint;
/** Initializes the function pointer map. */
@ -241,6 +287,19 @@ void MVKInstance::initProcAddrs() {
ADD_PROC_ADDR(vkGetSwapchainImagesKHR);
ADD_PROC_ADDR(vkAcquireNextImageKHR);
ADD_PROC_ADDR(vkQueuePresentKHR);
ADD_PROC_ADDR(vkTrimCommandPoolKHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceFeatures2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceProperties2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceFormatProperties2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceImageFormatProperties2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceQueueFamilyProperties2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceMemoryProperties2KHR);
ADD_PROC_ADDR(vkGetPhysicalDeviceSparseImageFormatProperties2KHR);
ADD_PROC_ADDR(vkCmdPushDescriptorSetKHR);
ADD_PROC_ADDR(vkCmdPushDescriptorSetWithTemplateKHR);
ADD_PROC_ADDR(vkCreateDescriptorUpdateTemplateKHR);
ADD_PROC_ADDR(vkDestroyDescriptorUpdateTemplateKHR);
ADD_PROC_ADDR(vkUpdateDescriptorSetWithTemplateKHR);
ADD_PROC_ADDR(vkGetMoltenVKConfigurationMVK);
ADD_PROC_ADDR(vkSetMoltenVKConfigurationMVK);
ADD_PROC_ADDR(vkGetPhysicalDeviceMetalFeaturesMVK);
@ -267,7 +326,6 @@ void MVKInstance::initProcAddrs() {
ADD_PROC_ADDR(vkSetMoltenVKDeviceConfigurationMVK);
#pragma clang diagnostic pop
}
void MVKInstance::logVersions() {
@ -275,74 +333,14 @@ void MVKInstance::logVersions() {
char mvkVer[buffLen];
char vkVer[buffLen];
vkGetVersionStringsMVK(mvkVer, buffLen, vkVer, buffLen);
MVKLogInfo("MoltenVK version %s. Vulkan version %s.", mvkVer, vkVer);
}
/**
* Returns an autoreleased array containing the MTLDevices available on this system,
* sorted according to power, with higher power GPU's at the front of the array.
* This ensures that a lazy app that simply grabs the first GPU will get a high-power one by default.
* If the MVK_FORCE_LOW_POWER_GPU is defined, the returned array will only include low-power devices.
*/
static NSArray<id<MTLDevice>>* getAvailableMTLDevices() {
#if MVK_MACOS
NSArray* mtlDevs = [MTLCopyAllDevices() autorelease];
#ifdef MVK_FORCE_LOW_POWER_GPU
NSMutableArray* lpDevs = [[NSMutableArray new] autorelease];
for (id<MTLDevice> md in mtlDevs) {
if (md.isLowPower) { [lpDevs addObject: md]; }
}
return lpDevs;
#else
return [mtlDevs sortedArrayUsingComparator: ^(id<MTLDevice> md1, id<MTLDevice> md2) {
BOOL md1IsLP = md1.isLowPower;
BOOL md2IsLP = md2.isLowPower;
if (md1IsLP == md2IsLP) {
// If one device is headless and the other one is not, select the
// one that is not headless first.
BOOL md1IsHeadless = md1.isHeadless;
BOOL md2IsHeadless = md2.isHeadless;
if (md1IsHeadless == md2IsHeadless ) {
return NSOrderedSame;
}
return md2IsHeadless ? NSOrderedAscending : NSOrderedDescending;
}
return md2IsLP ? NSOrderedAscending : NSOrderedDescending;
}];
#endif // MVK_MACOS
#endif
#if MVK_IOS
return [NSArray arrayWithObject: MTLCreateSystemDefaultDevice()];
#endif
}
MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) {
_appInfo.apiVersion = MVK_VULKAN_API_VERSION; // Default
mvkSetOrClear(&_appInfo, pCreateInfo->pApplicationInfo);
logVersions(); // Log the MoltenVK and Vulkan versions
initProcAddrs(); // Init function pointers
initConfig();
// Populate the array of physical GPU devices
NSArray<id<MTLDevice>>* mtlDevices = getAvailableMTLDevices();
_physicalDevices.reserve(mtlDevices.count);
for (id<MTLDevice> mtlDev in mtlDevices) {
_physicalDevices.push_back(new MVKPhysicalDevice(this, mtlDev));
}
if (MVK_VULKAN_API_VERSION_CONFORM(MVK_VULKAN_API_VERSION) <
MVK_VULKAN_API_VERSION_CONFORM(_appInfo.apiVersion)) {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, "Request for driver version %x is not compatible with provided version %x.", _appInfo.apiVersion, MVK_VULKAN_API_VERSION));
}
setConfigurationResult(verifyLayers(pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames));
setConfigurationResult(verifyExtensions(pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames));
const char* indent = "\n\t\t";
string logMsg = "MoltenVK version %s. Vulkan version %s.";
logMsg += "\n\tThe following Vulkan extensions are supported:";
logMsg += getDriverLayer()->getSupportedExtensions()->enabledNamesString(indent, true);
logMsg += "\n\tCreated VkInstance with the following Vulkan extensions enabled:";
logMsg += _enabledExtensions.enabledNamesString(indent, true);
MVKLogInfo(logMsg.c_str(), mvkVer, vkVer);
}
// Init config.
@ -360,6 +358,16 @@ void MVKInstance::initConfig() {
_mvkConfig.metalCompileTimeout = MVK_CONFIG_METAL_COMPILE_TIMEOUT;
}
VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < count; i++) {
if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
result = mvkNotifyErrorWithText(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
}
}
return result;
}
MVKInstance::~MVKInstance() {
mvkDestroyContainerContents(_physicalDevices);
}

View File

@ -50,6 +50,17 @@ public:
/** Populates the specified shader converter context. */
void populateShaderConverterContext(SPIRVToMSLConverterContext& context);
/** Updates a descriptor set in a command encoder. */
void pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
std::vector<VkWriteDescriptorSet>& descriptorWrites,
uint32_t set);
/** Updates a descriptor set from a template in a command encoder. */
void pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
MVKDescriptorUpdateTemplate* descriptorUpdateTemplate,
uint32_t set,
const void* pData);
/** Constructs an instance for the specified device. */
MVKPipelineLayout(MVKDevice* device, const VkPipelineLayoutCreateInfo* pCreateInfo);

View File

@ -54,6 +54,30 @@ void MVKPipelineLayout::bindDescriptorSets(MVKCommandEncoder* cmdEncoder,
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
}
void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
vector<VkWriteDescriptorSet>& descriptorWrites,
uint32_t set) {
_descriptorSetLayouts[set].pushDescriptorSet(cmdEncoder, descriptorWrites,
_dslMTLResourceIndexOffsets[set]);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.vertexStage.bufferIndex);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.fragmentStage.bufferIndex);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
}
void MVKPipelineLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
MVKDescriptorUpdateTemplate* descUpdateTemplate,
uint32_t set,
const void* pData) {
_descriptorSetLayouts[set].pushDescriptorSet(cmdEncoder, descUpdateTemplate,
pData,
_dslMTLResourceIndexOffsets[set]);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.vertexStage.bufferIndex);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_FRAGMENT_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.fragmentStage.bufferIndex);
cmdEncoder->getPushConstants(VK_SHADER_STAGE_COMPUTE_BIT)->setMTLBufferIndex(_pushConstantsMTLResourceIndexOffsets.computeStage.bufferIndex);
}
void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConverterContext& context) {
context.resourceBindings.clear();

View File

@ -0,0 +1,151 @@
/*
* MVKExtensions.cpp
*
* Copyright (c) 2014-2018 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 "MVKExtensions.h"
#include "MVKFoundation.h"
#include "vk_mvk_moltenvk.h"
#include <vulkan/vulkan_ios.h>
#include <vulkan/vulkan_macos.h>
using namespace std;
// Returns a VkExtensionProperties struct populated with a name and version
static VkExtensionProperties mvkMakeExtProps(const char* extensionName, uint32_t specVersion) {
VkExtensionProperties extProps;
memset(extProps.extensionName, 0, sizeof(extProps.extensionName));
if (extensionName) { strcpy(extProps.extensionName, extensionName); }
extProps.specVersion = specVersion;
return extProps;
}
// Declares and populates a static VkExtensionProperties variable for the extention EXT,
// which should include the unique portion of the extension name, as uppercase.
// For example, for the extension VK_KHR_surface, use KHR_SURFACE.
#define MVK_MAKE_VK_EXT_PROPS(EXT) \
static VkExtensionProperties kVkExtProps_ ##EXT = mvkMakeExtProps(VK_ ##EXT ##_EXTENSION_NAME, VK_ ##EXT ##_SPEC_VERSION)
// Extension properties
MVK_MAKE_VK_EXT_PROPS(MVK_MOLTENVK);
MVK_MAKE_VK_EXT_PROPS(MVK_MACOS_SURFACE);
MVK_MAKE_VK_EXT_PROPS(MVK_IOS_SURFACE);
MVK_MAKE_VK_EXT_PROPS(KHR_SURFACE);
MVK_MAKE_VK_EXT_PROPS(KHR_SWAPCHAIN);
MVK_MAKE_VK_EXT_PROPS(KHR_MAINTENANCE1);
MVK_MAKE_VK_EXT_PROPS(IMG_FORMAT_PVRTC);
MVK_MAKE_VK_EXT_PROPS(AMD_NEGATIVE_VIEWPORT_HEIGHT);
MVK_MAKE_VK_EXT_PROPS(KHR_SHADER_DRAW_PARAMETERS);
MVK_MAKE_VK_EXT_PROPS(KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2);
MVK_MAKE_VK_EXT_PROPS(KHR_PUSH_DESCRIPTOR);
MVK_MAKE_VK_EXT_PROPS(KHR_DESCRIPTOR_UPDATE_TEMPLATE);
// Calls the constructor for a MVKExtension member variable, using the member name and the
// portion of the extension name, as uppercase, used in the MVK_MAKE_VK_EXT_PROPS() macro above.
// For example, for the memeber variable vk_KHR_surface, use MVKExt_CONSTRUCT(vk_KHR_surface, KHR_SURFACE).
#define MVKExt_CONSTRUCT(var, EXT) var(&kVkExtProps_ ##EXT, enableForPlatform)
MVKExtensionList::MVKExtensionList(bool enableForPlatform) :
MVKExt_CONSTRUCT(vk_MVK_moltenvk, MVK_MOLTENVK),
MVKExt_CONSTRUCT(vk_MVK_macos_surface, MVK_MACOS_SURFACE),
MVKExt_CONSTRUCT(vk_MVK_ios_surface, MVK_IOS_SURFACE),
MVKExt_CONSTRUCT(vk_KHR_surface, KHR_SURFACE),
MVKExt_CONSTRUCT(vk_KHR_swapchain, KHR_SWAPCHAIN),
MVKExt_CONSTRUCT(vk_KHR_maintenance1, KHR_MAINTENANCE1),
MVKExt_CONSTRUCT(vk_IMG_format_pvrtc, IMG_FORMAT_PVRTC),
MVKExt_CONSTRUCT(vk_AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT),
MVKExt_CONSTRUCT(vk_KHR_shader_draw_parameters, KHR_SHADER_DRAW_PARAMETERS),
MVKExt_CONSTRUCT(vk_KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2),
MVKExt_CONSTRUCT(vk_KHR_push_descriptor, KHR_PUSH_DESCRIPTOR),
MVKExt_CONSTRUCT(vk_KHR_descriptor_update_template, KHR_DESCRIPTOR_UPDATE_TEMPLATE)
{}
bool MVKExtensionList::isEnabled(const char* extnName) const {
uint32_t extnCnt = getCount();
const MVKExtension* extnAry = &extensionArray;
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
const MVKExtension& extn = extnAry[extnIdx];
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
return extn.enabled;
}
}
return false;
}
void MVKExtensionList::enable(const char* extnName) {
uint32_t extnCnt = getCount();
MVKExtension* extnAry = &extensionArray;
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
MVKExtension& extn = extnAry[extnIdx];
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
extn.enabled = true;
return;
}
}
}
VkResult MVKExtensionList::enable(uint32_t count, const char* const* names, MVKExtensionList* parent) {
VkResult result = VK_SUCCESS;
for (uint32_t i = 0; i < count; i++) {
auto extnName = names[i];
if (parent && !parent->isEnabled(extnName)) {
result = mvkNotifyErrorWithText(VK_ERROR_EXTENSION_NOT_PRESENT, "Vulkan extension %s is not supported.", extnName);
} else {
enable(extnName);
}
}
return result;
}
string MVKExtensionList::enabledNamesString(const char* separator, bool prefixFirstWithSeparator) const {
string logMsg;
bool isFirst = true;
uint32_t extnCnt = getCount();
const MVKExtension* extnAry = &extensionArray;
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
const MVKExtension& extn = extnAry[extnIdx];
if (extn.enabled) {
if ( !isFirst || prefixFirstWithSeparator ) { logMsg += separator; }
logMsg += extn.pProperties->extensionName;
logMsg += " v";
logMsg += to_string(extn.pProperties->specVersion);
isFirst = false;
}
}
return logMsg;
}
// Returns whether the specified properties are valid for this platform
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
#if !(MVK_IOS)
if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
#endif
#if !(MVK_MACOS)
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
#endif
if (pProperties == &kVkExtProps_AMD_NEGATIVE_VIEWPORT_HEIGHT) { return false; }
return true;
}
// Disable by default unless asked to enable for platform and the extension is valid for this platform
MVKExtension::MVKExtension(VkExtensionProperties* pProperties, bool enableForPlatform) {
this->pProperties = pProperties;
this->enabled = enableForPlatform && mvkIsSupportedOnPlatform(pProperties);
}

View File

@ -0,0 +1,83 @@
/*
* MVKExtensions.h
*
* Copyright (c) 2014-2018 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.
*/
#pragma once
#include "mvk_vulkan.h"
#include <string>
/** Describes a Vulkan extension and whether or not it is enabled or supported. */
struct MVKExtension {
bool enabled = false;
VkExtensionProperties* pProperties;
MVKExtension(VkExtensionProperties* pProperties, bool enableForPlatform = false);
};
/**
* A fixed list of the Vulkan extensions known to MoltenVK, with
* an indication of whether each extension is supported/enabled.
*
* To add support for a Vulkan extension, add a variable to this list.
*/
struct MVKExtensionList {
union {
struct {
MVKExtension vk_MVK_moltenvk;
MVKExtension vk_MVK_macos_surface;
MVKExtension vk_MVK_ios_surface;
MVKExtension vk_KHR_surface;
MVKExtension vk_KHR_swapchain;
MVKExtension vk_KHR_maintenance1;
MVKExtension vk_IMG_format_pvrtc;
MVKExtension vk_AMD_negative_viewport_height;
MVKExtension vk_KHR_shader_draw_parameters;
MVKExtension vk_KHR_get_physical_device_properties2;
MVKExtension vk_KHR_push_descriptor;
MVKExtension vk_KHR_descriptor_update_template;
};
MVKExtension extensionArray;
};
/** Returns the total number of extensions that are tracked by this object. */
static uint32_t getCount() { return sizeof(MVKExtensionList) / sizeof(MVKExtension); }
/** Returns whether the named extension is enabled. */
bool isEnabled(const char* extnName) const;
/** Enables the named extension. */
void enable(const char* extnName);
/**
* Enables the named extensions.
*
* If parent is non null, the extension must also be enabled in the parent in order
* for it to be enabled here. If it is not enabled in the parent, an error is logged
* and returned. Returns VK_SUCCESS if all requested extensions were able to be enabled.
*/
VkResult enable(uint32_t count, const char* const* names, MVKExtensionList* parent = nullptr);
/**
* Returns a string containing the names of the enabled extensions, separated by the separator string.
* If prefixFirstWithSeparator is true the separator will also appear before the first extension name.
*/
std::string enabledNamesString(const char* separator = " ", bool prefixFirstWithSeparator = false) const;
MVKExtensionList(bool enableForPlatform = false);
};

View File

@ -18,8 +18,8 @@
#pragma once
#include "mvk_vulkan.h"
#include "MVKBaseObject.h"
#include "MVKExtensions.h"
#include <vector>
@ -50,16 +50,16 @@ public:
*/
VkResult getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties);
/** Returns whether this layer supports the specified extension. */
bool hasExtensionNamed(const char* extnName);
/** Returns the list of supported extensions. */
MVKExtensionList* getSupportedExtensions() { return &_supportedExtensions; }
/** Default constructor. This represents the driver implementation. */
MVKLayer();
protected:
VkLayerProperties _layerProperties;
std::vector<VkExtensionProperties> _extensions;
MVKExtensionList _supportedExtensions;
};
@ -70,12 +70,11 @@ class MVKLayerManager : public MVKConfigurableObject {
public:
/** Returns a pointer to the driver layer. */
/** Returns the driver layer. */
MVKLayer* getDriverLayer();
/**
* Returns a pointe to the layer with the specified name,
* or null if no layer was found with that name.
* Returns the layer with the specified name, or null if no layer was found with that name.
*
* If pLayerName is null, returns the driver layer, which is
* the same layer returned by the getDriverLayer() function.

View File

@ -32,83 +32,43 @@ VkLayerProperties* const MVKLayer::getLayerProperties() { return &_layerProperti
VkResult MVKLayer::getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties) {
// If properties aren't actually being requested yet, simply update the returned count
if ( !pProperties ) {
*pCount = (uint32_t)_extensions.size();
return VK_SUCCESS;
uint32_t enabledCnt = 0;
// Iterate extensions and handle those that are enabled. Count them,
// and if they are to be returned, and there is room, do so.
uint32_t extnCnt = _supportedExtensions.getCount();
MVKExtension* extnAry = &_supportedExtensions.extensionArray;
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
if (extnAry[extnIdx].enabled) {
if (pProperties) {
if (enabledCnt < *pCount) {
pProperties[enabledCnt] = *(extnAry[extnIdx].pProperties);
} else {
return VK_INCOMPLETE;
}
}
enabledCnt++;
}
}
// Othewise, determine how many extensions we'll return, and return that count
uint32_t extCnt = (uint32_t)_extensions.size();
VkResult result = (*pCount <= extCnt) ? VK_SUCCESS : VK_INCOMPLETE;
*pCount = min(extCnt, *pCount);
// Now populate the layer properties
for (uint32_t extIdx = 0; extIdx < *pCount; extIdx++) {
pProperties[extIdx] = _extensions[extIdx];
}
return result;
}
bool MVKLayer::hasExtensionNamed(const char* extnName) {
for (auto& extn : _extensions) {
if ( strcmp(extn.extensionName, extnName) == 0 ) { return true; }
}
return false;
// Return the count of enabled extensions. This will either be a
// count of all enabled extensions, or a count of those returned.
*pCount = enabledCnt;
return VK_SUCCESS;
}
#pragma mark Object Creation
MVKLayer::MVKLayer() {
MVKLayer::MVKLayer() : _supportedExtensions(true) {
// The core driver layer
memset(_layerProperties.layerName, 0, sizeof(_layerProperties.layerName));
strcpy(_layerProperties.layerName, "MoltenVK");
memset(_layerProperties.description, 0, sizeof(_layerProperties.description));
strcpy(_layerProperties.description, "MoltenVK driver layer");
_layerProperties.specVersion = MVK_VULKAN_API_VERSION;
_layerProperties.implementationVersion = MVK_VERSION;
// Extensions
VkExtensionProperties extTmplt;
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME);
extTmplt.specVersion = VK_MVK_MOLTENVK_SPEC_VERSION;
_extensions.push_back(extTmplt);
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
extTmplt.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
_extensions.push_back(extTmplt);
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_KHR_SURFACE_EXTENSION_NAME);
extTmplt.specVersion = VK_KHR_SURFACE_SPEC_VERSION;
_extensions.push_back(extTmplt);
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME);
extTmplt.specVersion = VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION;
_extensions.push_back(extTmplt);
#if MVK_IOS
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_MVK_IOS_SURFACE_EXTENSION_NAME);
extTmplt.specVersion = VK_MVK_IOS_SURFACE_SPEC_VERSION;
_extensions.push_back(extTmplt);
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_IMG_FORMAT_PVRTC_EXTENSION_NAME);
extTmplt.specVersion = VK_IMG_FORMAT_PVRTC_SPEC_VERSION;
_extensions.push_back(extTmplt);
#endif
#if MVK_MACOS
memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName));
strcpy(extTmplt.extensionName, VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
extTmplt.specVersion = VK_MVK_MACOS_SURFACE_SPEC_VERSION;
_extensions.push_back(extTmplt);
#endif
}
@ -130,7 +90,6 @@ MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) {
return VK_NULL_HANDLE;
}
VkResult MVKLayerManager::getLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
// If properties aren't actually being requested yet, simply update the returned count

View File

@ -18,7 +18,7 @@
#pragma once
#include <vulkan/vulkan.h>
#include "mvk_vulkan.h"
#import <Metal/Metal.h>

View File

@ -18,7 +18,7 @@
#pragma once
#include <vulkan/vulkan.h>
#include "mvk_vulkan.h"
#include <vulkan/vk_icd.h>
#include <string>

View File

@ -1,5 +1,5 @@
/*
* MVKFoundation.mm
* MVKFoundation.cpp
*
* Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
@ -52,8 +52,8 @@ char* mvkResultName(VkResult vkResult, char* name) {
CASE_RESULT(VK_ERROR_VALIDATION_FAILED_EXT)
CASE_RESULT(VK_ERROR_INVALID_SHADER_NV)
CASE_RESULT(VK_ERROR_OUT_OF_POOL_MEMORY_KHR)
CASE_RESULT(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR)
CASE_RESULT(VK_ERROR_OUT_OF_POOL_MEMORY)
CASE_RESULT(VK_ERROR_INVALID_EXTERNAL_HANDLE)
default:
sprintf(name, "UNKNOWN_VkResult(%d)", vkResult);

View File

@ -20,7 +20,7 @@
#pragma once
#include <vulkan/vulkan.h>
#include "mvk_vulkan.h"
#include "MVKLogging.h"
#include <algorithm>
#include <simd/simd.h>
@ -311,11 +311,13 @@ void mvkDestroyContainerContents(C& container) {
* Iterates through the contents of the specified Objective-C object pointer
* container and releases each object, and clears the container.
*/
#ifdef __OBJC__
template<typename C>
void mvkReleaseContainerContents(C& container) {
for (auto elem : container) { [elem release]; }
container.clear();
}
#endif
/** Removes the first occurance of the specified value from the specified container. */
template<class C, class T>

View File

@ -32,7 +32,7 @@ MVK_PUBLIC_SYMBOL void vkGetMoltenVKConfigurationMVK(
MVKConfiguration* pConfiguration) {
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
if (pConfiguration) { *pConfiguration = mvkInst->_mvkConfig; }
if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkInst->getMoltenVKConfiguration(); }
}
MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKConfigurationMVK(
@ -40,7 +40,7 @@ MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKConfigurationMVK(
MVKConfiguration* pConfiguration) {
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
if (pConfiguration) { mvkInst->_mvkConfig = *pConfiguration; }
if (pConfiguration) { mvkInst->setMoltenVKConfiguration(pConfiguration); }
return VK_SUCCESS;
}
@ -142,7 +142,7 @@ MVK_PUBLIC_SYMBOL void vkGetMoltenVKDeviceConfigurationMVK(
MVKDeviceConfiguration* pConfiguration) {
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
if (pConfiguration) { *pConfiguration = mvkDev->getInstance()->_mvkConfig; }
if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkDev->getInstance()->getMoltenVKConfiguration(); }
}
MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKDeviceConfigurationMVK(
@ -150,7 +150,7 @@ MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKDeviceConfigurationMVK(
MVKDeviceConfiguration* pConfiguration) {
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
if (pConfiguration) { mvkDev->getInstance()->_mvkConfig = *pConfiguration; }
if (pConfiguration) { mvkDev->getInstance()->setMoltenVKConfiguration(pConfiguration); }
return VK_SUCCESS;
}

View File

@ -1601,6 +1601,145 @@ MVK_PUBLIC_SYMBOL VkResult vkCreate_PLATFORM_SurfaceMVK(
}
#pragma mark -
#pragma mark VK_KHR_maintenace1 extension
MVK_PUBLIC_SYMBOL void vkTrimCommandPoolKHR(
VkDevice device,
VkCommandPool commandPool,
VkCommandPoolTrimFlagsKHR flags) {
MVKCommandPool* mvkCmdPool = (MVKCommandPool*)commandPool;
mvkCmdPool->trimCommandPool();
}
#pragma mark -
#pragma mark VK_KHR_get_physical_device_properties2 extension
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceFeatures2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2KHR* pFeatures) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
mvkPD->getFeatures(pFeatures);
}
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceProperties2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2KHR* pProperties) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
mvkPD->getProperties(pProperties);
}
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceFormatProperties2KHR(
VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties2KHR* pFormatProperties) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
mvkPD->getFormatProperties(format, pFormatProperties);
}
MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceImageFormatProperties2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo,
VkImageFormatProperties2KHR* pImageFormatProperties) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
return mvkPD->getImageFormatProperties(pImageFormatInfo, pImageFormatProperties);
}
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceQueueFamilyProperties2KHR(
VkPhysicalDevice physicalDevice,
uint32_t* pQueueFamilyPropertyCount,
VkQueueFamilyProperties2KHR* pQueueFamilyProperties) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
mvkPD->getQueueFamilyProperties(pQueueFamilyPropertyCount, pQueueFamilyProperties);
}
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMemoryProperties2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties) {
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
mvkPD->getPhysicalDeviceMemoryProperties(pMemoryProperties);
}
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo,
uint32_t* pPropertyCount,
VkSparseImageFormatProperties2KHR* pProperties) {
MVKLogUnimplemented("vkGetPhysicalDeviceSparseImageFormatProperties");
}
#pragma mark -
#pragma mark VK_KHR_push_descriptor extension
MVK_PUBLIC_SYMBOL void vkCmdPushDescriptorSetKHR(
VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites) {
MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
mvkCmdPushDescriptorSet(cmdBuff, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
}
MVK_PUBLIC_SYMBOL void vkCmdPushDescriptorSetWithTemplateKHR(
VkCommandBuffer commandBuffer,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
VkPipelineLayout layout,
uint32_t set,
const void* pData) {
MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
mvkCmdPushDescriptorSetWithTemplate(cmdBuff, descriptorUpdateTemplate, layout, set, pData);
}
#pragma mark -
#pragma mark VK_KHR_descriptor_update_template extension
MVK_PUBLIC_SYMBOL VkResult vkCreateDescriptorUpdateTemplateKHR(
VkDevice device,
const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate) {
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
auto *mvkDUT = mvkDev->createDescriptorUpdateTemplate(pCreateInfo,
pAllocator);
*pDescriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)mvkDUT;
return mvkDUT->getConfigurationResult();
}
MVK_PUBLIC_SYMBOL void vkDestroyDescriptorUpdateTemplateKHR(
VkDevice device,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
const VkAllocationCallbacks* pAllocator) {
if (!descriptorUpdateTemplate) { return; }
MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
mvkDev->destroyDescriptorUpdateTemplate((MVKDescriptorUpdateTemplate*)descriptorUpdateTemplate, pAllocator);
}
MVK_PUBLIC_SYMBOL void vkUpdateDescriptorSetWithTemplateKHR(
VkDevice device,
VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
const void* pData) {
mvkUpdateDescriptorSetWithTemplate(descriptorSet, descriptorUpdateTemplate, pData);
}
#pragma mark -
#pragma mark Loader and Layer ICD interface extension

View File

@ -0,0 +1,33 @@
#!/bin/bash
set -e
export MVK_PROD_NAME="MoltenVK"
export MVK_DYLIB_NAME="lib${MVK_PROD_NAME}.dylib"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
export MVK_SYS_FWK_DIR="${SDK_DIR}/System/Library/Frameworks"
export MVK_USR_LIB_DIR="${SDK_DIR}/usr/lib"
# Do not link to IOSurface if deploying to iOS versions below 11.0, doing so will
# link IOSurface as a private framework, which will trigger App Store rejection.
if [ $(echo "${IPHONEOS_DEPLOYMENT_TARGET} >= 11.0" | bc) -eq 1 ]
then
export MVK_IOSURFACE_FWK="-framework IOSurface"
else
export MVK_IOSURFACE_FWK=""
fi
clang \
-dynamiclib \
-arch arm64 \
-mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET} \
-compatibility_version 1.0.0 -current_version 1.0.0 \
-install_name "@rpath/${MVK_DYLIB_NAME}" \
-Wno-incompatible-sysroot \
-isysroot ${SDK_DIR} \
-iframework ${MVK_SYS_FWK_DIR} \
-framework Metal ${MVK_IOSURFACE_FWK} -framework UIKit -framework QuartzCore -framework Foundation \
--library-directory ${MVK_USR_LIB_DIR} \
-lSystem -lc++ \
-o "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" \
-force_load "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}"

View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
export MVK_PROD_NAME="MoltenVK"
export MVK_DYLIB_NAME="lib${MVK_PROD_NAME}.dylib"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
export MVK_SYS_FWK_DIR="${SDK_DIR}/System/Library/Frameworks"
export MVK_USR_LIB_DIR="${SDK_DIR}/usr/lib"
clang \
-dynamiclib \
-arch x86_64 \
-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} \
-compatibility_version 1.0.0 -current_version 1.0.0 \
-install_name "@rpath/${MVK_DYLIB_NAME}" \
-Wno-incompatible-sysroot \
-isysroot ${SDK_DIR} \
-iframework ${MVK_SYS_FWK_DIR} \
-framework Metal -framework IOSurface -framework IOKit -framework QuartzCore -framework Foundation \
--library-directory ${MVK_USR_LIB_DIR} \
-lSystem -lc++ \
-o "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" \
-force_load "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}"

View File

@ -7,14 +7,40 @@
objects = {
/* Begin PBXAggregateTarget section */
A975D5782140585200D4834F /* MoltenVK-iOS */ = {
isa = PBXAggregateTarget;
buildConfigurationList = A975D5882140585200D4834F /* Build configuration list for PBXAggregateTarget "MoltenVK-iOS" */;
buildPhases = (
A975D5872140585200D4834F /* Package MoltenVK */,
);
dependencies = (
A975D5792140585200D4834F /* PBXTargetDependency */,
A975D57D2140585200D4834F /* PBXTargetDependency */,
A975D5812140585200D4834F /* PBXTargetDependency */,
);
name = "MoltenVK-iOS";
productName = Package;
};
A975D58B2140586700D4834F /* MoltenVK-macOS */ = {
isa = PBXAggregateTarget;
buildConfigurationList = A975D59B2140586700D4834F /* Build configuration list for PBXAggregateTarget "MoltenVK-macOS" */;
buildPhases = (
A975D59A2140586700D4834F /* Package MoltenVK */,
);
dependencies = (
A975D58E2140586700D4834F /* PBXTargetDependency */,
A975D5922140586700D4834F /* PBXTargetDependency */,
A975D5962140586700D4834F /* PBXTargetDependency */,
A975D5982140586700D4834F /* PBXTargetDependency */,
);
name = "MoltenVK-macOS";
productName = Package;
};
A9FEADBC1F3517480010240E /* MoltenVK */ = {
isa = PBXAggregateTarget;
buildConfigurationList = A9FEADDC1F3517480010240E /* Build configuration list for PBXAggregateTarget "MoltenVK" */;
buildPhases = (
A9FEADD61F3517480010240E /* Package MoltenVK */,
A9FEADD71F3517480010240E /* Package MoltenVKShaderConverter */,
A9A5D8A61FB3AABA00F20475 /* Package Docs */,
A9FEADDB1F3517480010240E /* Update Latest */,
);
dependencies = (
A9FEADBD1F3517480010240E /* PBXTargetDependency */,
@ -45,6 +71,55 @@
remoteGlobalIDString = A9CBEE011B6299D800E45FDC;
remoteInfo = "MoltenVK-macOS";
};
A975D57A2140585200D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB3EE1CE0F72500FBC835 /* MoltenVK.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A9B8EE091A98D796009C5A02;
remoteInfo = "MoltenVK-iOS";
};
A975D57E2140585200D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A93903B81C57E9D700FE90DC;
remoteInfo = "MoltenVKSPIRVToMSLConverter-iOS";
};
A975D5822140585200D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A937472B1A9A8B2900F29B34;
remoteInfo = "MoltenVKGLSLToSPIRVConverter-iOS";
};
A975D58F2140586700D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB3EE1CE0F72500FBC835 /* MoltenVK.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A9CBED861B6299D800E45FDC;
remoteInfo = "MoltenVK-macOS";
};
A975D5932140586700D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A93903C01C57E9ED00FE90DC;
remoteInfo = "MoltenVKSPIRVToMSLConverter-macOS";
};
A975D5972140586700D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A93747701A9A98D000F29B34;
remoteInfo = "MoltenVKGLSLToSPIRVConverter-macOS";
};
A975D5992140586700D4834F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A9092A8C1A81717B00051823;
remoteInfo = MoltenVKShaderConverter;
};
A981498A1FB6B566005F00B4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */;
@ -138,6 +213,13 @@
A92DB3EE1CE0F72500FBC835 /* MoltenVK.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MoltenVK.xcodeproj; path = MoltenVK/MoltenVK.xcodeproj; sourceTree = "<group>"; };
A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MoltenVKShaderConverter.xcodeproj; path = MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj; sourceTree = "<group>"; };
A943100220546CDD00F5CF87 /* fetchDependencies */ = {isa = PBXFileReference; lastKnownFileType = text; name = fetchDependencies; path = ../fetchDependencies; sourceTree = "<group>"; };
A975D55C213F25D700D4834F /* create_dylib_ios.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = create_dylib_ios.sh; path = MoltenVK/scripts/create_dylib_ios.sh; sourceTree = SOURCE_ROOT; };
A975D55D213F266000D4834F /* create_dylib_macos.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = create_dylib_macos.sh; path = MoltenVK/scripts/create_dylib_macos.sh; sourceTree = SOURCE_ROOT; };
A975D561213F299500D4834F /* update_latest.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = update_latest.sh; sourceTree = "<group>"; };
A975D562213F2B7700D4834F /* package_docs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_docs.sh; sourceTree = "<group>"; };
A975D566213F2DAA00D4834F /* package_shader_converter.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_shader_converter.sh; sourceTree = "<group>"; };
A975D573214050AB00D4834F /* package_moltenvk.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_moltenvk.sh; sourceTree = "<group>"; };
A975D5742140567B00D4834F /* package_all.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_all.sh; sourceTree = "<group>"; };
A98149E51FB78829005F00B4 /* MoltenVK_Runtime_UserGuide.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = MoltenVK_Runtime_UserGuide.md; path = Docs/MoltenVK_Runtime_UserGuide.md; sourceTree = "<group>"; };
A9AD67D12054E2D700ED3C08 /* VulkanSamples_repo_revision */ = {isa = PBXFileReference; lastKnownFileType = text; path = VulkanSamples_repo_revision; sourceTree = "<group>"; };
A9AD67D32054E2D700ED3C08 /* SPIRV-Cross_repo_revision */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SPIRV-Cross_repo_revision"; sourceTree = "<group>"; };
@ -154,6 +236,7 @@
children = (
A92DB3EE1CE0F72500FBC835 /* MoltenVK.xcodeproj */,
A92DB40E1CE0F89600FBC835 /* MoltenVKShaderConverter.xcodeproj */,
A975D55B213F25AD00D4834F /* Scripts */,
A92DB3E11CE0F34500FBC835 /* Docs */,
A939A6FB1F5479D0006ACA0C /* External */,
);
@ -195,6 +278,20 @@
path = ExternalRevisions;
sourceTree = "<group>";
};
A975D55B213F25AD00D4834F /* Scripts */ = {
isa = PBXGroup;
children = (
A975D55C213F25D700D4834F /* create_dylib_ios.sh */,
A975D55D213F266000D4834F /* create_dylib_macos.sh */,
A975D5742140567B00D4834F /* package_all.sh */,
A975D562213F2B7700D4834F /* package_docs.sh */,
A975D573214050AB00D4834F /* package_moltenvk.sh */,
A975D566213F2DAA00D4834F /* package_shader_converter.sh */,
A975D561213F299500D4834F /* update_latest.sh */,
);
path = Scripts;
sourceTree = "<group>";
};
A98149741FB6B565005F00B4 /* Products */ = {
isa = PBXGroup;
children = (
@ -242,6 +339,8 @@
projectRoot = "";
targets = (
A9FEADBC1F3517480010240E /* MoltenVK */,
A975D5782140585200D4834F /* MoltenVK-iOS */,
A975D58B2140586700D4834F /* MoltenVK-macOS */,
);
};
/* End PBXProject section */
@ -299,19 +398,33 @@
/* End PBXReferenceProxy section */
/* Begin PBXShellScriptBuildPhase section */
A9A5D8A61FB3AABA00F20475 /* Package Docs */ = {
A975D5872140585200D4834F /* Package MoltenVK */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Package Docs";
name = "Package MoltenVK";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\n# Package folder\nexport MVK_WKSPC_PATH=\"${PROJECT_DIR}\"\nexport MVK_PKG_LOCN=\"${MVK_WKSPC_PATH}/Package\"\nexport MVK_PKG_CONFIG_PATH=\"${MVK_PKG_LOCN}/${CONFIGURATION}\"\n\n# Copy the docs. Allow silent fail if a symlinked doc is not built.\ncp -a \"${MVK_WKSPC_PATH}/LICENSE\" \"${MVK_PKG_CONFIG_PATH}\"\ncp -pRLf \"${MVK_WKSPC_PATH}/Docs\" \"${MVK_PKG_CONFIG_PATH}\" 2> /dev/null || true\n";
shellScript = "${SRCROOT}/Scripts/package_all.sh";
};
A975D59A2140586700D4834F /* Package MoltenVK */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Package MoltenVK";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "${SRCROOT}/Scripts/package_all.sh";
};
A9FEADD61F3517480010240E /* Package MoltenVK */ = {
isa = PBXShellScriptBuildPhase;
@ -325,39 +438,46 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\n# Package folder\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_ICD_NAME=\"${MVK_PROD_NAME}_icd.json\"\nexport MVK_WKSPC_PATH=\"${PROJECT_DIR}\"\nexport MVK_PROD_PROJ_PATH=\"${MVK_WKSPC_PATH}/${MVK_PROD_NAME}\"\nexport MVK_PKG_LOCN=\"${MVK_WKSPC_PATH}/Package\"\nexport MVK_PKG_CONFIG_PATH=\"${MVK_PKG_LOCN}/${CONFIGURATION}\"\nexport MVK_PKG_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/${MVK_PROD_NAME}\"\n\n# Remove the product folder\nrm -rf \"${MVK_PKG_PROD_PATH}\"\n\n# Remove and replace the existing macOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_PROD_PATH}/macOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_PROD_PROJ_PATH}/icd/${MVK_ICD_NAME}\" \"${MVK_OS_PROD_PATH}\"\n\n# Remove and replace the existing iOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_PROD_PATH}/iOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}-iphoneos\"\nrm -rf \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_PROD_PROJ_PATH}/icd/${MVK_ICD_NAME}\" \"${MVK_OS_PROD_PATH}\"\n\n# Remove and replace header include folder\nrm -rf \"${MVK_PKG_PROD_PATH}/include\"\ncp -pRL \"${MVK_PROD_PROJ_PATH}/include\" \"${MVK_PKG_PROD_PATH}\"";
};
A9FEADD71F3517480010240E /* Package MoltenVKShaderConverter */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Package MoltenVKShaderConverter";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\n# Package folder\nexport MVK_PROD_BASE_NAME=\"MoltenVKShaderConverter\"\nexport MVK_WKSPC_PATH=\"${PROJECT_DIR}\"\nexport MVK_PKG_LOCN=\"${MVK_WKSPC_PATH}/Package\"\n\n# Remove the base product folder\nrm -rf \"${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}\"\n\n#-----------------------------------\n# MoltenVKGLSLToSPIRVConverter\nexport MVK_PROD_NAME=\"MoltenVKGLSLToSPIRVConverter\"\nexport MVK_PKG_CONFIG_PATH=\"${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}/${MVK_PROD_NAME}\"\n\n# Remove and replace the existing macOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/macOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\n\n# Remove and replace the existing iOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/iOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}-iphoneos\"\nrm -rf \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\n\n#-----------------------------------\n# MoltenVKSPIRVToMSLConverter\nexport MVK_PROD_NAME=\"MoltenVKSPIRVToMSLConverter\"\nexport MVK_PKG_CONFIG_PATH=\"${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}/${MVK_PROD_NAME}\"\n\n# Remove and replace the existing macOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/macOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\n\n# Remove and replace the existing iOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/iOS\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}-iphoneos\"\nrm -rf \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework\" \"${MVK_OS_PROD_PATH}\"\n\n#-----------------------------------\n# MoltenVKShaderConverter Tool\nexport MVK_PROD_NAME=\"MoltenVKShaderConverter\"\nexport MVK_PKG_CONFIG_PATH=\"${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}\"\n\n# Remove and replace the existing macOS framework folder and copy framework into it\nexport MVK_OS_PROD_PATH=\"${MVK_PKG_CONFIG_PATH}/Tools\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nrm -rf \"${MVK_OS_PROD_PATH}\"\nmkdir -p \"${MVK_OS_PROD_PATH}\"\ncp -a \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}\" \"${MVK_OS_PROD_PATH}\"\n";
};
A9FEADDB1F3517480010240E /* Update Latest */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Update Latest";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\n# Package folder\nexport MVK_WKSPC_LOCN=\"${PROJECT_DIR}\"\nexport MVK_PKG_LOCN=\"${MVK_WKSPC_LOCN}/Package\"\n\n# Configuration package folder location\nexport MVK_PKG_CONFIG_LOCN=\"${CONFIGURATION}\"\nexport MVK_PKG_LATEST_LOCN=\"Latest\"\n\n# Assign symlink from Latest\nln -sfn \"${MVK_PKG_LOCN}/${MVK_PKG_CONFIG_LOCN}\" \"${MVK_PKG_LOCN}/${MVK_PKG_LATEST_LOCN}\"";
shellScript = "${SRCROOT}/Scripts/package_all.sh";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXTargetDependency section */
A975D5792140585200D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVK-iOS";
targetProxy = A975D57A2140585200D4834F /* PBXContainerItemProxy */;
};
A975D57D2140585200D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKSPIRVToMSLConverter-iOS";
targetProxy = A975D57E2140585200D4834F /* PBXContainerItemProxy */;
};
A975D5812140585200D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKGLSLToSPIRVConverter-iOS";
targetProxy = A975D5822140585200D4834F /* PBXContainerItemProxy */;
};
A975D58E2140586700D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVK-macOS";
targetProxy = A975D58F2140586700D4834F /* PBXContainerItemProxy */;
};
A975D5922140586700D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKSPIRVToMSLConverter-macOS";
targetProxy = A975D5932140586700D4834F /* PBXContainerItemProxy */;
};
A975D5962140586700D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKGLSLToSPIRVConverter-macOS";
targetProxy = A975D5972140586700D4834F /* PBXContainerItemProxy */;
};
A975D5982140586700D4834F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = MoltenVKShaderConverter;
targetProxy = A975D5992140586700D4834F /* PBXContainerItemProxy */;
};
A98149CB1FB7689D005F00B4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = MoltenVKShaderConverter;
@ -408,10 +528,37 @@
};
name = Release;
};
A975D5892140585200D4834F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
A975D58A2140585200D4834F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
A975D59C2140586700D4834F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
A975D59D2140586700D4834F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
A9FEADDD1F3517480010240E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -419,7 +566,6 @@
A9FEADDE1F3517480010240E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -436,6 +582,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A975D5882140585200D4834F /* Build configuration list for PBXAggregateTarget "MoltenVK-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A975D5892140585200D4834F /* Debug */,
A975D58A2140585200D4834F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A975D59B2140586700D4834F /* Build configuration list for PBXAggregateTarget "MoltenVK-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A975D59C2140586700D4834F /* Debug */,
A975D59D2140586700D4834F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A9FEADDC1F3517480010240E /* Build configuration list for PBXAggregateTarget "MoltenVK" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D5782140585200D4834F"
BuildableName = "MoltenVK-iOS"
BlueprintName = "MoltenVK-iOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A975D58B2140586700D4834F"
BuildableName = "MoltenVK-macOS"
BlueprintName = "MoltenVK-macOS"
ReferencedContainer = "container:MoltenVKPackaging.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

7
Scripts/package_all.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
${SRCROOT}/Scripts/package_moltenvk.sh
${SRCROOT}/Scripts/package_shader_converter.sh
${SRCROOT}/Scripts/package_docs.sh
${SRCROOT}/Scripts/update_latest.sh

12
Scripts/package_docs.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
# Package folder
export MVK_WKSPC_PATH="${PROJECT_DIR}"
export MVK_PKG_LOCN="${MVK_WKSPC_PATH}/Package"
export MVK_PKG_CONFIG_PATH="${MVK_PKG_LOCN}/${CONFIGURATION}"
# Copy the docs. Allow silent fail if a symlinked doc is not built.
cp -a "${MVK_WKSPC_PATH}/LICENSE" "${MVK_PKG_CONFIG_PATH}"
cp -pRLf "${MVK_WKSPC_PATH}/Docs" "${MVK_PKG_CONFIG_PATH}" 2> /dev/null || true

43
Scripts/package_moltenvk.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
set -e
# Package folder
export MVK_PROD_NAME="MoltenVK"
export MVK_DYLIB_NAME="lib${MVK_PROD_NAME}.dylib"
export MVK_ICD_NAME="${MVK_PROD_NAME}_icd.json"
export MVK_WKSPC_PATH="${PROJECT_DIR}"
export MVK_PROD_PROJ_PATH="${MVK_WKSPC_PATH}/${MVK_PROD_NAME}"
export MVK_PKG_LOCN="${MVK_WKSPC_PATH}/Package"
export MVK_PKG_CONFIG_PATH="${MVK_PKG_LOCN}/${CONFIGURATION}"
export MVK_PKG_PROD_PATH="${MVK_PKG_CONFIG_PATH}/${MVK_PROD_NAME}"
# Remove the product folder
rm -rf "${MVK_PKG_PROD_PATH}"
# Remove and replace the existing macOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_PROD_PATH}/macOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" "${MVK_OS_PROD_PATH}"
cp -a "${MVK_PROD_PROJ_PATH}/icd/${MVK_ICD_NAME}" "${MVK_OS_PROD_PATH}"
fi
# Remove and replace the existing iOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_PROD_PATH}/iOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}-iphoneos"
rm -rf "${MVK_OS_PROD_PATH}"
echo MVK_BUILT_PROD_PATH = "${MVK_BUILT_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
rm -rf "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature"
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" "${MVK_OS_PROD_PATH}"
cp -a "${MVK_PROD_PROJ_PATH}/icd/${MVK_ICD_NAME}" "${MVK_OS_PROD_PATH}"
fi
# Remove and replace header include folder
rm -rf "${MVK_PKG_PROD_PATH}/include"
cp -pRL "${MVK_PROD_PROJ_PATH}/include" "${MVK_PKG_PROD_PATH}"

View File

@ -0,0 +1,73 @@
#!/bin/bash
set -e
# Package folder
export MVK_PROD_BASE_NAME="MoltenVKShaderConverter"
export MVK_WKSPC_PATH="${PROJECT_DIR}"
export MVK_PKG_LOCN="${MVK_WKSPC_PATH}/Package"
# Remove the base product folder
rm -rf "${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}"
#-----------------------------------
# MoltenVKGLSLToSPIRVConverter
export MVK_PROD_NAME="MoltenVKGLSLToSPIRVConverter"
export MVK_PKG_CONFIG_PATH="${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}/${MVK_PROD_NAME}"
# Remove and replace the existing macOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_CONFIG_PATH}/macOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
fi
# Remove and replace the existing iOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_CONFIG_PATH}/iOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}-iphoneos"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
rm -rf "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature"
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
fi
#-----------------------------------
# MoltenVKSPIRVToMSLConverter
export MVK_PROD_NAME="MoltenVKSPIRVToMSLConverter"
export MVK_PKG_CONFIG_PATH="${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}/${MVK_PROD_NAME}"
# Remove and replace the existing macOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_CONFIG_PATH}/macOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
fi
# Remove and replace the existing iOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_CONFIG_PATH}/iOS"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}-iphoneos"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
rm -rf "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/_CodeSignature"
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_OS_PROD_PATH}"
fi
#-----------------------------------
# MoltenVKShaderConverter Tool
export MVK_PROD_NAME="MoltenVKShaderConverter"
export MVK_PKG_CONFIG_PATH="${MVK_PKG_LOCN}/${CONFIGURATION}/${MVK_PROD_BASE_NAME}"
# Remove and replace the existing macOS framework folder and copy framework into it
export MVK_OS_PROD_PATH="${MVK_PKG_CONFIG_PATH}/Tools"
export MVK_BUILT_PROD_PATH="${BUILT_PRODUCTS_DIR}"
rm -rf "${MVK_OS_PROD_PATH}"
if [ -e "${MVK_BUILT_PROD_PATH}" ]; then
mkdir -p "${MVK_OS_PROD_PATH}"
cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}" "${MVK_OS_PROD_PATH}"
fi

14
Scripts/update_latest.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# Package folder
export MVK_WKSPC_LOCN="${PROJECT_DIR}"
export MVK_PKG_LOCN="${MVK_WKSPC_LOCN}/Package"
# Configuration package folder location
export MVK_PKG_CONFIG_LOCN="${CONFIGURATION}"
export MVK_PKG_LATEST_LOCN="Latest"
# Assign symlink from Latest
ln -sfn "${MVK_PKG_LOCN}/${MVK_PKG_CONFIG_LOCN}" "${MVK_PKG_LOCN}/${MVK_PKG_LATEST_LOCN}"