Skip to content

Commit 7e875bd

Browse files
committed
Share submit fences with the game
1 parent 435e0b4 commit 7e875bd

2 files changed

Lines changed: 44 additions & 40 deletions

File tree

src/main/java/git/artdeell/artvk/Vk11CommandEncoder.java

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class Vk11CommandEncoder implements CommandEncoderBackend, Destroyable {
2929
public static final int MAX_SUBMITS_IN_FLIGHT = 3;
3030
private final Vk11Device device;
3131
private final Vk11TransientMemory transientMemory;
32-
private final Vk11Fence[] frameFences = new Vk11Fence[MAX_SUBMITS_IN_FLIGHT];
32+
private final Vk11Fence[] submitFences = new Vk11Fence[MAX_SUBMITS_IN_FLIGHT];
3333
private int currentSubmitIndex = 0;
3434
private Vk11Queue.Submission submissionBuilder;
3535
private final DestructionQueue<Destroyable> destroyQueue = new DestructionQueue<>(MAX_SUBMITS_IN_FLIGHT, Destroyable::destroy);
@@ -43,7 +43,7 @@ public Vk11CommandEncoder(final Vk11Device device) {
4343
this.transientMemory = new Vk11TransientMemory(device, this);
4444

4545
for (int i = 0; i < MAX_SUBMITS_IN_FLIGHT; i++) {
46-
this.frameFences[i] = new Vk11Fence(device, true);
46+
this.submitFences[i] = new Vk11Fence(device, true);
4747
this.commandPools[i] = new Vk11CommandPool(device, device.graphicsQueue());
4848
}
4949

@@ -62,7 +62,7 @@ public void destroy() {
6262

6363
for (int i = 0; i < MAX_SUBMITS_IN_FLIGHT; i++) {
6464
this.commandPools[i].destroy();
65-
this.frameFences[i].destroy();
65+
this.submitFences[i].destroy();
6666
}
6767
}
6868

@@ -156,38 +156,20 @@ public static void memoryBarrier(final VkCommandBuffer commandBuffer, final Memo
156156
);
157157
}
158158

159-
public boolean waitForFences(long... fences) {
160-
int result = VK10.VK_TIMEOUT;
161-
while(result == VK10.VK_TIMEOUT) {
162-
result = VK10.vkWaitForFences(device.vkDevice(), fences, true, 1_000_000_000L);
163-
}
164-
Vk11Utils.crashIfFailure(result, "fence wait failed");
165-
return true;
166-
}
167-
168-
public void resetFences(long... fences) {
169-
Vk11Utils.crashIfFailure(VK10.vkResetFences(device.vkDevice(), fences), "fence reset failed");
170-
}
171-
172-
public void requireFencesComplete(long... fences) {
173-
if(!waitForFences(fences)) throw new IllegalStateException("Failed to wait for completion fence");
174-
resetFences(fences);
175-
}
176-
177159
@Override
178160
public void submit() {
179161
this.endCommandBuffer();
180162
this.transientMemory.endSubmit();
181-
long lastFence = this.frameFences[this.currentSubmitIndex].vkFence();
182163

183-
requireFencesComplete(lastFence);
164+
Vk11Fence lastFence = this.submitFences[this.currentSubmitIndex];
165+
lastFence.autoWait();
184166

185-
this.submissionBuilder.close(lastFence);
167+
this.submissionBuilder.close(lastFence.vkFence());
186168
this.submissionBuilder = this.device.graphicsQueue().beginSubmit();
187169

188170
currentSubmitIndex = (currentSubmitIndex + 1) % MAX_SUBMITS_IN_FLIGHT;
189171

190-
waitForFences(frameFences[currentSubmitIndex].vkFence());
172+
submitFences[currentSubmitIndex].waitForever();
191173

192174
for (Vk11DescriptorPool pool : this.descriptorPools) {
193175
pool.resetFrame(this.currentSubmitIndex);
@@ -571,17 +553,7 @@ public void copyTextureToTexture(
571553

572554
@Override
573555
public @NotNull GpuFence createFence() {
574-
return new GpuFence() {
575-
// Don't gaf
576-
// Maybe TODO: implement fence for previous frame's submit
577-
@Override
578-
public void close() {}
579-
580-
@Override
581-
public boolean awaitCompletion(long timeoutNS) {
582-
return true;
583-
}
584-
};
556+
return submitFences[currentSubmitIndex];
585557
}
586558

587559
@Override

src/main/java/git/artdeell/artvk/Vk11Fence.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package git.artdeell.artvk;
22

33
import java.nio.LongBuffer;
4+
5+
import com.mojang.blaze3d.buffers.GpuFence;
46
import net.fabricmc.api.EnvType;
57
import net.fabricmc.api.Environment;
68
import org.lwjgl.system.MemoryStack;
79
import org.lwjgl.vulkan.VK10;
810
import org.lwjgl.vulkan.VkFenceCreateInfo;
911

1012
@Environment(EnvType.CLIENT)
11-
public class Vk11Fence implements Destroyable {
13+
public class Vk11Fence implements Destroyable, GpuFence {
1214
private final Vk11Device device;
1315
private final long vkFence;
16+
private boolean completed = false;
1417

1518
public Vk11Fence(final Vk11Device device, final boolean signaled) {
1619
this.device = device;
@@ -30,7 +33,36 @@ public void destroy() {
3033
VK10.vkDestroyFence(device.vkDevice(), vkFence, null);
3134
}
3235

33-
public long vkFence() {
34-
return this.vkFence;
35-
}
36+
protected void reset() {
37+
VK10.vkResetFences(device.vkDevice(), vkFence);
38+
completed = false;
39+
}
40+
41+
public long vkFence() {
42+
return vkFence;
43+
}
44+
45+
@Override
46+
public void close() {
47+
// TODO: Implement this? Is it necessary if the fences should only be reset in submit()?
48+
}
49+
50+
@Override
51+
public boolean awaitCompletion(long timeoutNS) {
52+
if(completed) return true;
53+
int result = VK10.vkWaitForFences(device.vkDevice(), vkFence, true, timeoutNS);
54+
if(result == VK10.VK_TIMEOUT) return false;
55+
Vk11Utils.crashIfFailure(result, "Failed to wait for fence");
56+
completed = true;
57+
return true;
58+
}
59+
60+
public void waitForever() {
61+
while(true) if(awaitCompletion(1_000_000_000)) break;
62+
}
63+
64+
public void autoWait() {
65+
waitForever();
66+
reset();
67+
}
3668
}

0 commit comments

Comments
 (0)