diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index d59b001ba..9fa951a67 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -45,6 +45,7 @@ import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; +import org.lwjgl.vulkan.VkCommandBuffer; import java.util.*; @@ -71,8 +72,6 @@ public class WorldRenderer { private SectionGraph sectionGraph; private boolean graphNeedsUpdate; - private final Set globalBlockEntities = Sets.newHashSet(); - private final TaskDispatcher taskDispatcher; private double xTransparentOld; @@ -246,9 +245,6 @@ public void allChanged() { } this.taskDispatcher.clearBatchQueue(); - synchronized (this.globalBlockEntities) { - this.globalBlockEntities.clear(); - } this.sectionGrid = new SectionGrid(this.level, this.renderDistance); this.sectionGraph = new SectionGraph(this.level, this.sectionGrid, this.taskDispatcher); @@ -312,28 +308,31 @@ public void renderSectionLayer(RenderType renderType, PoseStack poseStack, doubl VRenderSystem.applyMVP(poseStack.last().pose(), projection); VRenderSystem.setPrimitiveTopologyGL(GL11.GL_TRIANGLES); - Renderer renderer = Renderer.getInstance(); - GraphicsPipeline pipeline = PipelineManager.getTerrainShader(terrainRenderType); - renderer.bindGraphicsPipeline(pipeline); - - IndexBuffer indexBuffer = Renderer.getDrawer().getQuadsIndexBuffer().getIndexBuffer(); - Renderer.getDrawer().bindIndexBuffer(Renderer.getCommandBuffer(), indexBuffer); int currentFrame = Renderer.getCurrentFrame(); Set allowedRenderTypes = Initializer.CONFIG.uniqueOpaqueLayer ? TerrainRenderType.COMPACT_RENDER_TYPES : TerrainRenderType.SEMI_COMPACT_RENDER_TYPES; if (allowedRenderTypes.contains(terrainRenderType)) { - terrainRenderType.setCutoutUniform(); + + //Moved inside allowedRenderTypes to reduce overall pipeline count + + Renderer renderer = Renderer.getInstance(); + GraphicsPipeline pipeline = PipelineManager.getTerrainShader(terrainRenderType); + renderer.bindGraphicsPipeline(pipeline); + + IndexBuffer indexBuffer = Renderer.getDrawer().getQuadsIndexBuffer().getIndexBuffer(); + final VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); + Renderer.getDrawer().bindIndexBuffer(commandBuffer, indexBuffer); + + renderer.uploadAndBindUBOs(pipeline); for (Iterator iterator = this.sectionGraph.getChunkAreaQueue().iterator(isTranslucent); iterator.hasNext(); ) { ChunkArea chunkArea = iterator.next(); var queue = chunkArea.sectionQueue; DrawBuffers drawBuffers = chunkArea.drawBuffers; - renderer.uploadAndBindUBOs(pipeline); if (drawBuffers.getAreaBuffer(terrainRenderType) != null && queue.size() > 0) { - drawBuffers.bindBuffers(Renderer.getCommandBuffer(), pipeline, terrainRenderType, camX, camY, camZ); - renderer.uploadAndBindUBOs(pipeline); + drawBuffers.bindBuffers(commandBuffer, pipeline, terrainRenderType, camX, camY, camZ); if (indirectDraw) drawBuffers.buildDrawBatchesIndirect(indirectBuffers[currentFrame], queue, terrainRenderType); @@ -343,17 +342,11 @@ public void renderSectionLayer(RenderType renderType, PoseStack poseStack, doubl } } - if (terrainRenderType == TerrainRenderType.CUTOUT || terrainRenderType == TerrainRenderType.TRIPWIRE) { + if (indirectDraw && (terrainRenderType == TerrainRenderType.CUTOUT || terrainRenderType == TerrainRenderType.TRIPWIRE)) { indirectBuffers[currentFrame].submitUploads(); // uniformBuffers.submitUploads(); } - //Need to reset push constants in case the pipeline will still be used for rendering - if (!indirectDraw) { - VRenderSystem.setChunkOffset(0, 0, 0); - renderer.pushConstants(pipeline); - } - this.minecraft.getProfiler().pop(); renderType.clearRenderState(); diff --git a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java index 258d55781..8f3ef6635 100644 --- a/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java +++ b/src/main/java/net/vulkanmod/render/vertex/TerrainRenderType.java @@ -2,43 +2,27 @@ import net.minecraft.client.renderer.RenderType; import net.vulkanmod.interfaces.ExtendedRenderType; -import net.vulkanmod.vulkan.VRenderSystem; import java.util.EnumSet; public enum TerrainRenderType { - SOLID(0.0f, 262144 /*BIG_BUFFER_SIZE*/), - CUTOUT_MIPPED(0.5f, 262144 /*MEDIUM_BUFFER_SIZE*/), - CUTOUT(0.1f, 131072 /*SMALL_BUFFER_SIZE*/), - TRANSLUCENT(0.0f, 131072 /*SMALL_BUFFER_SIZE*/), - TRIPWIRE(0.1f, 131072 /*SMALL_BUFFER_SIZE*/); + SOLID(262144 /*BIG_BUFFER_SIZE*/), + CUTOUT_MIPPED(262144 /*MEDIUM_BUFFER_SIZE*/), + CUTOUT(131072 /*SMALL_BUFFER_SIZE*/), + TRANSLUCENT(131072 /*SMALL_BUFFER_SIZE*/), + TRIPWIRE(131072 /*SMALL_BUFFER_SIZE*/); public static final TerrainRenderType[] VALUES = TerrainRenderType.values(); public static final EnumSet COMPACT_RENDER_TYPES = EnumSet.of(CUTOUT_MIPPED, TRANSLUCENT); public static final EnumSet SEMI_COMPACT_RENDER_TYPES = EnumSet.of(CUTOUT_MIPPED, CUTOUT, TRANSLUCENT); - static { - SEMI_COMPACT_RENDER_TYPES.add(CUTOUT); - SEMI_COMPACT_RENDER_TYPES.add(CUTOUT_MIPPED); - SEMI_COMPACT_RENDER_TYPES.add(TRANSLUCENT); - - COMPACT_RENDER_TYPES.add(CUTOUT_MIPPED); - COMPACT_RENDER_TYPES.add(TRANSLUCENT); - } - - public final float alphaCutout; public final int initialSize; - TerrainRenderType(float alphaCutout, int initialSize) { - this.alphaCutout = alphaCutout; + TerrainRenderType(int initialSize) { this.initialSize = initialSize; } - public void setCutoutUniform() { - VRenderSystem.alphaCutout = this.alphaCutout; - } - public static TerrainRenderType get(RenderType renderType) { return ((ExtendedRenderType)renderType).getTerrainRenderType(); } diff --git a/src/main/java/net/vulkanmod/vulkan/Renderer.java b/src/main/java/net/vulkanmod/vulkan/Renderer.java index 7524489ab..7f2a4cae7 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -299,12 +299,11 @@ private void submitFrame() { submitInfo.pCommandBuffers(stack.pointers(currentCmdBuffer)); - vkResetFences(device, stack.longs(inFlightFences.get(currentFrame))); + vkResetFences(device, inFlightFences.get(currentFrame)); Synchronization.INSTANCE.waitFences(); if ((vkResult = vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), submitInfo, inFlightFences.get(currentFrame))) != VK_SUCCESS) { - vkResetFences(device, stack.longs(inFlightFences.get(currentFrame))); throw new RuntimeException("Failed to submit draw command buffer: " + vkResult); } diff --git a/src/main/java/net/vulkanmod/vulkan/Synchronization.java b/src/main/java/net/vulkanmod/vulkan/Synchronization.java index 1ca14c95d..9fab0d864 100644 --- a/src/main/java/net/vulkanmod/vulkan/Synchronization.java +++ b/src/main/java/net/vulkanmod/vulkan/Synchronization.java @@ -18,7 +18,7 @@ public class Synchronization { private final LongBuffer fences; private int idx = 0; - private ObjectArrayList commandBuffers = new ObjectArrayList<>(); + private final ObjectArrayList commandBuffers = new ObjectArrayList<>(); Synchronization(int allocSize) { this.fences = MemoryUtil.memAllocLong(allocSize); @@ -45,9 +45,7 @@ public synchronized void waitFences() { fences.limit(idx); - for (int i = 0; i < idx; i++) { - vkWaitForFences(device, fences.get(i), true, VUtil.UINT64_MAX); - } + vkWaitForFences(device, fences,true, VUtil.UINT64_MAX); this.commandBuffers.forEach(CommandPool.CommandBuffer::reset); this.commandBuffers.clear(); diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index 400eaf59b..4cb6d2fb5 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -20,6 +20,8 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import static org.lwjgl.opengl.GL11C.GL_DEPTH_BUFFER_BIT; + public abstract class VRenderSystem { private static long window; @@ -33,13 +35,13 @@ public abstract class VRenderSystem { public static int colorMask = PipelineState.ColorMask.getColorMask(true, true, true, true); public static boolean cull = true; - + private static boolean canApplyClear = false; public static boolean logicOp = false; public static int logicOpFun = 0; public static final float clearDepth = 1.0f; public static FloatBuffer clearColor = MemoryUtil.memCallocFloat(4); - + private static final float[] checkedClearColor = new float[4]; public static MappedBuffer modelViewMatrix = new MappedBuffer(16 * 4); public static MappedBuffer projectionMatrix = new MappedBuffer(16 * 4); public static MappedBuffer TextureMatrix = new MappedBuffer(16 * 4); @@ -153,12 +155,25 @@ public static MappedBuffer getShaderFogColor() { return shaderFogColor; } - public static void clearColor(float f1, float f2, float f3, float f4) { - ColorUtil.setRGBA_Buffer(clearColor, f1, f2, f3, f4); + public static void clearColor(float f0, float f1, float f2, float f3) { + //set to true if different color + if(!(canApplyClear = checkClearColor(f0, f1, f2, f3))) return; + ColorUtil.setRGBA_Buffer(clearColor, f0, f1, f2, f3); + checkedClearColor[0]=f0; + checkedClearColor[1]=f1; + checkedClearColor[2]=f2; + checkedClearColor[3]=f3; + } + + private static boolean checkClearColor(float f0, float f1, float f2, float f3) { + return checkedClearColor[0] !=f0 | checkedClearColor[1] !=f1 | checkedClearColor[2] !=f2 | checkedClearColor[3] != f3; } public static void clear(int v) { - Renderer.clearAttachments(v); + //Skip reapplying the same color over and over per clear + //Depth clears can be significantly faster than color clears + Renderer.clearAttachments(canApplyClear ? v : GL_DEPTH_BUFFER_BIT); //Depth Only Clears needed to fix Chat + Command Elements + canApplyClear=false; } // Pipeline state diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java index 24cc8c031..d7084f6ce 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java @@ -61,7 +61,7 @@ private void createRenderPass() { .storeOp(colorAttachmentInfo.storeOp) .stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE) .stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE) - .initialLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + .initialLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) .finalLayout(colorAttachmentInfo.finalLayout); VkAttachmentReference colorAttachmentRef = attachmentRefs.get(0) @@ -106,9 +106,10 @@ private void createRenderPass() { .srcSubpass(VK_SUBPASS_EXTERNAL) .dstSubpass(0) .srcStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) - .dstStageMask(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT) + .dstStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) .srcAccessMask(0) - .dstAccessMask(0); + .dstAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) + .dependencyFlags(VK_DEPENDENCY_BY_REGION_BIT); renderPassInfo.pDependencies(subpassDependencies); } @@ -120,7 +121,8 @@ private void createRenderPass() { .srcStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) .dstStageMask(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) .srcAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) - .dstAccessMask(VK_ACCESS_SHADER_READ_BIT); + .dstAccessMask(VK_ACCESS_SHADER_READ_BIT) + .dependencyFlags(VK_DEPENDENCY_BY_REGION_BIT); renderPassInfo.pDependencies(subpassDependencies); } @@ -139,8 +141,8 @@ private void createRenderPass() { public void beginRenderPass(VkCommandBuffer commandBuffer, long framebufferId, MemoryStack stack) { if (colorAttachmentInfo != null - && framebuffer.getColorAttachment().getCurrentLayout() != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - framebuffer.getColorAttachment().transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + && framebuffer.getColorAttachment().getCurrentLayout() != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + framebuffer.getColorAttachment().transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); if (depthAttachmentInfo != null && framebuffer.getDepthAttachment().getCurrentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) framebuffer.getDepthAttachment().transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java index af5ef7619..e4816df3e 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/MemoryManager.java @@ -158,9 +158,9 @@ public static synchronized void createImage(int width, int height, int mipLevels imageInfo.initialLayout(VK_IMAGE_LAYOUT_UNDEFINED); imageInfo.usage(usage); imageInfo.samples(VK_SAMPLE_COUNT_1_BIT); -// imageInfo.sharingMode(VK_SHARING_MODE_CONCURRENT); - //TODO - imageInfo.pQueueFamilyIndices(stack.ints(0,1)); + imageInfo.sharingMode(VK_SHARING_MODE_EXCLUSIVE); + //Forcing Queue family to 0: which is always the Graphics Queue + imageInfo.pQueueFamilyIndices(stack.ints(0)); VmaAllocationCreateInfo allocationInfo = VmaAllocationCreateInfo.callocStack(stack); //allocationInfo.usage(VMA_MEMORY_USAGE_CPU_ONLY); diff --git a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java index 59b1c2afe..1374d106f 100644 --- a/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/pass/DefaultMainPass.java @@ -23,14 +23,12 @@ public static DefaultMainPass create() { return new DefaultMainPass(); } - private RenderTarget mainTarget; private final Framebuffer mainFramebuffer; private RenderPass mainRenderPass; private RenderPass auxRenderPass; DefaultMainPass() { - this.mainTarget = Minecraft.getInstance().getMainRenderTarget(); this.mainFramebuffer = Vulkan.getSwapChain(); createRenderPasses(); @@ -38,17 +36,14 @@ public static DefaultMainPass create() { private void createRenderPasses() { RenderPass.Builder builder = RenderPass.builder(this.mainFramebuffer); - builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - builder.getColorAttachmentInfo().setOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE); - builder.getDepthAttachmentInfo().setOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE); - + builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); this.mainRenderPass = builder.build(); // Create an auxiliary RenderPass needed in case of main target rebinding builder = RenderPass.builder(this.mainFramebuffer); builder.getColorAttachmentInfo().setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); builder.getDepthAttachmentInfo().setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); - builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + builder.getColorAttachmentInfo().setFinalLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); this.auxRenderPass = builder.build(); } @@ -57,9 +52,6 @@ private void createRenderPasses() { public void begin(VkCommandBuffer commandBuffer, MemoryStack stack) { SwapChain framebuffer = Vulkan.getSwapChain(); - VulkanImage colorAttachment = framebuffer.getColorAttachment(); - colorAttachment.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - framebuffer.beginRenderPass(commandBuffer, this.mainRenderPass, stack); VkViewport.Buffer pViewport = framebuffer.viewport(stack); @@ -73,11 +65,6 @@ public void begin(VkCommandBuffer commandBuffer, MemoryStack stack) { public void end(VkCommandBuffer commandBuffer) { Renderer.getInstance().endRenderPass(commandBuffer); - try(MemoryStack stack = MemoryStack.stackPush()) { - SwapChain framebuffer = Vulkan.getSwapChain(); - framebuffer.getColorAttachment().transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); - } - int result = vkEndCommandBuffer(commandBuffer); if(result != VK_SUCCESS) { throw new RuntimeException("Failed to record command buffer:" + result); diff --git a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java index eff323b7f..6240aa257 100644 --- a/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java +++ b/src/main/java/net/vulkanmod/vulkan/queue/CommandPool.java @@ -67,7 +67,6 @@ public CommandBuffer beginCommands() { vkCreateFence(Vulkan.getVkDevice(), fenceInfo, null, pFence); CommandBuffer commandBuffer = new CommandBuffer(new VkCommandBuffer(pCommandBuffer.get(i), Vulkan.getVkDevice()), pFence.get(0)); - commandBuffer.handle = new VkCommandBuffer(pCommandBuffer.get(i), Vulkan.getVkDevice()); commandBuffers.add(commandBuffer); availableCmdBuffers.add(commandBuffer); } @@ -120,8 +119,8 @@ public void cleanUp() { } public class CommandBuffer { - VkCommandBuffer handle; - long fence; + final VkCommandBuffer handle; + final long fence; boolean submitted; boolean recording; diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh index c1f23d57f..f1a793ef9 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.fsh @@ -9,7 +9,6 @@ layout(binding = 1) uniform UBO { vec4 FogColor; float FogStart; float FogEnd; - float AlphaCutout; }; @@ -23,7 +22,7 @@ layout(location = 0) out vec4 fragColor; void main() { vec4 color = texture(Sampler0, texCoord0) * vertexColor; - if (color.a < AlphaCutout) { + if (color.a < 0.5f) { discard; } fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json index dbb8efcbc..4b6105db1 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.json @@ -33,8 +33,7 @@ { "type": "fragment", "binding": 1, "fields": [ { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "AlphaCutout", "type": "float", "count": 1, "values": [ 1.0 ] } + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } ] } ], "PushConstants": [