Don't call MTLCreateSystemDefaultDevice() on every swapchain creation.
- When forcing the window system to use the same high-power GPU as the app, move the call to MTLCreateSystemDefaultDevice() to MVKDevice constructor, instead of MVKDevice::createSwapchain(), and test whether the VK_KHR_swapchain extension is enabled to determine the need to swap GPUs. - After calling MTLCreateSystemDefaultDevice() the GPU will already be the same high-power GPU, so remove attempting to replace the MTLDevice. - Remove MVKPhysicalDevice::replaceMTLDevice() as no longer used. - Remove many unnecessary inline declarations in MVKDevice.h (unrelated).
This commit is contained in:
parent
4a9bf78e03
commit
425505da47
@ -138,7 +138,7 @@ public:
|
||||
void getProperties(VkPhysicalDeviceProperties2* properties);
|
||||
|
||||
/** Returns the name of this device. */
|
||||
inline const char* getName() { return _properties.deviceName; }
|
||||
const char* getName() { return _properties.deviceName; }
|
||||
|
||||
/** Populates the specified structure with the format properties of this device. */
|
||||
void getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties);
|
||||
@ -285,7 +285,7 @@ public:
|
||||
#pragma mark Memory models
|
||||
|
||||
/** Returns a pointer to the memory characteristics of this device. */
|
||||
inline const VkPhysicalDeviceMemoryProperties* getMemoryProperties() { return &_memoryProperties; }
|
||||
const VkPhysicalDeviceMemoryProperties* getMemoryProperties() { return &_memoryProperties; }
|
||||
|
||||
/** Populates the specified memory properties with the memory characteristics of this device. */
|
||||
VkResult getMemoryProperties(VkPhysicalDeviceMemoryProperties* pMemoryProperties);
|
||||
@ -297,31 +297,31 @@ public:
|
||||
* Returns a bit mask of all memory type indices.
|
||||
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
|
||||
*/
|
||||
inline uint32_t getAllMemoryTypes() { return _allMemoryTypes; }
|
||||
uint32_t getAllMemoryTypes() { return _allMemoryTypes; }
|
||||
|
||||
/**
|
||||
* Returns a bit mask of all memory type indices that allow host visibility to the memory.
|
||||
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
|
||||
*/
|
||||
inline uint32_t getHostVisibleMemoryTypes() { return _hostVisibleMemoryTypes; }
|
||||
uint32_t getHostVisibleMemoryTypes() { return _hostVisibleMemoryTypes; }
|
||||
|
||||
/**
|
||||
* Returns a bit mask of all memory type indices that are coherent between host and device.
|
||||
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
|
||||
*/
|
||||
inline uint32_t getHostCoherentMemoryTypes() { return _hostCoherentMemoryTypes; }
|
||||
uint32_t getHostCoherentMemoryTypes() { return _hostCoherentMemoryTypes; }
|
||||
|
||||
/**
|
||||
* Returns a bit mask of all memory type indices that do NOT allow host visibility to the memory.
|
||||
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
|
||||
*/
|
||||
inline uint32_t getPrivateMemoryTypes() { return _privateMemoryTypes; }
|
||||
uint32_t getPrivateMemoryTypes() { return _privateMemoryTypes; }
|
||||
|
||||
/**
|
||||
* Returns a bit mask of all memory type indices that are lazily allocated.
|
||||
* Each bit [0..31] in the returned bit mask indicates a distinct memory type.
|
||||
*/
|
||||
inline uint32_t getLazilyAllocatedMemoryTypes() { return _lazilyAllocatedMemoryTypes; }
|
||||
uint32_t getLazilyAllocatedMemoryTypes() { return _lazilyAllocatedMemoryTypes; }
|
||||
|
||||
/** Returns whether this is a unified memory device. */
|
||||
bool getHasUnifiedMemory();
|
||||
@ -336,21 +336,13 @@ public:
|
||||
#pragma mark Metal
|
||||
|
||||
/** Populates the specified structure with the Metal-specific features of this device. */
|
||||
inline const MVKPhysicalDeviceMetalFeatures* getMetalFeatures() { return &_metalFeatures; }
|
||||
const MVKPhysicalDeviceMetalFeatures* getMetalFeatures() { return &_metalFeatures; }
|
||||
|
||||
/** Returns whether or not vertex instancing can be used to implement multiview. */
|
||||
inline bool canUseInstancingForMultiview() { return _metalFeatures.layeredRendering && _metalFeatures.deferredStoreActions; }
|
||||
bool canUseInstancingForMultiview() { return _metalFeatures.layeredRendering && _metalFeatures.deferredStoreActions; }
|
||||
|
||||
/** Returns the underlying Metal device. */
|
||||
inline id<MTLDevice> getMTLDevice() { return _mtlDevice; }
|
||||
|
||||
/*** Replaces the underlying Metal device .*/
|
||||
inline void replaceMTLDevice(id<MTLDevice> mtlDevice) {
|
||||
if (mtlDevice != _mtlDevice) {
|
||||
[_mtlDevice release];
|
||||
_mtlDevice = [mtlDevice retain];
|
||||
}
|
||||
}
|
||||
id<MTLDevice> getMTLDevice() { return _mtlDevice; }
|
||||
|
||||
/** Returns whether the MSL version is supported on this device. */
|
||||
bool mslVersionIsAtLeast(MTLLanguageVersion minVer) { return _metalFeatures.mslVersionEnum >= minVer; }
|
||||
@ -387,7 +379,7 @@ public:
|
||||
* Returns a reference to this object suitable for use as a Vulkan API handle.
|
||||
* This is the compliment of the getMVKPhysicalDevice() method.
|
||||
*/
|
||||
inline VkPhysicalDevice getVkPhysicalDevice() { return (VkPhysicalDevice)getVkHandle(); }
|
||||
VkPhysicalDevice getVkPhysicalDevice() { return (VkPhysicalDevice)getVkHandle(); }
|
||||
|
||||
/**
|
||||
* Retrieves the MVKPhysicalDevice instance referenced by the VkPhysicalDevice handle.
|
||||
@ -475,16 +467,16 @@ public:
|
||||
MVKInstance* getInstance() override { return _physicalDevice->getInstance(); }
|
||||
|
||||
/** Returns the physical device underlying this logical device. */
|
||||
inline MVKPhysicalDevice* getPhysicalDevice() { return _physicalDevice; }
|
||||
MVKPhysicalDevice* getPhysicalDevice() { return _physicalDevice; }
|
||||
|
||||
/** Returns info about the pixel format supported by the physical device. */
|
||||
inline MVKPixelFormats* getPixelFormats() { return &_physicalDevice->_pixelFormats; }
|
||||
MVKPixelFormats* getPixelFormats() { return &_physicalDevice->_pixelFormats; }
|
||||
|
||||
/** Returns the name of this device. */
|
||||
inline const char* getName() { return _pProperties->deviceName; }
|
||||
const char* getName() { return _pProperties->deviceName; }
|
||||
|
||||
/** Returns the common resource factory for creating command resources. */
|
||||
inline MVKCommandResourceFactory* getCommandResourceFactory() { return _commandResourceFactory; }
|
||||
MVKCommandResourceFactory* getCommandResourceFactory() { return _commandResourceFactory; }
|
||||
|
||||
/** Returns the function pointer corresponding to the specified named entry point. */
|
||||
PFN_vkVoidFunction getProcAddr(const char* pName);
|
||||
@ -699,7 +691,7 @@ public:
|
||||
* number of nanoseconds between the two calls. The convenience function mvkGetElapsedMilliseconds()
|
||||
* can be used to perform this calculation.
|
||||
*/
|
||||
inline uint64_t getPerformanceTimestamp() { return _isPerformanceTracking ? mvkGetTimestamp() : 0; }
|
||||
uint64_t getPerformanceTimestamp() { return _isPerformanceTracking ? mvkGetTimestamp() : 0; }
|
||||
|
||||
/**
|
||||
* If performance is being tracked, adds the performance for an activity with a duration
|
||||
@ -707,8 +699,8 @@ public:
|
||||
*
|
||||
* If endTime is zero or not supplied, the current time is used.
|
||||
*/
|
||||
inline void addActivityPerformance(MVKPerformanceTracker& activityTracker,
|
||||
uint64_t startTime, uint64_t endTime = 0) {
|
||||
void addActivityPerformance(MVKPerformanceTracker& activityTracker,
|
||||
uint64_t startTime, uint64_t endTime = 0) {
|
||||
if (_isPerformanceTracking) {
|
||||
updateActivityPerformance(activityTracker, startTime, endTime);
|
||||
|
||||
@ -742,7 +734,7 @@ public:
|
||||
#pragma mark Metal
|
||||
|
||||
/** Returns the underlying Metal device. */
|
||||
inline id<MTLDevice> getMTLDevice() { return _physicalDevice->getMTLDevice(); }
|
||||
id<MTLDevice> getMTLDevice() { return _physicalDevice->getMTLDevice(); }
|
||||
|
||||
/** Returns whether this device is using Metal argument buffers. */
|
||||
bool isUsingMetalArgumentBuffers() { return _isUsingMetalArgumentBuffers; };
|
||||
@ -818,7 +810,7 @@ public:
|
||||
void stopAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope);
|
||||
|
||||
/** Returns whether this instance is currently automatically capturing a GPU trace. */
|
||||
inline bool isCurrentlyAutoGPUCapturing() { return _isCurrentlyAutoGPUCapturing; }
|
||||
bool isCurrentlyAutoGPUCapturing() { return _isCurrentlyAutoGPUCapturing; }
|
||||
|
||||
/** Returns the Metal objects underpinning the Vulkan objects indicated in the pNext chain of pMetalObjectsInfo. */
|
||||
void getMetalObjects(VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
|
||||
@ -866,7 +858,7 @@ public:
|
||||
* Returns a reference to this object suitable for use as a Vulkan API handle.
|
||||
* This is the compliment of the getMVKDevice() method.
|
||||
*/
|
||||
inline VkDevice getVkDevice() { return (VkDevice)getVkHandle(); }
|
||||
VkDevice getVkDevice() { return (VkDevice)getVkHandle(); }
|
||||
|
||||
/**
|
||||
* Retrieves the MVKDevice instance referenced by the VkDevice handle.
|
||||
|
@ -3629,20 +3629,6 @@ void MVKDevice::destroyImageView(MVKImageView* mvkImgView,
|
||||
|
||||
MVKSwapchain* MVKDevice::createSwapchain(const VkSwapchainCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
#if MVK_MACOS
|
||||
// If we have selected a high-power GPU and want to force the window system
|
||||
// to use it, force the window system to use a high-power GPU by calling the
|
||||
// MTLCreateSystemDefaultDevice function, and if that GPU is the same as the
|
||||
// selected GPU, update the MTLDevice instance used by the MVKPhysicalDevice.
|
||||
id<MTLDevice> mtlDevice = _physicalDevice->getMTLDevice();
|
||||
if (mvkConfig().switchSystemGPU && !(mtlDevice.isLowPower || mtlDevice.isHeadless) ) {
|
||||
id<MTLDevice> sysMTLDevice = MTLCreateSystemDefaultDevice();
|
||||
if (mvkGetRegistryID(sysMTLDevice) == mvkGetRegistryID(mtlDevice)) {
|
||||
_physicalDevice->replaceMTLDevice(sysMTLDevice);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return new MVKSwapchain(this, pCreateInfo);
|
||||
}
|
||||
|
||||
@ -4488,6 +4474,18 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
|
||||
initQueues(pCreateInfo);
|
||||
reservePrivateData(pCreateInfo);
|
||||
|
||||
#if MVK_MACOS
|
||||
// After enableExtensions
|
||||
// If the VK_KHR_swapchain extension is enabled, we expect to render to the screen.
|
||||
// In a multi-GPU system, if we are using the high-power GPU and want the window system
|
||||
// to also use that GPU to avoid copying content between GPUs, force the window system
|
||||
// to use the high-power GPU by calling the MTLCreateSystemDefaultDevice() function.
|
||||
if (_enabledExtensions.vk_KHR_swapchain.enabled && mvkConfig().switchSystemGPU &&
|
||||
!(_physicalDevice->_mtlDevice.isLowPower || _physicalDevice->_mtlDevice.isHeadless) ) {
|
||||
MTLCreateSystemDefaultDevice();
|
||||
}
|
||||
#endif
|
||||
|
||||
// After enableExtensions && enableFeatures
|
||||
// Use Metal arg buffs if available, and either config wants them always,
|
||||
// or config wants them with descriptor indexing and descriptor indexing has been enabled.
|
||||
|
Loading…
x
Reference in New Issue
Block a user