ParticleLab
ParticleLab copied to clipboard
Black screen on iPad Mini Retina 8.3 (12F69) with Xcode 6.3.2
App results in black screen with upper left menu (working) and a green square in top right.
Touch circles are visible, but otherwise black.
For about a second after startup, I can see a very thin 1px "rainbow" around the perimeter of a completely black screen, before it is replaced by the black screen with menu etc. I assume the rainbow is the particle system, as it's palette matches that of your screenshot.
Perhaps the overlay is not transparent to the underlying CAMetalLayer?
Also occurs on my iPad Air (iPad4,2).
Hi, the only two devices I have access to are an iPad Air 2 and an iPhone 6 and the app displays particles as expected on both. I know other people have experienced issues with A7 based iPhone 5s - maybe this code really needs an A8, it's pretty intensive stuff
Could you try dropping the particle count in the view controller's viewDidLoad() method? It's currently set at .TwoMillion, maybe .HalfMillion would work on your devices. Something else to look at - are view.frame.width and .height correctly set in viewDidLoad()?
Sorry I can't be more helpful, but without access to your devices, I'm a little stuck.
Cheers,
Simon
Hey, I can confirm that my iPhone 6 works as expected (caveat other issue raised re:menu).
Dropping to .HalfMillion had no effect on iPad Mini & iPad Air.
Having now seen it working correctly on the iPhone, the 1px border would appear to be the output of the simulation.. so I would assume we are seeing at least a few frames from it (limited to the 1px border) initially, before something else occludes or halts frame updates.
Profiling: Console shows 60fps, but OpenGL ES Profiler shows Renderer & Tiler Utilisation 25-35% and 5-8% respectively for 2/10th secs then it flatlines to 0%. CPU is spending majority of it's time doing replaceRegion as expected (even with GPU at 0%):
Running Time Self (ms) Symbol Name
1650.0ms 71.3% 0.0 start
1650.0ms 71.3% 0.0 main
1650.0ms 71.3% 0.0 UIApplicationMain
1472.0ms 63.6% 0.0 GSEventRunModal
1472.0ms 63.6% 0.0 CFRunLoopRunSpecific
1472.0ms 63.6% 0.0 __CFRunLoopRun
1416.0ms 61.2% 0.0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
1416.0ms 61.2% 0.0 _dispatch_main_queue_callback_4CF
1409.0ms 60.9% 0.0 _dispatch_client_callout
1409.0ms 60.9% 0.0 _dispatch_call_block_and_release
1407.0ms 60.8% 0.0 partial apply forwarder for MetalParticles.ParticleLab.((step in _29AAAFF9A8428D5EB133BE609C7CEFE6) (MetalParticles.ParticleLab) -> () -> ()).(closure #1)
1407.0ms 60.8% 0.0 MetalParticles.ParticleLab.((step in _29AAAFF9A8428D5EB133BE609C7CEFE6) (MetalParticles.ParticleLab) -> () -> ()).(closure #1)
1396.0ms 60.4% 0.0 function signature specialization <Arg[0] = Owned To Guaranteed> of MetalParticles.ParticleLab.(step in _29AAAFF9A8428D5EB133BE609C7CEFE6) (MetalParticles.ParticleLab)() -> ()
846.0ms 36.6% 0.0 -[MTLIOAccelTexture replaceRegion:mipmapLevel:withBytes:bytesPerRow:]
I'd love to see this working on the iPad (ideally without having to buy an Air 2 ;) ) - email me if you'd like to do a Skype/Hangout to pair on it.
Issue is not resolved by #24 FYI
Curious.. any ideas on the little green box in the top right? It's static and unchanging.
It's the battery power level :)
Need to change the status bar tint to white.
Simon
On 1 June 2015 at 17:18, Jay Fenton [email protected] wrote:
Curious.. any ideas on the little green box in the top right? It's static and unchanging.
[image: img_0001] https://cloud.githubusercontent.com/assets/224096/7917398/7e3cceaa-08cd-11e5-97ae-0eb129be80c4.PNG
— Reply to this email directly or view it on GitHub https://github.com/FlexMonkey/ParticleLab/issues/21#issuecomment-107618828 .
flexmonkey.co.uk http://flexmonkey.co.uk | @FlexMonkey https://twitter.com/FlexMonkey | +44 (0) 7973 669691
Damnit, just realised that. :)
ReDiLab works fine on the iPad Air - what's the fundamental difference between the two codebases? Just the shared memory technique?
I guess the main difference is that ReDiLab doesn't use CAMetalLayer, it creates a UIImage from the texture returned by Metal and displays it with a UIImageView.
Simon
On 1 June 2015 at 17:26, Jay Fenton [email protected] wrote:
ReDiLab works fine on the iPad Air - what's the fundamental difference between the two codebases? Just the shared memory technique?
— Reply to this email directly or view it on GitHub https://github.com/FlexMonkey/ParticleLab/issues/21#issuecomment-107623851 .
flexmonkey.co.uk http://flexmonkey.co.uk | @FlexMonkey https://twitter.com/FlexMonkey | +44 (0) 7973 669691
I've made some progress. It seems to be related to number of thread groups you're dispatching:
Relevant code:
let threadExecutionWidth = pipelineState.threadExecutionWidth
let threadExecutionMax = pipelineState.maxTotalThreadsPerThreadgroup
particle_threadGroups = MTLSize(width:(particleCount + threadExecutionWidth - 1) / 16, height:1, depth:1)
particle_threadsPerThreadGroup = MTLSize(width:threadExecutionWidth, height:1, depth:1)
...
commandEncoder.dispatchThreadgroups(particle_threadGroups, threadsPerThreadgroup: particle_threadsPerThreadGroup)
Results:
- iPhone 6
Particle Count = 131072 Thread Execution Width = 32 Thread Execution Max = 352
Thread Groups = 4096 Threads per Thread Group = 32
Works great!
- iPad Mini Retina
Particle Count = 131072 Thread Execution Width = 32 Thread Execution Max = 416
Thread Groups = 4096 Threads per Thread Group = 32
No particles displayed.
- iPad Mini Retina
Particle Count = 131072 Thread Execution Width = 32 Thread Execution Max = 416
Thread Groups = 128 ...any higher results in zero particles! Threads per Thread Group = 32
Result is only 4 particles rendered and animating, but stable. Seems odd that just 4 would render...
Reading the Apple Metal Programming Guide > Executing a Compute Command, it seems to me that the second param to dispatchThreadgroups should be a multiple of the threadExecutionWidth, up to maxTotalThreadsPerThreadgroup in our case (as it's 1-dimensional).
I tried it (as well as maxTotalThreadsPerThreadgroup/2) but still results in zero pixels :(
//let threadExecutionWidth = pipelineState.threadExecutionWidth
let threadExecutionMax = pipelineState.maxTotalThreadsPerThreadgroup
let threadExecutionWidth = threadExecutionMax / 2
particle_threadGroups = MTLSize(width:(particleCount + threadExecutionWidth - 1) / threadExecutionWidth, height:1, depth:1)
particle_threadsPerThreadGroup = MTLSize(width:threadExecutionWidth, height:1, depth:1)
Intuitively, I feel like the A7 and A8 are acting very differently with respect to the dispatchThreadgroups call (based on our having to dial it down so much to even get a handful of pixels rendering on A7).
I'm actually surprised that the it works on A8 works, as the docs would suggest there is a hard limit (Thread Execution Max above) that we are way over with the existing params (e.g. 131072*32).
I don't know this empirically just yet, but perhaps the underlying A7 target does not just Do The Right Thing™ when given too much in a single dispatchThreadgroups call.