-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathcapabilities.mm
More file actions
175 lines (142 loc) · 5.66 KB
/
capabilities.mm
File metadata and controls
175 lines (142 loc) · 5.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// Copyright 2020 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#include "pxr/imaging/hgiMetal/capabilities.h"
#include "pxr/imaging/hgiMetal/hgi.h"
#include "pxr/base/arch/defines.h"
#include "pxr/base/tf/envSetting.h"
#include <Metal/Metal.h>
PXR_NAMESPACE_OPEN_SCOPE
TF_DEFINE_ENV_SETTING(HGIMETAL_ENABLE_INDIRECT_COMMAND_BUFFER, true,
"Enable indirect command buffers");
HgiMetalCapabilities::HgiMetalCapabilities(id<MTLDevice> device)
{
if (@available(macOS 10.14.5, ios 12.0, *)) {
_SetFlag(HgiDeviceCapabilitiesBitsConcurrentDispatch, true);
}
#if defined(ARCH_OS_OSX)
bool const hasIntelGPU = [device isLowPower];
#else
bool const hasIntelGPU = false;
#endif
defaultStorageMode = MTLResourceStorageModeShared;
bool unifiedMemory = false;
bool barycentrics = false;
bool hasAppleSilicon = false;
bool icbSupported = false;
if (@available(macOS 100.100, ios 12.0, *)) {
unifiedMemory = true;
} else if (@available(macOS 10.15, ios 13.0, *)) {
#if defined(ARCH_OS_IPHONE) || (defined(__MAC_10_15) && __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_15)
unifiedMemory = [device hasUnifiedMemory];
#else
unifiedMemory = [device isLowPower];
#endif
// On macOS 10.15 and 11.0 the AMD drivers reported the wrong value for
// supportsShaderBarycentricCoordinates so check both flags.
// Also, Intel GPU drivers do not correctly support barycentrics.
barycentrics = ([device supportsShaderBarycentricCoordinates]
|| [device areBarycentricCoordsSupported])
&& !hasIntelGPU;
hasAppleSilicon = [device hasUnifiedMemory] && !hasIntelGPU;
}
if (hasAppleSilicon) {
// Indirect command buffers supported only on
// Apple Silicon GPUs with macOS 12.3 or later.
icbSupported = false;
if (@available(macOS 12.3, *)) {
icbSupported = true;
}
} else if (hasIntelGPU) {
// Indirect command buffers not currently supported on Intel GPUs.
icbSupported = false;
}
if (!TfGetEnvSetting(HGIMETAL_ENABLE_INDIRECT_COMMAND_BUFFER)) {
icbSupported = false;
}
_SetFlag(HgiDeviceCapabilitiesBitsUnifiedMemory, unifiedMemory);
_SetFlag(HgiDeviceCapabilitiesBitsBuiltinBarycentrics, barycentrics);
_SetFlag(HgiDeviceCapabilitiesBitsShaderDoublePrecision, false);
_SetFlag(HgiDeviceCapabilitiesBitsDepthRangeMinusOnetoOne, false);
_SetFlag(HgiDeviceCapabilitiesBitsCppShaderPadding, true);
_SetFlag(HgiDeviceCapabilitiesBitsMetalTessellation, true);
_SetFlag(HgiDeviceCapabilitiesBitsMultiDrawIndirect, true);
_SetFlag(HgiDeviceCapabilitiesBitsIndirectCommandBuffers, icbSupported);
// This is done to decide whether to use a workaround for post tess
// patch primitive ID lookup. The bug causes the firstPatch offset
// to be included incorrectly in the primitive ID. Our workaround
// is to subtract it based on the base primitive offset
// Found in MacOS 13. If confirmed fixed for MacOS 14, add a check
// if we are on MacOS 14 or less
//bool isMacOs13OrLess = NSProcessInfo.processInfo.operatingSystemVersion.majorVersion <= 13
//bool requireBasePrimitiveOffset = hasAppleSilicon && isMacOs13OrLess;
bool requiresBasePrimitiveOffset = hasAppleSilicon || hasIntelGPU;
_SetFlag(HgiDeviceCapabilitiesBitsBasePrimitiveOffset,
requiresBasePrimitiveOffset);
// Intel GPU drivers do not correctly support primitive_id.
if (hasIntelGPU) {
_SetFlag(HgiDeviceCapabilitiesBitsPrimitiveIdEmulation, true);
}
#if defined(ARCH_OS_OSX)
if (!unifiedMemory) {
defaultStorageMode = MTLResourceStorageModeManaged;
}
#endif
_maxUniformBlockSize = 64 * 1024;
_maxShaderStorageBlockSize = 1 * 1024 * 1024 * 1024;
_uniformBufferOffsetAlignment = 16;
_maxClipDistances = 8;
_pageSizeAlignment = 4096;
// TODO: [VG]
// Apple Silicon only support memory barriers between vertex stages after
// macOS 12.3.
hasVertexMemoryBarrier = !hasAppleSilicon;
if (@available(macOS 12.3, *)) {
hasVertexMemoryBarrier = true;
}
// Vega GPUs require a fix to the indirect draw before macOS 12.2
requiresIndirectDrawFix = false;
if ([[device name] rangeOfString: @"Vega"].location != NSNotFound) {
if (@available(macOS 12.2, *)) {}
else
{
requiresIndirectDrawFix = true;
}
}
// Return immediately from the fragment shader main function after
// executing discard_fragment() in order to avoid side effects
// from buffer writes. We disable this behavior for MTLGPUFamilyApple9
// (Apple M3) devices until macOS 14.4.
requiresReturnAfterDiscard = true;
if ([[device name] rangeOfString: @"Apple M3"].location != NSNotFound) {
if (@available(macOS 14.4, *)) {}
else
{
requiresReturnAfterDiscard = false;
}
}
useParallelEncoder = true;
}
HgiMetalCapabilities::~HgiMetalCapabilities() = default;
int
HgiMetalCapabilities::GetAPIVersion() const
{
if (@available(macOS 10.15, ios 13.0, *)) {
return APIVersion_Metal3_0;
}
if (@available(macOS 10.13, ios 11.0, *)) {
return APIVersion_Metal2_0;
}
return APIVersion_Metal1_0;
}
int
HgiMetalCapabilities::GetShaderVersion() const
{
// Note: This is not the Metal Shader Language version. It is provided for
// compatibility with code that is asking for the GLSL version.
return 450;
}
PXR_NAMESPACE_CLOSE_SCOPE