Reland "Set up eGPU/discrete support for MacOS."
This is a reland of 1c3bea4593
Original change's description:
> Set up eGPU/discrete support for MacOS.
>
> Pulled out of https://skia-review.googlesource.com/c/skia/+/271319.
>
> For Metal, will default to an eGPU or discrete GPU if one is available.
> For GL, will attempt to use a Radeon eGPU, and will fallback
> if one can't be found.
>
> Change-Id: I0a1efb3afca612ac75be56f633d811dda68f9d10
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/277516
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Change-Id: I1f9dcbf82465533ae8bce96b5cc73a7c627071a4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/277696
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
8370fd1267
commit
d29d885c88
@ -96,6 +96,7 @@ public:
|
||||
#if GR_TEST_UTILS
|
||||
std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
|
||||
#endif
|
||||
void onDumpJSON(SkJSONWriter*) const override;
|
||||
|
||||
private:
|
||||
void initFeatureSet(MTLFeatureSet featureSet);
|
||||
|
@ -1104,3 +1104,43 @@ std::vector<GrCaps::TestFormatColorTypeCombination> GrMtlCaps::getTestingCombina
|
||||
return combos;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_ENABLE_DUMP_GPU
|
||||
#include "src/utils/SkJSONWriter.h"
|
||||
void GrMtlCaps::onDumpJSON(SkJSONWriter* writer) const {
|
||||
|
||||
// We are called by the base class, which has already called beginObject(). We choose to nest
|
||||
// all of our caps information in a named sub-object.
|
||||
writer->beginObject("Metal caps");
|
||||
|
||||
writer->beginObject("Preferred Stencil Format");
|
||||
writer->appendS32("stencil bits", fPreferredStencilFormat.fStencilBits);
|
||||
writer->appendS32("total bits", fPreferredStencilFormat.fTotalBits);
|
||||
writer->endObject();
|
||||
|
||||
switch (fPlatform) {
|
||||
case Platform::kMac:
|
||||
writer->appendString("Platform", "Mac");
|
||||
break;
|
||||
case Platform::kIOS:
|
||||
writer->appendString("Platform", "iOS");
|
||||
break;
|
||||
default:
|
||||
writer->appendString("Platform", "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
writer->appendS32("Family Group", fFamilyGroup);
|
||||
writer->appendS32("Version", fVersion);
|
||||
|
||||
writer->beginArray("Sample Counts");
|
||||
for (int v : fSampleCounts) {
|
||||
writer->appendS32(nullptr, v);
|
||||
}
|
||||
writer->endArray();
|
||||
|
||||
writer->endObject();
|
||||
}
|
||||
#else
|
||||
void GrMtlCaps::onDumpJSON(SkJSONWriter* writer) const { }
|
||||
#endif
|
||||
|
@ -224,6 +224,10 @@ private:
|
||||
void testingOnly_endCapture() override;
|
||||
#endif
|
||||
|
||||
#ifdef SK_ENABLE_DUMP_GPU
|
||||
void onDumpJSON(SkJSONWriter*) const override;
|
||||
#endif
|
||||
|
||||
sk_sp<GrMtlCaps> fMtlCaps;
|
||||
|
||||
id<MTLDevice> fDevice;
|
||||
|
@ -1421,3 +1421,137 @@ void GrMtlGpu::testingOnly_endCapture() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_ENABLE_DUMP_GPU
|
||||
#include "src/utils/SkJSONWriter.h"
|
||||
void GrMtlGpu::onDumpJSON(SkJSONWriter* writer) const {
|
||||
// We are called by the base class, which has already called beginObject(). We choose to nest
|
||||
// all of our caps information in a named sub-object.
|
||||
writer->beginObject("Metal GPU");
|
||||
|
||||
writer->beginObject("Device");
|
||||
writer->appendString("name", fDevice.name.UTF8String);
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.11, *)) {
|
||||
writer->appendBool("isHeadless", fDevice.isHeadless);
|
||||
writer->appendBool("isLowPower", fDevice.isLowPower);
|
||||
}
|
||||
if (@available(macOS 10.13, *)) {
|
||||
writer->appendBool("isRemovable", fDevice.isRemovable);
|
||||
}
|
||||
#endif
|
||||
if (@available(macOS 10.13, iOS 11.0, *)) {
|
||||
writer->appendU64("registryID", fDevice.registryID);
|
||||
}
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.15, *)) {
|
||||
switch (fDevice.location) {
|
||||
case MTLDeviceLocationBuiltIn:
|
||||
writer->appendString("location", "builtIn");
|
||||
break;
|
||||
case MTLDeviceLocationSlot:
|
||||
writer->appendString("location", "slot");
|
||||
break;
|
||||
case MTLDeviceLocationExternal:
|
||||
writer->appendString("location", "external");
|
||||
break;
|
||||
case MTLDeviceLocationUnspecified:
|
||||
writer->appendString("location", "unspecified");
|
||||
break;
|
||||
default:
|
||||
writer->appendString("location", "unknown");
|
||||
break;
|
||||
}
|
||||
writer->appendU64("locationNumber", fDevice.locationNumber);
|
||||
writer->appendU64("maxTransferRate", fDevice.maxTransferRate);
|
||||
}
|
||||
#endif // SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.15, iOS 13.0, *)) {
|
||||
writer->appendBool("hasUnifiedMemory", fDevice.hasUnifiedMemory);
|
||||
}
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.15, *)) {
|
||||
writer->appendU64("peerGroupID", fDevice.peerGroupID);
|
||||
writer->appendU32("peerCount", fDevice.peerCount);
|
||||
writer->appendU32("peerIndex", fDevice.peerIndex);
|
||||
}
|
||||
if (@available(macOS 10.12, *)) {
|
||||
writer->appendU64("recommendedMaxWorkingSetSize", fDevice.recommendedMaxWorkingSetSize);
|
||||
}
|
||||
#endif // SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.13, iOS 11.0, *)) {
|
||||
writer->appendU64("currentAllocatedSize", fDevice.currentAllocatedSize);
|
||||
writer->appendU64("maxThreadgroupMemoryLength", fDevice.maxThreadgroupMemoryLength);
|
||||
}
|
||||
|
||||
writer->beginObject("maxThreadsPerThreadgroup");
|
||||
writer->appendU64("width", fDevice.maxThreadsPerThreadgroup.width);
|
||||
writer->appendU64("height", fDevice.maxThreadsPerThreadgroup.height);
|
||||
writer->appendU64("depth", fDevice.maxThreadsPerThreadgroup.depth);
|
||||
writer->endObject();
|
||||
|
||||
if (@available(macOS 10.13, iOS 11.0, *)) {
|
||||
writer->appendBool("areProgrammableSamplePositionsSupported",
|
||||
fDevice.areProgrammableSamplePositionsSupported);
|
||||
writer->appendBool("areRasterOrderGroupsSupported",
|
||||
fDevice.areRasterOrderGroupsSupported);
|
||||
}
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.11, *)) {
|
||||
writer->appendBool("isDepth24Stencil8PixelFormatSupported",
|
||||
fDevice.isDepth24Stencil8PixelFormatSupported);
|
||||
|
||||
}
|
||||
if (@available(macOS 10.15, *)) {
|
||||
writer->appendBool("areBarycentricCoordsSupported",
|
||||
fDevice.areBarycentricCoordsSupported);
|
||||
writer->appendBool("supportsShaderBarycentricCoordinates",
|
||||
fDevice.supportsShaderBarycentricCoordinates);
|
||||
}
|
||||
#endif // SK_BUILD_FOR_MAC
|
||||
if (@available(macOS 10.14, iOS 12.0, *)) {
|
||||
writer->appendU64("maxBufferLength", fDevice.maxBufferLength);
|
||||
}
|
||||
if (@available(macOS 10.13, iOS 11.0, *)) {
|
||||
switch (fDevice.readWriteTextureSupport) {
|
||||
case MTLReadWriteTextureTier1:
|
||||
writer->appendString("readWriteTextureSupport", "tier1");
|
||||
break;
|
||||
case MTLReadWriteTextureTier2:
|
||||
writer->appendString("readWriteTextureSupport", "tier2");
|
||||
break;
|
||||
case MTLReadWriteTextureTierNone:
|
||||
writer->appendString("readWriteTextureSupport", "tierNone");
|
||||
break;
|
||||
default:
|
||||
writer->appendString("readWriteTextureSupport", "unknown");
|
||||
break;
|
||||
}
|
||||
switch (fDevice.argumentBuffersSupport) {
|
||||
case MTLArgumentBuffersTier1:
|
||||
writer->appendString("argumentBuffersSupport", "tier1");
|
||||
break;
|
||||
case MTLArgumentBuffersTier2:
|
||||
writer->appendString("argumentBuffersSupport", "tier2");
|
||||
break;
|
||||
default:
|
||||
writer->appendString("argumentBuffersSupport", "unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (@available(macOS 10.14, iOS 12.0, *)) {
|
||||
writer->appendU64("maxArgumentBufferSamplerCount", fDevice.maxArgumentBufferSamplerCount);
|
||||
}
|
||||
#ifdef SK_BUILD_FOR_IOS
|
||||
if (@available(iOS 13.0, *)) {
|
||||
writer->appendU64("sparseTileSizeInBytes", fDevice.sparseTileSizeInBytes);
|
||||
}
|
||||
#endif
|
||||
writer->endObject();
|
||||
|
||||
writer->appendString("queue", fQueue.label.UTF8String);
|
||||
writer->appendBool("disconnected", fDisconnected);
|
||||
|
||||
writer->endObject();
|
||||
}
|
||||
#endif
|
||||
|
@ -40,18 +40,41 @@ private:
|
||||
MacGLTestContext::MacGLTestContext(MacGLTestContext* shareContext)
|
||||
: fContext(nullptr)
|
||||
, fGLLibrary(RTLD_DEFAULT) {
|
||||
// We first try to request a Radeon eGPU if one is available.
|
||||
// This will be a Radeon HD7000 and up, which includes all eGPU configs.
|
||||
// If that fails, we try again with only the base parameters.
|
||||
CGLPixelFormatAttribute attributes[] = {
|
||||
// base parameters
|
||||
#if MAC_OS_X_VERSION_10_7
|
||||
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
|
||||
kCGLPFAOpenGLProfile,
|
||||
(CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
|
||||
#endif
|
||||
kCGLPFADoubleBuffer,
|
||||
(CGLPixelFormatAttribute)0
|
||||
|
||||
#if MAC_OS_X_VERSION_10_8
|
||||
// eGPU parameters
|
||||
kCGLPFAAllowOfflineRenderers, // Enables e-GPU.
|
||||
kCGLPFANoRecovery, // Disallows software rendering.
|
||||
kCGLPFARendererID, (CGLPixelFormatAttribute)kCGLRendererATIRadeonX4000ID, // Select Radeon
|
||||
#endif
|
||||
(CGLPixelFormatAttribute)NULL
|
||||
};
|
||||
#if MAC_OS_X_VERSION_10_8
|
||||
static const int kFirstEGPUParameter = 3;
|
||||
SkASSERT(kCGLPFAAllowOfflineRenderers == attributes[kFirstEGPUParameter]);
|
||||
#endif
|
||||
|
||||
CGLPixelFormatObj pixFormat;
|
||||
GLint npix;
|
||||
|
||||
CGLChoosePixelFormat(attributes, &pixFormat, &npix);
|
||||
|
||||
#if MAC_OS_X_VERSION_10_8
|
||||
if (nullptr == pixFormat) {
|
||||
// Move the NULL-termination up to remove the eGPU parameters and try again
|
||||
attributes[kFirstEGPUParameter] = (CGLPixelFormatAttribute)NULL;
|
||||
CGLChoosePixelFormat(attributes, &pixFormat, &npix);
|
||||
}
|
||||
#endif
|
||||
if (nullptr == pixFormat) {
|
||||
SkDebugf("CGLChoosePixelFormat failed.");
|
||||
return;
|
||||
|
@ -27,7 +27,25 @@ public:
|
||||
device = sharedContextImpl->device();
|
||||
queue = sharedContextImpl->queue();
|
||||
} else {
|
||||
#ifdef SK_BUILD_FOR_MAC
|
||||
NSArray<id <MTLDevice>>* availableDevices = MTLCopyAllDevices();
|
||||
// Choose the non-integrated CPU if available
|
||||
for (id<MTLDevice> dev in availableDevices) {
|
||||
if (!dev.isLowPower) {
|
||||
device = dev;
|
||||
break;
|
||||
}
|
||||
if (dev.isRemovable) {
|
||||
device = dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!device) {
|
||||
device = MTLCreateSystemDefaultDevice();
|
||||
}
|
||||
#else
|
||||
device = MTLCreateSystemDefaultDevice();
|
||||
#endif
|
||||
queue = [device newCommandQueue];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user