diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java index 5705b9f52..faaef9c30 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java @@ -36,6 +36,15 @@ public static void glBindTexture(@NativeType("GLenum") int target, @NativeType(" GlTexture.bindTexture(texture); } + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glLineWidth(@NativeType("GLfloat") float width) { + VRenderSystem.setLineWidth(width); + } + /** * @author * @reason diff --git a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java index e1bdea153..2dd2ea22e 100644 --- a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java @@ -6,8 +6,9 @@ import net.minecraft.client.renderer.ShaderInstance; import net.vulkanmod.interfaces.ShaderMixed; import net.vulkanmod.vulkan.Renderer; +import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.shader.GraphicsPipeline; -import net.vulkanmod.vulkan.shader.Pipeline; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -32,15 +33,17 @@ public static void drawWithShader(BufferBuilder.RenderedBuffer buffer) { Renderer renderer = Renderer.getInstance(); - if(parameters.vertexCount() <= 0) + if(parameters.vertexCount() <= 0) { return; + } ShaderInstance shaderInstance = RenderSystem.getShader(); - //Used to update legacy shader uniforms - //TODO it would be faster to allocate a buffer from stack and set all values + // Used to update legacy shader uniforms + // TODO it would be faster to allocate a buffer from stack and set all values shaderInstance.apply(); GraphicsPipeline pipeline = ((ShaderMixed)(shaderInstance)).getPipeline(); + VRenderSystem.setPrimitiveTopologyGL(parameters.mode().asGLMode); renderer.bindGraphicsPipeline(pipeline); renderer.uploadAndBindUBOs(pipeline); Renderer.getDrawer().draw(buffer.vertexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount()); diff --git a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java index d1ade0713..5563850a5 100644 --- a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java @@ -313,6 +313,15 @@ public static void disableCull() { VRenderSystem.disableCull(); } + /** + * @author + */ + @Overwrite(remap = false) + public static void polygonMode(final int i, final int j) { + assertOnGameThread(); + VRenderSystem.setPolygonModeGL(i); + } + /** * @author */ diff --git a/src/main/java/net/vulkanmod/render/VBO.java b/src/main/java/net/vulkanmod/render/VBO.java index df32109b0..f1d45ea57 100644 --- a/src/main/java/net/vulkanmod/render/VBO.java +++ b/src/main/java/net/vulkanmod/render/VBO.java @@ -9,9 +9,11 @@ import net.vulkanmod.interfaces.ShaderMixed; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; -import net.vulkanmod.vulkan.memory.*; +import net.vulkanmod.vulkan.memory.AutoIndexBuffer; +import net.vulkanmod.vulkan.memory.IndexBuffer; +import net.vulkanmod.vulkan.memory.MemoryTypes; +import net.vulkanmod.vulkan.memory.VertexBuffer; import net.vulkanmod.vulkan.shader.GraphicsPipeline; -import net.vulkanmod.vulkan.shader.Pipeline; import org.joml.Matrix4f; import java.nio.ByteBuffer; @@ -34,7 +36,6 @@ public void upload(BufferBuilder.RenderedBuffer buffer) { this.indexCount = parameters.indexCount(); this.vertexCount = parameters.vertexCount(); -// this.indexType = parameters.indexType(); this.mode = parameters.mode(); this.configureVertexFormat(parameters, buffer.vertexBuffer()); @@ -47,11 +48,11 @@ public void upload(BufferBuilder.RenderedBuffer buffer) { private void configureVertexFormat(BufferBuilder.DrawState parameters, ByteBuffer data) { if (!parameters.indexOnly()) { - if(vertexBuffer != null) + if (this.vertexBuffer != null) this.vertexBuffer.freeBuffer(); this.vertexBuffer = new VertexBuffer(data.remaining(), MemoryTypes.GPU_MEM); - vertexBuffer.copyToVertexBuffer(parameters.format().getVertexSize(), parameters.vertexCount(), data); + this.vertexBuffer.copyToVertexBuffer(parameters.format().getVertexSize(), parameters.vertexCount(), data); } } @@ -63,34 +64,43 @@ private void configureIndexBuffer(BufferBuilder.DrawState parameters, ByteBuffer switch (this.mode) { case TRIANGLE_FAN -> { autoIndexBuffer = Renderer.getDrawer().getTriangleFanIndexBuffer(); - this.indexCount = (vertexCount - 2) * 3; + this.indexCount = AutoIndexBuffer.DrawType.getTriangleStripIndexCount(this.vertexCount); + } + case TRIANGLE_STRIP, LINE_STRIP -> { + autoIndexBuffer = Renderer.getDrawer().getTriangleStripIndexBuffer(); + this.indexCount = AutoIndexBuffer.DrawType.getTriangleStripIndexCount(this.vertexCount); } case QUADS -> { autoIndexBuffer = Renderer.getDrawer().getQuadsIndexBuffer(); } - case TRIANGLES -> { + case LINES -> { + autoIndexBuffer = Renderer.getDrawer().getLinesIndexBuffer(); + } + case DEBUG_LINE_STRIP -> { + autoIndexBuffer = Renderer.getDrawer().getDebugLineStripIndexBuffer(); + } + case TRIANGLES, DEBUG_LINES -> { autoIndexBuffer = null; } - default -> throw new IllegalStateException("Unexpected draw mode:" + this.mode); + default -> throw new IllegalStateException("Unexpected draw mode: %s".formatted(this.mode)); } - if(indexBuffer != null && !this.autoIndexed) - indexBuffer.freeBuffer(); + if (this.indexBuffer != null && !this.autoIndexed) + this.indexBuffer.freeBuffer(); - if(autoIndexBuffer != null) { - autoIndexBuffer.checkCapacity(vertexCount); - indexBuffer = autoIndexBuffer.getIndexBuffer(); + if (autoIndexBuffer != null) { + autoIndexBuffer.checkCapacity(this.vertexCount); + this.indexBuffer = autoIndexBuffer.getIndexBuffer(); } this.autoIndexed = true; - } - else { - if(indexBuffer != null) + } else { + if (this.indexBuffer != null) this.indexBuffer.freeBuffer(); + this.indexBuffer = new IndexBuffer(data.remaining(), MemoryTypes.GPU_MEM); -// this.indexBuffer = new AsyncIndexBuffer(data.remaining()); - indexBuffer.copyBuffer(data); + this.indexBuffer.copyBuffer(data); } } @@ -101,7 +111,7 @@ public void drawWithShader(Matrix4f MV, Matrix4f P, ShaderInstance shader) { RenderSystem.setShader(() -> shader); - drawWithShader(MV, P, ((ShaderMixed)shader).getPipeline()); + drawWithShader(MV, P, ((ShaderMixed) shader).getPipeline()); } } @@ -116,10 +126,10 @@ public void drawWithShader(Matrix4f MV, Matrix4f P, GraphicsPipeline pipeline) { renderer.bindGraphicsPipeline(pipeline); renderer.uploadAndBindUBOs(pipeline); - if(indexBuffer != null) - Renderer.getDrawer().drawIndexed(vertexBuffer, indexBuffer, indexCount); + if (this.indexBuffer != null) + Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount); else - Renderer.getDrawer().draw(vertexBuffer, vertexCount); + Renderer.getDrawer().draw(this.vertexBuffer, this.vertexCount); VRenderSystem.applyMVP(RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); @@ -130,25 +140,24 @@ public void drawChunkLayer() { if (this.indexCount != 0) { RenderSystem.assertOnRenderThread(); - Renderer.getDrawer().drawIndexed(vertexBuffer, indexBuffer, indexCount); + Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount); } } public void close() { - if(vertexCount <= 0) return; - vertexBuffer.freeBuffer(); - vertexBuffer = null; - if(!autoIndexed) { - indexBuffer.freeBuffer(); - indexBuffer = null; + if (this.vertexCount <= 0) + return; + + this.vertexBuffer.freeBuffer(); + this.vertexBuffer = null; + + if (!this.autoIndexed) { + this.indexBuffer.freeBuffer(); + this.indexBuffer = null; } this.vertexCount = 0; this.indexCount = 0; } -// public VertexFormat getFormat() { -// return this.vertexFormat; -// } - } diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index 1024a8968..6c12813e5 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -38,6 +38,7 @@ import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.memory.Buffer; +import net.vulkanmod.vulkan.memory.IndexBuffer; import net.vulkanmod.vulkan.memory.IndirectBuffer; import net.vulkanmod.vulkan.memory.MemoryTypes; import net.vulkanmod.vulkan.shader.GraphicsPipeline; @@ -312,7 +313,9 @@ public void renderSectionLayer(RenderType renderType, PoseStack poseStack, doubl Renderer renderer = Renderer.getInstance(); GraphicsPipeline pipeline = PipelineManager.getTerrainShader(terrainRenderType); renderer.bindGraphicsPipeline(pipeline); - Renderer.getDrawer().bindAutoIndexBuffer(Renderer.getCommandBuffer(), 7); + + 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; diff --git a/src/main/java/net/vulkanmod/vulkan/Drawer.java b/src/main/java/net/vulkanmod/vulkan/Drawer.java index 6c223d4aa..1c8926e70 100644 --- a/src/main/java/net/vulkanmod/vulkan/Drawer.java +++ b/src/main/java/net/vulkanmod/vulkan/Drawer.java @@ -36,11 +36,11 @@ public class Drawer { public Drawer() { // Index buffers - quadsIndexBuffer = new AutoIndexBuffer(MAX_QUAD_VERTICES_UINT16, AutoIndexBuffer.DrawType.QUADS); - linesIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.LINES); - debugLineStripIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.DEBUG_LINE_STRIP); - triangleFanIndexBuffer = new AutoIndexBuffer(1000, AutoIndexBuffer.DrawType.TRIANGLE_FAN); - triangleStripIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.TRIANGLE_STRIP); + this.quadsIndexBuffer = new AutoIndexBuffer(MAX_QUAD_VERTICES_UINT16, AutoIndexBuffer.DrawType.QUADS); + this.linesIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.LINES); + this.debugLineStripIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.DEBUG_LINE_STRIP); + this.triangleFanIndexBuffer = new AutoIndexBuffer(1000, AutoIndexBuffer.DrawType.TRIANGLE_FAN); + this.triangleStripIndexBuffer = new AutoIndexBuffer(10000, AutoIndexBuffer.DrawType.TRIANGLE_STRIP); } public void setCurrentFrame(int currentFrame) { @@ -50,7 +50,7 @@ public void setCurrentFrame(int currentFrame) { public void createResources(int framesNum) { this.framesNum = framesNum; - if (vertexBuffers != null) { + if (this.vertexBuffers != null) { Arrays.stream(this.vertexBuffers).iterator().forEachRemaining( Buffer::freeBuffer ); @@ -76,7 +76,7 @@ public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexF AutoIndexBuffer autoIndexBuffer; int indexCount; - VertexBuffer vertexBuffer = this.vertexBuffers[currentFrame]; + VertexBuffer vertexBuffer = this.vertexBuffers[this.currentFrame]; vertexBuffer.copyToVertexBuffer(vertexFormat.getVertexSize(), vertexCount, buffer); switch (mode) { @@ -117,18 +117,6 @@ public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexF } - public AutoIndexBuffer getQuadsIndexBuffer() { - return quadsIndexBuffer; - } - - public AutoIndexBuffer getTriangleFanIndexBuffer() { - return triangleFanIndexBuffer; - } - - public UniformBuffer getUniformBuffer() { - return this.uniformBuffers[currentFrame]; - } - public void drawIndexed(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int indexCount) { VkCommandBuffer commandBuffer = Renderer.getCommandBuffer(); @@ -150,22 +138,13 @@ public void draw(VertexBuffer vertexBuffer, int vertexCount) { vkCmdDraw(commandBuffer, vertexCount, 1, 0, 0); } - public void bindAutoIndexBuffer(VkCommandBuffer commandBuffer, int drawMode) { - AutoIndexBuffer autoIndexBuffer; - switch (drawMode) { - case 7 -> autoIndexBuffer = this.quadsIndexBuffer; - case 6 -> autoIndexBuffer = this.triangleFanIndexBuffer; - case 5 -> autoIndexBuffer = this.triangleStripIndexBuffer; - default -> throw new RuntimeException("unknown drawType"); - } - IndexBuffer indexBuffer = autoIndexBuffer.getIndexBuffer(); - + public void bindIndexBuffer(VkCommandBuffer commandBuffer, IndexBuffer indexBuffer) { vkCmdBindIndexBuffer(commandBuffer, indexBuffer.getId(), indexBuffer.getOffset(), VK_INDEX_TYPE_UINT16); } public void cleanUpResources() { Buffer buffer; - for (int i = 0; i < framesNum; ++i) { + for (int i = 0; i < this.framesNum; ++i) { buffer = this.vertexBuffers[i]; MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); @@ -174,12 +153,34 @@ public void cleanUpResources() { } - buffer = this.quadsIndexBuffer.getIndexBuffer(); - MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); - buffer = this.triangleFanIndexBuffer.getIndexBuffer(); - MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); - buffer = this.triangleStripIndexBuffer.getIndexBuffer(); - MemoryManager.freeBuffer(buffer.getId(), buffer.getAllocation()); + this.quadsIndexBuffer.freeBuffer(); + this.linesIndexBuffer.freeBuffer(); + this.triangleFanIndexBuffer.freeBuffer(); + this.debugLineStripIndexBuffer.freeBuffer(); + } + + public AutoIndexBuffer getQuadsIndexBuffer() { + return this.quadsIndexBuffer; + } + + public AutoIndexBuffer getLinesIndexBuffer() { + return this.linesIndexBuffer; + } + + public AutoIndexBuffer getTriangleFanIndexBuffer() { + return this.triangleFanIndexBuffer; + } + + public AutoIndexBuffer getTriangleStripIndexBuffer() { + return this.triangleStripIndexBuffer; + } + + public AutoIndexBuffer getDebugLineStripIndexBuffer() { + return this.debugLineStripIndexBuffer; + } + + public UniformBuffer getUniformBuffer() { + return this.uniformBuffers[this.currentFrame]; } } diff --git a/src/main/java/net/vulkanmod/vulkan/Renderer.java b/src/main/java/net/vulkanmod/vulkan/Renderer.java index 6819635d1..7524489ab 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -104,6 +104,13 @@ public Renderer() { imagesNum = getSwapChain().getImagesNum(); } + public static void setLineWidth(float width) { + if (INSTANCE.boundFramebuffer == null) { + return; + } + vkCmdSetLineWidth(INSTANCE.currentCmdBuffer, width); + } + private void init() { MemoryManager.createInstance(Renderer.getFramesNum()); Vulkan.createStagingBuffers(); @@ -250,6 +257,8 @@ public void beginFrame() { mainPass.begin(commandBuffer, stack); vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F); + + vkCmdSetLineWidth(commandBuffer, 1.0F); } p.pop(); diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index f48f25430..0e8ee79a2 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -3,6 +3,8 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.VertexFormat; + import net.minecraft.client.Minecraft; import net.vulkanmod.vulkan.device.DeviceManager; import net.vulkanmod.vulkan.shader.PipelineState; @@ -10,8 +12,11 @@ import net.vulkanmod.vulkan.util.MappedBuffer; import net.vulkanmod.vulkan.util.VUtil; import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; import org.lwjgl.system.MemoryUtil; +import static org.lwjgl.vulkan.VK10.*; + import java.nio.ByteBuffer; import java.nio.FloatBuffer; @@ -21,6 +26,9 @@ public abstract class VRenderSystem { public static boolean depthTest = true; public static boolean depthMask = true; public static int depthFun = 515; + public static int topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + public static int polygonMode = VK_POLYGON_MODE_FILL; + public static boolean canSetLineWidth = false; public static int colorMask = PipelineState.ColorMask.getColorMask(true, true, true, true); @@ -30,7 +38,7 @@ public abstract class VRenderSystem { public static int logicOpFun = 0; public static final float clearDepth = 1.0f; - public static FloatBuffer clearColor = MemoryUtil.memAllocFloat(4); + public static FloatBuffer clearColor = MemoryUtil.memCallocFloat(4); public static MappedBuffer modelViewMatrix = new MappedBuffer(16 * 4); public static MappedBuffer projectionMatrix = new MappedBuffer(16 * 4); @@ -163,6 +171,30 @@ public static void depthMask(boolean b) { depthMask = b; } + public static void setPrimitiveTopologyGL(final int mode) { + VRenderSystem.topology = switch (mode) { + case GL11.GL_LINES -> VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case GL11.GL_LINE_STRIP, GL11.GL_TRIANGLE_FAN, + GL11.GL_TRIANGLES, GL11.GL_TRIANGLE_STRIP -> VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + default -> throw new RuntimeException(String.format("Unknown GL primitive topology: %s", mode)); + }; + } + + public static void setPolygonModeGL(final int mode) { + VRenderSystem.polygonMode = switch (mode) { + case GL11.GL_POINT -> VK_POLYGON_MODE_POINT; + case GL11.GL_LINE -> VK_POLYGON_MODE_LINE; + case GL11.GL_FILL -> VK_POLYGON_MODE_FILL; + default -> throw new RuntimeException(String.format("Unknown GL polygon mode: %s", mode)); + }; + } + + public static void setLineWidth(final float width) { + if (canSetLineWidth) { + Renderer.setLineWidth(width); + } + } + public static void colorMask(boolean b, boolean b1, boolean b2, boolean b3) { colorMask = PipelineState.ColorMask.getColorMask(b, b1, b2, b3); } diff --git a/src/main/java/net/vulkanmod/vulkan/device/DeviceManager.java b/src/main/java/net/vulkanmod/vulkan/device/DeviceManager.java index 7b3bb7100..1c1febe1b 100644 --- a/src/main/java/net/vulkanmod/vulkan/device/DeviceManager.java +++ b/src/main/java/net/vulkanmod/vulkan/device/DeviceManager.java @@ -2,6 +2,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.vulkanmod.Initializer; +import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.Vulkan; import net.vulkanmod.vulkan.queue.*; import org.lwjgl.PointerBuffer; @@ -169,31 +170,28 @@ public static void createLogicalDevice() { queueCreateInfo.pQueuePriorities(stack.floats(1.0f)); } - VkPhysicalDeviceFeatures2 deviceFeatures = VkPhysicalDeviceFeatures2.calloc(stack); - deviceFeatures.sType$Default(); - - //TODO indirect draw option disabled in case it is not supported - if (device.availableFeatures.features().samplerAnisotropy()) - deviceFeatures.features().samplerAnisotropy(true); - if (device.availableFeatures.features().logicOp()) - deviceFeatures.features().logicOp(true); - VkPhysicalDeviceVulkan11Features deviceVulkan11Features = VkPhysicalDeviceVulkan11Features.calloc(stack); deviceVulkan11Features.sType$Default(); + deviceVulkan11Features.shaderDrawParameters(device.isDrawIndirectSupported()); - if (device.isDrawIndirectSupported()) { - deviceFeatures.features().multiDrawIndirect(true); - deviceVulkan11Features.shaderDrawParameters(true); + VkPhysicalDeviceFeatures2 deviceFeatures = VkPhysicalDeviceFeatures2.calloc(stack); + deviceFeatures.sType$Default(); + deviceFeatures.features().samplerAnisotropy(device.availableFeatures.features().samplerAnisotropy()); + deviceFeatures.features().logicOp(device.availableFeatures.features().logicOp()); + // TODO: Disable indirect draw option if unsupported. + deviceFeatures.features().multiDrawIndirect(device.isDrawIndirectSupported()); + + // Must not set line width to anything other than 1.0 if this is not supported + if (device.availableFeatures.features().wideLines()) { + deviceFeatures.features().wideLines(true); + VRenderSystem.canSetLineWidth = true; } VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.calloc(stack); - + createInfo.sType$Default(); createInfo.sType(VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); createInfo.pQueueCreateInfos(queueCreateInfos); - // queueCreateInfoCount is automatically set - createInfo.pEnabledFeatures(deviceFeatures.features()); - createInfo.pNext(deviceVulkan11Features); if (Vulkan.DYNAMIC_RENDERING) { @@ -218,9 +216,7 @@ public static void createLogicalDevice() { // Configuration.DEBUG_FUNCTIONS.set(true); - if (Vulkan.ENABLE_VALIDATION_LAYERS) { - createInfo.ppEnabledLayerNames(asPointerBuffer(Vulkan.VALIDATION_LAYERS)); - } + createInfo.ppEnabledLayerNames(Vulkan.ENABLE_VALIDATION_LAYERS ? asPointerBuffer(Vulkan.VALIDATION_LAYERS) : null); PointerBuffer pDevice = stack.pointers(VK_NULL_HANDLE); diff --git a/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java b/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java index 3146552bc..d52a60bcb 100644 --- a/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/memory/AutoIndexBuffer.java @@ -21,18 +21,18 @@ private void createIndexBuffer(int vertexCount) { this.vertexCount = vertexCount; ByteBuffer buffer; - switch (drawType) { + switch (this.drawType) { case QUADS -> buffer = genQuadIndices(vertexCount); case TRIANGLE_FAN -> buffer = genTriangleFanIndices(vertexCount); case TRIANGLE_STRIP -> buffer = genTriangleStripIndices(vertexCount); case LINES -> buffer = genLinesIndices(vertexCount); case DEBUG_LINE_STRIP -> buffer = genDebugLineStripIndices(vertexCount); - default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(drawType)); + default -> throw new IllegalArgumentException("Unsupported drawType: %s".formatted(this.drawType)); } int size = buffer.capacity(); - indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM); - indexBuffer.copyBuffer(buffer); + this.indexBuffer = new IndexBuffer(size, MemoryTypes.GPU_MEM); + this.indexBuffer.copyBuffer(buffer); MemoryUtil.memFree(buffer); } @@ -42,7 +42,7 @@ public void checkCapacity(int vertexCount) { int newVertexCount = this.vertexCount * 2; Initializer.LOGGER.info("Reallocating AutoIndexBuffer from {} to {}", this.vertexCount, newVertexCount); - indexBuffer.freeBuffer(); + this.indexBuffer.freeBuffer(); createIndexBuffer(newVertexCount); } } @@ -56,10 +56,10 @@ public static ByteBuffer genQuadIndices(int vertexCount) { int j = 0; for(int i = 0; i < vertexCount; i += 4) { - idxs.put(j + 0, (short) (i + 0)); + idxs.put(j, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); - idxs.put(j + 3, (short) (i + 0)); + idxs.put(j + 3, (short) (i)); idxs.put(j + 4, (short) (i + 2)); idxs.put(j + 5, (short) (i + 3)); @@ -78,7 +78,7 @@ public static ByteBuffer genLinesIndices(int vertexCount) { int j = 0; for(int i = 0; i < vertexCount; i += 4) { - idxs.put(j + 0, (short) (i + 0)); + idxs.put(j, (short) (i)); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); idxs.put(j + 3, (short) (i + 3)); @@ -98,7 +98,7 @@ public static ByteBuffer genTriangleFanIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 2; ++i) { - idxs.put(j + 0, (short) 0); + idxs.put(j, (short) 0); idxs.put(j + 1, (short) (i + 1)); idxs.put(j + 2, (short) (i + 2)); @@ -134,7 +134,7 @@ public static ByteBuffer genDebugLineStripIndices(int vertexCount) { int j = 0; for (int i = 0; i < vertexCount - 1; ++i) { - idxs.put(j + 0, (short) i); + idxs.put(j, (short) i); idxs.put(j + 1, (short) (i + 1)); j += 2; @@ -147,7 +147,11 @@ public static int roundUpToDivisible(int n, int d) { return ((n + d - 1) / d) * d; } - public IndexBuffer getIndexBuffer() { return indexBuffer; } + public IndexBuffer getIndexBuffer() { return this.indexBuffer; } + + public void freeBuffer() { + this.indexBuffer.freeBuffer(); + } public enum DrawType { QUADS(7), @@ -159,7 +163,7 @@ public enum DrawType { public final int n; - DrawType (int n) { + DrawType(int n) { this.n = n; } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index 5679abb6c..86b4a1f36 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -84,9 +84,11 @@ private long createGraphicsPipeline(PipelineState state) { // ===> ASSEMBLY STAGE <=== + final int topology = PipelineState.AssemblyRasterState.decodeTopology(state.assemblyRasterState); + VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.calloc(stack); inputAssembly.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO); - inputAssembly.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + inputAssembly.topology(topology); inputAssembly.primitiveRestartEnable(false); // ===> VIEWPORT & SCISSOR @@ -99,18 +101,16 @@ private long createGraphicsPipeline(PipelineState state) { // ===> RASTERIZATION STAGE <=== + final int polygonMode = PipelineState.AssemblyRasterState.decodePolygonMode(state.assemblyRasterState); + final int cullMode = PipelineState.AssemblyRasterState.decodeCullMode(state.assemblyRasterState); + VkPipelineRasterizationStateCreateInfo rasterizer = VkPipelineRasterizationStateCreateInfo.calloc(stack); rasterizer.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); rasterizer.depthClampEnable(false); rasterizer.rasterizerDiscardEnable(false); - rasterizer.polygonMode(VK_POLYGON_MODE_FILL); + rasterizer.polygonMode(polygonMode); rasterizer.lineWidth(1.0f); - - if (state.cullState) - rasterizer.cullMode(VK_CULL_MODE_BACK_BIT); - else - rasterizer.cullMode(VK_CULL_MODE_NONE); - + rasterizer.cullMode(cullMode); rasterizer.frontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE); rasterizer.depthBiasEnable(true); @@ -161,7 +161,11 @@ private long createGraphicsPipeline(PipelineState state) { VkPipelineDynamicStateCreateInfo dynamicStates = VkPipelineDynamicStateCreateInfo.calloc(stack); dynamicStates.sType(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); - dynamicStates.pDynamicStates(stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); + + if (topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || polygonMode == VK_POLYGON_MODE_LINE) + dynamicStates.pDynamicStates(stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH)); + else + dynamicStates.pDynamicStates(stack.ints(VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR)); VkGraphicsPipelineCreateInfo.Buffer pipelineInfo = VkGraphicsPipelineCreateInfo.calloc(1, stack); pipelineInfo.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java index 9626f3f8c..af857d070 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/PipelineState.java @@ -15,27 +15,31 @@ public class PipelineState { public static PipelineState.BlendInfo blendInfo = PipelineState.defaultBlendInfo(); - public static final PipelineState DEFAULT = new PipelineState(true, getBlendState(), getDepthState(), getLogicOpState(), VRenderSystem.getColorMask(), null); + public static final PipelineState DEFAULT = new PipelineState(getAssemblyRasterState(), getBlendState(), getDepthState(), getLogicOpState(), VRenderSystem.getColorMask(), null); public static PipelineState currentState = DEFAULT; public static PipelineState getCurrentPipelineState(RenderPass renderPass) { - boolean cullState = VRenderSystem.cull; + int assemblyRasterState = getAssemblyRasterState(); int blendState = getBlendState(); int currentColorMask = VRenderSystem.getColorMask(); int depthState = getDepthState(); int logicOp = getLogicOpState(); - if(currentState.checkEquals(cullState, blendState, depthState, logicOp, currentColorMask, renderPass)) + if(currentState.checkEquals(assemblyRasterState, blendState, depthState, logicOp, currentColorMask, renderPass)) return currentState; else - return currentState = new PipelineState(cullState, blendState, depthState, logicOp, currentColorMask, renderPass); + return currentState = new PipelineState(assemblyRasterState, blendState, depthState, logicOp, currentColorMask, renderPass); } public static int getBlendState() { return BlendState.getState(blendInfo); } + public static int getAssemblyRasterState() { + return AssemblyRasterState.encode(VRenderSystem.cull, VRenderSystem.topology, VRenderSystem.polygonMode); + } + public static int getDepthState() { int depthState = 0; @@ -57,28 +61,29 @@ public static int getLogicOpState() { return logicOpState; } - final boolean cullState; final RenderPass renderPass; + int assemblyRasterState; int blendState_i; int depthState_i; int colorMask_i; int logicOp_i; - public PipelineState(boolean cullState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { + public PipelineState(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { this.renderPass = renderPass; - this.cullState = cullState; + this.assemblyRasterState = assemblyRasterState; this.blendState_i = blendState; this.depthState_i = depthState; this.colorMask_i = colorMask; this.logicOp_i = logicOp; } - private boolean checkEquals(boolean cullState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { + private boolean checkEquals(int assemblyRasterState, int blendState, int depthState, int logicOp, int colorMask, RenderPass renderPass) { return (blendState == this.blendState_i) && (depthState == this.depthState_i) && renderPass == this.renderPass && logicOp == this.logicOp_i - && (cullState == this.cullState) && colorMask == this.colorMask_i; + && (assemblyRasterState == this.assemblyRasterState) + && colorMask == this.colorMask_i; } @Override @@ -91,12 +96,13 @@ public boolean equals(Object o) { PipelineState that = (PipelineState) o; return (blendState_i == that.blendState_i) && (depthState_i == that.depthState_i) && this.renderPass == that.renderPass && logicOp_i == that.logicOp_i - && (cullState == that.cullState) && colorMask_i == that.colorMask_i; + && this.assemblyRasterState == that.assemblyRasterState + && this.colorMask_i == that.colorMask_i; } @Override public int hashCode() { - return Objects.hash(blendState_i, depthState_i, logicOp_i, cullState, colorMask_i, renderPass); + return Objects.hash(blendState_i, depthState_i, logicOp_i, assemblyRasterState, colorMask_i, renderPass); } public static BlendInfo defaultBlendInfo() { @@ -299,6 +305,37 @@ public static int glToVulkan(int f) { } + public abstract static class AssemblyRasterState { + public static final int POLYGON_MODE_MASK = 7; + + public static final int TOPOLOGY_OFFSET = 3; + public static final int TOPOLOGY_BITS = 4; + public static final int TOPOLOGY_MASK = 0b11111; + + public static final int CULL_MODE_OFFSET = TOPOLOGY_OFFSET + TOPOLOGY_BITS; + public static final int CULL_MODE_BITS = 2; + public static final int CULL_MODE_MASK = 0b11; + + public static int encode(boolean cull, int topology, int polygonMode) { + int state = (polygonMode | (topology << TOPOLOGY_OFFSET)); + state |= ((cull ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_NONE) << CULL_MODE_OFFSET); + + return state; + } + + public static int decodeTopology(int state) { + return (state >>> TOPOLOGY_OFFSET) & TOPOLOGY_MASK; + } + + public static int decodePolygonMode(int state) { + return state & POLYGON_MODE_MASK; + } + + public static int decodeCullMode(int state) { + return (state >>> CULL_MODE_OFFSET) & CULL_MODE_MASK; + } + } + public static abstract class ColorMask { public static int getColorMask(boolean r, boolean g, boolean b, boolean a) {