diff --git a/gradle.properties b/gradle.properties index 3185a05c0..0a7a9b7fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,6 +11,6 @@ org.gradle.jvmargs=-Xmx3G fabric_version=0.89.0+1.20.2 # Mod Properties - mod_version = 0.3.5 + mod_version = 0.3.5_dev maven_group = net.vulkanmod archives_base_name = VulkanMod_1.20 diff --git a/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java b/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java index dfcca58bc..95135ab60 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java +++ b/src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java @@ -39,7 +39,7 @@ public void tick() { tickable.tick(); } if(SpriteUtil.shouldUpload()) { - SpriteUtil.transitionLayouts(Device.getGraphicsQueue().getCommandBuffer()); + SpriteUtil.transitionLayouts(Device.getGraphicsQueue().getCommandBuffer().getHandle()); Device.getGraphicsQueue().endRecordingAndSubmit(); // Synchronization.INSTANCE.waitFences(); } diff --git a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java index 373fc17e0..3ff00396c 100644 --- a/src/main/java/net/vulkanmod/render/chunk/RenderSection.java +++ b/src/main/java/net/vulkanmod/render/chunk/RenderSection.java @@ -137,7 +137,7 @@ public ChunkTask.BuildTask createCompileTask(RenderRegionCache renderRegionCache RenderChunkRegion renderchunkregion = renderRegionCache.createRegion(WorldRenderer.getLevel(), blockpos.offset(-1, -1, -1), blockpos.offset(16, 16, 16), 1); boolean flag1 = this.compileStatus.compiledSection == CompiledSection.UNCOMPILED; - this.compileStatus.rebuildTask = new ChunkTask.BuildTask(this, renderchunkregion, !flag1); + this.compileStatus.rebuildTask = ChunkTask.createBuildTask(this, renderchunkregion, !flag1); return this.compileStatus.rebuildTask; } diff --git a/src/main/java/net/vulkanmod/render/chunk/TerrainShaderManager.java b/src/main/java/net/vulkanmod/render/chunk/TerrainShaderManager.java index affbeeea8..9b18e3748 100644 --- a/src/main/java/net/vulkanmod/render/chunk/TerrainShaderManager.java +++ b/src/main/java/net/vulkanmod/render/chunk/TerrainShaderManager.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType; import net.vulkanmod.Initializer; +import net.vulkanmod.render.chunk.build.ThreadBuilderPack; import net.vulkanmod.render.vertex.CustomVertexFormat; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; @@ -26,6 +27,7 @@ public static void init() { setTerrainVertexFormat(CustomVertexFormat.COMPRESSED_TERRAIN); createBasicPipelines(); setDefaultShader(); + ThreadBuilderPack.defaultTerrainBuilderConstructor(); } public static void setDefaultShader() { diff --git a/src/main/java/net/vulkanmod/render/chunk/build/ChunkTask.java b/src/main/java/net/vulkanmod/render/chunk/build/ChunkTask.java index 343f4f256..2a6d351ea 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/ChunkTask.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/ChunkTask.java @@ -22,25 +22,31 @@ import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.VisibilitySetExtended; import net.vulkanmod.render.chunk.RenderSection; +import net.vulkanmod.render.chunk.TerrainShaderManager; import net.vulkanmod.render.chunk.WorldRenderer; import net.vulkanmod.render.vertex.TerrainBufferBuilder; import net.vulkanmod.render.vertex.TerrainRenderType; -import net.vulkanmod.render.chunk.TerrainShaderManager; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -public class ChunkTask { +public abstract class ChunkTask { private static TaskDispatcher taskDispatcher; - //TODO stats public static final boolean bench = false; public static AtomicInteger totalBuildTime = new AtomicInteger(0); public static AtomicInteger buildCount = new AtomicInteger(0); + public static BuildTask createBuildTask(RenderSection renderSection, RenderChunkRegion renderChunkRegion, boolean highPriority) { + return new BuildTask(renderSection, renderChunkRegion, highPriority); + } + protected AtomicBoolean cancelled = new AtomicBoolean(false); protected final RenderSection renderSection; public boolean highPriority = false; @@ -49,13 +55,9 @@ public class ChunkTask { this.renderSection = renderSection; } - public String name() { - return "generic_chk_task"; - } + public abstract String name(); - public CompletableFuture doTask(ThreadBuilderPack builderPack) { - return null; - } + public abstract CompletableFuture doTask(ThreadBuilderPack builderPack); public void cancel() { this.cancelled.set(true); @@ -115,9 +117,8 @@ public CompletableFuture doTask(ThreadBuilderPack chunkBufferBuilderPack compiledChunk.renderableBlockEntities.addAll(compileResults.blockEntities); compiledChunk.transparencyState = compileResults.transparencyState; - if(!compileResults.renderedLayers.isEmpty()) { + if(!compileResults.renderedLayers.isEmpty()) compiledChunk.isCompletelyEmpty = false; - } taskDispatcher.scheduleSectionUpdate(renderSection, compileResults.renderedLayers); compiledChunk.renderTypes.addAll(compileResults.renderedLayers.keySet()); @@ -141,9 +142,9 @@ public CompletableFuture doTask(ThreadBuilderPack chunkBufferBuilderPack private CompileResults compile(float camX, float camY, float camZ, ThreadBuilderPack chunkBufferBuilderPack) { CompileResults compileResults = new CompileResults(); - BlockPos blockPos = new BlockPos(renderSection.xOffset(), renderSection.yOffset(), renderSection.zOffset()).immutable(); + BlockPos startBlockPos = new BlockPos(renderSection.xOffset(), renderSection.yOffset(), renderSection.zOffset()).immutable(); - BlockPos blockPos2 = blockPos.offset(15, 15, 15); + BlockPos endBlockPos = startBlockPos.offset(15, 15, 15); VisGraph visGraph = new VisGraph(); RenderChunkRegion renderChunkRegion = this.region; this.region = null; @@ -154,21 +155,21 @@ private CompileResults compile(float camX, float camY, float camZ, ThreadBuilder RandomSource randomSource = RandomSource.create(); BlockRenderDispatcher blockRenderDispatcher = Minecraft.getInstance().getBlockRenderer(); - for(BlockPos blockPos3 : BlockPos.betweenClosed(blockPos, blockPos2)) { - BlockState blockState = renderChunkRegion.getBlockState(blockPos3); - if (blockState.isSolidRender(renderChunkRegion, blockPos3)) { - visGraph.setOpaque(blockPos3); + for(BlockPos blockPos : BlockPos.betweenClosed(startBlockPos, endBlockPos)) { + BlockState blockState = renderChunkRegion.getBlockState(blockPos); + if (blockState.isSolidRender(renderChunkRegion, blockPos)) { + visGraph.setOpaque(blockPos); } if (blockState.hasBlockEntity()) { - BlockEntity blockEntity = renderChunkRegion.getBlockEntity(blockPos3); + BlockEntity blockEntity = renderChunkRegion.getBlockEntity(blockPos); if (blockEntity != null) { this.handleBlockEntity(compileResults, blockEntity); } } - BlockState blockState2 = renderChunkRegion.getBlockState(blockPos3); - FluidState fluidState = blockState2.getFluidState(); +// BlockState blockState2 = renderChunkRegion.getBlockState(blockPos); + FluidState fluidState = blockState.getFluidState(); RenderType renderType; TerrainBufferBuilder bufferBuilder; if (!fluidState.isEmpty()) { @@ -182,7 +183,9 @@ private CompileResults compile(float camX, float camY, float camZ, ThreadBuilder bufferBuilder.begin(VertexFormat.Mode.QUADS, TerrainShaderManager.TERRAIN_VERTEX_FORMAT); } - blockRenderDispatcher.renderLiquid(blockPos3, renderChunkRegion, bufferBuilder, blockState2, fluidState); + bufferBuilder.setBlockAttributes(fluidState.createLegacyBlock()); + + blockRenderDispatcher.renderLiquid(blockPos, renderChunkRegion, bufferBuilder, blockState, fluidState); } if (blockState.getRenderShape() != RenderShape.INVISIBLE) { @@ -196,9 +199,11 @@ private CompileResults compile(float camX, float camY, float camZ, ThreadBuilder bufferBuilder.begin(VertexFormat.Mode.QUADS, TerrainShaderManager.TERRAIN_VERTEX_FORMAT); } + bufferBuilder.setBlockAttributes(blockState); + poseStack.pushPose(); - poseStack.translate(blockPos3.getX() & 15, blockPos3.getY() & 15, blockPos3.getZ() & 15); - blockRenderDispatcher.renderBatched(blockState, blockPos3, renderChunkRegion, poseStack, bufferBuilder, true, randomSource); + poseStack.translate(blockPos.getX() & 15, blockPos.getY() & 15, blockPos.getZ() & 15); + blockRenderDispatcher.renderBatched(blockState, blockPos, renderChunkRegion, poseStack, bufferBuilder, true, randomSource); poseStack.popPose(); } } @@ -206,7 +211,7 @@ private CompileResults compile(float camX, float camY, float camZ, ThreadBuilder if (set.contains(RenderType.translucent())) { TerrainBufferBuilder bufferBuilder2 = chunkBufferBuilderPack.builder(RenderType.translucent()); if (!bufferBuilder2.isCurrentBatchEmpty()) { - bufferBuilder2.setQuadSortOrigin(camX - (float)blockPos.getX(), camY - (float)blockPos.getY(), camZ - (float)blockPos.getZ()); + bufferBuilder2.setQuadSortOrigin(camX - (float)startBlockPos.getX(), camY - (float)startBlockPos.getY(), camZ - (float)startBlockPos.getZ()); compileResults.transparencyState = bufferBuilder2.getSortState(); } } @@ -329,6 +334,5 @@ public CompletableFuture doTask(ThreadBuilderPack builderPack) { public enum Result { CANCELLED, SUCCESSFUL; - } } diff --git a/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java b/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java index 25e0c41ce..5beb3f145 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java @@ -14,8 +14,6 @@ import java.util.Queue; public class TaskDispatcher { - private static final Logger LOGGER = LogUtils.getLogger(); - private int highPriorityQuota = 2; private final Queue toUpload = Queues.newLinkedBlockingDeque(); @@ -84,10 +82,10 @@ public void schedule(ChunkTask chunkTask) { return; if (chunkTask.highPriority) { - this.highPriorityTasks.offer(chunkTask); - } else { - this.lowPriorityTasks.offer(chunkTask); - } + this.highPriorityTasks.offer(chunkTask); + } else { + this.lowPriorityTasks.offer(chunkTask); + } synchronized (this) { notify(); diff --git a/src/main/java/net/vulkanmod/render/chunk/build/ThreadBuilderPack.java b/src/main/java/net/vulkanmod/render/chunk/build/ThreadBuilderPack.java index 061869e54..b61b94e8d 100644 --- a/src/main/java/net/vulkanmod/render/chunk/build/ThreadBuilderPack.java +++ b/src/main/java/net/vulkanmod/render/chunk/build/ThreadBuilderPack.java @@ -4,12 +4,27 @@ import net.vulkanmod.render.vertex.TerrainBufferBuilder; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; public class ThreadBuilderPack { - private final Map builders = RenderType.chunkBufferLayers().stream().collect(Collectors.toMap( - (renderType) -> renderType, - (renderType) -> new TerrainBufferBuilder(renderType.bufferSize()))); + private static Function terrainBuilderConstructor; + + public static void defaultTerrainBuilderConstructor() { + terrainBuilderConstructor = renderType -> new TerrainBufferBuilder(renderType.bufferSize()); + } + + public static void setTerrainBuilderConstructor(Function constructor) { + terrainBuilderConstructor = constructor; + } + + private final Map builders; + + public ThreadBuilderPack() { + builders = RenderType.chunkBufferLayers().stream().collect(Collectors.toMap( + (renderType) -> renderType, + renderType -> terrainBuilderConstructor.apply(renderType))); + } public TerrainBufferBuilder builder(RenderType renderType) { return this.builders.get(renderType); diff --git a/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java b/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java index 961142bba..b3b70c9ef 100644 --- a/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java +++ b/src/main/java/net/vulkanmod/render/texture/SpriteUtil.java @@ -1,7 +1,7 @@ package net.vulkanmod.render.texture; -import net.vulkanmod.vulkan.queue.CommandPool; import net.vulkanmod.vulkan.texture.VulkanImage; +import org.lwjgl.vulkan.VkCommandBuffer; import java.util.HashSet; import java.util.Set; @@ -24,7 +24,7 @@ public static void addTransitionedLayout(VulkanImage image) { transitionedLayouts.add(image); } - public static void transitionLayouts(CommandPool.CommandBuffer commandBuffer) { + public static void transitionLayouts(VkCommandBuffer commandBuffer) { transitionedLayouts.forEach(image -> image.readOnlyLayout(commandBuffer)); transitionedLayouts.clear(); diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java index 064adfb60..2768e3198 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainBufferBuilder.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.*; import com.mojang.logging.LogUtils; import net.minecraft.util.Mth; +import net.minecraft.world.level.block.state.BlockState; import net.vulkanmod.render.util.SortUtil; import net.vulkanmod.render.chunk.TerrainShaderManager; import org.apache.commons.lang3.mutable.MutableInt; @@ -18,8 +19,8 @@ import java.util.function.IntConsumer; public class TerrainBufferBuilder implements VertexConsumer { - private static final float POS_CONV = 1900.0f; - private static final float UV_CONV = 65536.0f; + protected static final float POS_CONV = 1900.0f; + protected static final float UV_CONV = 65536.0f; private static final int GROWTH_SIZE = 2097152; private static final Logger LOGGER = LogUtils.getLogger(); @@ -27,7 +28,7 @@ public class TerrainBufferBuilder implements VertexConsumer { private ByteBuffer buffer; private int renderedBufferCount; private int renderedBufferPointer; - private int nextElementByte; + protected int nextElementByte; private int vertices; @Nullable private VertexFormatElement currentElement; @@ -44,10 +45,10 @@ public class TerrainBufferBuilder implements VertexConsumer { private float sortZ = Float.NaN; private boolean indexOnly; - private long bufferPtr; + protected long bufferPtr; // private long ptr; - VertexBuilder vertexBuilder; + protected VertexBuilder vertexBuilder; public TerrainBufferBuilder(int i) { this.buffer = MemoryTracker.create(i * 6); @@ -342,58 +343,7 @@ public void vertex(float x, float y, float z, float red, float green, float blue this.vertexBuilder.vertex(x, y, z, red, green, blue, alpha, u, v, overlay, light, normalX, normalY, normalZ); } - private void defaultVertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) { - this.putFloat(0, x); - this.putFloat(4, y); - this.putFloat(8, z); - this.putByte(12, (byte)((int)(red * 255.0F))); - this.putByte(13, (byte)((int)(green * 255.0F))); - this.putByte(14, (byte)((int)(blue * 255.0F))); - this.putByte(15, (byte)((int)(alpha * 255.0F))); - this.putFloat(16, u); - this.putFloat(20, v); - byte i; - i = 24; - - this.putShort(i, (short)(light & '\uffff')); - this.putShort(i + 2, (short)(light >> 16 & '\uffff')); - this.putByte(i + 4, BufferVertexConsumer.normalIntValue(normalX)); - this.putByte(i + 5, BufferVertexConsumer.normalIntValue(normalY)); - this.putByte(i + 6, BufferVertexConsumer.normalIntValue(normalZ)); - this.nextElementByte += i + 8; - this.endVertex(); - } - - private void compressedVertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int light) { - long ptr = this.bufferPtr + this.nextElementByte; - - short sX = (short) (x * POS_CONV + 0.1f); - short sY = (short) (y * POS_CONV + 0.1f); - short sZ = (short) (z * POS_CONV + 0.1f); - - //Debug -// short x1 = (short) Math.round((x) * POS_CONV); -// float y1 = (short) Math.round((y) * POS_CONV); -// float z1 = (short) Math.round((z) * POS_CONV); -// -// if(x1 != sX || y1 != sY || z1 != sZ) -// System.nanoTime(); - - MemoryUtil.memPutShort(ptr + 0, sX); - MemoryUtil.memPutShort(ptr + 2, sY); - MemoryUtil.memPutShort(ptr + 4, sZ); - - int temp = VertexUtil.packColor(red, green, blue, alpha); - MemoryUtil.memPutInt(ptr + 8, temp); - - MemoryUtil.memPutShort(ptr + 12, (short) (u * UV_CONV)); - MemoryUtil.memPutShort(ptr + 14, (short) (v * UV_CONV)); - - MemoryUtil.memPutInt(ptr + 16, light); - - this.nextElementByte += 20; - this.endVertex(); - } + public void setBlockAttributes(BlockState blockState) {} @Override public VertexConsumer vertex(double d, double e, double f) { @@ -602,7 +552,7 @@ public boolean sequentialIndex() { } } - interface VertexBuilder { + public interface VertexBuilder { void vertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ); } diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java index af824a349..4582ac6f9 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java @@ -176,7 +176,7 @@ public static void addImage(VulkanImage image) { images.putIfAbsent(image.getId(), image); } - public void MapAndCopy(long allocation, long bufferSize, Consumer consumer){ + public static void MapAndCopy(long allocation, Consumer consumer){ try(MemoryStack stack = stackPush()) { PointerBuffer data = stack.mallocPointer(1); diff --git a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java index f406e3ab4..1f9465d96 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java @@ -27,7 +27,7 @@ public void createCommandPool(int familyIndex) { try(MemoryStack stack = stackPush()) { - VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.callocStack(stack); + VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.calloc(stack); poolInfo.sType(VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); poolInfo.queueFamilyIndex(familyIndex); poolInfo.flags(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); @@ -47,10 +47,10 @@ public CommandBuffer beginCommands() { try(MemoryStack stack = stackPush()) { final int size = 10; - if(availableCmdBuffers.size() == 0) { + if(availableCmdBuffers.isEmpty()) { - VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.callocStack(stack); - allocInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); + VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo.calloc(stack); + allocInfo.sType$Default(); allocInfo.level(VK_COMMAND_BUFFER_LEVEL_PRIMARY); allocInfo.commandPool(id); allocInfo.commandBufferCount(size); @@ -58,8 +58,8 @@ public CommandBuffer beginCommands() { PointerBuffer pCommandBuffer = stack.mallocPointer(size); vkAllocateCommandBuffers(Vulkan.getDevice(), allocInfo, pCommandBuffer); - VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.callocStack(stack); - fenceInfo.sType(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); + VkFenceCreateInfo fenceInfo = VkFenceCreateInfo.calloc(stack); + fenceInfo.sType$Default(); fenceInfo.flags(VK_FENCE_CREATE_SIGNALED_BIT); for(int i = 0; i < size; ++i) { @@ -76,7 +76,7 @@ public CommandBuffer beginCommands() { CommandBuffer commandBuffer = availableCmdBuffers.poll(); - VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.callocStack(stack); + VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.calloc(stack); beginInfo.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); beginInfo.flags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); @@ -88,7 +88,7 @@ public CommandBuffer beginCommands() { } } - public synchronized long submitCommands(CommandBuffer commandBuffer, VkQueue queue) { + public long submitCommands(CommandBuffer commandBuffer, VkQueue queue) { try(MemoryStack stack = stackPush()) { long fence = commandBuffer.fence; @@ -97,14 +97,12 @@ public synchronized long submitCommands(CommandBuffer commandBuffer, VkQueue que vkResetFences(Vulkan.getDevice(), commandBuffer.fence); - VkSubmitInfo submitInfo = VkSubmitInfo.callocStack(stack); + VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); submitInfo.pCommandBuffers(stack.pointers(commandBuffer.handle)); vkQueueSubmit(queue, submitInfo, fence); - //vkQueueWaitIdle(graphicsQueue); - //vkFreeCommandBuffers(device, commandPool, commandBuffer); return fence; } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index 3fe15a346..e273533d1 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -34,7 +34,7 @@ public class GraphicsPipeline extends Pipeline { super(builder.shaderPath); this.buffers = builder.UBOs; this.manualUBO = builder.manualUBO; - this.images = builder.images; + this.imageDescriptors = builder.imageDescriptors; this.pushConstants = builder.pushConstants; this.vertexFormat = builder.vertexFormat; @@ -243,6 +243,8 @@ private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions VertexFormatElement formatElement = elements.get(i); VertexFormatElement.Usage usage = formatElement.getUsage(); VertexFormatElement.Type type = formatElement.getType(); + int elementCount = formatElement.getCount(); + switch (usage) { case POSITION : if(type == VertexFormatElement.Type.FLOAT) { @@ -303,6 +305,28 @@ else if(type == VertexFormatElement.Type.USHORT){ break; case PADDING: + //Do nothing as padding format (VK_FORMAT_R8) is not supported everywhere + break; + + case GENERIC: + if(type == VertexFormatElement.Type.SHORT && elementCount == 1){ + posDescription.format(VK_FORMAT_R16_SINT); + posDescription.offset(offset); + + offset += 2; + break; + } + else if (type == VertexFormatElement.Type.INT && elementCount == 1) { + posDescription.format(VK_FORMAT_R32_SINT); + posDescription.offset(offset); + + offset += 4; + break; + } + else { + throw new RuntimeException(String.format("Unknown format: %s", usage)); + } + default: throw new RuntimeException(String.format("Unknown format: %s", usage)); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java index 23732bd73..8160437a5 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java @@ -11,7 +11,7 @@ import net.vulkanmod.vulkan.shader.SPIRVUtils.ShaderKind; import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.memory.UniformBuffers; -import net.vulkanmod.vulkan.shader.descriptor.Image; +import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; import net.vulkanmod.vulkan.shader.descriptor.ManualUBO; import net.vulkanmod.vulkan.shader.layout.AlignedStruct; import net.vulkanmod.vulkan.shader.layout.PushConstants; @@ -76,7 +76,7 @@ public static void recreateDescriptorSets(int frames) { protected DescriptorSets[] descriptorSets; protected List buffers; protected ManualUBO manualUBO; - protected List images; + protected List imageDescriptors; protected PushConstants pushConstants; public Pipeline(String name) { @@ -85,7 +85,7 @@ public Pipeline(String name) { protected void createDescriptorSetLayout() { try(MemoryStack stack = stackPush()) { - int bindingsSize = this.buffers.size() + images.size(); + int bindingsSize = this.buffers.size() + imageDescriptors.size(); VkDescriptorSetLayoutBinding.Buffer bindings = VkDescriptorSetLayoutBinding.calloc(bindingsSize, stack); @@ -98,13 +98,13 @@ protected void createDescriptorSetLayout() { uboLayoutBinding.stageFlags(ubo.getStages()); } - for(Image image : this.images) { - VkDescriptorSetLayoutBinding samplerLayoutBinding = bindings.get(image.getBinding()); - samplerLayoutBinding.binding(image.getBinding()); + for(ImageDescriptor imageDescriptor : this.imageDescriptors) { + VkDescriptorSetLayoutBinding samplerLayoutBinding = bindings.get(imageDescriptor.getBinding()); + samplerLayoutBinding.binding(imageDescriptor.getBinding()); samplerLayoutBinding.descriptorCount(1); - samplerLayoutBinding.descriptorType(image.getType()); + samplerLayoutBinding.descriptorType(imageDescriptor.getType()); samplerLayoutBinding.pImmutableSamplers(null); - samplerLayoutBinding.stageFlags(image.getStages()); + samplerLayoutBinding.stageFlags(imageDescriptor.getStages()); } VkDescriptorSetLayoutCreateInfo layoutInfo = VkDescriptorSetLayoutCreateInfo.calloc(stack); @@ -155,6 +155,10 @@ protected void createDescriptorSets(int frames) { } } + public void scheduleCleanUp() { + MemoryManager.getInstance().addFrameOp(this::cleanUp); + } + public abstract void cleanUp(); void destroyDescriptorSets() { @@ -179,11 +183,11 @@ public void resetDescriptorPool(int i) { public void bindDescriptorSets(VkCommandBuffer commandBuffer, int frame) { UniformBuffers uniformBuffers = Renderer.getDrawer().getUniformBuffers(); - this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffers); + this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffers, VK_PIPELINE_BIND_POINT_GRAPHICS); } public void bindDescriptorSets(VkCommandBuffer commandBuffer, UniformBuffers uniformBuffers, int frame) { - this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffers); + this.descriptorSets[frame].bindSets(commandBuffer, uniformBuffers, VK_PIPELINE_BIND_POINT_GRAPHICS); } static long createShaderModule(ByteBuffer spirvCode) { @@ -205,7 +209,7 @@ static long createShaderModule(ByteBuffer spirvCode) { } } - private class DescriptorSets { + protected class DescriptorSets { private int poolSize = 10; private long descriptorPool; private LongBuffer sets; @@ -214,8 +218,8 @@ private class DescriptorSets { private int currentIdx = -1; private final int frame; - private final VulkanImage.Sampler[] boundTextures = new VulkanImage.Sampler[images.size()]; - private final IntBuffer dynamicOffsets = MemoryUtil.memAllocInt(buffers.size());; + private final VulkanImage.Sampler[] boundTextures = new VulkanImage.Sampler[imageDescriptors.size()]; + private final IntBuffer dynamicOffsets = MemoryUtil.memAllocInt(buffers.size()); DescriptorSets(int frame) { this.frame = frame; @@ -226,13 +230,13 @@ private class DescriptorSets { } } - private void bindSets(VkCommandBuffer commandBuffer, UniformBuffers uniformBuffers) { + protected void bindSets(VkCommandBuffer commandBuffer, UniformBuffers uniformBuffers, int bindPoint) { try(MemoryStack stack = stackPush()) { this.updateUniforms(uniformBuffers); this.updateDescriptorSet(stack, uniformBuffers); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, + vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, stack.longs(currentSet), dynamicOffsets); } } @@ -263,11 +267,13 @@ private void updateUniforms(UniformBuffers uniformBuffers) { private void updateDescriptorSet(MemoryStack stack, UniformBuffers uniformBuffers) { boolean changed = false; - for(int j = 0; j < images.size(); ++j) { - Image image = images.get(j); + for(int j = 0; j < imageDescriptors.size(); ++j) { + ImageDescriptor imageDescriptor = imageDescriptors.get(j); + + VulkanImage.Sampler texture = VTextureSelector.getTexture(imageDescriptor.name).getTextureSampler(); + if(imageDescriptor.useSampler) + texture.image().readOnlyLayout(); - VulkanImage.Sampler texture = VTextureSelector.getTexture(image.name).getTextureSampler(); - texture.image().readOnlyLayout(); if(this.boundTextures[j] != texture) { changed = true; break; @@ -298,7 +304,7 @@ private void updateDescriptorSet(MemoryStack stack, UniformBuffers uniformBuffer this.currentSet = this.sets.get(this.currentIdx); - VkWriteDescriptorSet.Buffer descriptorWrites = VkWriteDescriptorSet.calloc(buffers.size() + images.size(), stack); + VkWriteDescriptorSet.Buffer descriptorWrites = VkWriteDescriptorSet.calloc(buffers.size() + imageDescriptors.size(), stack); VkDescriptorBufferInfo.Buffer[] bufferInfos = new VkDescriptorBufferInfo.Buffer[buffers.size()]; //TODO maybe ubo update is not needed everytime @@ -321,25 +327,29 @@ private void updateDescriptorSet(MemoryStack stack, UniformBuffers uniformBuffer ++i; } - VkDescriptorImageInfo.Buffer[] imageInfo = new VkDescriptorImageInfo.Buffer[images.size()]; + VkDescriptorImageInfo.Buffer[] imageInfo = new VkDescriptorImageInfo.Buffer[imageDescriptors.size()]; - for(int j = 0; j < images.size(); ++j) { - Image image = images.get(j); - VulkanImage texture = VTextureSelector.getTexture(image.name); - VulkanImage.Sampler textureSampler = texture.getTextureSampler(); - texture.readOnlyLayout(); + for(int j = 0; j < imageDescriptors.size(); ++j) { + ImageDescriptor imageDescriptor = imageDescriptors.get(j); + VulkanImage image = VTextureSelector.getTexture(imageDescriptor.name); + VulkanImage.Sampler textureSampler = image.getTextureSampler(); imageInfo[j] = VkDescriptorImageInfo.calloc(1, stack); - imageInfo[j].imageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - - imageInfo[j].imageView(texture.getImageView()); - imageInfo[j].sampler(textureSampler.sampler()); + imageInfo[j].imageView(image.getImageView()); + + if(imageDescriptor.useSampler) { + imageInfo[j].imageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + imageInfo[j].sampler(textureSampler.sampler()); + image.readOnlyLayout(); + } else { + imageInfo[j].imageLayout(VK_IMAGE_LAYOUT_GENERAL); + } VkWriteDescriptorSet samplerDescriptorWrite = descriptorWrites.get(i); samplerDescriptorWrite.sType(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); - samplerDescriptorWrite.dstBinding(image.getBinding()); + samplerDescriptorWrite.dstBinding(imageDescriptor.getBinding()); samplerDescriptorWrite.dstArrayElement(0); - samplerDescriptorWrite.descriptorType(image.getType()); + samplerDescriptorWrite.descriptorType(imageDescriptor.getType()); samplerDescriptorWrite.descriptorCount(1); samplerDescriptorWrite.pImageInfo(imageInfo[j]); samplerDescriptorWrite.dstSet(currentSet); @@ -373,7 +383,7 @@ private void createDescriptorSets(MemoryStack stack) { } private void createDescriptorPool(MemoryStack stack) { - int size = buffers.size() + images.size(); + int size = buffers.size() + imageDescriptors.size(); VkDescriptorPoolSize.Buffer poolSizes = VkDescriptorPoolSize.calloc(size, stack); @@ -385,7 +395,7 @@ private void createDescriptorPool(MemoryStack stack) { uniformBufferPoolSize.descriptorCount(this.poolSize); } - for(; i < buffers.size() + images.size(); ++i) { + for(; i < buffers.size() + imageDescriptors.size(); ++i) { VkDescriptorPoolSize textureSamplerPoolSize = poolSizes.get(i); textureSamplerPoolSize.type(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); textureSamplerPoolSize.descriptorCount(this.poolSize); @@ -435,7 +445,7 @@ public static GraphicsPipeline createGraphicsPipeline(VertexFormat format, Strin List UBOs; ManualUBO manualUBO; PushConstants pushConstants; - List images; + List imageDescriptors; int currentBinding; SPIRV vertShaderSPIRV; @@ -453,7 +463,7 @@ public Builder(VertexFormat vertexFormat) { } public GraphicsPipeline createGraphicsPipeline() { - Validate.isTrue(this.images != null && this.UBOs != null + Validate.isTrue(this.imageDescriptors != null && this.UBOs != null && this.vertShaderSPIRV != null && this.fragShaderSPIRV != null, "Cannot create Pipeline: resources missing"); @@ -463,9 +473,9 @@ public GraphicsPipeline createGraphicsPipeline() { return new GraphicsPipeline(this); } - public void setUniforms(List UBOs, List images) { + public void setUniforms(List UBOs, List imageDescriptors) { this.UBOs = UBOs; - this.images = images; + this.imageDescriptors = imageDescriptors; } public void compileShaders() { @@ -484,7 +494,7 @@ public void parseBindingsJSON() { Validate.notNull(this.shaderPath, "Cannot parse bindings: shaderPath is null"); this.UBOs = new ArrayList<>(); - this.images = new ArrayList<>(); + this.imageDescriptors = new ArrayList<>(); JsonObject jsonObject; @@ -496,10 +506,10 @@ public void parseBindingsJSON() { jsonObject = GsonHelper.parse(new InputStreamReader(stream, StandardCharsets.UTF_8)); - JsonArray jsonUbos = GsonHelper.getAsJsonArray(jsonObject, "UBOs", (JsonArray)null); - JsonArray jsonManualUbos = GsonHelper.getAsJsonArray(jsonObject, "ManualUBOs", (JsonArray)null); - JsonArray jsonSamplers = GsonHelper.getAsJsonArray(jsonObject, "samplers", (JsonArray)null); - JsonArray jsonPushConstants = GsonHelper.getAsJsonArray(jsonObject, "PushConstants", (JsonArray)null); + JsonArray jsonUbos = GsonHelper.getAsJsonArray(jsonObject, "UBOs", null); + JsonArray jsonManualUbos = GsonHelper.getAsJsonArray(jsonObject, "ManualUBOs", null); + JsonArray jsonSamplers = GsonHelper.getAsJsonArray(jsonObject, "samplers", null); + JsonArray jsonPushConstants = GsonHelper.getAsJsonArray(jsonObject, "PushConstants", null); if (jsonUbos != null) { for (JsonElement jsonelement : jsonUbos) { @@ -566,7 +576,7 @@ private void parseSamplerNode(JsonElement jsonelement) { this.currentBinding++; - this.images.add(new Image(this.currentBinding, "sampler2D", name)); + this.imageDescriptors.add(new ImageDescriptor(this.currentBinding, "sampler2D", name)); } private void parsePushConstantNode(JsonArray jsonArray) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Image.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java similarity index 68% rename from src/main/java/net/vulkanmod/vulkan/shader/descriptor/Image.java rename to src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java index f96be3ef8..3718d35e5 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/Image.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/ImageDescriptor.java @@ -2,7 +2,7 @@ import static org.lwjgl.vulkan.VK10.*; -public class Image implements Descriptor { +public class ImageDescriptor implements Descriptor { private final int descriptorType; private final int binding; @@ -10,17 +10,17 @@ public class Image implements Descriptor { public final String name; public final boolean useSampler; - public Image(int binding, String type, String name) { + public ImageDescriptor(int binding, String type, String name) { this(binding, type, name, true); } - public Image(int binding, String type, String name, boolean useSampler) { + public ImageDescriptor(int binding, String type, String name, boolean useSampler) { this.binding = binding; this.qualifier = type; this.name = name; this.useSampler = useSampler; - descriptorType = useSampler ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptorType = useSampler ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; } @Override @@ -35,6 +35,6 @@ public int getType() { @Override public int getStages() { - return VK_SHADER_STAGE_ALL_GRAPHICS; + return VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT; } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java b/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java index 1ca9895c7..78d6f2915 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java @@ -1,8 +1,7 @@ package net.vulkanmod.vulkan.shader.parser; import com.mojang.blaze3d.vertex.VertexFormat; -import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.shader.descriptor.Image; +import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; import net.vulkanmod.vulkan.shader.descriptor.UBO; import java.util.Arrays; @@ -144,7 +143,7 @@ public UBO getUBO() { return this.uniformParser.getUbo(); } - public List getSamplerList() { + public List getSamplerList() { return this.uniformParser.getSamplers(); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java b/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java index 1909bc563..d9aeec8df 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java @@ -2,7 +2,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.shader.descriptor.Image; +import net.vulkanmod.vulkan.shader.descriptor.ImageDescriptor; import net.vulkanmod.vulkan.shader.layout.AlignedStruct; import net.vulkanmod.vulkan.shader.descriptor.UBO; @@ -20,7 +20,7 @@ public class UniformParser { private String name; private UBO ubo; - private List images; + private List imageDescriptors; public UniformParser(GlslConverter converterInstance) { this.converterInstance = converterInstance; @@ -87,10 +87,10 @@ public String createUniformsCode() { public String createSamplersCode(GlslConverter.ShaderStage shaderStage) { StringBuilder builder = new StringBuilder(); - this.images = createSamplerList(); + this.imageDescriptors = createSamplerList(); - for(Image image : this.images) { - builder.append(String.format("layout(binding = %d) uniform %s %s;\n", image.getBinding(), image.qualifier, image.name)); + for(ImageDescriptor imageDescriptor : this.imageDescriptors) { + builder.append(String.format("layout(binding = %d) uniform %s %s;\n", imageDescriptor.getBinding(), imageDescriptor.qualifier, imageDescriptor.name)); } builder.append("\n"); @@ -108,19 +108,19 @@ private UBO createUBO() { return builder.buildUBO(0, Pipeline.Builder.getStageFromString("all")); } - private List createSamplerList() { + private List createSamplerList() { int currentLocation = 1; - List images = new ObjectArrayList<>(); + List imageDescriptors = new ObjectArrayList<>(); for(StageUniforms stageUniforms : this.stageUniforms) { for(Uniform uniform : stageUniforms.samplers) { - images.add(new Image(currentLocation, uniform.type, uniform.name)); + imageDescriptors.add(new ImageDescriptor(currentLocation, uniform.type, uniform.name)); currentLocation++; } } - return images; + return imageDescriptors; } public static String removeSemicolon(String s) { @@ -134,8 +134,8 @@ public UBO getUbo() { return this.ubo; } - public List getSamplers() { - return this.images; + public List getSamplers() { + return this.imageDescriptors; } public record Uniform(String type, String name) {} diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java index aa9a7a92a..c732b834b 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java @@ -20,6 +20,7 @@ import static net.vulkanmod.vulkan.Vulkan.*; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK12.VK_SAMPLER_REDUCTION_MODE_MIN; public class VulkanImage { public static int DefaultFormat = VK_FORMAT_R8G8B8A8_UNORM; @@ -125,7 +126,7 @@ public static long createImageView(long image, int format, int aspectFlags, int try(MemoryStack stack = stackPush()) { - VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.callocStack(stack); + VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.calloc(stack); viewInfo.sType(VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); viewInfo.image(image); viewInfo.viewType(VK_IMAGE_VIEW_TYPE_2D); @@ -180,7 +181,7 @@ public static void downloadTexture(int width, int height, int formatSize, ByteBu copyImageToBuffer(pStagingBuffer.get(0), image, 0, width, height, 0, 0, 0, 0, 0); - MemoryManager.getInstance().MapAndCopy(pStagingAllocation.get(0), imageSize, + MemoryManager.MapAndCopy(pStagingAllocation.get(0), (data) -> VUtil.memcpy(data.getByteBuffer(0, (int)imageSize), buffer) ); @@ -195,7 +196,7 @@ private void transferDstLayout(CommandPool.CommandBuffer commandBuffer) { try(MemoryStack stack = stackPush()) { - VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.callocStack(1, stack); + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); barrier.oldLayout(this.currentLayout); barrier.newLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); @@ -238,18 +239,18 @@ public void readOnlyLayout() { return; CommandPool.CommandBuffer commandBuffer = Device.getGraphicsQueue().getCommandBuffer(); - readOnlyLayout(commandBuffer); + readOnlyLayout(commandBuffer.getHandle()); Device.getGraphicsQueue().submitCommands(commandBuffer); Synchronization.INSTANCE.addCommandBuffer(commandBuffer); } - public void readOnlyLayout(CommandPool.CommandBuffer commandBuffer) { + public void readOnlyLayout(VkCommandBuffer commandBuffer) { if (this.currentLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) return; try(MemoryStack stack = stackPush()) { - VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.callocStack(1, stack); + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); barrier.oldLayout(this.currentLayout); barrier.newLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); @@ -273,7 +274,7 @@ public void readOnlyLayout(CommandPool.CommandBuffer commandBuffer) { sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; destinationStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; - vkCmdPipelineBarrier(commandBuffer.getHandle(), + vkCmdPipelineBarrier(commandBuffer, sourceStage, destinationStage, 0, null, @@ -284,11 +285,52 @@ public void readOnlyLayout(CommandPool.CommandBuffer commandBuffer) { this.currentLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } + public void generalLayout(VkCommandBuffer commandBuffer) { + if (this.currentLayout == VK_IMAGE_LAYOUT_GENERAL) + return; + + try(MemoryStack stack = stackPush()) { + + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); + barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + barrier.oldLayout(this.currentLayout); + barrier.newLayout(VK_IMAGE_LAYOUT_GENERAL); + barrier.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.image(this.id); + + barrier.subresourceRange().baseMipLevel(0); + barrier.subresourceRange().levelCount(mipLevels); + barrier.subresourceRange().baseArrayLayer(0); + barrier.subresourceRange().layerCount(1); + + barrier.subresourceRange().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + + int sourceStage; + int destinationStage; + + barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); + barrier.dstAccessMask(VK_ACCESS_SHADER_READ_BIT); + + sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + destinationStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; + + vkCmdPipelineBarrier(commandBuffer, + sourceStage, destinationStage, + 0, + null, + null, + barrier); + } + + this.currentLayout = VK_IMAGE_LAYOUT_GENERAL; + } + private void createTextureSampler(boolean blur, boolean clamp, boolean mipmap) { try(MemoryStack stack = stackPush()) { - VkSamplerCreateInfo samplerInfo = VkSamplerCreateInfo.callocStack(stack); + VkSamplerCreateInfo samplerInfo = VkSamplerCreateInfo.calloc(stack); samplerInfo.sType(VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); if(blur) { @@ -328,6 +370,12 @@ private void createTextureSampler(boolean blur, boolean clamp, boolean mipmap) { samplerInfo.minLod(0.0F); } + //Reduction Mode +// VkSamplerReductionModeCreateInfo reductionModeInfo = VkSamplerReductionModeCreateInfo.calloc(stack); +// reductionModeInfo.sType$Default(); +// reductionModeInfo.reductionMode(VK_SAMPLER_REDUCTION_MODE_MIN); +// samplerInfo.pNext(reductionModeInfo.address()); + LongBuffer pTextureSampler = stack.mallocLong(1); if(vkCreateSampler(getDevice(), samplerInfo, null, pTextureSampler) != VK_SUCCESS) { @@ -355,7 +403,7 @@ private void copyBufferToImageCmd(CommandPool.CommandBuffer commandBuffer, long try(MemoryStack stack = stackPush()) { - VkBufferImageCopy.Buffer region = VkBufferImageCopy.callocStack(1, stack); + VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); region.bufferOffset(bufferOffset); region.bufferRowLength(bufferRowLenght); // Tightly packed region.bufferImageHeight(bufferImageHeight); // Tightly packed @@ -364,7 +412,7 @@ private void copyBufferToImageCmd(CommandPool.CommandBuffer commandBuffer, long region.imageSubresource().baseArrayLayer(0); region.imageSubresource().layerCount(1); region.imageOffset().set(xOffset, yOffset, 0); - region.imageExtent(VkExtent3D.callocStack(stack).set(width, height, 1)); + region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); vkCmdCopyBufferToImage(commandBuffer.getHandle(), buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); } @@ -376,7 +424,7 @@ private static void copyImageToBuffer(long buffer, long image, int mipLevel, int CommandPool.CommandBuffer commandBuffer = Device.getGraphicsQueue().beginCommands(); - VkBufferImageCopy.Buffer region = VkBufferImageCopy.callocStack(1, stack); + VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); region.bufferOffset(bufferOffset); region.bufferRowLength(bufferRowLenght); // Tightly packed region.bufferImageHeight(bufferImageHeight); // Tightly packed @@ -385,7 +433,7 @@ private static void copyImageToBuffer(long buffer, long image, int mipLevel, int region.imageSubresource().baseArrayLayer(0); region.imageSubresource().layerCount(1); region.imageOffset().set(xOffset, yOffset, 0); - region.imageExtent(VkExtent3D.callocStack(stack).set(width, height, 1)); + region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); vkCmdCopyImageToBuffer(commandBuffer.getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, region); @@ -396,90 +444,97 @@ private static void copyImageToBuffer(long buffer, long image, int mipLevel, int } public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { - transitionImageLayout(stack, commandBuffer, this.id, this.format, this.currentLayout, newLayout, this.mipLevels); + transitionImageLayout(stack, commandBuffer, this, newLayout); this.currentLayout = newLayout; } - public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, long image, int format, int oldLayout, int newLayout, int mipLevels) { - - if(oldLayout == newLayout) { + public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, VulkanImage image, int newLayout) { + if(image.currentLayout == newLayout) { // System.out.println("new layout is equal to current layout"); return; } - VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.callocStack(1, stack); - barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); - barrier.oldLayout(oldLayout); - barrier.newLayout(newLayout); -// barrier.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); -// barrier.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); - barrier.image(image); - - barrier.subresourceRange().baseMipLevel(0); - barrier.subresourceRange().levelCount(mipLevels); - barrier.subresourceRange().baseArrayLayer(0); - barrier.subresourceRange().layerCount(1); - - if(format == VK_FORMAT_D32_SFLOAT) { - barrier.subresourceRange().aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); - } else { - barrier.subresourceRange().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - } - - int sourceStage; - int destinationStage; + int sourceStage, srcAccessMask, destinationStage, dstAccessMask = 0; - switch (oldLayout) { + switch (image.currentLayout) { case VK_IMAGE_LAYOUT_UNDEFINED -> { -// barrier.srcAccessMask(0); + srcAccessMask = 0; sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; } case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> { - barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); + srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; } case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL -> { - barrier.srcAccessMask(VK_ACCESS_SHADER_READ_BIT); + srcAccessMask = VK_ACCESS_SHADER_READ_BIT; sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; } case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> { - barrier.srcAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; } case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> { - barrier.srcAccessMask(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); - sourceStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + sourceStage = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; } - default -> throw new RuntimeException("Unexpected value"); + default -> throw new RuntimeException("Unexpected value:" + image.currentLayout); } switch (newLayout) { case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> { - barrier.dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); + dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; } case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL -> { - barrier.dstAccessMask(VK_ACCESS_SHADER_READ_BIT); + dstAccessMask = VK_ACCESS_SHADER_READ_BIT; destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; } case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> { - barrier.dstAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; } case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> { - barrier.dstAccessMask(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); + dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; } - default -> throw new RuntimeException("Unexpected value"); + default -> throw new RuntimeException("Unexpected value:" + newLayout); } + transitionLayout(stack, commandBuffer, image, image.currentLayout, newLayout, + sourceStage, srcAccessMask, destinationStage, dstAccessMask); + } + + public static void transitionLayout(MemoryStack stack, VkCommandBuffer commandBuffer, VulkanImage image, int oldLayout, int newLayout, + int sourceStage, int srcAccessMask, int destinationStage, int dstAccessMask) { + + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); + barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + barrier.oldLayout(image.currentLayout); + barrier.newLayout(newLayout); + barrier.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.image(image.getId()); + + barrier.subresourceRange().baseMipLevel(0); + barrier.subresourceRange().levelCount(image.mipLevels); + barrier.subresourceRange().baseArrayLayer(0); + barrier.subresourceRange().layerCount(1); + + barrier.subresourceRange() + .aspectMask(image.format == VK_FORMAT_D32_SFLOAT ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT); + + barrier.srcAccessMask(srcAccessMask); + barrier.dstAccessMask(dstAccessMask); + vkCmdPipelineBarrier(commandBuffer, sourceStage, destinationStage, 0, null, null, barrier); + + image.currentLayout = newLayout; } private static boolean hasStencilComponent(int format) { diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 57c299caf..6743f7d3d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "vulkanmod", - "version": "0.3.5", + "version": "0.3.5_dev", "name": "VulkanMod", "description": "Bring Vulkan to Minecraft!",