Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Remove busy loops in SDL_GPUFence#14547

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
alexgu754 wants to merge10 commits intolibsdl-org:main
base:main
Choose a base branch
Loading
fromalexgu754:patch-2

Conversation

@alexgu754
Copy link

SDL_GPUFence is implemented as just a busy loop on an atomic int, a SDL_GPUCondition gives the cpu some rest

SDL_GPUFence is implemented as just a busy loop on an atomic int, a SDL_GPUCondition gives the cpu some rest
@sloukenslouken added this to the3.6.0 milestoneNov 29, 2025
removed bad casts
@alexgu754alexgu754 marked this pull request as ready for reviewNovember 30, 2025 07:21
@TheSpydog
Copy link
Collaborator

Will defer to@thatcosmonaut here. All of this logic is shared between Vulkan, D3D12, and Metal, so whatever strategy we use here should apply to all drivers.

@thatcosmonaut
Copy link
Collaborator

I think Metal is kind of unique here, because if I recall correctly it doesn't provide an explicit wait mechanism. Vulkan and D3D12 provide waits in the spec.

@alexgu754
Copy link
Author

is nobody going to merge? seems pretty serious. I think when the user calls wait for the gpu work to finish, they don't expect it to busy loop on apple devices, destroying the battery life

// Notify the fence when the command buffer has completed
[metalCommandBuffer->handleaddCompletedHandler:^(id<MTLCommandBuffer> buffer) {
SDL_AtomicIncRef(&metalCommandBuffer->fence->complete);
SDL_LockMutex(metalCommandBuffer->fence->mutex);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Again, create a local variable for the fence instead of indirecting it several times in a row.

@slouken
Copy link
Collaborator

METAL_INTERNAL_FenceOpen() seems like an odd choice for a function name. What is it opening? Would METAL_INTERNAL_FenceComplete() be more appropriate?

@slouken
Copy link
Collaborator

This code feels very much like something thrown together very quickly. If you clean it up and@thatcosmonaut approves, we can potentially merge this for 3.4, but it's more likely to need more testing and go in for 3.6.

alexgu754and others added2 commitsDecember 16, 2025 10:17
semantic fixesCo-authored-by: Sam Lantinga <slouken@libsdl.org>
more semantic changes
@alexgu754
Copy link
Author

alexgu754 commentedDec 16, 2025
edited
Loading

ok, good I just want people to be aware that these issues exist in the metal implementation and it won't pass app store review for example. The max frames in flight, waiting on a command buffer, waiting for a swapchain texture, etc. is done through a busy loop and I hope the pull requests or other fixes will be merged in the foreseeable future so I can ship a game

Comment on lines 3595 to 3596
while(!((MetalFence *)fences[i])->complete) {
SDL_WaitCondition(((MetalFence *)fences[i])->condition, ((MetalFence *)fences[i])->mutex);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
while(!((MetalFence *)fences[i])->complete) {
SDL_WaitCondition(((MetalFence *)fences[i])->condition,((MetalFence *)fences[i])->mutex);
while(!fence->complete) {
SDL_WaitCondition(fence->condition,fence->mutex);

while(!((MetalFence *)fences[i])->complete) {
SDL_WaitCondition(((MetalFence *)fences[i])->condition, ((MetalFence *)fences[i])->mutex);
}
SDL_UnlockMutex(((MetalFence *)fences[i])->mutex);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
SDL_UnlockMutex(((MetalFence *)fences[i])->mutex);
SDL_UnlockMutex(fence->mutex);

@alexgu754
Copy link
Author

yeah, I'm going to be honest. syntax highlighting doesn't work in .mm files on clion so I don't see anything

if (windowData->inFlightFences[windowData->frameCounter] !=NULL) {
if (!METAL_WaitForFences(
driverData,
(SDL_GPURenderer *)driverData,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Is this cast necessary?

while (!SDL_GetAtomicInt(&renderer->submittedCommandBuffers[i]->fence->complete)) {
// Spin!
}
METAL_WaitForFences((SDL_GPURenderer *)renderer,true, (SDL_GPUFence **)&renderer->submittedCommandBuffers[i]->fence,1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Are these casts necessary? You can just pass driverData for the first one.

@TheSpydog
Copy link
Collaborator

Apologies for the lack of review, I've been very busy and haven't had an opportunity to test this.

it won't pass app store review for example.

At least one app has already passed App Store review on iOS and tvOS with the current implementation. Busy-waiting may not be optimal but it's not prohibitive for shipping games, so I agree with Sam that we should hold off on this until 3.6.

@alexgu754
Copy link
Author

alexgu754 commentedDec 17, 2025
edited
Loading

Apologies for the lack of review, I've been very busy and haven't had an opportunity to test this.

it won't pass app store review for example.

At least one app has already passed App Store review on iOS and tvOS with the current implementation. Busy-waiting may not be optimal but it's not prohibitive for shipping games, so I agree with Sam that we should hold off on this until 3.6.

ok, well that's because max frames in flight also currently does nothing so that issue silences this issue for now, it waits when you call next drawable on CAMetalLayer* after maxing out drawables, so it never ends up waiting on the gpu fence even when frames in flight=1, and the developer didn't use the wait for swapchain api or wait for command buffers in his app

alexgu754and others added3 commitsDecember 17, 2025 06:21
Co-authored-by: Sam Lantinga <slouken@libsdl.org>
removed redundant casts
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@sloukensloukenslouken left review comments

@TheSpydogTheSpydogAwaiting requested review from TheSpydog

@thatcosmonautthatcosmonautAwaiting requested review from thatcosmonaut

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

3.6.0

Development

Successfully merging this pull request may close these issues.

4 participants

@alexgu754@TheSpydog@thatcosmonaut@slouken

[8]ページ先頭

©2009-2025 Movatter.jp