diff --git a/MoltenVK/MoltenVK/API/mvk_datatypes.h b/MoltenVK/MoltenVK/API/mvk_datatypes.h index 4ecd65003..b5579e500 100644 --- a/MoltenVK/MoltenVK/API/mvk_datatypes.h +++ b/MoltenVK/MoltenVK/API/mvk_datatypes.h @@ -443,7 +443,7 @@ static inline VkExtent3D mvkVkExtent3DFromMTLSize(MTLSize mtlSize) { #define MVK_VK_MEMORY_TYPE_METAL_PRIVATE (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) /** Macro indicating the Vulkan memory type bits corresponding to Metal shared memory (host visible and coherent). */ -#define MVK_VK_MEMORY_TYPE_METAL_SHARED (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) +#define MVK_VK_MEMORY_TYPE_METAL_SHARED (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT) /** Macro indicating the Vulkan memory type bits corresponding to Metal managed memory (host visible and non-coherent). */ #define MVK_VK_MEMORY_TYPE_METAL_MANAGED (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm index 91054c660..72804cda1 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm @@ -52,7 +52,7 @@ pMemoryRequirements->alignment = _byteAlignment; } pMemoryRequirements->memoryTypeBits = _device->getPhysicalDevice()->getAllMemoryTypes(); -#if MVK_IOS +#if MVK_IOS_OR_TVOS // Memoryless storage is not allowed for buffers mvkDisableFlags(pMemoryRequirements->memoryTypeBits, _device->getPhysicalDevice()->getLazilyAllocatedMemoryTypes()); #endif diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 7e4ff3069..7788b8d25 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -41,7 +41,7 @@ using namespace std; -#if MVK_IOS +#if MVK_IOS_OR_TVOS # include # define MVKViewClass UIView #endif @@ -425,7 +425,7 @@ } // Metal does not allow compressed or depth/stencil formats on 3D textures if (mvkFmt == kMVKFormatDepthStencil -#if MVK_IOS +#if MVK_IOS_OR_TVOS || mvkFmt == kMVKFormatCompressed #endif ) { @@ -643,7 +643,7 @@ colorSpaces.push_back(VK_COLOR_SPACE_HDR10_HLG_EXT); } #endif -#if MVK_IOS +#if MVK_IOS_OR_TVOS // iOS 8 doesn't support anything but sRGB. if (mvkOSVersionIsAtLeast(9.0)) { colorSpaces.push_back(VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT); @@ -945,6 +945,7 @@ _metalFeatures.mtlCopyBufferAlignment = 1; _metalFeatures.texelBuffers = true; _metalFeatures.maxTextureDimension = (8 * KIBI); + _metalFeatures.dynamicMTLBufferSize = (4 * KIBI); if (supportsMTLFeatureSet(tvOS_GPUFamily1_v2)) { _metalFeatures.mslVersionEnum = MTLLanguageVersion1_2; @@ -959,6 +960,8 @@ if (supportsMTLFeatureSet(tvOS_GPUFamily1_v4)) { _metalFeatures.mslVersionEnum = MTLLanguageVersion2_1; + _metalFeatures.events = true; + _metalFeatures.textureBuffers = true; } if (supportsMTLFeatureSet(tvOS_GPUFamily2_v1)) { @@ -1407,7 +1410,7 @@ #if MVK_MACOS _properties.limits.maxUniformBufferRange = (64 * KIBI); #endif -#if MVK_IOS +#if MVK_IOS_OR_TVOS _properties.limits.maxUniformBufferRange = (uint32_t)_metalFeatures.maxMTLBufferSize; #endif _properties.limits.maxStorageBufferRange = (uint32_t)_metalFeatures.maxMTLBufferSize; @@ -1500,6 +1503,18 @@ _texelBuffAlignProperties.uniformTexelBufferOffsetSingleTexelAlignment = VK_FALSE; } +#if MVK_TVOS + _properties.limits.maxFragmentInputComponents = 60; + + if (supportsMTLFeatureSet(tvOS_GPUFamily2_v1)) { + _properties.limits.optimalBufferCopyOffsetAlignment = 16; + } else { + _properties.limits.optimalBufferCopyOffsetAlignment = 64; + } + + _properties.limits.maxTessellationGenerationLevel = 16; + _properties.limits.maxTessellationPatchSize = 32; +#endif #if MVK_IOS _properties.limits.maxFragmentInputComponents = 60; @@ -1576,6 +1591,13 @@ if ( [_mtlDevice respondsToSelector: @selector(maxThreadgroupMemoryLength)] ) { _properties.limits.maxComputeSharedMemorySize = (uint32_t)_mtlDevice.maxThreadgroupMemoryLength; } else { +#if MVK_TVOS + if (supportsMTLFeatureSet(tvOS_GPUFamily2_v1)) { + _properties.limits.maxComputeSharedMemorySize = (16 * KIBI); + } else { + _properties.limits.maxComputeSharedMemorySize = ((16 * KIBI) - 32); + } +#endif #if MVK_IOS if (supportsMTLFeatureSet(iOS_GPUFamily4_v1)) { _properties.limits.maxComputeSharedMemorySize = (32 * KIBI); @@ -1903,7 +1925,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope // On newer OS's, combine highest Metal version with highest GPU family // (Mac & Apple GPU lists should be mutex on platform) uint32_t mtlVer = 0; -#if MVK_IOS +#if MVK_IOS_OR_TVOS if (mvkOSVersionIsAtLeast(13.0)) { mtlVer = 0x30000; } #endif #if MVK_MACOS @@ -2061,6 +2083,13 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope typeIdx++; } #endif +#if MVK_TVOS + if (supportsMTLFeatureSet(tvOS_GPUFamily1_v2)) { + memlessBit = 1 << typeIdx; + setMemoryType(typeIdx, mainHeapIdx, MVK_VK_MEMORY_TYPE_METAL_MEMORYLESS); + typeIdx++; + } +#endif _memoryProperties.memoryTypeCount = typeIdx; @@ -2097,7 +2126,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope return _mtlDevice.recommendedMaxWorkingSetSize; } #endif -#if MVK_IOS +#if MVK_IOS_OR_TVOS // GPU and CPU use shared memory. Estimate the current free memory in the system. uint64_t freeMem = mvkGetAvailableMemorySize(); if (freeMem) { return freeMem; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 0f3523b81..6efd58fa7 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -583,7 +583,7 @@ mvkDisableFlags(pMemoryRequirements->memoryTypeBits, _device->getPhysicalDevice()->getHostCoherentMemoryTypes()); } #endif -#if MVK_IOS +#if MVK_IOS_OR_TVOS // Only transient attachments may use memoryless storage if (!mvkAreAllFlagsEnabled(_usage, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) ) { mvkDisableFlags(pMemoryRequirements->memoryTypeBits, _device->getPhysicalDevice()->getLazilyAllocatedMemoryTypes());