Merge pull request #872 from billhollings/master
Add support for VK_KHR_external_memory extension.
This commit is contained in:
commit
5fe0b91fc7
@ -19,6 +19,12 @@ MoltenVK 1.0.42
|
||||
|
||||
Released TBD
|
||||
|
||||
- Add support for extensions:
|
||||
- `VK_KHR_external_memory` (non-functional groundwork for future
|
||||
Metal-resource Vulkan extension).
|
||||
- `VK_KHR_external_memory_capabilities` (non-functional groundwork
|
||||
for future Metal-resource Vulkan extension).
|
||||
- Memory consumption improvements when handling Vulkan commands.
|
||||
- Reinstate `VulkanSamples API-Samples` demo apps and add
|
||||
`input_attachment` and `push_descriptors` demos.
|
||||
- `vkQueuePresentKHR()` returns a `VkResult` for each swapchain.
|
||||
|
@ -261,18 +261,17 @@ VkResult MVKCmdPushDescriptorSet::setContent(MVKCommandBuffer* cmdBuff,
|
||||
}
|
||||
if (mvkDvc->_enabledExtensions.vk_EXT_inline_uniform_block.enabled) {
|
||||
const VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock = nullptr;
|
||||
for (auto* next = (VkWriteDescriptorSetInlineUniformBlockEXT*)descWrite.pNext; next; next = (VkWriteDescriptorSetInlineUniformBlockEXT*)next->pNext)
|
||||
{
|
||||
for (const auto* next = (VkBaseInStructure*)descWrite.pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
pInlineUniformBlock = next;
|
||||
pInlineUniformBlock = (VkWriteDescriptorSetInlineUniformBlockEXT*)next;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pInlineUniformBlock != nullptr) {
|
||||
if (pInlineUniformBlock) {
|
||||
auto *pNewInlineUniformBlock = new VkWriteDescriptorSetInlineUniformBlockEXT(*pInlineUniformBlock);
|
||||
pNewInlineUniformBlock->pNext = nullptr; // clear pNext just in case, no other extensions are supported at this time
|
||||
descWrite.pNext = pNewInlineUniformBlock;
|
||||
@ -300,11 +299,10 @@ void MVKCmdPushDescriptorSet::clearDescriptorWrites() {
|
||||
if (descWrite.pTexelBufferView) { delete[] descWrite.pTexelBufferView; }
|
||||
|
||||
const VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock = nullptr;
|
||||
for (auto* next = (VkWriteDescriptorSetInlineUniformBlockEXT*)descWrite.pNext; next; next = (VkWriteDescriptorSetInlineUniformBlockEXT*)next->pNext)
|
||||
{
|
||||
for (const auto* next = (VkBaseInStructure*)descWrite.pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
pInlineUniformBlock = next;
|
||||
pInlineUniformBlock = (VkWriteDescriptorSetInlineUniformBlockEXT*)next;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -48,6 +48,9 @@ public:
|
||||
/** Binds this resource to the specified offset within the specified memory allocation. */
|
||||
VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;
|
||||
|
||||
/** Binds this resource to the specified offset within the specified memory allocation. */
|
||||
VkResult bindDeviceMemory2(const VkBindBufferMemoryInfo* pBindInfo);
|
||||
|
||||
/** Applies the specified global memory barrier. */
|
||||
void applyMemoryBarrier(VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
@ -92,6 +95,7 @@ protected:
|
||||
bool shouldFlushHostMemory();
|
||||
VkResult flushToDevice(VkDeviceSize offset, VkDeviceSize size);
|
||||
VkResult pullFromDevice(VkDeviceSize offset, VkDeviceSize size);
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
|
||||
VkBufferUsageFlags _usage;
|
||||
bool _isHostCoherentTexelBuffer = false;
|
||||
|
@ -66,8 +66,8 @@ VkResult MVKBuffer::getMemoryRequirements(const void*, VkMemoryRequirements2* pM
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
||||
auto* dedicatedReqs = (VkMemoryDedicatedRequirements*)next;
|
||||
dedicatedReqs->prefersDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = _requiresDedicatedMemoryAllocation;
|
||||
dedicatedReqs->prefersDedicatedAllocation = dedicatedReqs->requiresDedicatedAllocation;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -93,6 +93,10 @@ VkResult MVKBuffer::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOf
|
||||
return _deviceMemory ? _deviceMemory->addBuffer(this) : VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult MVKBuffer::bindDeviceMemory2(const VkBindBufferMemoryInfo* pBindInfo) {
|
||||
return bindDeviceMemory((MVKDeviceMemory*)pBindInfo->memory, pBindInfo->memoryOffset);
|
||||
}
|
||||
|
||||
void MVKBuffer::applyMemoryBarrier(VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
VkMemoryBarrier* pMemoryBarrier,
|
||||
@ -192,6 +196,28 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
MVKBuffer::MVKBuffer(MVKDevice* device, const VkBufferCreateInfo* pCreateInfo) : MVKResource(device), _usage(pCreateInfo->usage) {
|
||||
_byteAlignment = _device->_pMetalFeatures->mtlBufferAlignment;
|
||||
_byteCount = pCreateInfo->size;
|
||||
|
||||
for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO: {
|
||||
auto* pExtMemInfo = (const VkExternalMemoryBufferCreateInfo*)next;
|
||||
initExternalMemory(pExtMemInfo->handleTypes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MVKBuffer::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) {
|
||||
_externalMemoryHandleTypes = handleTypes;
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR);
|
||||
_requiresDedicatedMemoryAllocation = _requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
} else {
|
||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateBuffer(): Only external memory handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR is supported."));
|
||||
}
|
||||
}
|
||||
|
||||
MVKBuffer::~MVKBuffer() {
|
||||
|
@ -109,11 +109,10 @@ void MVKDescriptorSetLayout::pushDescriptorSet(MVKCommandEncoder* cmdEncoder,
|
||||
const VkBufferView* pTexelBufferView = descWrite.pTexelBufferView;
|
||||
const VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock = nullptr;
|
||||
if (_device->_enabledExtensions.vk_EXT_inline_uniform_block.enabled) {
|
||||
for (auto* next = (VkWriteDescriptorSetInlineUniformBlockEXT*)descWrite.pNext; next; next = (VkWriteDescriptorSetInlineUniformBlockEXT*)next->pNext)
|
||||
{
|
||||
for (const auto* next = (VkBaseInStructure*)descWrite.pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
pInlineUniformBlock = next;
|
||||
pInlineUniformBlock = (VkWriteDescriptorSetInlineUniformBlockEXT*)next;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -689,11 +688,10 @@ void mvkUpdateDescriptorSets(uint32_t writeCount,
|
||||
|
||||
const VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock = nullptr;
|
||||
if (dstSet->getDevice()->_enabledExtensions.vk_EXT_inline_uniform_block.enabled) {
|
||||
for (auto* next = (VkWriteDescriptorSetInlineUniformBlockEXT*)pDescWrite->pNext; next; next = (VkWriteDescriptorSetInlineUniformBlockEXT*)next->pNext)
|
||||
{
|
||||
for (const auto* next = (VkBaseInStructure*)pDescWrite->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
pInlineUniformBlock = next;
|
||||
pInlineUniformBlock = (VkWriteDescriptorSetInlineUniformBlockEXT*)next;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -117,12 +117,9 @@ public:
|
||||
void getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties);
|
||||
|
||||
/** Populates the specified structure with the format properties of this device. */
|
||||
void getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties);
|
||||
void getFormatProperties(VkFormat format, VkFormatProperties2* pFormatProperties);
|
||||
|
||||
/**
|
||||
* Populates the specified structure with the image format properties
|
||||
* supported for the specified image characteristics on this device.
|
||||
*/
|
||||
/** Populates the image format properties supported on this device. */
|
||||
VkResult getImageFormatProperties(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
@ -130,12 +127,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);
|
||||
/** Populates the image format properties supported on this device. */
|
||||
VkResult getImageFormatProperties(const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
|
||||
VkImageFormatProperties2* pImageFormatProperties);
|
||||
|
||||
/** Populates the external buffer properties supported on this device. */
|
||||
void getExternalBufferProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
|
||||
VkExternalBufferProperties* pExternalBufferProperties);
|
||||
|
||||
#pragma mark Surfaces
|
||||
|
||||
@ -244,13 +242,13 @@ public:
|
||||
#pragma mark Memory models
|
||||
|
||||
/** Returns a pointer to the memory characteristics of this device. */
|
||||
inline const VkPhysicalDeviceMemoryProperties* getPhysicalDeviceMemoryProperties() { return &_memoryProperties; }
|
||||
inline const VkPhysicalDeviceMemoryProperties* getMemoryProperties() { return &_memoryProperties; }
|
||||
|
||||
/** Populates the specified memory properties with the memory characteristics of this device. */
|
||||
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties);
|
||||
VkResult getMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties);
|
||||
|
||||
/** Populates the specified memory properties with the memory characteristics of this device. */
|
||||
VkResult getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
|
||||
VkResult getMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
|
||||
|
||||
/**
|
||||
* Returns a bit mask of all memory type indices.
|
||||
@ -285,6 +283,12 @@ public:
|
||||
/** Returns whether this is a unified memory device. */
|
||||
bool getHasUnifiedMemory();
|
||||
|
||||
/** Returns the external memory properties supported for buffers for the handle type. */
|
||||
VkExternalMemoryProperties& getExternalBufferProperties(VkExternalMemoryHandleTypeFlagBits handleType);
|
||||
|
||||
/** Returns the external memory properties supported for images for the handle type. */
|
||||
VkExternalMemoryProperties& getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType);
|
||||
|
||||
|
||||
#pragma mark Metal
|
||||
|
||||
@ -339,12 +343,14 @@ protected:
|
||||
uint64_t getVRAMSize();
|
||||
uint64_t getRecommendedMaxWorkingSetSize();
|
||||
uint64_t getCurrentAllocatedSize();
|
||||
void initExternalMemoryProperties();
|
||||
void initExtensions();
|
||||
MVKVector<MVKQueueFamily*>& getQueueFamilies();
|
||||
void initPipelineCacheUUID();
|
||||
uint32_t getHighestMTLFeatureSet();
|
||||
uint64_t getSpirvCrossRevision();
|
||||
bool getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo);
|
||||
bool getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo);
|
||||
void populate(VkPhysicalDeviceIDProperties* pDevIdProps);
|
||||
void logGPUInfo();
|
||||
|
||||
id<MTLDevice> _mtlDevice;
|
||||
@ -362,6 +368,8 @@ protected:
|
||||
uint32_t _hostCoherentMemoryTypes;
|
||||
uint32_t _privateMemoryTypes;
|
||||
uint32_t _lazilyAllocatedMemoryTypes;
|
||||
VkExternalMemoryProperties _mtlBufferExternalMemoryProperties;
|
||||
VkExternalMemoryProperties _mtlTextureExternalMemoryProperties;
|
||||
};
|
||||
|
||||
|
||||
|
@ -62,166 +62,216 @@ VkResult MVKPhysicalDevice::getExtensionProperties(const char* pLayerName, uint3
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures* features) {
|
||||
if (features) { *features = _features; }
|
||||
*features = _features;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
||||
if (features) {
|
||||
features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
features->features = _features;
|
||||
for (auto* next = (VkBaseOutStructure*)features->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
||||
auto* storageFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
|
||||
storageFeatures->storageBuffer16BitAccess = true;
|
||||
storageFeatures->uniformAndStorageBuffer16BitAccess = true;
|
||||
storageFeatures->storagePushConstant16 = true;
|
||||
storageFeatures->storageInputOutput16 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
|
||||
auto* storageFeatures = (VkPhysicalDevice8BitStorageFeaturesKHR*)next;
|
||||
storageFeatures->storageBuffer8BitAccess = true;
|
||||
storageFeatures->uniformAndStorageBuffer8BitAccess = true;
|
||||
storageFeatures->storagePushConstant8 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
|
||||
auto* f16Features = (VkPhysicalDeviceFloat16Int8FeaturesKHR*)next;
|
||||
f16Features->shaderFloat16 = true;
|
||||
f16Features->shaderInt8 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
|
||||
auto* uboLayoutFeatures = (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR*)next;
|
||||
uboLayoutFeatures->uniformBufferStandardLayout = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
|
||||
auto* varPtrFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next;
|
||||
varPtrFeatures->variablePointersStorageBuffer = true;
|
||||
varPtrFeatures->variablePointers = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
|
||||
auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
|
||||
interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
|
||||
interlockFeatures->fragmentShaderPixelInterlock = _metalFeatures.rasterOrderGroups;
|
||||
interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
|
||||
auto* hostQueryResetFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
|
||||
hostQueryResetFeatures->hostQueryReset = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
|
||||
auto* scalarLayoutFeatures = (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT*)next;
|
||||
scalarLayoutFeatures->scalarBlockLayout = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
|
||||
auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
|
||||
texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)];
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
|
||||
auto* divisorFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
|
||||
divisorFeatures->vertexAttributeInstanceRateDivisor = true;
|
||||
divisorFeatures->vertexAttributeInstanceRateZeroDivisor = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX: {
|
||||
auto* portabilityFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesEXTX*)next;
|
||||
portabilityFeatures->triangleFans = false;
|
||||
portabilityFeatures->separateStencilMaskRef = true;
|
||||
portabilityFeatures->events = true;
|
||||
portabilityFeatures->standardImageViews = _mvkInstance->getMoltenVKConfiguration()->fullImageViewSwizzle || _metalFeatures.nativeTextureSwizzle;
|
||||
portabilityFeatures->samplerMipLodBias = false;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: {
|
||||
auto* shaderIntFuncsFeatures = (VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL*)next;
|
||||
shaderIntFuncsFeatures->shaderIntegerFunctions2 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
|
||||
auto* inlineUniformBlockFeatures = (VkPhysicalDeviceInlineUniformBlockFeaturesEXT*)next;
|
||||
inlineUniformBlockFeatures->inlineUniformBlock = true;
|
||||
inlineUniformBlockFeatures->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
features->features = _features;
|
||||
for (auto* next = (VkBaseOutStructure*)features->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
||||
auto* storageFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
|
||||
storageFeatures->storageBuffer16BitAccess = true;
|
||||
storageFeatures->uniformAndStorageBuffer16BitAccess = true;
|
||||
storageFeatures->storagePushConstant16 = true;
|
||||
storageFeatures->storageInputOutput16 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
|
||||
auto* storageFeatures = (VkPhysicalDevice8BitStorageFeaturesKHR*)next;
|
||||
storageFeatures->storageBuffer8BitAccess = true;
|
||||
storageFeatures->uniformAndStorageBuffer8BitAccess = true;
|
||||
storageFeatures->storagePushConstant8 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
|
||||
auto* f16Features = (VkPhysicalDeviceFloat16Int8FeaturesKHR*)next;
|
||||
f16Features->shaderFloat16 = true;
|
||||
f16Features->shaderInt8 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
|
||||
auto* uboLayoutFeatures = (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR*)next;
|
||||
uboLayoutFeatures->uniformBufferStandardLayout = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
|
||||
auto* varPtrFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next;
|
||||
varPtrFeatures->variablePointersStorageBuffer = true;
|
||||
varPtrFeatures->variablePointers = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
|
||||
auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
|
||||
interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
|
||||
interlockFeatures->fragmentShaderPixelInterlock = _metalFeatures.rasterOrderGroups;
|
||||
interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
|
||||
auto* hostQueryResetFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
|
||||
hostQueryResetFeatures->hostQueryReset = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
|
||||
auto* scalarLayoutFeatures = (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT*)next;
|
||||
scalarLayoutFeatures->scalarBlockLayout = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
|
||||
auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
|
||||
texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)];
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
|
||||
auto* divisorFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
|
||||
divisorFeatures->vertexAttributeInstanceRateDivisor = true;
|
||||
divisorFeatures->vertexAttributeInstanceRateZeroDivisor = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX: {
|
||||
auto* portabilityFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesEXTX*)next;
|
||||
portabilityFeatures->triangleFans = false;
|
||||
portabilityFeatures->separateStencilMaskRef = true;
|
||||
portabilityFeatures->events = true;
|
||||
portabilityFeatures->standardImageViews = _mvkInstance->getMoltenVKConfiguration()->fullImageViewSwizzle || _metalFeatures.nativeTextureSwizzle;
|
||||
portabilityFeatures->samplerMipLodBias = false;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: {
|
||||
auto* shaderIntFuncsFeatures = (VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL*)next;
|
||||
shaderIntFuncsFeatures->shaderIntegerFunctions2 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
|
||||
auto* inlineUniformBlockFeatures = (VkPhysicalDeviceInlineUniformBlockFeaturesEXT*)next;
|
||||
inlineUniformBlockFeatures->inlineUniformBlock = true;
|
||||
inlineUniformBlockFeatures->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties* properties) {
|
||||
if (properties) { *properties = _properties; }
|
||||
*properties = _properties;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
|
||||
if (properties) {
|
||||
properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties->properties = _properties;
|
||||
for (auto* next = (VkBaseOutStructure*)properties->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
|
||||
auto* pointClipProps = (VkPhysicalDevicePointClippingProperties*)next;
|
||||
pointClipProps->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
|
||||
auto* maint3Props = (VkPhysicalDeviceMaintenance3Properties*)next;
|
||||
maint3Props->maxPerSetDescriptors = (_metalFeatures.maxPerStageBufferCount + _metalFeatures.maxPerStageTextureCount + _metalFeatures.maxPerStageSamplerCount) * 4;
|
||||
maint3Props->maxMemoryAllocationSize = _metalFeatures.maxMTLBufferSize;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
|
||||
auto* pushDescProps = (VkPhysicalDevicePushDescriptorPropertiesKHR*)next;
|
||||
pushDescProps->maxPushDescriptors = _properties.limits.maxPerStageResources;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {
|
||||
auto* texelBuffAlignProps = (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT*)next;
|
||||
// Save the 'next' pointer; we'll unintentionally overwrite it
|
||||
// on the next line. Put it back when we're done.
|
||||
void* savedNext = texelBuffAlignProps->pNext;
|
||||
*texelBuffAlignProps = _texelBuffAlignProperties;
|
||||
texelBuffAlignProps->pNext = savedNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
||||
auto* divisorProps = (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT*)next;
|
||||
divisorProps->maxVertexAttribDivisor = kMVKUndefinedLargeUInt32;
|
||||
break;
|
||||
}
|
||||
properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties->properties = _properties;
|
||||
for (auto* next = (VkBaseOutStructure*)properties->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
|
||||
auto* pointClipProps = (VkPhysicalDevicePointClippingProperties*)next;
|
||||
pointClipProps->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
|
||||
auto* maint3Props = (VkPhysicalDeviceMaintenance3Properties*)next;
|
||||
maint3Props->maxPerSetDescriptors = (_metalFeatures.maxPerStageBufferCount + _metalFeatures.maxPerStageTextureCount + _metalFeatures.maxPerStageSamplerCount) * 4;
|
||||
maint3Props->maxMemoryAllocationSize = _metalFeatures.maxMTLBufferSize;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
|
||||
auto* pushDescProps = (VkPhysicalDevicePushDescriptorPropertiesKHR*)next;
|
||||
pushDescProps->maxPushDescriptors = _properties.limits.maxPerStageResources;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {
|
||||
auto* texelBuffAlignProps = (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT*)next;
|
||||
// Save the 'next' pointer; we'll unintentionally overwrite it
|
||||
// on the next line. Put it back when we're done.
|
||||
void* savedNext = texelBuffAlignProps->pNext;
|
||||
*texelBuffAlignProps = _texelBuffAlignProperties;
|
||||
texelBuffAlignProps->pNext = savedNext;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
||||
auto* divisorProps = (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT*)next;
|
||||
divisorProps->maxVertexAttribDivisor = kMVKUndefinedLargeUInt32;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
|
||||
populate((VkPhysicalDeviceIDProperties*)next);
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_EXTX: {
|
||||
auto* portabilityProps = (VkPhysicalDevicePortabilitySubsetPropertiesEXTX*)next;
|
||||
portabilityProps->minVertexInputBindingStrideAlignment = 4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Populates the device ID properties structure
|
||||
void MVKPhysicalDevice::populate(VkPhysicalDeviceIDProperties* pDevIdProps) {
|
||||
|
||||
uint8_t* uuid;
|
||||
size_t uuidComponentOffset;
|
||||
|
||||
// ---- Device ID ----------------------------------------------
|
||||
uuid = pDevIdProps->deviceUUID;
|
||||
uuidComponentOffset = 0;
|
||||
mvkClear(uuid, VK_UUID_SIZE);
|
||||
|
||||
// First 4 bytes contains GPU vendor ID
|
||||
uint32_t vendorID = _properties.vendorID;
|
||||
*(uint32_t*)&uuid[uuidComponentOffset] = NSSwapHostIntToBig(vendorID);
|
||||
uuidComponentOffset += sizeof(vendorID);
|
||||
|
||||
// Next 4 bytes contains GPU device ID
|
||||
uint32_t deviceID = _properties.deviceID;
|
||||
*(uint32_t*)&uuid[uuidComponentOffset] = NSSwapHostIntToBig(deviceID);
|
||||
uuidComponentOffset += sizeof(deviceID);
|
||||
|
||||
// Last 8 bytes contain the GPU registry ID
|
||||
uint64_t regID = mvkGetRegistryID(_mtlDevice);
|
||||
*(uint64_t*)&uuid[uuidComponentOffset] = NSSwapHostLongLongToBig(regID);
|
||||
uuidComponentOffset += sizeof(regID);
|
||||
|
||||
|
||||
// ---- Driver ID ----------------------------------------------
|
||||
uuid = pDevIdProps->driverUUID;
|
||||
uuidComponentOffset = 0;
|
||||
mvkClear(uuid, VK_UUID_SIZE);
|
||||
|
||||
// First 4 bytes contains MoltenVK prefix
|
||||
const char* mvkPfx = "MVK";
|
||||
size_t mvkPfxLen = strlen(mvkPfx);
|
||||
mvkCopy(&uuid[uuidComponentOffset], (uint8_t*)mvkPfx, mvkPfxLen);
|
||||
uuidComponentOffset += mvkPfxLen + 1;
|
||||
|
||||
// Next 4 bytes contains MoltenVK version
|
||||
uint32_t mvkVersion = MVK_VERSION;
|
||||
*(uint32_t*)&uuid[uuidComponentOffset] = NSSwapHostIntToBig(mvkVersion);
|
||||
uuidComponentOffset += sizeof(mvkVersion);
|
||||
|
||||
// Next 4 bytes contains highest Metal feature set supported by this device
|
||||
uint32_t mtlFeatSet = getHighestMTLFeatureSet();
|
||||
*(uint32_t*)&uuid[uuidComponentOffset] = NSSwapHostIntToBig(mtlFeatSet);
|
||||
uuidComponentOffset += sizeof(mtlFeatSet);
|
||||
|
||||
|
||||
// ---- LUID ignored for Metal devices ------------------------
|
||||
mvkClear(pDevIdProps->deviceLUID, VK_LUID_SIZE);
|
||||
pDevIdProps->deviceNodeMask = 0;
|
||||
pDevIdProps->deviceLUIDValid = VK_FALSE;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) {
|
||||
if (pFormatProperties) {
|
||||
*pFormatProperties = _pixelFormats.getVkFormatProperties(format);
|
||||
}
|
||||
*pFormatProperties = _pixelFormats.getVkFormatProperties(format);
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getFormatProperties(VkFormat format,
|
||||
VkFormatProperties2KHR* pFormatProperties) {
|
||||
if (pFormatProperties) {
|
||||
pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
|
||||
pFormatProperties->formatProperties = _pixelFormats.getVkFormatProperties(format);
|
||||
}
|
||||
void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties) {
|
||||
pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
|
||||
pFormatProperties->formatProperties = _pixelFormats.getVkFormatProperties(format);
|
||||
}
|
||||
|
||||
VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
|
||||
@ -357,32 +407,41 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult MVKPhysicalDevice::getImageFormatProperties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
|
||||
VkImageFormatProperties2KHR* pImageFormatProperties) {
|
||||
VkResult MVKPhysicalDevice::getImageFormatProperties(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
|
||||
VkImageFormatProperties2* pImageFormatProperties) {
|
||||
|
||||
if ( !pImageFormatInfo || pImageFormatInfo->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR ) {
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
for (const auto* nextInfo = (VkBaseInStructure*)pImageFormatInfo->pNext; nextInfo; nextInfo = nextInfo->pNext) {
|
||||
switch (nextInfo->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: {
|
||||
// Return information about external memory support for MTLTexture.
|
||||
// Search VkImageFormatProperties2 for the corresponding VkExternalImageFormatProperties and populate it.
|
||||
auto* pExtImgFmtInfo = (VkPhysicalDeviceExternalImageFormatInfo*)nextInfo;
|
||||
for (auto* nextProps = (VkBaseOutStructure*)pImageFormatProperties->pNext; nextProps; nextProps = nextProps->pNext) {
|
||||
if (nextProps->sType == VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES) {
|
||||
auto* pExtImgFmtProps = (VkExternalImageFormatProperties*)nextProps;
|
||||
pExtImgFmtProps->externalMemoryProperties = getExternalImageProperties(pExtImgFmtInfo->handleType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !_pixelFormats.isSupported(pImageFormatInfo->format) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
|
||||
if ( !_pixelFormats.isSupported(pImageFormatInfo->format) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
|
||||
|
||||
if ( !getImageViewIsSupported(pImageFormatInfo) ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
|
||||
|
||||
if (pImageFormatProperties) {
|
||||
pImageFormatProperties->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
|
||||
return getImageFormatProperties(pImageFormatInfo->format, pImageFormatInfo->type,
|
||||
pImageFormatInfo->tiling, pImageFormatInfo->usage,
|
||||
pImageFormatInfo->flags,
|
||||
&pImageFormatProperties->imageFormatProperties);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
return getImageFormatProperties(pImageFormatInfo->format, pImageFormatInfo->type,
|
||||
pImageFormatInfo->tiling, pImageFormatInfo->usage,
|
||||
pImageFormatInfo->flags,
|
||||
&pImageFormatProperties->imageFormatProperties);
|
||||
}
|
||||
|
||||
// If the image format info links portability image view info, test if an image view of that configuration is supported
|
||||
bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo) {
|
||||
auto* next = (MVKVkAPIStructHeader*)pImageFormatInfo->pNext;
|
||||
while (next) {
|
||||
bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo) {
|
||||
for (const auto* next = (VkBaseInStructure*)pImageFormatInfo->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_SUPPORT_EXTX: {
|
||||
auto* portImgViewInfo = (VkPhysicalDeviceImageViewSupportEXTX*)next;
|
||||
@ -390,7 +449,7 @@ bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageForma
|
||||
// Create an image view and test whether it could be configured
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = (VkStructureType*)portImgViewInfo->pNext,
|
||||
.pNext = portImgViewInfo->pNext,
|
||||
.flags = portImgViewInfo->flags,
|
||||
.image = nullptr,
|
||||
.viewType = portImgViewInfo->viewType,
|
||||
@ -411,7 +470,6 @@ bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageForma
|
||||
mtlPixFmt, useSwizzle) == VK_SUCCESS);
|
||||
}
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -419,6 +477,27 @@ bool MVKPhysicalDevice::getImageViewIsSupported(const VkPhysicalDeviceImageForma
|
||||
return true;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::getExternalBufferProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
|
||||
VkExternalBufferProperties* pExternalBufferProperties) {
|
||||
pExternalBufferProperties->externalMemoryProperties = getExternalBufferProperties(pExternalBufferInfo->handleType);
|
||||
}
|
||||
|
||||
static VkExternalMemoryProperties _emptyExtMemProps = {};
|
||||
|
||||
VkExternalMemoryProperties& MVKPhysicalDevice::getExternalBufferProperties(VkExternalMemoryHandleTypeFlagBits handleType) {
|
||||
switch (handleType) {
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR: return _mtlBufferExternalMemoryProperties;
|
||||
default: return _emptyExtMemProps;
|
||||
}
|
||||
}
|
||||
|
||||
VkExternalMemoryProperties& MVKPhysicalDevice::getExternalImageProperties(VkExternalMemoryHandleTypeFlagBits handleType) {
|
||||
switch (handleType) {
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR: return _mtlTextureExternalMemoryProperties;
|
||||
default: return _emptyExtMemProps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Surfaces
|
||||
|
||||
@ -722,17 +801,16 @@ VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
|
||||
#pragma mark Memory models
|
||||
|
||||
/** Populates the specified memory properties with the memory characteristics of this device. */
|
||||
VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
|
||||
VkResult MVKPhysicalDevice::getMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
|
||||
*pMemoryProperties = _memoryProperties;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
|
||||
if (pMemoryProperties) {
|
||||
pMemoryProperties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
|
||||
pMemoryProperties->memoryProperties = _memoryProperties;
|
||||
for (auto* next = (VkBaseOutStructure*)pMemoryProperties->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
VkResult MVKPhysicalDevice::getMemoryProperties(VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
|
||||
pMemoryProperties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
|
||||
pMemoryProperties->memoryProperties = _memoryProperties;
|
||||
for (auto* next = (VkBaseOutStructure*)pMemoryProperties->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: {
|
||||
auto* budgetProps = (VkPhysicalDeviceMemoryBudgetPropertiesEXT*)next;
|
||||
mvkClear(budgetProps->heapBudget, VK_MAX_MEMORY_HEAPS);
|
||||
@ -747,7 +825,6 @@ VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMe
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
@ -765,8 +842,9 @@ MVKPhysicalDevice::MVKPhysicalDevice(MVKInstance* mvkInstance, id<MTLDevice> mtl
|
||||
initMetalFeatures(); // Call first.
|
||||
initFeatures(); // Call second.
|
||||
initProperties(); // Call third.
|
||||
initMemoryProperties();
|
||||
initExtensions();
|
||||
initMemoryProperties();
|
||||
initExternalMemoryProperties();
|
||||
logGPUInfo();
|
||||
}
|
||||
|
||||
@ -1470,8 +1548,7 @@ void MVKPhysicalDevice::initGPUInfoProperties() {
|
||||
if (regID) {
|
||||
entry = IOServiceGetMatchingService(kIOMasterPortDefault, IORegistryEntryIDMatching(regID));
|
||||
if (entry) {
|
||||
// That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual
|
||||
// PCI device.
|
||||
// That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual PCI device.
|
||||
io_registry_entry_t parent;
|
||||
if (IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent) == kIOReturnSuccess) {
|
||||
isFound = true;
|
||||
@ -1665,7 +1742,7 @@ void MVKPhysicalDevice::initPipelineCacheUUID() {
|
||||
*(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(mvkVersion);
|
||||
uuidComponentOffset += sizeof(mvkVersion);
|
||||
|
||||
// Next 4 bytes contains hightest Metal feature set supported by this device
|
||||
// Next 4 bytes contains highest Metal feature set supported by this device
|
||||
uint32_t mtlFeatSet = getHighestMTLFeatureSet();
|
||||
*(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(mtlFeatSet);
|
||||
uuidComponentOffset += sizeof(mtlFeatSet);
|
||||
@ -1892,6 +1969,23 @@ uint64_t MVKPhysicalDevice::getCurrentAllocatedSize() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::initExternalMemoryProperties() {
|
||||
|
||||
// Buffers
|
||||
_mtlBufferExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT);
|
||||
_mtlBufferExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR;
|
||||
_mtlBufferExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR;
|
||||
|
||||
// Images
|
||||
_mtlTextureExternalMemoryProperties.externalMemoryFeatures = (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT);
|
||||
_mtlTextureExternalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
|
||||
_mtlTextureExternalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
|
||||
}
|
||||
|
||||
void MVKPhysicalDevice::initExtensions() {
|
||||
MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_supportedExtensions;
|
||||
pWritableExtns->disableAllButEnabledDeviceExtensions();
|
||||
@ -2815,8 +2909,7 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
||||
&pdFeats2.features.robustBufferAccess, 55);
|
||||
}
|
||||
|
||||
auto* next = (MVKVkAPIStructHeader*)pCreateInfo->pNext;
|
||||
while (next) {
|
||||
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
|
||||
auto* requestedFeatures = (VkPhysicalDeviceFeatures2*)next;
|
||||
@ -2905,7 +2998,6 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
class MVKBuffer;
|
||||
class MVKImage;
|
||||
|
||||
// TODO: These are inoperable placeholders until VK_KHR_external_memory_metal defines them properly
|
||||
static const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM;
|
||||
static const VkExternalMemoryHandleTypeFlagBits VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM;
|
||||
|
||||
|
||||
#pragma mark MVKDeviceMemory
|
||||
|
||||
@ -141,6 +145,7 @@ protected:
|
||||
bool ensureHostMemory();
|
||||
void freeHostMemory();
|
||||
MVKResource* getDedicatedResource();
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
|
||||
MVKVectorInline<MVKBuffer*, 4> _buffers;
|
||||
MVKVectorInline<MVKImage*, 4> _images;
|
||||
|
@ -266,10 +266,7 @@ void MVKDeviceMemory::freeHostMemory() {
|
||||
|
||||
MVKResource* MVKDeviceMemory::getDedicatedResource() {
|
||||
MVKAssert(_isDedicated, "This method should only be called on dedicated allocations!");
|
||||
if (_buffers.empty())
|
||||
return _images[0];
|
||||
else
|
||||
return _buffers[0];
|
||||
return _buffers.empty() ? (MVKResource*)_images[0] : (MVKResource*)_buffers[0];
|
||||
}
|
||||
|
||||
MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
@ -284,22 +281,28 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
|
||||
VkImage dedicatedImage = VK_NULL_HANDLE;
|
||||
VkBuffer dedicatedBuffer = VK_NULL_HANDLE;
|
||||
auto* next = (VkStructureType*)pAllocateInfo->pNext;
|
||||
while (next) {
|
||||
switch (*next) {
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: {
|
||||
auto* pDedicatedInfo = (VkMemoryDedicatedAllocateInfo*)next;
|
||||
dedicatedImage = pDedicatedInfo->image;
|
||||
dedicatedBuffer = pDedicatedInfo->buffer;
|
||||
next = (VkStructureType*)pDedicatedInfo->pNext;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
next = (VkStructureType*)((VkMemoryAllocateInfo*)next)->pNext;
|
||||
break;
|
||||
VkExternalMemoryHandleTypeFlags handleTypes = 0;
|
||||
for (const auto* next = (const VkBaseInStructure*)pAllocateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: {
|
||||
auto* pDedicatedInfo = (VkMemoryDedicatedAllocateInfo*)next;
|
||||
dedicatedImage = pDedicatedInfo->image;
|
||||
dedicatedBuffer = pDedicatedInfo->buffer;
|
||||
_isDedicated = dedicatedImage || dedicatedBuffer;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: {
|
||||
auto* pExpMemInfo = (VkExportMemoryAllocateInfo*)next;
|
||||
handleTypes = pExpMemInfo->handleTypes;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initExternalMemory(handleTypes); // After setting _isDedicated
|
||||
|
||||
// "Dedicated" means this memory can only be used for this image or buffer.
|
||||
if (dedicatedImage) {
|
||||
#if MVK_MACOS
|
||||
@ -316,14 +319,16 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_isDedicated = true;
|
||||
_images.push_back((MVKImage*)dedicatedImage);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can, create a MTLHeap. This should happen before creating the buffer
|
||||
// allowing us to map its contents.
|
||||
if (!dedicatedImage && !dedicatedBuffer) {
|
||||
if (dedicatedBuffer) {
|
||||
_buffers.push_back((MVKBuffer*)dedicatedBuffer);
|
||||
}
|
||||
|
||||
// If we can, create a MTLHeap. This should happen before creating the buffer, allowing us to map its contents.
|
||||
if ( !_isDedicated ) {
|
||||
if (!ensureMTLHeap()) {
|
||||
setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not allocate VkDeviceMemory of size %llu bytes.", _allocationSize));
|
||||
return;
|
||||
@ -334,10 +339,26 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
|
||||
if (isMemoryHostCoherent() && !ensureMTLBuffer() ) {
|
||||
setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not allocate a host-coherent VkDeviceMemory of size %llu bytes. The maximum memory-aligned size of a host-coherent VkDeviceMemory is %llu bytes.", _allocationSize, _device->_pMetalFeatures->maxMTLBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
if (dedicatedBuffer) {
|
||||
_isDedicated = true;
|
||||
_buffers.push_back((MVKBuffer*)dedicatedBuffer);
|
||||
void MVKDeviceMemory::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if ( !handleTypes ) { return; }
|
||||
|
||||
if ( !mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR) ) {
|
||||
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): Only external memory handle types VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR or VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR are supported."));
|
||||
}
|
||||
|
||||
bool requiresDedicated = false;
|
||||
if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR)) {
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalBufferProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR);
|
||||
requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
}
|
||||
if (mvkIsAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) {
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
|
||||
requiresDedicated = requiresDedicated || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
}
|
||||
if (requiresDedicated && !_isDedicated) {
|
||||
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkAllocateMemory(): External memory requires a dedicated VkBuffer or VkImage."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,9 @@ public:
|
||||
/** Binds this resource to the specified offset within the specified memory allocation. */
|
||||
VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;
|
||||
|
||||
/** Binds this resource to the specified offset within the specified memory allocation. */
|
||||
virtual VkResult bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo);
|
||||
|
||||
/** Applies the specified global memory barrier. */
|
||||
void applyMemoryBarrier(VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
@ -235,6 +238,7 @@ protected:
|
||||
bool validateUseTexelBuffer();
|
||||
void initSubresources(const VkImageCreateInfo* pCreateInfo);
|
||||
void initSubresourceLayout(MVKImageSubresource& imgSubRez);
|
||||
void initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes);
|
||||
id<MTLTexture> newMTLTexture();
|
||||
void releaseMTLTexture();
|
||||
void releaseIOSurface();
|
||||
@ -380,7 +384,7 @@ class MVKPeerSwapchainImage : public MVKSwapchainImage {
|
||||
public:
|
||||
|
||||
/** Binds this resource according to the specified bind information. */
|
||||
VkResult bindDeviceMemory2(const void* pBindInfo) override;
|
||||
VkResult bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo) override;
|
||||
|
||||
|
||||
#pragma mark Construction
|
||||
|
@ -182,8 +182,9 @@ VkResult MVKImage::getMemoryRequirements(const void*, VkMemoryRequirements2* pMe
|
||||
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
||||
auto* dedicatedReqs = (VkMemoryDedicatedRequirements*)next;
|
||||
bool writable = mvkIsAnyFlagEnabled(_usage, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
dedicatedReqs->prefersDedicatedAllocation = !_usesTexelBuffer && (writable || !_device->_pMetalFeatures->placementHeaps);
|
||||
dedicatedReqs->requiresDedicatedAllocation = VK_FALSE;
|
||||
dedicatedReqs->requiresDedicatedAllocation = _requiresDedicatedMemoryAllocation;
|
||||
dedicatedReqs->prefersDedicatedAllocation = (dedicatedReqs->requiresDedicatedAllocation ||
|
||||
(!_usesTexelBuffer && (writable || !_device->_pMetalFeatures->placementHeaps)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -206,6 +207,10 @@ VkResult MVKImage::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOff
|
||||
return _deviceMemory ? _deviceMemory->addImage(this) : VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult MVKImage::bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo) {
|
||||
return bindDeviceMemory((MVKDeviceMemory*)pBindInfo->memory, pBindInfo->memoryOffset);
|
||||
}
|
||||
|
||||
bool MVKImage::validateUseTexelBuffer() {
|
||||
VkExtent2D blockExt = getPixelFormats()->getBlockTexelSize(_mtlPixelFormat);
|
||||
bool isUncompressed = blockExt.width == 1 && blockExt.height == 1;
|
||||
@ -615,6 +620,18 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
|
||||
}
|
||||
|
||||
initSubresources(pCreateInfo);
|
||||
|
||||
for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO: {
|
||||
auto* pExtMemInfo = (const VkExternalMemoryImageCreateInfo*)next;
|
||||
initExternalMemory(pExtMemInfo->handleTypes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
|
||||
@ -784,6 +801,16 @@ void MVKImage::initSubresourceLayout(MVKImageSubresource& imgSubRez) {
|
||||
layout.depthPitch = bytesPerLayerCurrLevel;
|
||||
}
|
||||
|
||||
void MVKImage::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
|
||||
if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) {
|
||||
_externalMemoryHandleTypes = handleTypes;
|
||||
auto& xmProps = _device->getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
|
||||
_requiresDedicatedMemoryAllocation = _requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
|
||||
} else {
|
||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage(): Only external memory handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR is supported."));
|
||||
}
|
||||
}
|
||||
|
||||
MVKImage::~MVKImage() {
|
||||
if (_deviceMemory) { _deviceMemory->removeImage(this); }
|
||||
releaseMTLTexture();
|
||||
@ -991,10 +1018,9 @@ MVKPresentableSwapchainImage::~MVKPresentableSwapchainImage() {
|
||||
#pragma mark -
|
||||
#pragma mark MVKPeerSwapchainImage
|
||||
|
||||
VkResult MVKPeerSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
|
||||
const auto* imageInfo = (const VkBindImageMemoryInfo*)pBindInfo;
|
||||
VkResult MVKPeerSwapchainImage::bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo) {
|
||||
const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
|
||||
for (const auto* next = (const VkBaseInStructure*)imageInfo->pNext; next; next = next->pNext) {
|
||||
for (const auto* next = (const VkBaseInStructure*)pBindInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
|
||||
swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
|
||||
@ -1002,11 +1028,9 @@ VkResult MVKPeerSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (swapchainInfo) { break; }
|
||||
}
|
||||
if (!swapchainInfo) {
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
}
|
||||
if (!swapchainInfo) { return VK_ERROR_OUT_OF_DEVICE_MEMORY; }
|
||||
|
||||
_swapchainIndex = swapchainInfo->imageIndex;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@ -1114,17 +1138,14 @@ MVKImageView::MVKImageView(MVKDevice* device,
|
||||
_image = (MVKImage*)pCreateInfo->image;
|
||||
_usage = _image->_usage;
|
||||
|
||||
auto* next = (MVKVkAPIStructHeader*)pCreateInfo->pNext;
|
||||
while (next) {
|
||||
switch ((uint32_t)next->sType) {
|
||||
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO: {
|
||||
auto* pViewUsageInfo = (VkImageViewUsageCreateInfo*)next;
|
||||
if (!(pViewUsageInfo->usage & ~_usage)) { _usage = pViewUsageInfo->usage; }
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -383,8 +383,7 @@ void MVKInstance::initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo) {
|
||||
_hasDebugUtilsMessengers = false;
|
||||
_debugReportCallbackLayerPrefix = getDriverLayer()->getName();
|
||||
|
||||
MVKVkAPIStructHeader* next = (MVKVkAPIStructHeader*)pCreateInfo->pNext;
|
||||
while (next) {
|
||||
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT:
|
||||
createDebugReportCallback((VkDebugReportCallbackCreateInfoEXT*)next, nullptr);
|
||||
@ -395,7 +394,6 @@ void MVKInstance::initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -944,15 +944,12 @@ bool MVKGraphicsPipeline::addVertexInputToPipeline(MTLRenderPipelineDescriptor*
|
||||
const SPIRVToMSLConversionConfiguration& shaderContext) {
|
||||
// Collect extension structures
|
||||
VkPipelineVertexInputDivisorStateCreateInfoEXT* pVertexInputDivisorState = nullptr;
|
||||
auto* next = (MVKVkAPIStructHeader*)pVI->pNext;
|
||||
while (next) {
|
||||
for (const auto* next = (VkBaseInStructure*)pVI->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT:
|
||||
pVertexInputDivisorState = (VkPipelineVertexInputDivisorStateCreateInfoEXT*)next;
|
||||
next = (MVKVkAPIStructHeader*)pVertexInputDivisorState->pNext;
|
||||
break;
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1032,15 +1029,12 @@ void MVKGraphicsPipeline::addTessellationToPipeline(MTLRenderPipelineDescriptor*
|
||||
|
||||
VkPipelineTessellationDomainOriginStateCreateInfo* pTessDomainOriginState = nullptr;
|
||||
if (reflectData.patchKind == spv::ExecutionModeTriangles) {
|
||||
auto* next = (MVKVkAPIStructHeader*)pTS->pNext;
|
||||
while (next) {
|
||||
for (const auto* next = (VkBaseInStructure*)pTS->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO:
|
||||
pTessDomainOriginState = (VkPipelineTessellationDomainOriginStateCreateInfo*)next;
|
||||
next = (MVKVkAPIStructHeader*)pTessDomainOriginState->pNext;
|
||||
break;
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1131,15 +1125,12 @@ void MVKGraphicsPipeline::initMVKShaderConverterContext(SPIRVToMSLConversionConf
|
||||
|
||||
VkPipelineTessellationDomainOriginStateCreateInfo* pTessDomainOriginState = nullptr;
|
||||
if (pCreateInfo->pTessellationState) {
|
||||
auto* next = (MVKVkAPIStructHeader*)pCreateInfo->pTessellationState->pNext;
|
||||
while (next) {
|
||||
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pTessellationState->pNext; next; next = next->pNext) {
|
||||
switch (next->sType) {
|
||||
case VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO:
|
||||
pTessDomainOriginState = (VkPipelineTessellationDomainOriginStateCreateInfo*)next;
|
||||
next = (MVKVkAPIStructHeader*)pTessDomainOriginState->pNext;
|
||||
break;
|
||||
default:
|
||||
next = (MVKVkAPIStructHeader*)next->pNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,6 @@ public:
|
||||
/** Binds this resource to the specified offset within the specified memory allocation. */
|
||||
virtual VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset);
|
||||
|
||||
/** Binds this resource according to the specified bind information. */
|
||||
virtual VkResult bindDeviceMemory2(const void* pBindInfo);
|
||||
|
||||
/** Returns the device memory underlying this resource. */
|
||||
inline MVKDeviceMemory* getDeviceMemory() { return _deviceMemory; }
|
||||
|
||||
@ -88,4 +85,6 @@ protected:
|
||||
VkDeviceSize _deviceMemoryOffset = 0;
|
||||
VkDeviceSize _byteCount = 0;
|
||||
VkDeviceSize _byteAlignment = 0;
|
||||
VkExternalMemoryHandleTypeFlags _externalMemoryHandleTypes = 0;
|
||||
bool _requiresDedicatedMemoryAllocation = false;
|
||||
};
|
||||
|
@ -21,18 +21,6 @@
|
||||
#include "MVKEnvironment.h"
|
||||
|
||||
|
||||
struct MVKBindDeviceMemoryInfo {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
union {
|
||||
VkBuffer buffer;
|
||||
VkImage image;
|
||||
};
|
||||
VkDeviceMemory memory;
|
||||
VkDeviceSize memoryOffset;
|
||||
};
|
||||
|
||||
|
||||
#pragma mark MVKResource
|
||||
|
||||
VkResult MVKResource::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) {
|
||||
@ -46,11 +34,6 @@ VkResult MVKResource::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize mem
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult MVKResource::bindDeviceMemory2(const void* pBindInfo) {
|
||||
auto* mvkBindInfo = (const MVKBindDeviceMemoryInfo*)pBindInfo;
|
||||
return bindDeviceMemory((MVKDeviceMemory*)mvkBindInfo->memory, mvkBindInfo->memoryOffset);
|
||||
}
|
||||
|
||||
// Returns whether the specified global memory barrier requires a sync between this
|
||||
// texture and host memory for the purpose of the host reading texture memory.
|
||||
bool MVKResource::needsHostReadSync(VkPipelineStageFlags srcStageMask,
|
||||
|
@ -39,58 +39,60 @@
|
||||
#define MVK_EXTENSION_LAST(var, EXT, type) MVK_EXTENSION(var, EXT, type)
|
||||
#endif
|
||||
|
||||
MVK_EXTENSION(KHR_16bit_storage, KHR_16BIT_STORAGE, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_8bit_storage, KHR_8BIT_STORAGE, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_bind_memory2, KHR_BIND_MEMORY_2, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_dedicated_allocation, KHR_DEDICATED_ALLOCATION, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_descriptor_update_template, KHR_DESCRIPTOR_UPDATE_TEMPLATE, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group, KHR_DEVICE_GROUP, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group_creation, KHR_DEVICE_GROUP_CREATION, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(KHR_get_memory_requirements2, KHR_GET_MEMORY_REQUIREMENTS_2, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(KHR_get_surface_capabilities2, KHR_GET_SURFACE_CAPABILITIES_2, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(KHR_image_format_list, KHR_IMAGE_FORMAT_LIST, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance1, KHR_MAINTENANCE1, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance2, KHR_MAINTENANCE2, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance3, KHR_MAINTENANCE3, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_push_descriptor, KHR_PUSH_DESCRIPTOR, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_relaxed_block_layout, KHR_RELAXED_BLOCK_LAYOUT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_sampler_mirror_clamp_to_edge, KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_shader_draw_parameters, KHR_SHADER_DRAW_PARAMETERS, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_shader_float16_int8, KHR_SHADER_FLOAT16_INT8, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_storage_buffer_storage_class, KHR_STORAGE_BUFFER_STORAGE_CLASS, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_surface, KHR_SURFACE, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(KHR_swapchain, KHR_SWAPCHAIN, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_swapchain_mutable_format, KHR_SWAPCHAIN_MUTABLE_FORMAT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_uniform_buffer_standard_layout, KHR_UNIFORM_BUFFER_STANDARD_LAYOUT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_inline_uniform_block, EXT_INLINE_UNIFORM_BLOCK, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(EXT_post_depth_coverage, EXT_POST_DEPTH_COVERAGE, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_scalar_block_layout, EXT_SCALAR_BLOCK_LAYOUT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_shader_stencil_export, EXT_SHADER_STENCIL_EXPORT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_swapchain_colorspace, EXT_SWAPCHAIN_COLOR_SPACE, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(EXT_texel_buffer_alignment, EXT_TEXEL_BUFFER_ALIGNMENT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(MVK_ios_surface, MVK_IOS_SURFACE, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(MVK_macos_surface, MVK_MACOS_SURFACE, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK, MVK_EXTENSION_INSTANCE)
|
||||
MVK_EXTENSION(AMD_gpu_shader_half_float, AMD_GPU_SHADER_HALF_FLOAT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(AMD_shader_image_load_store_lod, AMD_SHADER_IMAGE_LOAD_STORE_LOD, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(AMD_shader_trinary_minmax, AMD_SHADER_TRINARY_MINMAX, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(IMG_format_pvrtc, IMG_FORMAT_PVRTC, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(INTEL_shader_integer_functions2, INTEL_SHADER_INTEGER_FUNCTIONS_2, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION_LAST(NV_glsl_shader, NV_GLSL_SHADER, MVK_EXTENSION_DEVICE)
|
||||
MVK_EXTENSION(KHR_16bit_storage, KHR_16BIT_STORAGE, DEVICE)
|
||||
MVK_EXTENSION(KHR_8bit_storage, KHR_8BIT_STORAGE, DEVICE)
|
||||
MVK_EXTENSION(KHR_bind_memory2, KHR_BIND_MEMORY_2, DEVICE)
|
||||
MVK_EXTENSION(KHR_dedicated_allocation, KHR_DEDICATED_ALLOCATION, DEVICE)
|
||||
MVK_EXTENSION(KHR_descriptor_update_template, KHR_DESCRIPTOR_UPDATE_TEMPLATE, DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group, KHR_DEVICE_GROUP, DEVICE)
|
||||
MVK_EXTENSION(KHR_device_group_creation, KHR_DEVICE_GROUP_CREATION, INSTANCE)
|
||||
MVK_EXTENSION(KHR_external_memory, KHR_EXTERNAL_MEMORY, DEVICE)
|
||||
MVK_EXTENSION(KHR_external_memory_capabilities, KHR_EXTERNAL_MEMORY_CAPABILITIES, INSTANCE)
|
||||
MVK_EXTENSION(KHR_get_memory_requirements2, KHR_GET_MEMORY_REQUIREMENTS_2, DEVICE)
|
||||
MVK_EXTENSION(KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2, INSTANCE)
|
||||
MVK_EXTENSION(KHR_get_surface_capabilities2, KHR_GET_SURFACE_CAPABILITIES_2, INSTANCE)
|
||||
MVK_EXTENSION(KHR_image_format_list, KHR_IMAGE_FORMAT_LIST, DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance1, KHR_MAINTENANCE1, DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance2, KHR_MAINTENANCE2, DEVICE)
|
||||
MVK_EXTENSION(KHR_maintenance3, KHR_MAINTENANCE3, DEVICE)
|
||||
MVK_EXTENSION(KHR_push_descriptor, KHR_PUSH_DESCRIPTOR, DEVICE)
|
||||
MVK_EXTENSION(KHR_relaxed_block_layout, KHR_RELAXED_BLOCK_LAYOUT, DEVICE)
|
||||
MVK_EXTENSION(KHR_sampler_mirror_clamp_to_edge, KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, DEVICE)
|
||||
MVK_EXTENSION(KHR_shader_draw_parameters, KHR_SHADER_DRAW_PARAMETERS, DEVICE)
|
||||
MVK_EXTENSION(KHR_shader_float16_int8, KHR_SHADER_FLOAT16_INT8, DEVICE)
|
||||
MVK_EXTENSION(KHR_storage_buffer_storage_class, KHR_STORAGE_BUFFER_STORAGE_CLASS, DEVICE)
|
||||
MVK_EXTENSION(KHR_surface, KHR_SURFACE, INSTANCE)
|
||||
MVK_EXTENSION(KHR_swapchain, KHR_SWAPCHAIN, DEVICE)
|
||||
MVK_EXTENSION(KHR_swapchain_mutable_format, KHR_SWAPCHAIN_MUTABLE_FORMAT, DEVICE)
|
||||
MVK_EXTENSION(KHR_uniform_buffer_standard_layout, KHR_UNIFORM_BUFFER_STANDARD_LAYOUT, DEVICE)
|
||||
MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS, DEVICE)
|
||||
MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER, DEVICE)
|
||||
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, INSTANCE)
|
||||
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, INSTANCE)
|
||||
MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, DEVICE)
|
||||
MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, DEVICE)
|
||||
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET, DEVICE)
|
||||
MVK_EXTENSION(EXT_inline_uniform_block, EXT_INLINE_UNIFORM_BLOCK, DEVICE)
|
||||
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET, DEVICE)
|
||||
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE, INSTANCE)
|
||||
MVK_EXTENSION(EXT_post_depth_coverage, EXT_POST_DEPTH_COVERAGE, DEVICE)
|
||||
MVK_EXTENSION(EXT_scalar_block_layout, EXT_SCALAR_BLOCK_LAYOUT, DEVICE)
|
||||
MVK_EXTENSION(EXT_shader_stencil_export, EXT_SHADER_STENCIL_EXPORT, DEVICE)
|
||||
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER, DEVICE)
|
||||
MVK_EXTENSION(EXT_swapchain_colorspace, EXT_SWAPCHAIN_COLOR_SPACE, INSTANCE)
|
||||
MVK_EXTENSION(EXT_texel_buffer_alignment, EXT_TEXEL_BUFFER_ALIGNMENT, DEVICE)
|
||||
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR, DEVICE)
|
||||
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET, DEVICE)
|
||||
MVK_EXTENSION(MVK_ios_surface, MVK_IOS_SURFACE, INSTANCE)
|
||||
MVK_EXTENSION(MVK_macos_surface, MVK_MACOS_SURFACE, INSTANCE)
|
||||
MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK, INSTANCE)
|
||||
MVK_EXTENSION(AMD_gpu_shader_half_float, AMD_GPU_SHADER_HALF_FLOAT, DEVICE)
|
||||
MVK_EXTENSION(AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT, DEVICE)
|
||||
MVK_EXTENSION(AMD_shader_image_load_store_lod, AMD_SHADER_IMAGE_LOAD_STORE_LOD, DEVICE)
|
||||
MVK_EXTENSION(AMD_shader_trinary_minmax, AMD_SHADER_TRINARY_MINMAX, DEVICE)
|
||||
MVK_EXTENSION(IMG_format_pvrtc, IMG_FORMAT_PVRTC, DEVICE)
|
||||
MVK_EXTENSION(INTEL_shader_integer_functions2, INTEL_SHADER_INTEGER_FUNCTIONS_2, DEVICE)
|
||||
MVK_EXTENSION_LAST(NV_glsl_shader, NV_GLSL_SHADER, DEVICE)
|
||||
|
||||
#undef MVK_EXTENSION
|
||||
#undef MVK_EXTENSION_LAST
|
||||
|
@ -47,54 +47,30 @@ static VkExtensionProperties kVkExtProps_ ##EXT = mvkMakeExtProps(VK_ ##EXT ##_E
|
||||
// Returns whether the specified properties are valid for this platform
|
||||
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
|
||||
#if MVK_MACOS
|
||||
if (pProperties == &kVkExtProps_EXT_HDR_METADATA) {
|
||||
return mvkOSVersionIsAtLeast(10.15);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) {
|
||||
return mvkOSVersionIsAtLeast(10.13);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
|
||||
return mvkOSVersionIsAtLeast(10.13);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_POST_DEPTH_COVERAGE) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) {
|
||||
return mvkOSVersionIsAtLeast(10.14);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) {
|
||||
return mvkOSVersionIsAtLeast(10.13);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_IMAGE_LOAD_STORE_LOD) { return false; }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_TRINARY_MINMAX) {
|
||||
return mvkOSVersionIsAtLeast(10.14);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_POST_DEPTH_COVERAGE) { return false; }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_IMAGE_LOAD_STORE_LOD) { return false; }
|
||||
|
||||
if (pProperties == &kVkExtProps_EXT_HDR_METADATA) { return mvkOSVersionIsAtLeast(10.15); }
|
||||
if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) { return mvkOSVersionIsAtLeast(10.13); }
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) { return mvkOSVersionIsAtLeast(10.13); }
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) { return mvkOSVersionIsAtLeast(10.14); }
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) { return mvkOSVersionIsAtLeast(10.13); }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_TRINARY_MINMAX) { return mvkOSVersionIsAtLeast(10.14); }
|
||||
#endif
|
||||
#if MVK_IOS
|
||||
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
|
||||
if (pProperties == &kVkExtProps_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_HDR_METADATA) { return false; }
|
||||
if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) {
|
||||
return mvkOSVersionIsAtLeast(11.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
|
||||
return mvkOSVersionIsAtLeast(11.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_POST_DEPTH_COVERAGE) {
|
||||
return mvkOSVersionIsAtLeast(11.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) {
|
||||
return mvkOSVersionIsAtLeast(12.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_SWAPCHAIN_COLOR_SPACE) {
|
||||
return mvkOSVersionIsAtLeast(9.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) {
|
||||
return mvkOSVersionIsAtLeast(11.0);
|
||||
}
|
||||
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_TRINARY_MINMAX) {
|
||||
return mvkOSVersionIsAtLeast(12.0);
|
||||
}
|
||||
|
||||
if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) { return mvkOSVersionIsAtLeast(11.0); }
|
||||
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) { return mvkOSVersionIsAtLeast(11.0); }
|
||||
if (pProperties == &kVkExtProps_EXT_POST_DEPTH_COVERAGE) { return mvkOSVersionIsAtLeast(11.0); }
|
||||
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) { return mvkOSVersionIsAtLeast(12.0); }
|
||||
if (pProperties == &kVkExtProps_EXT_SWAPCHAIN_COLOR_SPACE) { return mvkOSVersionIsAtLeast(9.0); }
|
||||
if (pProperties == &kVkExtProps_EXT_TEXEL_BUFFER_ALIGNMENT) { return mvkOSVersionIsAtLeast(11.0); }
|
||||
if (pProperties == &kVkExtProps_AMD_SHADER_TRINARY_MINMAX) { return mvkOSVersionIsAtLeast(12.0); }
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@ -127,17 +103,19 @@ void MVKExtensionList::initCount() {
|
||||
#include "MVKExtensions.def"
|
||||
}
|
||||
|
||||
#define MVK_ENSURE_EXTENSION_TYPE(var, EXT, type) vk_ ##var.enabled = vk_ ##var.enabled && MVK_EXTENSION_ ##type;
|
||||
|
||||
void MVKExtensionList::disableAllButEnabledInstanceExtensions() {
|
||||
#define MVK_EXTENSION_INSTANCE true
|
||||
#define MVK_EXTENSION_DEVICE false
|
||||
#define MVK_EXTENSION(var, EXT, type) vk_ ##var.enabled = type && vk_ ##var.enabled;
|
||||
#define MVK_EXTENSION_INSTANCE true
|
||||
#define MVK_EXTENSION_DEVICE false
|
||||
#define MVK_EXTENSION(var, EXT, type) MVK_ENSURE_EXTENSION_TYPE(var, EXT, type)
|
||||
#include "MVKExtensions.def"
|
||||
}
|
||||
|
||||
void MVKExtensionList::disableAllButEnabledDeviceExtensions() {
|
||||
#define MVK_EXTENSION_INSTANCE false
|
||||
#define MVK_EXTENSION_DEVICE true
|
||||
#define MVK_EXTENSION(var, EXT, type) vk_ ##var.enabled = type && vk_ ##var.enabled;
|
||||
#define MVK_EXTENSION_INSTANCE false
|
||||
#define MVK_EXTENSION_DEVICE true
|
||||
#define MVK_EXTENSION(var, EXT, type) MVK_ENSURE_EXTENSION_TYPE(var, EXT, type)
|
||||
#include "MVKExtensions.def"
|
||||
}
|
||||
|
||||
|
@ -55,12 +55,6 @@ typedef uint16_t MVKHalfFloat;
|
||||
/** A representation of the value of 1.0 as a 16-bit half-float. */
|
||||
#define kHalfFloat1 0x3C00
|
||||
|
||||
/** Common header for many standard Vulkan API structures. */
|
||||
typedef struct {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
} MVKVkAPIStructHeader;
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Vertex content structures
|
||||
|
@ -230,7 +230,7 @@ MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMemoryProperties(
|
||||
|
||||
MVKTraceVulkanCallStart();
|
||||
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
|
||||
mvkPD->getPhysicalDeviceMemoryProperties(pMemoryProperties);
|
||||
mvkPD->getMemoryProperties(pMemoryProperties);
|
||||
MVKTraceVulkanCallEnd();
|
||||
}
|
||||
|
||||
@ -2113,7 +2113,7 @@ MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMemoryProperties2KHR(
|
||||
|
||||
MVKTraceVulkanCallStart();
|
||||
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
|
||||
mvkPD->getPhysicalDeviceMemoryProperties(pMemoryProperties);
|
||||
mvkPD->getMemoryProperties(pMemoryProperties);
|
||||
MVKTraceVulkanCallEnd();
|
||||
}
|
||||
|
||||
@ -2664,6 +2664,21 @@ MVK_PUBLIC_SYMBOL void vkResetQueryPoolEXT(
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark VK_KHR_external_memory_capabilities extension
|
||||
|
||||
MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceExternalBufferPropertiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
|
||||
VkExternalBufferProperties* pExternalBufferProperties) {
|
||||
|
||||
MVKTraceVulkanCallStart();
|
||||
MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
|
||||
mvkPD->getExternalBufferProperties(pExternalBufferInfo, pExternalBufferProperties);
|
||||
MVKTraceVulkanCallEnd();
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark VK_EXT_metal_surface extension
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user