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

[Reminder]: expose Metal's render pass store action in public API? #563

Closed
septag opened this issue Sep 20, 2021 · 5 comments
Closed

[Reminder]: expose Metal's render pass store action in public API? #563

septag opened this issue Sep 20, 2021 · 5 comments
Assignees

Comments

@septag
Copy link
Contributor

septag commented Sep 20, 2021

Is it possible to do two default passes with sampleCount > 1 on Metal device ?

I'm using SG_ACTION_LOAD for the second pass, but after the second one, drawable contents gets wiped with purple color. This behavior does not happen with other APIs (d3d11+GL).

This is for example what I'm doing with sokol-triangle sample (with sampleCount = 4):

    action.colors[0].action = SG_ACTION_CLEAR;
    action.colors[0].value = (sg_color) {1.0f, 0, 0, 1.0f};
    sg_begin_default_pass(&action, osx_width(), osx_height());
    sg_apply_pipeline(state.pip);
    sg_apply_bindings(&state.bind);
    sg_draw(0, 3, 1);
    sg_end_pass();

    action.colors[0].action = SG_ACTION_LOAD;
    sg_begin_default_pass(&action, osx_width(), osx_height());
    sg_apply_pipeline(state.pip);
    sg_apply_bindings(&state.bind);
    sg_end_pass();
@floooh
Copy link
Owner

floooh commented Sep 21, 2021

Hmm, I wouldn't recommend this with any backend, two default passes in one frame is basically "undefined behaviour", it might work in some situations (or backends) but not in others.

I think the reason why you're seeing a blank surface is the MTLStoreActionMultisampleResolve here in this line:

sokol/sokol_gfx.h

Line 10627 in 89b1b6b

pass_desc.colorAttachments[i].storeAction = is_msaa ? MTLStoreActionMultisampleResolve : MTLStoreActionStore;

You could try to replace this with MTLStoreActionStoreAndMultisampleResolve and see what happens, but there will be lots of other unexpected problems with two default passes in the same frame (because in the Metal backend each default pass requests a new drawable to render into if I'm not mistaken).

With offscreen passes there's probably fewer problems (but I think the MSAA case still won't work because of the Metal store action that's used). I don't want to always do MTLStoreActionStoreAndMultisampleResolve because that shouldn't be usually needed, but maybe it makes sense to expose both the load- and store-action in the API (when creating a pass object).

Ah PS: of course replacing this MTLStoreActionMultisampleResolve with MTLStoreActionStoreAndMultisampleResolve will not work in the default pass anyway, only in an offscreen pass, because in a default pass you have no control over the load- and store-action (because that's provided by MTKView in sokol_app.h).

@septag
Copy link
Contributor Author

septag commented Sep 22, 2021

Ah nice! Thanks for the explanation.

I used your tip (MTLStoreActionMultisampleResolve) and modified here at line 10680 instead of the spot you mentioned (that one was for offscreen rendering):

bool is_msaa = _sg.desc.context.sample_count > 1;
pass_desc.colorAttachments[0].loadAction = _sg_mtl_load_action(action->colors[0].action);
pass_desc.colorAttachments[0].storeAction = is_msaa ? MTLStoreActionStoreAndMultisampleResolve :
                                                              MTLStoreActionStore;

It is now fixed and behaves like no msaa mode and other graphics backends.
I'm not sure if this is undefined, since I couldn't find anything in the documentation. So I can confirm that it works on the default pass. Regarding the thing you said about having no control over actions, for drawables, you are getting the descriptor (MTLRenderPassDescriptor) from [MTKView currentRenderPassDescriptor] so we could change it's behavior like offscreen ones.

And I checked, as far as I understood, you are discarding the drawable in commit and not on every pass, so it should be safe.

@floooh
Copy link
Owner

floooh commented Sep 22, 2021

Ah yeah right. I'll keep the ticket open as reminder (and change the title). I think it's better to give the API user more control over the store action, but I need to think about this a bit more.

@floooh floooh changed the title [Question]: Two default_passes with Metal + MSAA ? [Reminder]: expose Metal's render pass store action in public API? Sep 22, 2021
@floooh floooh self-assigned this Sep 22, 2021
@septag
Copy link
Contributor Author

septag commented Sep 22, 2021

Sure thing, thanks for your support.

@floooh
Copy link
Owner

floooh commented May 19, 2023

Fixed via: #834

@floooh floooh closed this as completed May 19, 2023
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