@@ -96,18 +96,19 @@ enum gptoss_status gptoss_metal_library_create_default(
96
96
enum gptoss_status status = gptoss_status_success;
97
97
id <MTLDevice > device_obj = (id <MTLDevice >) device->object ;
98
98
id <MTLLibrary > library_obj = nil ;
99
- NSError * error_obj = nil ;
100
- NSString * error_string_obj = nil ;
99
+ NSAutoreleasePool * autorelease_pool = nil ;
101
100
dispatch_data_t library_blob = NULL ;
102
101
103
102
unsigned long library_size = 0 ;
104
103
uint8_t * library_data = getsectiondata (&__dso_handle, " __METAL" , " __shaders" , &library_size);
105
104
if (library_data != NULL ) {
106
105
library_blob = dispatch_data_create (library_data, library_size, NULL , DISPATCH_DATA_DESTRUCTOR_DEFAULT);
106
+
107
+ autorelease_pool = [[NSAutoreleasePool alloc ] init ];
108
+ NSError * error_obj = nil ;
107
109
library_obj = [device_obj newLibraryWithData: library_blob error: &error_obj];
108
110
if (library_obj == nil ) {
109
- error_string_obj = [error_obj localizedDescription ];
110
- GPTOSS_LOG_ERROR (" failed to create Metal library: %s " , [error_string_obj UTF8String ]);
111
+ GPTOSS_LOG_ERROR (" failed to create Metal library: %s " , [[error_obj localizedDescription ] UTF8String ]);
111
112
status = gptoss_status_unsupported_system;
112
113
goto cleanup;
113
114
}
@@ -129,11 +130,8 @@ enum gptoss_status gptoss_metal_library_create_default(
129
130
if (library_blob != NULL ) {
130
131
dispatch_release (library_blob);
131
132
}
132
- if (error_string_obj != nil ) {
133
- [error_string_obj release ];
134
- }
135
- if (error_obj != nil ) {
136
- [error_obj release ];
133
+ if (autorelease_pool != nil ) {
134
+ [autorelease_pool drain ];
137
135
}
138
136
return status;
139
137
}
@@ -154,26 +152,50 @@ enum gptoss_status gptoss_metal_function_create(
154
152
const char * name,
155
153
struct gptoss_metal_function* function_out)
156
154
{
157
- NSString * name_obj = nil ;
158
- NSError * error_obj = nil ;
159
- NSString * error_string_obj = nil ;
155
+ __block NSString * error_string_obj = nil ;
160
156
id <MTLFunction > function_obj = nil ;
157
+ MTLComputePipelineDescriptor * pipeline_descriptor_obj = nil ;
158
+ __block id <MTLComputePipelineState > pipeline_state_obj = nil ;
159
+ dispatch_semaphore_t pipeline_build_semaphore = NULL ;
161
160
enum gptoss_status status = gptoss_status_success;
162
161
162
+ NSAutoreleasePool * autorelease_pool = [[NSAutoreleasePool alloc ] init ];
163
163
id <MTLLibrary > library_obj = (id <MTLLibrary >) library->object ;
164
- name_obj = [NSString stringWithUTF8String: name];
164
+ NSString * name_obj = [NSString stringWithUTF8String: name];
165
165
function_obj = [library_obj newFunctionWithName: name_obj];
166
166
if (function_obj == nil ) {
167
167
GPTOSS_LOG_ERROR (" failed to create Metal function %s " , name);
168
168
status = gptoss_status_unsupported_system;
169
169
goto cleanup;
170
170
}
171
171
id <MTLDevice > device_obj = [library_obj device ];
172
- id <MTLComputePipelineState > pipeline_state_obj = [device_obj newComputePipelineStateWithFunction: function_obj error: &error_obj];
172
+ pipeline_descriptor_obj = [[MTLComputePipelineDescriptor alloc ] init ];
173
+ [pipeline_descriptor_obj setComputeFunction: function_obj];
174
+ [pipeline_descriptor_obj setThreadGroupSizeIsMultipleOfThreadExecutionWidth: YES ];
175
+
176
+ pipeline_build_semaphore = dispatch_semaphore_create (/* value=*/ 0 );
177
+ [device_obj newComputePipelineStateWithDescriptor: pipeline_descriptor_obj
178
+ options: MTLPipelineOptionNone
179
+ completionHandler: ^(id <MTLComputePipelineState > _Nullable new_state,
180
+ MTLComputePipelineReflection * _Nullable reflection,
181
+ NSError * _Nullable error_obj) {
182
+ if (new_state != nil ) {
183
+ pipeline_state_obj = [new_state retain ];
184
+ }
185
+ if (error_obj != nil ) {
186
+ error_string_obj = [[error_obj localizedDescription ] copy ];
187
+ }
188
+ dispatch_semaphore_signal (pipeline_build_semaphore);
189
+ }];
190
+ dispatch_semaphore_wait (pipeline_build_semaphore, DISPATCH_TIME_FOREVER);
191
+
173
192
if (pipeline_state_obj == nil ) {
174
- error_string_obj = [error_obj localizedDescription ];
193
+ const char * error_string = " unknown error" ;
194
+ if (error_string_obj != nil ) {
195
+ error_string = [error_string_obj UTF8String ];
196
+ }
175
197
GPTOSS_LOG_ERROR (" failed to create Metal compute pipeline state for function %s : %s " ,
176
- name, [error_string_obj UTF8String ] );
198
+ name, error_string );
177
199
status = gptoss_status_unsupported_system;
178
200
goto cleanup;
179
201
}
@@ -189,17 +211,20 @@ enum gptoss_status gptoss_metal_function_create(
189
211
pipeline_state_obj = nil ;
190
212
191
213
cleanup:
192
- if (name_obj != nil ) {
193
- [name_obj release ];
194
- }
195
214
if (function_obj != nil ) {
196
215
[function_obj release ];
197
216
}
217
+ if (pipeline_descriptor_obj != nil ) {
218
+ [pipeline_descriptor_obj release ];
219
+ }
198
220
if (error_string_obj != nil ) {
199
221
[error_string_obj release ];
200
222
}
201
- if (error_obj != nil ) {
202
- [error_obj release ];
223
+ if (pipeline_build_semaphore != NULL ) {
224
+ dispatch_release (pipeline_build_semaphore);
225
+ }
226
+ if (autorelease_pool != nil ) {
227
+ [autorelease_pool drain ];
203
228
}
204
229
return status;
205
230
}
0 commit comments