Post

Replies

Boosts

Views

Activity

Reply to Clarification of Tier 2 Argument Buffer Capabilities
Pretty sure the limitation is in dynamic indexing into Argument Buffers, so maybe constant indexing works. You need iPhone 11+ or macOS on a Tier 2 GPU which are newer Intel/AMD parts. I have the Vulkan specs for this, but don't have them handy, but it's newer phones. Useful for raytracing and also to avoid needing to use sparse textures. Bindless graphics are the way things are headed now, but Nvidia had this technology for over 10 years in OpenGL.
Apr ’21
Reply to macOS 10.15 deployment breaks monkeypatching C++ vtable
I believe this code is only used during development, but I only found out it broke trying to move our base deployment off of 10.9. 10.14 worked, and 10.15 didn't. On another thread, I'd also mentioned that iOS 10+ blocking mmap also prevents C++ dylib hotloading. I feel like blocking this prevents all gamedevs from hotloading their C++ game logic. That's a big deal when you're trying to modify code and content quickly. As games get bigger in size and complexity, the time to launch increases. Even Unity or Unreal require a reload after engine changes. If Apple's going to really push game tech, then this would be a big help even if we have to set a security/dev-only entitlement. Anyways, Quinn thanks so much for the quick response on this.
Apr ’21
Reply to dylib: file system sandbox blocked mmap()
We also have the same issue. This used to work in iOS 9, and was blocked in iOS 10+. Can we have a mode or entitlement that removes the code blocking mmap from an alternate folder? There are many titles that need to hotload C++ dylibs during development, and this restriction totally kills that. Our min-spec can't move off iOS 9 until this issue is addressed. Swift supports hotloading now, so this really can't be an Apple only feature.
Apr ’21
Reply to dlopen() reloads original instead of new dylib after changes
The forums allow a reply and then say the content is restricted. That loses so many replies. So we think we found the issue with dyld return the same dylib on hotload and even on relaunch of the application. Unlike linux, which sets RTLD_LOCAL by default, Apple's "man dlopen" indicates that RTLD_GLOBAL is set by default on macOS. We verfied with "image list -b -m foo.dylib" that the timestamp doesn't update while running when the dylib is changed out during a hotload with the default setting (RTLD_GLOBAL) and we only set RTLD_NOW. Also relaunching the app, still returns the old dylib and no the new one in the folder. So something about the internal caching and trying to accelerate re-launch isn't correct. We now set RTLD_LOCAL | RGLD_NOW and are seeing the correct dylib behavior. The new dylib is picked up during app execution and when the app is relaunched.
Apr ’21
Reply to How to enable Rez in Xcode 12.2
This was the CMake command to build with Rez. Finally got it to generate a non-zero file. The -useDF to use the data fork was important. I guess will move to command line Rez builds instead, but the plugin isn't recognized like it is when Xcode processes the .r file. That may have other causes. add_custom_command(TARGET ${myTargetApp} PRE_BUILD DEPENDS ${MY_SOURCE_DIR}/MyResource.r COMMAND ${rezCompiler} several .r are located across the build I ${MY_SOURCE_DIR}/resources/ arch x86_64 use the datafork useDF needs to specify for Carbon.r and CoreServices.r? #-F Carbon #-F CoreServices where to find framework files isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/ o "${MY_SOURCE_DIR}/${myTargetApp}.rsrc" ${MY_SOURCE_DIR}/MyResource.r )
Mar ’21
Reply to dlopen() reloads original instead of new dylib after changes
Also just to emphasize the broken behavior. If lldb cannot report the correct data, then I'm not sure how to triage this. "image list" and "image list <name>" report different output. One doesn't and one does list the original dylib that's already been unloaded (at least according to dyld printouts). So I think the dyld gets confused, and starts trying to return the original dylib from time to tim. (lldb) image list -b -m bar_signed_000.dylib [  0] bar_signed_000.dylib Fri Jan 15 11:23:27 2021 dlclose(lib) <- "bar_signed_000.dylib" dyld: unloaded: <A6723547-512E-30A0-9EE5-6E17DB08F79B> /foo/bar_signed_000.dylib <- great dlopen(“/foo/bar_signed_001.dylib”) (lldb) image list -b -m /foo/bar_signed_000.dylib [ 0] bar_signed_000.dylib Fri Jan 15 11:23:27 2021. <- why is this still listed? it’s not in "image list" dyld: Mapping /foo/bar_signed_001.dylib dyld: loaded: <A6723547-512E-30A0-9EE5-6E17DB08F79B> /foo/bar_signed_001.dylib (lldb) image list -b -m Game_signed_001.dylib error: no modules found that match 'Game_signed_001.dylib’ <- dyld said it just loaded 001, why can “image list” find it?
Jan ’21
Reply to dlopen() reloads original instead of new dylib after changes
I should add that in the lldb session above, the library hotloads correctly despite "image list" reporting the name of the older library. Also "image list barsigned000.dylib" always reports something even when the library isn't loaded, but "image list" does not. It would be nice to not have to list every dylib from lldb to verify where one is loaded, but that appears to not be possible with current lldb. Also I forgot it in the example, but "image list -b" no longer listed the barsigned000.dylib after dlclose(). So that in addition to the dyld printout leads me to believe the dylib was purged. So we get stuck in a state where hotloading stops working, and we get constant crashes in dylib init code at startup after a test hotload that shouldn't crash. Then a few hours later, this problem goes away, as if there was a timeout on the dyld dylib cache that is failing.
Jan ’21
Reply to dlopen() reloads original instead of new dylib after changes
So here's a capture from dlopen/dlclose() of the same library renumbered at the end. The path doesn't change, and it's looks like the cache restores the original 000.dylib instead of the 001.dylib that dlopen() requested on the second call. I have dyld environment settings providing a little more insight here. (lldb) image list -b [621] other.dylib [622] other2.dylib dlopen("/foo/bar_signed_000.dylib") dyld: Mapping /foo/bar_signed_000.dylib dyld: loaded: <A6723547-512E-30A0-9EE5-6E17DB08F79B> /foo/bar_signed_000.dylib (lldb) image list -b [621] other.dylib [622] other2.dylib [623] bar_signed_000.dylib <- correct, it’s loaded and in the list dlclose() dyld: unloaded: <A6723547-512E-30A0-9EE5-6E17DB08F79B> /foo/bar_signed_000.dylib <- correct, unloaded dlopen("/foo/bar_signed_001.dylib") dyld: loaded: <A6723547-512E-30A0-9EE5-6E17DB08F79B> /foo/bar_signed_001.dylib <- dyld reused the UUID? (lldb) image list -b [627] bar_signed_000.dylib <- ugh, this is wrong path
Jan ’21
Reply to dlopen() reloads original instead of new dylib after changes
Hi Quinn, The "image list" is a good suggestion. I was just using that other day. I'll try that, and see what lldb reports. This is pure C++, no Swift or ObjC usage. For some of our users, the dylib hotloads and for others not. It's a mix of people mostly on 10.15.7 and XCode 12.2/3. I did the implementation mentioned above of renaming the lib, but it seems like we have a partial reload. So some code hotloads fine, and other code is still pointing to the old lib. Some code at init of the dylib where we crash (with renaming) is reporting the previous numbered dylib in the debugger. This may be an artifact of how Xcode loads the sources once at launch, but when I do hotload, my breakpoints show the new sources. By ODR, do you mean on-demand-resource? We did have those a while back, but I think they're disabled currently. it’s definitely not there after dlclose() on my system. But my system works. Others don't. So I'll get some more info on the machines that don't hotload. after dlopen() (lldb) image list  [623] 1BA9F1FE-153F-3F2B-94ED-A7F7CDD466D7 0x0000000180800000 foosigned.dylib after dlclose()  dyld: unloaded: <1BA9F1FE-153F-3F2B-94ED-A7F7CDD466D7> foosigned.dylib (lldb) image list  (lldb)
Jan ’21
Reply to dlopen() reloads original instead of new dylib after changes
Here's one theoretical workaround, but which seems like a hack to what is a fundamental dyld problem. Dynamic libraries make little sense if you can't reload them dynamically. The dyld cache has been around forever, but seems to be not functioning properly here. The modstamp on the dylib is completely different in this case, and should be detected and that version loaded, instead of returning the old dylib. Also how do you tell with otool if a dylib doesn't meet the criteria for hotloading? Are there any parameters which state that it uses ObjC, thread_local, or Swift code? There must be criteria that dyld uses to prevent hotloading. Also is there a way to tell with all of the dyld environment flags the modstamp of the dylib that was just loaded? In this case, I'm just modifying a print statement, and then running that code, but it doesn't print the changed line until the app is reloaded. if (modstamp differs from last load) {  Create a temp file (writeable since it’s in temp directory), use mkstmp  Store the modstamp  Copy newly built file from Library/Caches over to temp  dlclose() old file  dlopen() temp file dylib (does that work?, @rpath issues)  Let the system delete the temp file when user quits, next load starts from Library/Caches directory.  }
Jan ’21
Reply to Is device.currentAllocatedSize and gpu capture buffer memory accurate on iOS/iPad?
We are using this number to sanity check our buffer and texture usage against the internal numbers that we have. For example, on macOS 3D textures were 8x bigger on non-pow2 textures than what the dimensions would suggest (384x384x3 texture). The texture correspondence looked reasonable on macOS and iOS (maybe 200K off from our totals). The buffers on iOS were way off (totaling up de-duped allocatedSize), but then device.currentAllocatedSize also reflected this much larger size that indicated that it was totaling up these larger values. We aren't hitting memory limits on this test, since my device has 4GB and we're around 0.8GB. In the past, though, we have had small buffer allocations (one quad per buffer) report 1gb of buffer memory use so we ended up optimizing it to consolidate those. Also gpu capture is reporting incorrect memory totals as a result of this so validation has to be done on macOS. And macOS reports 220MB less than iOS even in the Xcode memory totals. Before we try to consolidate to fewer MTLBuffer, having allocatedSize/currentAllocatedSize be correct on iOS would really help.
Dec ’20