Andy - yes thanks for the guidance and great job on your guide. There's a lot to absorb there. I think the metal samples are another great use case for your new apis. I have a small side project in mind to analyze its impact on performance, comparing the swift 3 compliant "safe" implementation versus straight objective-c.
P. > On Sep 8, 2016, at 1:35 PM, Andrew Trick via swift-users > <[email protected]> wrote: > > >> On Sep 8, 2016, at 4:04 AM, Gerard Iglesias <[email protected]> wrote: >> >> Andrew, >> >> Thank you for the compliment ;) >> >> And thank you for the 2 advices >> >> And the question about use of size or stride ? I understand that the >> underlaying float data are aligned in this specific case, but I wonder in >> fact if the shader compiler align memory the same way the swift compiler do, >> I suppose yes unless it would be a nightmare, but murphy’s principle says me >> … take care ;) > > Always use stride for contiguous in-memory values. > > -Andy > >> >> Thanks in advance >> >> Gerard >> >>>> On 8 Sep 2016, at 07:21, Andrew Trick <[email protected]> wrote: >>>> >>>> >>>> On Sep 3, 2016, at 6:03 PM, Gerard Iglesias via swift-users >>>> <[email protected]> wrote: >>>> >>>> This is my funny version… I succeeded and I didn’t come back to find an >>>> other way… >>>> >>>> // Grab a pointer to the constant buffer's data store >>>> // Since we are using Swift, it is easier to cast the pointer to the >>>> ShadowPass type to fill the constant buffer >>>> // We need to make a copy of these so the block captures the correct data >>>> >>>> //let shadowPtr = >>>> UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents()) >>>> let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: >>>> ShadowPass.self) >>>> shadowPtr.pointee = shadowPassData[0] >>>> >>>> //More Swift specific stuff - advance pointer and cast to MainPass >>>> >>>> //let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1)) >>>> let mainPtr = constantBufferForFrame.contents().advanced(by: >>>> MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self) >>>> mainPtr.pointee = mainPassFrameData >>>> >>>> //Advance and cast to ObjectData >>>> >>>> //var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1)) >>>> var ptr = constantBufferForFrame.contents().advanced(by: >>>> MemoryLayout<ShadowPass>.size + >>>> MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self) >>> >>> Gerard, >>> >>> I like your code. A couple of things to consider: >>> >>> 1. If the memory has never been bound to a type (i.e. it's straight from >>> MTLBuffer.newBuffer), then rather than “assuming” memory is bound to these >>> types, you should just bind it here (substitute all your >>> assumingMemoryBound(to: _) with bindMemory(to: _, capacity: 1). Think of it >>> as two-phase initialization of the memory. First declare the memory's type >>> (e.g. some structure that holds a bunch of floats), then write individual >>> float values into the memory. >>> >>> 2. If you want the compiler to compute byte offsets for you like the >>> original code, then can be done as follows: >>> >>> let mainPtr = UnsafeMutableRawPointer(shadowPtr + 1).bindMemory( >>> to: MainPass.self, capacity: 1) >>> mainPtr.pointee = mainPassFrameData >>> ... >>> >>> However, your approach of computing byte offsets is more explicit. >>> >>> My migration guide landed on swift.org today! I think it will be a big help. >>> https://swift.org/migration-guide/se-0107-migrate.html >>> >>> -Andy >>> >>>>> On 3 Sep 2016, at 19:22, Patrice Kouame <[email protected]> wrote: >>>>> >>>>> Gerard- >>>>> >>>>> Excellent! Looking forward to seeing your fix (hoping you get your book >>>>> back soon ;-) ) >>>>> >>>>> I think Xcode/Swift gags on the last ptr advance to objectData. I >>>>> recently tried another variant using withUnsafeMutablePointer like this: >>>>> >>>>> var ptr : UnsafeMutablePointer<ObjectData> = >>>>> withUnsafeMutablePointer(to: &mainPtr) { >>>>> $0.withMemoryRebound(to: ObjectData.self, capacity: >>>>> objectsToRender) { >>>>> $0.pointee = renderables[0].objectData >>>>> } >>>>> } >>>>> >>>>> ..but still crashes with no hints. >>>>> >>>>> My bug report also mentions that the Xcode migration/conversion tool is >>>>> incomplete. >>>>> It handles the “simpler" UnsafeMutableRawPointer<X> to >>>>> UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to >>>>> mind the capacity value though) >>>>> In all fairness, migrating/converting automagically in these cases is >>>>> always a little bit tricky - the proposed Xcode fixes should always be >>>>> reviewed by a human... >>>>> >>>>> Patrice >>>>> >>>>>> On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users >>>>>> <[email protected]> wrote: >>>>>> >>>>>> Ok >>>>>> >>>>>> For the record I succeeded this transformation phase last week >>>>>> >>>>>> I remember the tedious stuff to advance pointer from one struct to the >>>>>> other kind of struct... it worked >>>>>> >>>>>> But I don't have my MacBook with me, only the phone, the six :) >>>>>> >>>>>> Gérard >>>>>> >>>>>>> Le 3 sept. 2016 à 18:22, Patrice Kouame <[email protected]> a écrit : >>>>>>> >>>>>>> Indeed. There is a difference between stride and size, but I >>>>>>> interpreted capacity incorrectly for my purposes. It should indicate >>>>>>> the number of <T> elements (not their size - right?) and the snippets >>>>>>> below should work. >>>>>>> >>>>>>> Still, compiler crashes and Xcode IDE is left in inconsistent state. >>>>>>> So I filed this Apple radar against Developer Tools. >>>>>>> >>>>>>> 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the >>>>>>> compiler and IDE >>>>>>> Should I file a Swift bug too? Would that be helpful? >>>>>>> >>>>>>> Regards, Patrice >>>>>>> >>>>>>>> On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users >>>>>>>> <[email protected]> wrote: >>>>>>>> >>>>>>>> Hello, >>>>>>>> >>>>>>>> I think that it is more secure to use stride in place of size, >>>>>>>> sometimes it is not the same value. >>>>>>>> >>>>>>>> I use it in my own use of raw bindings >>>>>>>> >>>>>>>> Regards >>>>>>>> >>>>>>>> Gérard >>>>>>>> >>>>>>>>> Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users >>>>>>>>> <[email protected]> a écrit : >>>>>>>>> >>>>>>>>> Hi Jacob - >>>>>>>>> >>>>>>>>> I think you’re right. “capacity” should be the count of type T >>>>>>>>> elements in my buffer. So in my case that line should read >>>>>>>>> >>>>>>>>> let shadowPtr = >>>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, >>>>>>>>> capacity: shadowPassData.count) >>>>>>>>> >>>>>>>>> The withMemoryRebound calls need similar adjustments. The pointer to >>>>>>>>> MainPass is actually a single structure to it should be safe to do >>>>>>>>> this >>>>>>>>> >>>>>>>>> let mainPtr : UnsafeMutablePointer<MainPass> = >>>>>>>>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, >>>>>>>>> capacity: 1) { >>>>>>>>> $0.pointee = mainPassFrameData >>>>>>>>> } >>>>>>>>> >>>>>>>>> Whereas the unsafe pointer to <ObjectData> is actually a buffer of >>>>>>>>> renderable objects, so this should work: >>>>>>>>> >>>>>>>>> var ptr : UnsafeMutablePointer<ObjectData> = >>>>>>>>> mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, >>>>>>>>> capacity: objectsToRender) {_ in >>>>>>>>> } >>>>>>>>> >>>>>>>>> There are surely ways to refactor and simplify this, but I’m trying >>>>>>>>> to retain as much of the original sample code approach as possible. >>>>>>>>> >>>>>>>>> However, the compiler still segs badly. >>>>>>>>> Xcode also borks an internal error often. Only cleaning or restarting >>>>>>>>> the project can clear up that state. >>>>>>>>> Compilers (or Playgrounds for that matter) should never crash, and >>>>>>>>> I’m not sure where to file this bug : Swift or Apple radar against >>>>>>>>> Xcode or both? I now Xcode 8 is beta but…it’s been doing this for >>>>>>>>> quite a while now... >>>>>>>>> >>>>>>>>> In both our “close to the metal” (no pun intended) cases, it seems >>>>>>>>> like a lot of churning for very little gain. Don’t you think? The >>>>>>>>> easier, but “unsafe” casting afforded previously did the trick with >>>>>>>>> the normal caveats. >>>>>>>>> Don’t get me wrong, I love Swift and “get" all the neat type safety >>>>>>>>> features. Guess we can’t have our cake and eat it too, especially >>>>>>>>> when interfacing with “unsafe” C APIs. >>>>>>>>> >>>>>>>>> Anyway, back to rtfm … maybe some of the Swift Gods can chime in? >>>>>>>>> ;-) >>>>>>>>> >>>>>>>>> I must be doing something stupid...Patrice >>>>>>>>> >>>>>>>>>> On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Hi Patrice, >>>>>>>>>> I don't have a solution for you, but I just wanted to point out what >>>>>>>>>> I think may be an error with your use of the new UnsafeRawPointer >>>>>>>>>> APIs: >>>>>>>>>> >>>>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, >>>>>>>>>> capacity: MemoryLayout<ShadowPass>.size) >>>>>>>>>> >>>>>>>>>> I believe the `capacity` should actually be the number of ShadowPass >>>>>>>>>> elements in the buffer, not the size of each element. Using >>>>>>>>>> `bindMemory(to: ShadowPass.self` already implies that >>>>>>>>>> MemoryLayout<ShadowPass>.size is the size of each element. >>>>>>>>>> >>>>>>>>>> More info at >>>>>>>>>> https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory >>>>>>>>>> >>>>>>>>>> I just updated a small Metal project of mine to Swift 3. I ran into >>>>>>>>>> some compiler (playground) crashes, but it does seem to work most of >>>>>>>>>> the time. Although I only have 1 buffer :-) >>>>>>>>>> https://github.com/jtbandes/Metalbrot.playground >>>>>>>>>> >>>>>>>>>> Jacob >>>>>>>>>> >>>>>>>>>>> On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users >>>>>>>>>>> <[email protected]> wrote: >>>>>>>>>>> Hi all - >>>>>>>>>>> >>>>>>>>>>> I’m converting Apple’s Swift Sample "Adopting Metal II: Designing >>>>>>>>>>> and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to >>>>>>>>>>> the latest UnsafeMutablePointer API for untyped memory access. >>>>>>>>>>> Changes are necessary in MetalView.swift (Apple hasn’t updated >>>>>>>>>>> their sample code for the latest beta yet…) >>>>>>>>>>> The Swift Compiler crashes (Segmentation Fault: 11) on the attempt: >>>>>>>>>>> >>>>>>>>>>> // Grab a pointer to the constant buffer's data store >>>>>>>>>>> // Since we are using Swift, it is easier to cast the >>>>>>>>>>> pointer to the ShadowPass type to fill the constant buffer >>>>>>>>>>> // We need to make a copy of these so the block captures >>>>>>>>>>> the correct data >>>>>>>>>>> >>>>>>>>>>> // let shadowPtr = >>>>>>>>>>> UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents()) >>>>>>>>>>> let shadowPtr = >>>>>>>>>>> constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, >>>>>>>>>>> capacity: MemoryLayout<ShadowPass>.size) >>>>>>>>>>> shadowPtr.pointee = shadowPassData[0] >>>>>>>>>>> >>>>>>>>>>> //More Swift specific stuff - advance pointer and cast to >>>>>>>>>>> MainPass >>>>>>>>>>> >>>>>>>>>>> // let mainPtr = >>>>>>>>>>> UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1)) >>>>>>>>>>> // mainPtr.pointee = mainPassFrameData >>>>>>>>>>> let mainPtr : UnsafeMutablePointer<MainPass> = >>>>>>>>>>> shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, >>>>>>>>>>> capacity: MemoryLayout<MainPass>.size) { >>>>>>>>>>> $0.pointee = mainPassFrameData >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> //Advance and cast to ObjectData >>>>>>>>>>> >>>>>>>>>>> // var ptr = >>>>>>>>>>> UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1)) >>>>>>>>>>> var ptr : UnsafeMutablePointer<ObjectData> = >>>>>>>>>>> mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, >>>>>>>>>>> capacity: MemoryLayout<ObjectData>.size) {_ in >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> let shadowOffset = 0 >>>>>>>>>>> let mainPassOffset = MemoryLayout<ShadowPass>.size + >>>>>>>>>>> shadowOffset >>>>>>>>>>> let objectDataOffset = MemoryLayout<MainPass>.size + >>>>>>>>>>> mainPassOffset >>>>>>>>>>> >>>>>>>>>>> // Update position of all the objects >>>>>>>>>>> if multithreadedUpdate { >>>>>>>>>>> DispatchQueue.concurrentPerform(iterations: >>>>>>>>>>> objectsToRender) { i in >>>>>>>>>>> let thisPtr = ptr.advanced(by: i) >>>>>>>>>>> _ = self.renderables[i].UpdateData(ptr, deltaTime: >>>>>>>>>>> 1.0/60.0) >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> else { >>>>>>>>>>> for index in 0..<objectsToRender { >>>>>>>>>>> ptr = renderables[index].UpdateData(ptr, deltaTime: >>>>>>>>>>> 1.0/60.0) >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> ptr = ptr.advanced(by: objectsToRender) >>>>>>>>>>> >>>>>>>>>>> _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0) >>>>>>>>>>> >>>>>>>>>>> Any help is appreciated. I have the latest Xcode log handy if >>>>>>>>>>> necessary. Here’s a clip of the stack trace. >>>>>>>>>>> >>>>>>>>>>> 0 swift 0x000000010714a99d >>>>>>>>>>> PrintStackTraceSignalHandler(void*) + 45 >>>>>>>>>>> 1 swift 0x000000010714a3e6 SignalHandler(int) + >>>>>>>>>>> 470 >>>>>>>>>>> 2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26 >>>>>>>>>>> 3 libsystem_platform.dylib 000000000000000000 _sigtramp + >>>>>>>>>>> 1857676384 >>>>>>>>>>> 4 swift 0x00000001047207b3 (anonymous >>>>>>>>>>> namespace)::SILGenApply::visitExpr(swift::Expr*) + 51 >>>>>>>>>>> 5 swift 0x0000000104723ace (anonymous >>>>>>>>>>> namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182 >>>>>>>>>>> 6 swift 0x0000000104711cc1 >>>>>>>>>>> prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + >>>>>>>>>>> 273 >>>>>>>>>>> 7 swift 0x00000001047624e7 >>>>>>>>>>> swift::ASTVisitor<(anonymous namespace)::RValueEmitter, >>>>>>>>>>> swift::Lowering::RValue, void, void, void, void, void, >>>>>>>>>>> swift::Lowering::SGFContext>::visit(swift::Expr*, >>>>>>>>>>> swift::Lowering::SGFContext) + 103 >>>>>>>>>>> 8 swift 0x0000000104762313 >>>>>>>>>>> swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, >>>>>>>>>>> swift::Lowering::Initialization*) + 195 >>>>>>>>>>> 9 swift 0x000000010474fbc3 >>>>>>>>>>> swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, >>>>>>>>>>> unsigned int) + 195 >>>>>>>>>>> 10 swift 0x00000001047077bd >>>>>>>>>>> swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, >>>>>>>>>>> void, void, void, void>::visit(swift::Decl*) + 125 >>>>>>>>>>> 11 swift 0x00000001047c0019 >>>>>>>>>>> swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, >>>>>>>>>>> void, void, void, void>::visit(swift::Stmt*) + 4169 >>>>>>>>>>> 12 swift 0x00000001047809ba >>>>>>>>>>> swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + >>>>>>>>>>> 314 >>>>>>>>>>> 13 swift 0x00000001046fd775 >>>>>>>>>>> swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) >>>>>>>>>>> const + 1877 >>>>>>>>>>> 14 swift 0x00000001046fc322 >>>>>>>>>>> swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626 >>>>>>>>>>> 15 swift 0x00000001047c7007 (anonymous >>>>>>>>>>> namespace)::SILGenType::emitType() + 1271 >>>>>>>>>>> 16 swift 0x00000001047c6a9e >>>>>>>>>>> swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) >>>>>>>>>>> + 30 >>>>>>>>>>> 17 swift 0x0000000104709093 >>>>>>>>>>> swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, >>>>>>>>>>> unsigned int) + 1795 >>>>>>>>>>> 18 swift 0x000000010470ad4d >>>>>>>>>>> swift::SILModule::constructSIL(swift::ModuleDecl*, >>>>>>>>>>> swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, >>>>>>>>>>> bool, bool) + 1629 >>>>>>>>>>> 19 swift 0x00000001045621bf >>>>>>>>>>> performCompile(swift::CompilerInstance&, >>>>>>>>>>> swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, >>>>>>>>>>> swift::FrontendObserver*) + 19487 >>>>>>>>>>> 20 swift 0x000000010455b2c5 >>>>>>>>>>> swift::performFrontend(llvm::ArrayRef<char const*>, char const*, >>>>>>>>>>> void*, swift::FrontendObserver*) + 17029 >>>>>>>>>>> 21 swift 0x000000010451888d main + 8685 >>>>>>>>>>> 22 libdyld.dylib 0x00007fff91255255 start + 1 >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Patrice >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> swift-users mailing list >>>>>>>>>>> [email protected] >>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> swift-users mailing list >>>>>>>>> [email protected] >>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>>>>> _______________________________________________ >>>>>>>> swift-users mailing list >>>>>>>> [email protected] >>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>>>> >>>>>> _______________________________________________ >>>>>> swift-users mailing list >>>>>> [email protected] >>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>> >>>> >>>> _______________________________________________ >>>> swift-users mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-users >> > > _______________________________________________ > swift-users mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-users
