Skip to content

Commit 5092531

Browse files
committed
exp: Simulate explicit clears with renderpass begin clears
1 parent 2086488 commit 5092531

6 files changed

Lines changed: 127 additions & 66 deletions

File tree

build.gradle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ dependencies {
2424
minecraft "com.mojang:minecraft:${project.minecraft_version}"
2525
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
2626

27-
// Fabric API. This is technically optional, but you probably want it anyway.
28-
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
29-
3027
compileOnly "maven.modrinth:AANobbMI:2Yom1N68" // Yes, this is Sodium from Modrinth (26.2-0.9.1-fabric)
3128
}
3229

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

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public void signalSemaphore(final long vkSemaphore) {
139139
this.submissionBuilder.signalSemaphore(vkSemaphore);
140140
}
141141

142-
private void memoryBarrier(final MemoryStack stack) {
142+
public void memoryBarrier(final MemoryStack stack) {
143143
memoryBarrier(this.commandBuffer(), stack);
144144
}
145145

@@ -196,6 +196,7 @@ public void submit() {
196196

197197
boolean hasDepth = depthAttachment != null;
198198
Vk11GpuTextureView[] attachmentViews = new Vk11GpuTextureView[colorCount + (hasDepth ? 1 : 0)];
199+
boolean[] clears = new boolean[attachmentViews.length];
199200

200201
VkClearValue.Buffer clearValues = VkClearValue.calloc(attachmentViews.length, memoryStack);
201202
int[] colorFormats = new int[colorCount];
@@ -212,15 +213,29 @@ public void submit() {
212213
textureView.disableTransferMode(memoryStack, currentCommandBuffer);
213214
attachmentViews[i] = textureView;
214215
colorFormats[i] = Vk11Const.toVk(textureView.texture().getFormat());
216+
float[] pendingClear = textureView.texture().consumeClear();
215217
if(attachment.clearValue().isPresent()) {
216218
Vk11Utils.putArgb(clearValues.get(i).color(), attachment.clearValue().get());
219+
clears[i] = true;
220+
}else if(pendingClear != null) {
221+
VkClearColorValue clearColorValue = clearValues.get(i).color();
222+
clearColorValue.float32(0, pendingClear[0]);
223+
clearColorValue.float32(1, pendingClear[1]);
224+
clearColorValue.float32(2, pendingClear[2]);
225+
clearColorValue.float32(3, pendingClear[3]);
226+
clears[i] = true;
217227
}
218228
}
219229
if(hasDepth) {
220230
attachmentViews[colorCount] = (Vk11GpuTextureView) depthAttachment.textureView();
221231
depthFormat = Vk11Const.toVk(depthAttachment.textureView().texture().getFormat());
232+
float[] pendingClearValue = attachmentViews[colorCount].texture().consumeClear();
222233
if(depthAttachment.clearValue().isPresent()) {
223234
clearValues.get(colorCount).depthStencil().depth((float) depthAttachment.clearValue().getAsDouble());
235+
clears[colorCount] = true;
236+
} else if(pendingClearValue != null) {
237+
clearValues.get(colorCount).depthStencil().set(pendingClearValue[0], 0);
238+
clears[colorCount] = true;
224239
}
225240
}
226241

@@ -234,7 +249,7 @@ public void submit() {
234249
break;
235250
}
236251

237-
long renderPass = this.device.renderPassCache().getOrCreateRenderPass(colorFormats, hasDepth, depthFormat);
252+
long renderPass = this.device.renderPassCache().getOrCreateRenderPass(clears, colorFormats, hasDepth, depthFormat);
238253

239254
long framebuffer = this.device.framebufferCache().getOrCreateFramebuffer(renderPass, width, height, attachmentViews);
240255

@@ -284,36 +299,9 @@ public void submitRenderPass() {
284299
submit();
285300
}
286301
}
287-
288-
private void clearColorTextureUnsynced(final MemoryStack stack, final GpuTexture colorTexture, final Vector4fc clearColor) {
289-
org.lwjgl.vulkan.VkClearColorValue vkClearColor = Vk11Utils.putArgb(org.lwjgl.vulkan.VkClearColorValue.calloc(stack), clearColor);
290-
VkImageSubresourceRange subresourceRange = VkImageSubresourceRange.calloc(stack);
291-
subresourceRange.baseMipLevel(0);
292-
subresourceRange.levelCount(colorTexture.getMipLevels());
293-
subresourceRange.baseArrayLayer(0);
294-
subresourceRange.layerCount(1);
295-
subresourceRange.aspectMask(VK10.VK_IMAGE_ASPECT_COLOR_BIT);
296-
VK10.vkCmdClearColorImage(this.commandBuffer(), ((Vk11GpuTexture)colorTexture).vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, vkClearColor, subresourceRange);
297-
}
298-
299-
public void clearDepthTextureUnsynced(final MemoryStack stack, final GpuTexture depthTexture, final double clearDepth) {
300-
VkClearDepthStencilValue vkClearDepth = VkClearDepthStencilValue.calloc(stack).depth((float)clearDepth);
301-
VkImageSubresourceRange subresourceRange = VkImageSubresourceRange.calloc(stack);
302-
subresourceRange.baseMipLevel(0);
303-
subresourceRange.levelCount(depthTexture.getMipLevels());
304-
subresourceRange.baseArrayLayer(0);
305-
subresourceRange.layerCount(1);
306-
subresourceRange.aspectMask(VK10.VK_IMAGE_ASPECT_DEPTH_BIT);
307-
VK10.vkCmdClearDepthStencilImage(this.commandBuffer(), ((Vk11GpuTexture)depthTexture).vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, vkClearDepth, subresourceRange);
308-
}
309-
310302
@Override
311303
public void clearColorTexture(final @NotNull GpuTexture colorTexture, final @NotNull Vector4fc clearColor) {
312-
try (MemoryStack stack = MemoryStack.stackPush()) {
313-
((Vk11GpuTexture) colorTexture).postTransferBarrier(stack, this.commandBuffer());
314-
this.clearColorTextureUnsynced(stack, colorTexture, clearColor);
315-
this.memoryBarrier(stack);
316-
}
304+
((Vk11GpuTexture) colorTexture).insertClear(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
317305
}
318306

319307
@Override
@@ -323,12 +311,8 @@ public void clearColorAndDepthTextures(
323311
final @NotNull GpuTexture depthTexture,
324312
final double clearDepth
325313
) {
326-
try (MemoryStack stack = MemoryStack.stackPush()) {
327-
((Vk11GpuTexture) colorTexture).postTransferBarrier(stack, this.commandBuffer());
328-
this.clearColorTextureUnsynced(stack, colorTexture, clearColor);
329-
this.clearDepthTextureUnsynced(stack, depthTexture, clearDepth);
330-
this.memoryBarrier(stack);
331-
}
314+
((Vk11GpuTexture) colorTexture).insertClear(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
315+
((Vk11GpuTexture) depthTexture).insertClear((float) clearDepth);
332316
}
333317

334318
@Override
@@ -380,10 +364,7 @@ public void clearColorAndDepthTextures(
380364

381365
@Override
382366
public void clearDepthTexture(final @NotNull GpuTexture depthTexture, final double clearDepth) {
383-
try (MemoryStack stack = MemoryStack.stackPush()) {
384-
this.clearDepthTextureUnsynced(stack, depthTexture, clearDepth);
385-
this.memoryBarrier(stack);
386-
}
367+
((Vk11GpuTexture) depthTexture).insertClear((float) clearDepth);
387368
}
388369

389370
@Override
@@ -425,8 +406,10 @@ public void writeToTexture(
425406
final int height
426407
) {
427408
GpuBufferSlice stagingBuffer = this.transientMemory.uploadStaging(source, 1L, 16);
428-
409+
Vk11GpuTexture vTex = (Vk11GpuTexture) destination;
429410
try (MemoryStack stack = MemoryStack.stackPush()) {
411+
vTex.postTransferBarrier(stack, commandBuffer());
412+
vTex.insertPendingClear(stack, this);
430413
VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack);
431414
region.bufferOffset(stagingBuffer.offset());
432415
region.bufferRowLength(width);
@@ -438,7 +421,7 @@ public void writeToTexture(
438421
imageSubresource.layerCount(1);
439422
region.imageOffset().set(destX, destY, 0);
440423
region.imageExtent().set(width, height, 1);
441-
VK10.vkCmdCopyBufferToImage(this.commandBuffer(), ((Vk11GpuBuffer)stagingBuffer.buffer()).vkBuffer(), ((Vk11GpuTexture)destination).vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, region);
424+
VK10.vkCmdCopyBufferToImage(this.commandBuffer(), ((Vk11GpuBuffer)stagingBuffer.buffer()).vkBuffer(), vTex.vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, region);
442425
this.memoryBarrier(stack);
443426
}
444427
}
@@ -461,8 +444,11 @@ public void copyBufferToTexture(
461444
int texelSize = destination.getFormat().blockSize();
462445
long skipTexels = sourceX + (long)sourceY * sourceWidth;
463446
long skipBytes = skipTexels * texelSize;
447+
Vk11GpuTexture vTex = (Vk11GpuTexture) destination;
464448

465449
try (MemoryStack stack = MemoryStack.stackPush()) {
450+
vTex.postTransferBarrier(stack, commandBuffer());
451+
vTex.insertPendingClear(stack, this);
466452
VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack);
467453
region.bufferOffset(source.offset() + skipBytes);
468454
region.bufferRowLength(sourceWidth);
@@ -474,7 +460,7 @@ public void copyBufferToTexture(
474460
imageSubresource.layerCount(1);
475461
region.imageOffset().set(destinationX, destinationY, 0);
476462
region.imageExtent().set(copyWidth, copyHeight, 1);
477-
VK10.vkCmdCopyBufferToImage(this.commandBuffer(), ((Vk11GpuBuffer)source.buffer()).vkBuffer(), ((Vk11GpuTexture)destination).vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, region);
463+
VK10.vkCmdCopyBufferToImage(this.commandBuffer(), ((Vk11GpuBuffer)source.buffer()).vkBuffer(), vTex.vkImage(), VK10.VK_IMAGE_LAYOUT_GENERAL, region);
478464
this.memoryBarrier(stack);
479465
}
480466
}
@@ -537,6 +523,7 @@ public void copyTextureToTexture(
537523
Vk11GpuTexture vk11Dst = (Vk11GpuTexture)destination;
538524

539525
try (MemoryStack stack = MemoryStack.stackPush()) {
526+
vk11Dst.insertPendingClear(stack, this);
540527
VkImageSubresourceLayers subresourceLayers = VkImageSubresourceLayers.calloc(stack);
541528
subresourceLayers.mipLevel(mipLevel);
542529
subresourceLayers.baseArrayLayer(0);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ private Vk11RenderPipeline compilePipeline(final RenderPipeline pipeline, final
313313
}
314314

315315
int depthFormat = VK10.VK_FORMAT_D32_SFLOAT;
316-
long renderPassWithDepth = this.renderPassCache.getOrCreateRenderPass(colorFormats, true, depthFormat);
317-
long renderPassWithoutDepth = this.renderPassCache.getOrCreateRenderPass(colorFormats, false, VK10.VK_FORMAT_UNDEFINED);
316+
boolean[] clears = new boolean[colorFormats.length + 1];
317+
long renderPassWithDepth = this.renderPassCache.getOrCreateRenderPass(clears, colorFormats, true, depthFormat);
318+
long renderPassWithoutDepth = this.renderPassCache.getOrCreateRenderPass(clears, colorFormats, false, VK10.VK_FORMAT_UNDEFINED);
318319
return Vk11RenderPipeline.compile(this, modules.layout(), pipeline, modules.vertex(), modules.fragment(), renderPassWithDepth, renderPassWithoutDepth, pushConstantRange);
319320
} catch (ShaderCompileException e) {
320321
ArtVK.LOGGER.error("Couldn't compile pipeline {}: {}", pipeline.getLocation(), e.getMessage());

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

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.mojang.blaze3d.GpuFormat;
44
import com.mojang.blaze3d.textures.GpuTexture;
5+
56
import java.nio.LongBuffer;
67
import net.fabricmc.api.EnvType;
78
import net.fabricmc.api.Environment;
@@ -17,9 +18,12 @@ public class Vk11GpuTexture extends GpuTexture implements Destroyable {
1718
private final Vk11Device device;
1819
private final long vkImage;
1920
private final long vmaAllocation;
21+
protected final int aspect;
2022
private boolean closed = false;
2123
private int transferLevel = -1;
2224
private int views = 0;
25+
private boolean clearPending = true;
26+
private final float[] clearValue = new float[4];
2327

2428
public Vk11GpuTexture(
2529
final Vk11Device device,
@@ -33,6 +37,7 @@ public Vk11GpuTexture(
3337
) {
3438
super(usage, label, format, width, height, depthOrLayers, mipLevels);
3539
this.device = device;
40+
this.aspect = this.getFormat().hasColorAspect() ? VK10.VK_IMAGE_ASPECT_COLOR_BIT : VK10.VK_IMAGE_ASPECT_DEPTH_BIT;
3641

3742
try (MemoryStack stack = MemoryStack.stackPush()) {
3843
VkImageCreateInfo imageCreateInfo = VkImageCreateInfo.calloc(stack).sType$Default();
@@ -64,18 +69,21 @@ public Vk11GpuTexture(
6469
barrier.srcQueueFamilyIndex(VK10.VK_QUEUE_FAMILY_IGNORED);
6570
barrier.dstQueueFamilyIndex(VK10.VK_QUEUE_FAMILY_IGNORED);
6671
barrier.image(this.vkImage);
67-
VkImageSubresourceRange subresourceRange = barrier.subresourceRange();
68-
subresourceRange.aspectMask(this.getFormat().hasColorAspect() ? VK10.VK_IMAGE_ASPECT_COLOR_BIT : VK10.VK_IMAGE_ASPECT_DEPTH_BIT);
69-
subresourceRange.baseMipLevel(0);
70-
subresourceRange.levelCount(this.getMipLevels());
71-
subresourceRange.baseArrayLayer(0);
72-
subresourceRange.layerCount(depthOrLayers);
72+
fullResourceRange(barrier.subresourceRange());
7373
VK10.vkCmdPipelineBarrier(device.createCommandEncoder().textureInitCommandBuffer(), VK10.VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK10.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, null, null, barrier);
7474
device.instance().debug().setObjectName(device.vkDevice(), VK10.VK_OBJECT_TYPE_IMAGE, this.vkImage, label);
7575
}
7676

7777
this.addViews();
7878
}
79+
80+
private void fullResourceRange(VkImageSubresourceRange subresourceRange) {
81+
subresourceRange.aspectMask(aspect);
82+
subresourceRange.baseMipLevel(0);
83+
subresourceRange.levelCount(this.getMipLevels());
84+
subresourceRange.baseArrayLayer(0);
85+
subresourceRange.layerCount(this.getDepthOrLayers());
86+
}
7987

8088
/**
8189
* Prepare texture subresource for transfer after rendering
@@ -137,6 +145,57 @@ void postTransferBarrier(MemoryStack memoryStack, VkCommandBuffer currentCommand
137145
transferLevel = -1;
138146
}
139147

148+
public void insertClear(float clearDepth) {
149+
clearValue[0] = clearDepth;
150+
clearPending = true;
151+
}
152+
153+
public void insertClear(float a, float r, float g, float b) {
154+
clearValue[0] = a;
155+
clearValue[1] = r;
156+
clearValue[2] = g;
157+
clearValue[3] = b;
158+
clearPending = true;
159+
}
160+
161+
protected float[] consumeClear() {
162+
boolean wasClearPending = clearPending;
163+
clearPending = false;
164+
return wasClearPending ? clearValue : null;
165+
}
166+
167+
public void insertPendingClear(MemoryStack memoryStack, Vk11CommandEncoder encoder) {
168+
if(!clearPending) return;
169+
VkImageSubresourceRange range = VkImageSubresourceRange.calloc(memoryStack);
170+
fullResourceRange(range);
171+
if(this.getFormat().hasDepthAspect()) {
172+
VkClearDepthStencilValue clearDepthStencilValue = VkClearDepthStencilValue.calloc(memoryStack);
173+
clearDepthStencilValue.set(clearValue[0], 0);
174+
VK10.vkCmdClearDepthStencilImage(
175+
encoder.commandBuffer(),
176+
vkImage,
177+
VK10.VK_IMAGE_LAYOUT_GENERAL,
178+
clearDepthStencilValue,
179+
range
180+
);
181+
} else {
182+
VkClearColorValue clearColorValue = VkClearColorValue.calloc(memoryStack);
183+
clearColorValue.float32(0, clearValue[0]);
184+
clearColorValue.float32(1, clearValue[1]);
185+
clearColorValue.float32(2, clearValue[2]);
186+
clearColorValue.float32(3, clearValue[3]);
187+
VK10.vkCmdClearColorImage(
188+
encoder.commandBuffer(),
189+
vkImage,
190+
VK10.VK_IMAGE_LAYOUT_GENERAL,
191+
clearColorValue,
192+
range
193+
);
194+
}
195+
encoder.memoryBarrier(memoryStack);
196+
clearPending = false;
197+
}
198+
140199
@Override
141200
public void destroy() {
142201
Vma.vmaDestroyImage(this.device.vma(), this.vkImage, this.vmaAllocation);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected Vk11GpuTextureView(final Vk11Device device, final Vk11GpuTexture textu
2929
imageViewCreateInfo.viewType(isCubemap ? VK10.VK_IMAGE_VIEW_TYPE_CUBE : VK10.VK_IMAGE_VIEW_TYPE_2D);
3030
imageViewCreateInfo.format(Vk11Const.toVk(texture.getFormat()));
3131
VkImageSubresourceRange subresourceRange = imageViewCreateInfo.subresourceRange();
32-
subresourceRange.aspectMask(texture.getFormat().hasColorAspect() ? VK10.VK_IMAGE_ASPECT_COLOR_BIT : VK10.VK_IMAGE_ASPECT_DEPTH_BIT);
32+
subresourceRange.aspectMask(texture.aspect);
3333
subresourceRange.baseMipLevel(baseMipLevel);
3434
subresourceRange.levelCount(mipLevels);
3535
subresourceRange.baseArrayLayer(0);

0 commit comments

Comments
 (0)