Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Black screen on iPad Mini Retina 8.3 (12F69) with Xcode 6.3.2 #21

Open
jfenton opened this issue May 31, 2015 · 12 comments
Open

Black screen on iPad Mini Retina 8.3 (12F69) with Xcode 6.3.2 #21

jfenton opened this issue May 31, 2015 · 12 comments

Comments

@jfenton
Copy link
Contributor

jfenton commented May 31, 2015

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?

@jfenton
Copy link
Contributor Author

jfenton commented May 31, 2015

Also occurs on my iPad Air (iPad4,2).

@FlexMonkey
Copy link
Owner

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

@jfenton
Copy link
Contributor Author

jfenton commented Jun 1, 2015

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.

@jfenton
Copy link
Contributor Author

jfenton commented Jun 1, 2015

Issue is not resolved by #24 FYI

@jfenton
Copy link
Contributor Author

jfenton commented Jun 1, 2015

Curious.. any ideas on the little green box in the top right? It's static and unchanging.

img_0001

@FlexMonkey
Copy link
Owner

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 notifications@github.com 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
#21 (comment)
.

flexmonkey.co.uk http://flexmonkey.co.uk | @FlexMonkey
https://twitter.com/FlexMonkey | +44 (0) 7973 669691

@jfenton
Copy link
Contributor Author

jfenton commented Jun 1, 2015

Damnit, just realised that. :)

@jfenton
Copy link
Contributor Author

jfenton commented Jun 1, 2015

ReDiLab works fine on the iPad Air - what's the fundamental difference between the two codebases? Just the shared memory technique?

@FlexMonkey
Copy link
Owner

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 notifications@github.com 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
#21 (comment)
.

flexmonkey.co.uk http://flexmonkey.co.uk | @FlexMonkey
https://twitter.com/FlexMonkey | +44 (0) 7973 669691

@jfenton
Copy link
Contributor Author

jfenton commented Jun 6, 2015

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...

@jfenton
Copy link
Contributor Author

jfenton commented Jun 6, 2015

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)

@jfenton
Copy link
Contributor Author

jfenton commented Jun 9, 2015

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants