From 501baa383d5e597fa21f28d184dc7e4a39630c74 Mon Sep 17 00:00:00 2001 From: thr3343 <125277899+thr3343@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:22:10 +0100 Subject: [PATCH 1/3] Re-implement 16-byte Vertex Format + use 4 Byte alignment --- .../java/net/vulkanmod/render/vertex/CustomVertexFormat.java | 4 ++-- src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java | 4 ++-- .../java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java | 5 +++++ .../assets/vulkanmod/shaders/basic/terrain/terrain.vsh | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java index 6e0c40318..4d4cecab0 100644 --- a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java +++ b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java @@ -8,11 +8,11 @@ public class CustomVertexFormat { public static final VertexFormatElement ELEMENT_POSITION = new VertexFormatElement(0,VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.POSITION, 4); public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(0, VertexFormatElement.Type.UBYTE, VertexFormatElement.Usage.COLOR, 4); - public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2); + public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(0, VertexFormatElement.Type.UINT, VertexFormatElement.Usage.UV, 1); public static final VertexFormatElement ELEMENT_UV2 = new VertexFormatElement(2, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.UV, 2); public static final VertexFormat COMPRESSED_TERRAIN = new VertexFormat(new ImmutableMap.Builder() - .put("Position",ELEMENT_POSITION).put("Color",ELEMENT_COLOR).put("UV0",ELEMENT_UV0).put("UV2",ELEMENT_UV2).build()); + .put("Position",ELEMENT_POSITION).put("Color",ELEMENT_COLOR).put("UV0",ELEMENT_UV0).build()); public static final VertexFormat NONE = new VertexFormat(ImmutableMap.of()); } diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java index 511845515..f604751d9 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java +++ b/src/main/java/net/vulkanmod/render/vertex/VertexBuilder.java @@ -33,13 +33,13 @@ public int getStride() { } class CompressedVertexBuilder implements VertexBuilder { - private static final int VERTEX_SIZE = 20; + private static final int VERTEX_SIZE = 16; public static final float POS_CONV_MUL = 2048.0f; public static final float POS_OFFSET = -4.0f; public static final float POS_OFFSET_CONV = POS_OFFSET * POS_CONV_MUL; - public static final float UV_CONV_MUL = 32768.0f; + public static final float UV_CONV_MUL = 65536.f; public void vertex(long ptr, float x, float y, float z, int color, float u, float v, int light, int packedNormal) { final short sX = (short) (x * POS_CONV_MUL + POS_OFFSET_CONV); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java index 86b4a1f36..3531c1601 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/GraphicsPipeline.java @@ -280,6 +280,11 @@ private static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions posDescription.offset(offset); offset += 8; + } else if (type == VertexFormatElement.Type.UINT) { + posDescription.format(VK_FORMAT_R32_UINT); + posDescription.offset(offset); + + offset += 4; } else if (type == VertexFormatElement.Type.SHORT) { posDescription.format(VK_FORMAT_R16G16_SINT); posDescription.offset(offset); diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh index 87a3531d5..695b75dce 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh @@ -21,7 +21,7 @@ layout (location = 2) out vec2 texCoord0; //Compressed Vertex layout (location = 0) in ivec4 Position; layout (location = 1) in vec4 Color; -layout (location = 2) in uvec2 UV0; +layout (location = 2) in uint UV0; const float UV_INV = 1.0 / 32768.0; //const vec3 POSITION_INV = vec3(1.0 / 1024.0); @@ -35,7 +35,7 @@ void main() { vertexDistance = fog_distance(pos.xyz, 0); vertexColor = Color * sample_lightmap2(Sampler2, Position.a); - texCoord0 = UV0 * UV_INV; + texCoord0 = unpackUnorm2x16(UV0); } ////Default Vertex From 2545ce366980408d7d7cb8c73333f0609945103a Mon Sep 17 00:00:00 2001 From: thr3343 <125277899+thr3343@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:00:24 +0100 Subject: [PATCH 2/3] Optimize format based on device architecture Select 2 Byte alignment by default (including Nvidia), otherwise use 4 Bytes on AMD (GCN) --- .../render/vertex/CustomVertexFormat.java | 5 ++++- .../vulkanmod/vulkan/shader/SPIRVUtils.java | 6 ++++++ .../shaders/basic/terrain/terrain.vsh | 20 +++++++++++++++---- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java index 4d4cecab0..48e330d1c 100644 --- a/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java +++ b/src/main/java/net/vulkanmod/render/vertex/CustomVertexFormat.java @@ -3,12 +3,15 @@ import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormatElement; +import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.device.Device; +import net.vulkanmod.vulkan.device.DeviceManager; public class CustomVertexFormat { public static final VertexFormatElement ELEMENT_POSITION = new VertexFormatElement(0,VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.POSITION, 4); public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(0, VertexFormatElement.Type.UBYTE, VertexFormatElement.Usage.COLOR, 4); - public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(0, VertexFormatElement.Type.UINT, VertexFormatElement.Usage.UV, 1); + public static final VertexFormatElement ELEMENT_UV0 = Vulkan.getDevice().isAMD() ? new VertexFormatElement(0,VertexFormatElement.Type.UINT, VertexFormatElement.Usage.UV, 1) : new VertexFormatElement(0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 2); public static final VertexFormatElement ELEMENT_UV2 = new VertexFormatElement(2, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.UV, 2); public static final VertexFormat COMPRESSED_TERRAIN = new VertexFormat(new ImmutableMap.Builder() diff --git a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java index f1d8001e6..c7534f59c 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java @@ -1,6 +1,7 @@ package net.vulkanmod.vulkan.shader; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.vulkanmod.vulkan.Vulkan; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeResource; @@ -22,8 +23,10 @@ import static org.lwjgl.system.MemoryUtil.NULL; import static org.lwjgl.system.MemoryUtil.memASCII; import static org.lwjgl.util.shaderc.Shaderc.*; +import static org.lwjgl.util.shaderc.Shaderc.shaderc_compile_options_set_optimization_level; public class SPIRVUtils { + private static final boolean use4ByteAlignFormat = Vulkan.getDevice().isAMD(); private static final boolean DEBUG = false; private static final boolean OPTIMIZATIONS = true; @@ -55,6 +58,9 @@ private static void initCompiler() { if(options == NULL) { throw new RuntimeException("Failed to create compiler options"); } + //Use the optimal most performant vertex format based on architecture: 4 byte alignment if on AMD GCN, otherwise defaults to 2 Bytes (including Nvidia) + if(use4ByteAlignFormat) + shaderc_compile_options_add_macro_definition(options, "USE_ALT_FORMAT", null); if(OPTIMIZATIONS) shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance); diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh index 695b75dce..2a23e2d8d 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh @@ -19,9 +19,16 @@ layout (location = 1) out vec4 vertexColor; layout (location = 2) out vec2 texCoord0; //Compressed Vertex -layout (location = 0) in ivec4 Position; -layout (location = 1) in vec4 Color; -layout (location = 2) in uint UV0; +#ifndef USE_ALT_FORMAT + layout (location = 0) in ivec4 Position; + layout (location = 1) in vec4 Color; + layout (location = 2) in uvec2 UV0; +#else + layout (location = 0) in ivec4 Position; + layout (location = 1) in vec4 Color; + layout (location = 2) in uint UV0; +#endif + const float UV_INV = 1.0 / 32768.0; //const vec3 POSITION_INV = vec3(1.0 / 1024.0); @@ -35,7 +42,12 @@ void main() { vertexDistance = fog_distance(pos.xyz, 0); vertexColor = Color * sample_lightmap2(Sampler2, Position.a); - texCoord0 = unpackUnorm2x16(UV0); + + #ifndef USE_ALT_FORMAT + texCoord0 = UV0 * UV_INV; + #else + texCoord0 = unpackUnorm2x16(UV0); + #endif } ////Default Vertex From 6eeb144538b2d2bdf9b0f0bd3c6e47baaa3a7894 Mon Sep 17 00:00:00 2001 From: thr3343 <125277899+thr3343@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:08:12 +0100 Subject: [PATCH 3/3] Adjust macro name --- src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java | 2 +- .../assets/vulkanmod/shaders/basic/terrain/terrain.vsh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java index c7534f59c..8923cbb28 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/SPIRVUtils.java @@ -60,7 +60,7 @@ private static void initCompiler() { } //Use the optimal most performant vertex format based on architecture: 4 byte alignment if on AMD GCN, otherwise defaults to 2 Bytes (including Nvidia) if(use4ByteAlignFormat) - shaderc_compile_options_add_macro_definition(options, "USE_ALT_FORMAT", null); + shaderc_compile_options_add_macro_definition(options, "GCN_FIX", null); if(OPTIMIZATIONS) shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance); diff --git a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh index 2a23e2d8d..cb47494e8 100644 --- a/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/basic/terrain/terrain.vsh @@ -19,7 +19,7 @@ layout (location = 1) out vec4 vertexColor; layout (location = 2) out vec2 texCoord0; //Compressed Vertex -#ifndef USE_ALT_FORMAT +#ifndef GCN_FIX layout (location = 0) in ivec4 Position; layout (location = 1) in vec4 Color; layout (location = 2) in uvec2 UV0; @@ -43,7 +43,7 @@ void main() { vertexDistance = fog_distance(pos.xyz, 0); vertexColor = Color * sample_lightmap2(Sampler2, Position.a); - #ifndef USE_ALT_FORMAT + #ifndef GCN_FIX texCoord0 = UV0 * UV_INV; #else texCoord0 = unpackUnorm2x16(UV0);