Merge pull request #1043 from cdavis5e/mac-linear-images

Support linear images and buffer views in shared memory on macOS 10.15.5+.
This commit is contained in:
Bill Hollings 2020-09-21 13:41:31 -04:00 committed by GitHub
commit a59a26816e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 14 deletions

View File

@ -617,6 +617,7 @@ typedef struct {
VkBool32 nonUniformThreadgroups; /**< If true, the device supports arbitrary-sized grids in compute workloads. */
VkBool32 renderWithoutAttachments; /**< If true, we don't have to create a dummy attachment for a render pass if there isn't one. */
VkBool32 deferredStoreActions; /**< If true, render pass store actions can be specified after the render encoder is created. */
VkBool32 sharedLinearTextures; /**< If true, linear textures and texture buffers can be created from buffers in Shared storage. */
} MVKPhysicalDeviceMetalFeatures;
/** MoltenVK performance of a particular type of activity. */

View File

@ -84,7 +84,7 @@ VkResult MVKBuffer::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOf
#if MVK_MACOS
if (_deviceMemory) {
_isHostCoherentTexelBuffer = _deviceMemory->isMemoryHostCoherent() && mvkIsAnyFlagEnabled(_usage, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
_isHostCoherentTexelBuffer = !_device->_pMetalFeatures->sharedLinearTextures && _deviceMemory->isMemoryHostCoherent() && mvkIsAnyFlagEnabled(_usage, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
}
#endif
@ -272,7 +272,7 @@ id<MTLTexture> MVKBufferView::getMTLTexture() {
}
id<MTLBuffer> mtlBuff;
VkDeviceSize mtlBuffOffset;
if (MVK_MACOS && _buffer->isMemoryHostCoherent()) {
if ( !_device->_pMetalFeatures->sharedLinearTextures && _buffer->isMemoryHostCoherent() ) {
mtlBuff = _buffer->getMTLBufferCache();
mtlBuffOffset = _offset;
} else {

View File

@ -997,6 +997,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
_metalFeatures.texelBuffers = true;
_metalFeatures.maxTextureDimension = (8 * KIBI);
_metalFeatures.dynamicMTLBufferSize = (4 * KIBI);
_metalFeatures.sharedLinearTextures = true;
if (supportsMTLFeatureSet(tvOS_GPUFamily1_v2)) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion1_2;
@ -1044,6 +1045,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
_metalFeatures.mtlCopyBufferAlignment = 1;
_metalFeatures.texelBuffers = true;
_metalFeatures.maxTextureDimension = (4 * KIBI);
_metalFeatures.sharedLinearTextures = true;
if (supportsMTLFeatureSet(iOS_GPUFamily1_v2)) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion1_1;
@ -1157,6 +1159,9 @@ void MVKPhysicalDevice::initMetalFeatures() {
_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
_metalFeatures.native3DCompressedTextures = true;
_metalFeatures.renderWithoutAttachments = true;
if ( mvkOSVersionIsAtLeast(mvkMakeOSVersion(10, 15, 5)) ) {
_metalFeatures.sharedLinearTextures = true;
}
if (supportsMTLGPUFamily(Mac2)) {
_metalFeatures.nativeTextureSwizzle = true;
_metalFeatures.placementHeaps = useMTLHeaps;

View File

@ -308,8 +308,10 @@ MVKDeviceMemory::MVKDeviceMemory(MVKDevice* device,
if (!((MVKImage*)dedicatedImage)->_isLinear) {
setConfigurationResult(reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Host-coherent VkDeviceMemory objects cannot be associated with optimal-tiling images."));
} else {
// Need to use the managed mode for images.
_mtlStorageMode = MTLStorageModeManaged;
if (!_device->_pMetalFeatures->sharedLinearTextures) {
// Need to use the managed mode for images.
_mtlStorageMode = MTLStorageModeManaged;
}
// Nonetheless, we need a buffer to be able to map the memory at will.
if (!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));

View File

@ -395,10 +395,8 @@ VkResult MVKImageMemoryBinding::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDevi
_usesTexelBuffer = _device->_pMetalFeatures->texelBuffers && _deviceMemory && _deviceMemory->_mtlBuffer; // Texel buffers available
_usesTexelBuffer = _usesTexelBuffer && (isMemoryHostAccessible() || _device->_pMetalFeatures->placementHeaps) && _image->_isLinear && !_image->getIsCompressed(); // Applicable memory layout
#if MVK_MACOS
// macOS cannot use shared memory for texel buffers.
_usesTexelBuffer = _usesTexelBuffer && !isMemoryHostCoherent();
#endif
// macOS before 10.15.5 cannot use shared memory for texel buffers.
_usesTexelBuffer = _usesTexelBuffer && (_device->_pMetalFeatures->sharedLinearTextures || !isMemoryHostCoherent());
flushToDevice(getDeviceMemoryOffset(), getByteCount());
return _deviceMemory ? _deviceMemory->addImageMemoryBinding(this) : VK_SUCCESS;
@ -430,10 +428,9 @@ bool MVKImageMemoryBinding::needsHostReadSync(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
MVKPipelineBarrier& barrier) {
#if MVK_MACOS
// On macOS, texture memory is never host-coherent, so don't test for it.
return ((barrier.newLayout == VK_IMAGE_LAYOUT_GENERAL) &&
mvkIsAnyFlagEnabled(barrier.dstAccessMask, (VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT)) &&
isMemoryHostAccessible());
isMemoryHostAccessible() && (!_device->_pMetalFeatures->sharedLinearTextures || !isMemoryHostCoherent()));
#endif
#if MVK_IOS_OR_TVOS
return false;
@ -761,10 +758,10 @@ MTLStorageMode MVKImage::getMTLStorageMode() {
if (_ioSurface && stgMode == MTLStorageModePrivate) { stgMode = MTLStorageModeShared; }
#if MVK_MACOS
// For macOS, textures cannot use Shared storage mode, so change to Managed storage mode.
if (stgMode == MTLStorageModeShared) { stgMode = MTLStorageModeManaged; }
#endif
// For macOS prior to 10.15.5, textures cannot use Shared storage mode, so change to Managed storage mode.
if (stgMode == MTLStorageModeShared && !_device->_pMetalFeatures->sharedLinearTextures) {
stgMode = MTLStorageModeManaged;
}
return stgMode;
}