Skip to content

[Vulkan1.2] (Proof of Concept) Implement Bindless Rendering #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 147 commits into from
Closed
Changes from all commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
90247f2
Use VRAM for Staging + refactor MemoryTypes
thr3343 Apr 5, 2024
7822e53
Queue Enum Refactor
thr3343 Apr 5, 2024
1ccb635
Use trimCmdPools + Refactor MemoryBarriers
thr3343 Apr 5, 2024
f601dfb
Enable Descriptor Indexing
thr3343 Apr 7, 2024
2910ce6
Add Pipeline BindSkip
thr3343 Apr 7, 2024
c9a4112
Add DEBUG_LINES Draw Mode
thr3343 Apr 7, 2024
6545bc6
use correct index count
thr3343 Apr 7, 2024
06ab3ed
Revert "use correct index count"
thr3343 Apr 7, 2024
1d0dc1b
Fix not setting Topology mode correctly
thr3343 Apr 7, 2024
8142029
Update VBO.java
thr3343 Apr 7, 2024
ea22e0e
Revert "Update VBO.java"
thr3343 Apr 7, 2024
bc4f53b
Reapply "use correct index count"
thr3343 Apr 7, 2024
052e278
Cleanup + Make RenderMode bool instead
thr3343 Apr 8, 2024
9caa8aa
Cleanup + Add bindlessUBO detection
thr3343 Apr 8, 2024
bdb1b9f
Basic Hash Skip testing
thr3343 Apr 9, 2024
844b63b
Enum Testing
thr3343 Apr 9, 2024
ebe4f99
Use more precise/Granular Sampler StageFlags
thr3343 Mar 14, 2024
4dec0bc
Add Sampler Binding Specifiers + Remove unused Descriptors
thr3343 Mar 19, 2024
cc96651
Merge Fixes
thr3343 Apr 10, 2024
baf5a3a
Testing: Remove non-critical Uniforms + Vertex fog
thr3343 Apr 10, 2024
0b732a2
Basic BindSkip testing
thr3343 Apr 10, 2024
33a8b6f
Test Unified DescriptorSetLayout
thr3343 Apr 11, 2024
ceea4d5
[Unstable] Initial Bindless UBO/Texture test (Extremely Unstable)
thr3343 Apr 11, 2024
1b9c3a4
[Testing] Use Global Pipeline layout + fix ChunkOffset Translations +…
thr3343 Apr 11, 2024
7f66a2b
Temp Fix Incompatible layout crashes
thr3343 Apr 12, 2024
b4fe505
[Temp Fix] Fix Entity + Terrain Rotations
thr3343 Apr 12, 2024
414b451
Update Pipeline.java
thr3343 Apr 12, 2024
a33b407
Update DescriptorSetArray.java
thr3343 Apr 12, 2024
4152fd2
Initoal test Classes+PseudoCode + Use singular global sampler for all…
thr3343 Apr 13, 2024
19570f3
tst
thr3343 Apr 13, 2024
fa3899f
Test using Lightmap + Block Texture Atlas
thr3343 Apr 13, 2024
bc3357a
revert sampler fix
thr3343 Apr 13, 2024
8ca90eb
[test] TextureID loading
thr3343 Apr 13, 2024
7d5d448
[Testing] Initial texture Indexing test
thr3343 Apr 13, 2024
15b0bb8
[Testing] Test Linear Bump Uniform Allocator + Ring Buffer
thr3343 Apr 14, 2024
ecb56aa
Further reeduce Unform duplciation + improve hash checking
thr3343 Apr 14, 2024
24ad2ae
[testing] More Bump Allocator testing
thr3343 Apr 14, 2024
9f02bed
Update Matrix4fM.java
thr3343 Apr 14, 2024
7e57ff1
[Testing] Use Uniform hashing to facilitate reuse + dedupe uploads
thr3343 Apr 14, 2024
1a339a5
Update Matrix4fM.java
thr3343 Apr 15, 2024
046e027
[Testing] Allow VTextureSelector to access textureID
thr3343 Apr 15, 2024
9eb7489
[Fix/Optimization] Skip Updating DescriptorSets once all textures are…
thr3343 Apr 15, 2024
474ffd7
Make PipelineLayout Final
thr3343 Apr 16, 2024
5026f17
Update DescriptorSetArray.java
thr3343 Apr 16, 2024
1e0053f
Fix incorrect VkDescriptorBufferInfo Range
thr3343 Apr 16, 2024
f953bd3
[Testing] Test Obtaining TextureID from Sampler index
thr3343 Apr 16, 2024
fe971f3
Hardcode Vertex Sampler IDs
thr3343 Apr 16, 2024
494b1e9
Revert "Hardcode Vertex Sampler IDs"
thr3343 Apr 16, 2024
23bec53
[testing] Test Register injection + shaderTexture index selection
thr3343 Apr 16, 2024
5d89943
Update DescriptorAbstractionArray.java
thr3343 Apr 17, 2024
24f19f8
Merge branch '1.20.x' into Enums
thr3343 Apr 17, 2024
8e02683
[Testing] More TextureID Testing
thr3343 Apr 18, 2024
a410fff
[Testing] Initial Texture Indexing test
thr3343 Apr 19, 2024
787ea72
[Testing] Re-add Descriptor update skip + Restore text rendering
thr3343 Apr 19, 2024
28acb92
[Testing] Test basic Texture index Hardcoding
thr3343 Apr 19, 2024
1fdd2a5
Add additional textures + Remove unused VK12 Features
thr3343 Apr 20, 2024
7915331
Color Clear Skip + Faster Renderpass Transitions
thr3343 Apr 3, 2024
5e0e087
Use VTextureselector instead of RenderSystem.GetShaderTexture() for T…
thr3343 Apr 20, 2024
28bf834
Disable SPIR-V Optimisations
thr3343 Apr 4, 2024
8a87bba
Use aggregate/grouped fence waits
thr3343 Apr 3, 2024
9d675fd
Dedupe/remove unused shaders/pipelines
thr3343 Apr 4, 2024
d625352
More cleanup
thr3343 Apr 20, 2024
f23b20a
Add Animation + RenderSky toggles
thr3343 Apr 6, 2024
bd66fe2
Fix Mob + additional textures
thr3343 Apr 20, 2024
536aa71
[TempFix] Fix broken/missing Uniform Updates
thr3343 Apr 20, 2024
448e334
Fix Particle MVP transform + Misc Optimisations
thr3343 Apr 20, 2024
d54a692
Make Missing TeTxure Default + Fix Rotation/POV Glitches in Nether/End
thr3343 Apr 20, 2024
a724c5c
Fix Incorrect/false positive Uniform checks
thr3343 Apr 21, 2024
db1c3b1
Fix undefined behaviour/potential driver segfaults when accessing uni…
thr3343 Apr 21, 2024
bb33010
[TempFix] Skip rendering if texture is uninitialized
thr3343 Apr 21, 2024
a2cd622
Merge branch '1.20.x' into BindlessRenderTest
thr3343 Apr 21, 2024
5f898d7
Merge Fixes
thr3343 Apr 21, 2024
9f35f8d
Merge branch 'Enums' into BindlessRenderTest
thr3343 Apr 21, 2024
be6f9c7
Move Indirect Buffer to RAM_MEM
thr3343 Apr 21, 2024
a1d3146
Use perRenderType EnumMaps + reduce Draw Direct CPU overhead
thr3343 Apr 4, 2024
76136ca
Update TaskDispatcher.java
thr3343 Apr 21, 2024
7b6bc37
Update DrawBuffers.java
thr3343 Apr 21, 2024
8e58840
Misc Cleanup Fixes + Disable Depth Writes w. Translucent TerrainRende…
thr3343 Apr 21, 2024
c29ee46
[VK13] Test using Inline Uniform Blocks + Fix EndPortals and ToolTip …
thr3343 Apr 23, 2024
fb190d9
Test Inline Uniforms w/ GameTime (i.e. Fix EndPortal Animation) [Temp…
thr3343 Apr 23, 2024
8d0b7eb
Update DescriptorSetArray.java
thr3343 Apr 23, 2024
194c29e
Make Frag uniforms readonly
thr3343 Apr 23, 2024
372fa14
Test custom SkyColor Uniform + Fix Banner vertex color blending
thr3343 Apr 23, 2024
e8bac33
Update InputConstantsM.java
thr3343 Apr 23, 2024
5958f8c
[Semi-broken] Test Push Constant Aliasing
thr3343 Apr 24, 2024
3b4b6dc
Fix LightDirection Flicker
thr3343 Apr 24, 2024
5848c42
Fix LightDirection Alignment
thr3343 Apr 24, 2024
0e496a9
Fix remaining Mob Shaders w/ Light Direction
thr3343 Apr 24, 2024
46fe5be
Move Indirect buffer to RAM + Fix memory heap detection
thr3343 Apr 26, 2024
247de54
Merge branch '1.20.x' into Enums
thr3343 Apr 26, 2024
8838ea2
Merge branch '1.20.x' into BindlessRenderTest
thr3343 Apr 26, 2024
b61c52a
Merge Fixes
thr3343 Apr 26, 2024
87bef19
Merge branch 'Enums' into BindlessRenderTest
thr3343 Apr 26, 2024
eb77d28
Fix ColorModulator
thr3343 Apr 26, 2024
85a131d
Temp fix black textures on LLVMPipe
thr3343 Apr 27, 2024
daa86be
Actually fix MemoryType Enumeration
thr3343 Apr 28, 2024
794442d
Add Debug Enumeration MemoryType output
thr3343 Apr 28, 2024
ba6e971
Fix PushConstant alignment + add Eyes and Translucent Emissive textures
thr3343 Apr 28, 2024
508bcdd
Add Mob Overlay + Test Texture Debug Info
thr3343 Apr 28, 2024
dbda7c5
Test Variable descriptor count
thr3343 Apr 29, 2024
eb490b5
Implement initial DescriptorArray resizing
thr3343 Apr 30, 2024
9619b42
Test Combined Sampler/ImageView Freeing
thr3343 Apr 30, 2024
e9d220b
[TempFix] Fix/Restore Mipmaps
thr3343 May 2, 2024
bdf964e
Fix Splash Screen Mipmaps (Restore per image samplers)
thr3343 May 2, 2024
9e6cdc6
Disable InlineUniformBlockUpdateAfterBind
thr3343 May 3, 2024
9bfb1a7
Add missing Sampler Cleanup
thr3343 May 3, 2024
04222b0
Add Missing Light_Direction Uniforms
thr3343 May 3, 2024
ea60ed4
test simplified uniform management
thr3343 May 7, 2024
0fc7607
[Testing] Attempt to fix out of pool memory errors on AMD
thr3343 May 7, 2024
5d6b0b7
[Bugged] Temp Fix/Restore Vertex Fog
thr3343 May 9, 2024
eac31fb
Fix Vertex Fog Bugs + Misaligned Uniform updates
thr3343 May 9, 2024
2905f77
Reduce quadsIndexBuffer size by 33% + Make allocation sizes constant
thr3343 May 9, 2024
23237dd
Try to fix inconsistent texture bleeding artifacts w/ F3+A
thr3343 May 9, 2024
3be586e
Revert "Fix Splash Screen Mipmaps (Restore per image samplers)" (Temp…
thr3343 May 10, 2024
10a7f39
Fix DescriptorPool + Layout Sizes
thr3343 May 10, 2024
38ff908
Restore per image Mipmaps + fix Texture bleed
thr3343 May 11, 2024
4e55667
Fix Cloud Layer Rendering
thr3343 May 11, 2024
005adb5
Fix Uniform Glitches w/ MiniHUD
thr3343 May 11, 2024
0b0f217
Fix Crash due to Vert Sampler Capacity overflow
thr3343 May 12, 2024
7dcbb92
[Testing] Test dynamically indexing multiple uniforms
thr3343 May 12, 2024
1d094b9
Test using Immutable Samplers
thr3343 May 12, 2024
b0deb55
Fix Sky Color Blending/Gradient
thr3343 May 12, 2024
1f49dee
Merge branch '1.20.x' into BindlessRenderTest2
thr3343 May 12, 2024
6a5ffc1
Improve handling for hardcoded textures
thr3343 May 15, 2024
59347af
Merge branch '1.20.x' into BindlessRenderTest2
thr3343 May 15, 2024
7134aac
Update GraphicsPipeline.java
thr3343 May 15, 2024
33657a3
Rename MemoryTypes
thr3343 May 19, 2024
0bd9c85
Merge branch '1.20.x' into BindlessRenderTest2
thr3343 May 19, 2024
95804da
Merge Fixes
thr3343 May 19, 2024
c7151d7
Fix Version
thr3343 May 19, 2024
80cdad3
[TempFix] Remove Immutable samplers
thr3343 May 20, 2024
c4aca58
[Testing] Test allocating new sets during recording + use Partially B…
thr3343 May 22, 2024
27dfc5b
Adjust Debug info
thr3343 May 23, 2024
0e8565d
Improve InlineUniformBlock handling
thr3343 May 23, 2024
282c314
[Testing] Tweak Image Registration/Binding
thr3343 May 23, 2024
09a25aa
[Testing] Tweak Image Registration/Binding 2
thr3343 May 24, 2024
44be8e5
Cleanup outdated code
thr3343 May 24, 2024
4ddb58c
Fix LLVMPipe crash
thr3343 May 26, 2024
3d2d33a
Ensure texture index is always dynamically uniform
thr3343 May 26, 2024
ed5a420
Correct miscellaneous rendering glitches
thr3343 May 27, 2024
0b8bd9b
Additional rendering fixes
thr3343 May 27, 2024
b60d2b7
Fix NameTag rendering
thr3343 May 27, 2024
7e07a88
Adjust defaults + remove chunk broadcast optimization
thr3343 May 29, 2024
6ffd8ac
Add RenderFog spec constant
thr3343 May 29, 2024
044c085
Readd Immutable samplers
thr3343 May 29, 2024
7653c83
Fix cloud depth ordering artifacts
thr3343 Jun 1, 2024
4191fde
Clarify name of PostEffect draw function
thr3343 Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -12,6 +12,6 @@ loader_version=0.15.7
fabric_version=0.96.4+1.20.4

# Mod Properties
mod_version = 0.4.1
mod_version = 0.4.2
maven_group = net.vulkanmod
archives_base_name = VulkanMod_1.20.4
Empty file modified gradlew
100644 → 100755
Empty file.
3 changes: 3 additions & 0 deletions src/main/java/net/vulkanmod/config/Config.java
Original file line number Diff line number Diff line change
@@ -24,8 +24,11 @@ public class Config {
public boolean uniqueOpaqueLayer = true;
public boolean entityCulling = true;
public int device = -1;
public boolean enableAnimations = true;
public boolean shouldRenderSky = true;

public int ambientOcclusion = 1;
public boolean renderFog = true;

public void write() {

33 changes: 25 additions & 8 deletions src/main/java/net/vulkanmod/config/option/Options.java
Original file line number Diff line number Diff line change
@@ -15,9 +15,9 @@
import java.util.stream.IntStream;

public abstract class Options {
static net.minecraft.client.Options minecraftOptions = Minecraft.getInstance().options;
private static net.minecraft.client.Options minecraftOptions = Minecraft.getInstance().options;
static Config config = Initializer.CONFIG;
static Window window = Minecraft.getInstance().getWindow();
private static final Window window = Minecraft.getInstance().getWindow();
public static boolean fullscreenDirty = false;

public static OptionBlock[] getVideoOpts() {
@@ -117,11 +117,11 @@ public static OptionBlock[] getVideoOpts() {
.setTranslator(value -> value == 0 ? Component.literal("Auto") : Component.literal(value.toString())),
new RangeOption(Component.translatable("Brightness"),
0, 100, 1,
value -> {
if (value == 0) return Component.translatable("options.gamma.min");
else if (value == 50) return Component.translatable("options.gamma.default");
else if (value == 100) return Component.translatable("options.gamma.max");
return Component.literal(String.valueOf(value));
value -> switch (value) {
case 0 -> Component.translatable("options.gamma.min");
case 50 -> Component.translatable("options.gamma.default");
case 100 -> Component.translatable("options.gamma.max");
default -> Component.literal(String.valueOf(value));
},
value -> minecraftOptions.gamma().set(value * 0.01),
() -> (int) (minecraftOptions.gamma().get() * 100.0)),
@@ -219,6 +219,18 @@ public static OptionBlock[] getGraphicsOpts() {
Minecraft.getInstance().levelRenderer.allChanged();
},
() -> minecraftOptions.biomeBlendRadius().get()),
new SwitchOption(Component.translatable("Animations"),
(value) -> config.enableAnimations = value,
() -> config.enableAnimations),
new SwitchOption(Component.translatable("RenderSky"),
(value) -> config.shouldRenderSky = value,
() -> config.shouldRenderSky),
new SwitchOption(Component.translatable("RenderFog"),
(value) -> {
config.renderFog = value;
Renderer.recomp=true;
},
() -> config.renderFog)
}),
new OptionBlock("", new Option<?>[]{
new SwitchOption(Component.translatable("Entity Shadows"),
@@ -234,6 +246,8 @@ public static OptionBlock[] getGraphicsOpts() {
minecraftOptions.mipmapLevels().set(value);
Minecraft.getInstance().updateMaxMipLevel(value);
Minecraft.getInstance().delayTextureReload();

Renderer.getDescriptorSetArray().forceDescriptorUpdate();
},
() -> minecraftOptions.mipmapLevels().get())
.setTranslator(value -> Component.nullToEmpty(value.toString()))
@@ -302,7 +316,10 @@ public static OptionBlock[] getOtherOpts() {
};

}

public static byte getMipmaps()
{
return (byte) (int) minecraftOptions.mipmapLevels().get();
}
static Integer[] getGuiScaleValues() {
int max = window.calculateScale(0, Minecraft.getInstance().isEnforceUnicode());

4 changes: 2 additions & 2 deletions src/main/java/net/vulkanmod/gl/GlRenderbuffer.java
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ public static void bindRenderbuffer(int target, int id) {

VulkanImage vulkanImage = bound.vulkanImage;
if(vulkanImage != null)
VTextureSelector.bindTexture(vulkanImage);
VTextureSelector.bindTexture(0, vulkanImage, id);
}

public static void deleteRenderbuffer(int i) {
@@ -151,7 +151,7 @@ void allocateImage(int width, int height, int vkFormat) {
.addUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.createVulkanImage();

VTextureSelector.bindTexture(this.vulkanImage);
VTextureSelector.bindTexture(0, this.vulkanImage, id);
}

void updateSampler() {
51 changes: 43 additions & 8 deletions src/main/java/net/vulkanmod/gl/GlTexture.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package net.vulkanmod.gl;

import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import net.minecraft.resources.ResourceLocation;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.memory.MemoryManager;
import net.vulkanmod.vulkan.texture.SamplerManager;
import net.vulkanmod.vulkan.texture.ImageUtil;
@@ -18,51 +20,65 @@
public class GlTexture {
private static int ID_COUNTER = 1;
private static final Int2ReferenceOpenHashMap<GlTexture> map = new Int2ReferenceOpenHashMap<>();
// private static final Int2ReferenceOpenHashMap<ResourceLocation> TexIDtoResourceName = new Int2ReferenceOpenHashMap<>();
// private static final Int2IntOpenHashMap TexIDtoDescriptorIndex = new Int2IntOpenHashMap();
private static int boundTextureId = 0;
private static GlTexture boundTexture;
private static int activeTexture = 0;

//TODO Separate Framebuffer Images from textures
// to handle Pushing Descpritors when handling PostEffect renderPasses

public static void bindIdToImage(int id, VulkanImage vulkanImage) {
GlTexture texture = map.get(id);
texture.vulkanImage = vulkanImage;
}

//TODO: Maybe bypass TextureIDs for Reserved slots + (e.g. Atlases)
// + May alos be optimal as a tmep workaround for Async Texture Atlas loader
public static int genTextureId() {
int id = ID_COUNTER;
map.put(id, new GlTexture(id));
ID_COUNTER++;
return id;
}

//TODO: Remove Bindfull Boilerplate+OpenGl handling and make this a selctor-based system instead
// + use GL_TEZXURE_UNIT IDS Directly Maybe a
public static void bindTexture(int id) {
boundTextureId = id;

boundTexture = map.get(id);

if(id <= 0)
if(id <= 0 || boundTextureId==id)
return;

boundTextureId = id;

if(boundTexture == null)
throw new NullPointerException("bound texture is null");

VulkanImage vulkanImage = boundTexture.vulkanImage;
if(vulkanImage != null)
VTextureSelector.bindTexture(activeTexture, vulkanImage);
VTextureSelector.bindTexture(activeTexture, vulkanImage, boundTextureId);
}

public static void glDeleteTextures(int i) {
GlTexture glTexture = map.remove(i);
VulkanImage image = glTexture != null ? glTexture.vulkanImage : null;
if(image != null)
{
//TODO; disseminate between Sampler/Currently Bound textrues and etxure snot be utilised in the Descriptor Array
MemoryManager.getInstance().addToFreeable(image);
}
// removeImageResource(i);
Renderer.getDescriptorSetArray().removeImage(i);
}

public static GlTexture getTexture(int id) {
if (id == 0)
if (id == 0 || id == -1)
return null;

return map.get(id);
}

//TODO: Descriptor Indexing
public static void activeTexture(int i) {
activeTexture = i - GL30.GL_TEXTURE0;

@@ -81,7 +97,7 @@ public static void texImage2D(int target, int level, int internalFormat, int wid
boundTexture.internalFormat = internalFormat;

boundTexture.allocateIfNeeded(width, height, format, type);
VTextureSelector.bindTexture(activeTexture, boundTexture.vulkanImage);
VTextureSelector.bindTexture(activeTexture, boundTexture.vulkanImage, boundTextureId);

if(pixels != null)
boundTexture.uploadImage(pixels);
@@ -177,6 +193,25 @@ public GlTexture(int id) {
this.id = id;
}

public static boolean hasImage(int textureID) {
return map.get(textureID).getVulkanImage()!=null;
}
public static boolean hasImageResource(int textureID) {
return map.containsKey(textureID);
}

/* public static void removeImageResource(int TextureID)
{
// if(TextureID!=-1)
// {
// var a = TexIDtoResourceName.remove(TextureID);
// if(a!=null) Initializer.LOGGER.info("UnRegistered texture: " + TextureID + " <-> " + "! -> "+a);
// }
}*/
public int getId() {
return id;
}

void allocateIfNeeded(int width, int height, int format, int type) {
int vkFormat = GlUtil.vulkanFormat(format, type);

Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ public interface VAbstractTextureI {

void bindTexture();

int getId2();
void setId(int i);

VulkanImage getVulkanImage();
Original file line number Diff line number Diff line change
@@ -38,7 +38,6 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.IntSupplier;
@@ -95,7 +94,11 @@ public void close() {
//TODO
// ProgramManager.releaseProgram(this);
}

//TODO: Compile all required Uniforms and aggregate them into a singular Descriptorset that can cover all required ShaderStages
// Vertex Shader uis always constant _(i.e. Blit)_ editl its not: varies on Configred Program -> DescritorSet
// Alias Programs -> DescriptorSets
// Auto promote Uniforms to Inline Uniforms or PushConstants based on Size + required states+Updates e.g.
// Convert/UnRoll Smapler Hbdings into Arrays + constant indices
private void createShaders(ResourceManager resourceManager, String vertexShader, String fragShader) {

try {
@@ -203,7 +206,7 @@ public void apply() {
uniform.upload();
}

renderer.uploadAndBindUBOs(pipeline);


}

11 changes: 8 additions & 3 deletions src/main/java/net/vulkanmod/mixin/debug/DebugScreenOverlayM.java
Original file line number Diff line number Diff line change
@@ -4,10 +4,11 @@
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import net.vulkanmod.render.chunk.WorldRenderer;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.SystemInfo;
import net.vulkanmod.vulkan.Vulkan;
import net.vulkanmod.vulkan.memory.MemoryTypes;
import net.vulkanmod.vulkan.device.Device;
import net.vulkanmod.vulkan.memory.MemoryManager;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -58,9 +59,11 @@ private ArrayList<String> redirectList(Object[] elements) {
strings.add(String.format("Mem: % 2d%% %03d/%03dMB", usedMemory * 100L / maxMemory, bytesToMegabytes(usedMemory), bytesToMegabytes(maxMemory)));
strings.add(String.format("Allocated: % 2d%% %03dMB", totalMemory * 100L / maxMemory, bytesToMegabytes(totalMemory)));
strings.add(String.format("Off-heap: " + getOffHeapMemory() + "MB"));
strings.add("NativeMemory: " + MemoryManager.getInstance().getNativeMemoryMB() + "MB");
strings.add("DeviceMemory: " + MemoryManager.getInstance().getDeviceMemoryMB() + "MB");
strings.add("BARMemory: " + MemoryTypes.BAR_MEM.usedBytes()+"/" + MemoryTypes.BAR_MEM.maxSize() + "MB");
strings.add("DeviceMemory: " + MemoryTypes.GPU_MEM.usedBytes()+"/" + MemoryTypes.GPU_MEM.maxSize() + "MB");
strings.add("");
// strings.add("PCIe Transfers");
// strings.add("GPU Transfers");
strings.add("VulkanMod " + getVersion());
strings.add("CPU: " + SystemInfo.cpuInfo);
strings.add("GPU: " + device.deviceName);
@@ -70,6 +73,8 @@ private ArrayList<String> redirectList(Object[] elements) {
strings.add("");

Collections.addAll(strings, WorldRenderer.getInstance().getChunkAreaManager().getStats());
strings.add("");
Collections.addAll(strings, Renderer.getDescriptorSetArray().getDebugInfo());

return strings;
}
59 changes: 59 additions & 0 deletions src/main/java/net/vulkanmod/mixin/matrix/Matrix4fM.java
Original file line number Diff line number Diff line change
@@ -11,6 +11,38 @@ public abstract class Matrix4fM {
@Shadow public abstract Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne);
@Shadow public abstract Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne);

@Shadow public abstract float m00();

@Shadow public abstract float m01();

@Shadow public abstract float m02();

@Shadow public abstract float m03();

@Shadow public abstract float m10();

@Shadow public abstract float m11();

@Shadow public abstract float m12();

@Shadow public abstract float m13();

@Shadow public abstract float m20();

@Shadow public abstract float m21();

@Shadow public abstract float m22();

@Shadow public abstract float m23();

@Shadow public abstract float m30();

@Shadow public abstract float m31();

@Shadow public abstract float m32();

@Shadow public abstract float m33();

/**
* @author
* @reason
@@ -46,4 +78,31 @@ public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) {
public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar) {
return new Matrix4f().setPerspective(fovy, aspect, zNear, zFar, true);
}

/**
* @author
* @reason
*/
@Overwrite(remap = false)
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToRawIntBits(m00());
result = prime * result + Float.floatToRawIntBits(m01());
result = prime * result + Float.floatToRawIntBits(m02());
result = prime * result + Float.floatToRawIntBits(m03());
result = prime * result + Float.floatToRawIntBits(m10());
result = prime * result + Float.floatToRawIntBits(m11());
result = prime * result + Float.floatToRawIntBits(m12());
result = prime * result + Float.floatToRawIntBits(m13());
result = prime * result + Float.floatToRawIntBits(m20());
result = prime * result + Float.floatToRawIntBits(m21());
result = prime * result + Float.floatToRawIntBits(m22());
result = prime * result + Float.floatToRawIntBits(m23());
result = prime * result + Float.floatToRawIntBits(m30());
result = prime * result + Float.floatToRawIntBits(m31());
result = prime * result + Float.floatToRawIntBits(m32());
result = prime * result + Float.floatToRawIntBits(m33());
return result;
}
}
9 changes: 6 additions & 3 deletions src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.VRenderSystem;
import net.vulkanmod.vulkan.shader.GraphicsPipeline;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;

@@ -42,11 +41,15 @@ public static void drawWithShader(BufferBuilder.RenderedBuffer buffer) {
// 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());

int textureID = pipeline.updateImageState();
if(textureID!=-1) Renderer.getDrawer().draw(buffer.vertexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount(), textureID);
}

}
65 changes: 38 additions & 27 deletions src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java
Original file line number Diff line number Diff line change
@@ -81,29 +81,30 @@ public abstract class GameRendererMixin {
@Shadow private @Nullable static ShaderInstance rendertypeEndGatewayShader;
@Shadow private @Nullable static ShaderInstance rendertypeLinesShader;
@Shadow private @Nullable static ShaderInstance rendertypeCrumblingShader;
@Shadow private static @Nullable ShaderInstance rendertypeBreezeWindShader;

@Shadow private static @Nullable ShaderInstance rendertypeTextBackgroundShader;
@Shadow private static @Nullable ShaderInstance rendertypeTextBackgroundSeeThroughShader;
@Shadow private static @Nullable ShaderInstance rendertypeGuiShader;
@Shadow private static @Nullable ShaderInstance rendertypeGuiOverlayShader;
@Shadow private static @Nullable ShaderInstance rendertypeGuiTextHighlightShader;
@Shadow private static @Nullable ShaderInstance rendertypeGuiGhostRecipeOverlayShader;

@Shadow private @Nullable static ShaderInstance positionColorLightmapShader;
@Shadow private @Nullable static ShaderInstance positionColorTexLightmapShader;
@Shadow private @Nullable static ShaderInstance positionTexLightmapColorShader;
//TODO: use as base shaders for deduping...
// @Shadow private @Nullable static ShaderInstance positionColorLightmapShader;
// @Shadow private @Nullable static ShaderInstance positionColorTexLightmapShader;
// @Shadow private @Nullable static ShaderInstance positionTexLightmapColorShader;

@Shadow public ShaderInstance blitShader;

@Shadow protected abstract ShaderInstance preloadShader(ResourceProvider resourceProvider, String string, VertexFormat vertexFormat);

@Shadow public abstract float getRenderDistance();

@Shadow private static @Nullable ShaderInstance rendertypeBreezeWindShader;

@Inject(method = "reloadShaders", at = @At("HEAD"), cancellable = true)
public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
RenderSystem.assertOnRenderThread();
List<Program> list = Lists.newArrayList();
// List<Program> list = Lists.newArrayList();
// list.addAll(Program.Type.FRAGMENT.getPrograms().values());
// list.addAll(Program.Type.VERTEX.getPrograms().values());
// list.forEach(Program::close);
@@ -122,7 +123,8 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
// list1.add(Pair.of(new ShaderInstance(provider, "position_color_lightmap", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), (shaderInstance) -> {
// positionColorLightmapShader = shaderInstance;
// }));
list1.add(Pair.of(new ShaderInstance(provider, "position_color_tex", DefaultVertexFormat.POSITION_COLOR_TEX), (shaderInstance) -> {
final ShaderInstance positionColorTex = new ShaderInstance(provider, "position_color_tex", DefaultVertexFormat.POSITION_COLOR_TEX);
list1.add(Pair.of(positionColorTex, (shaderInstance) -> {
positionColorTexShader = shaderInstance;
}));
// list1.add(Pair.of(new ShaderInstance(provider, "position_color_tex_lightmap", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> {
@@ -140,19 +142,21 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
// list1.add(Pair.of(new ShaderInstance(provider, "position_tex_lightmap_color", DefaultVertexFormat.POSITION_TEX_LIGHTMAP_COLOR), (shaderInstance) -> {
// positionTexLightmapColorShader = shaderInstance;
// }));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_solid", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
//TODO: only used for Falling Blocks,
final ShaderInstance rendertypeSolid = new ShaderInstance(provider, "rendertype_solid", DefaultVertexFormat.BLOCK);
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeSolidShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_cutout_mipped", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeCutoutMippedShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_cutout", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeCutoutShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_translucent", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeTranslucentShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_translucent_moving_block", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeTranslucentMovingBlockShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_armor_cutout_no_cull", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
@@ -204,13 +208,15 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_entity_shadow", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
rendertypeEntityShadowShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_entity_alpha", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
//Only used for EnderDragon death (//TODO: may crash)
list1.add(Pair.of(positionColorTex, (shaderInstance) -> {
rendertypeEntityAlphaShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_eyes", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
rendertypeEyesShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_energy_swirl", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
ShaderInstance energySwirl = new ShaderInstance(provider, "rendertype_energy_swirl", DefaultVertexFormat.NEW_ENTITY);
list1.add(Pair.of(energySwirl, (shaderInstance) -> {
rendertypeEnergySwirlShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_leash", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), (shaderInstance) -> {
@@ -219,31 +225,33 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_water_mask", DefaultVertexFormat.POSITION), (shaderInstance) -> {
rendertypeWaterMaskShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_outline", DefaultVertexFormat.POSITION_COLOR_TEX), (shaderInstance) -> {
//TODO: might break Glowing Effect
list1.add(Pair.of(positionColorTex, (shaderInstance) -> {
rendertypeOutlineShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_armor_glint", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
final ShaderInstance rendertypeGlintTranslucent = new ShaderInstance(provider, "rendertype_glint_translucent", DefaultVertexFormat.POSITION_TEX);
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeArmorGlintShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_armor_entity_glint", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeArmorEntityGlintShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_glint_translucent", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeGlintTranslucentShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_glint", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeGlintShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_glint_direct", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeGlintDirectShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_entity_glint", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeEntityGlintShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_entity_glint_direct", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> {
list1.add(Pair.of(rendertypeGlintTranslucent, (shaderInstance) -> {
rendertypeEntityGlintDirectShader = shaderInstance;
}));

//TODO; Text Shaders can be replaced w/ positionColorTex if POSITION_COLOR_TEX_LIGHTMAP is replaced w/ POSITION_COLOR_TEX;
//Text
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> {
rendertypeTextShader = shaderInstance;
@@ -254,6 +262,7 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_intensity", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> {
rendertypeTextIntensityShader = shaderInstance;
}));
//TODO; Text Shaders can be replaced w/ positionColorTex if POSITION_COLOR_TEX_LIGHTMAP is replaced w/ POSITION_COLOR_TEX;
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> {
rendertypeTextSeeThroughShader = shaderInstance;
}));
@@ -267,7 +276,7 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_lightning", DefaultVertexFormat.POSITION_COLOR), (shaderInstance) -> {
rendertypeLightningShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_tripwire", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
list1.add(Pair.of(rendertypeSolid, (shaderInstance) -> {
rendertypeTripwireShader = shaderInstance;
}));
ShaderInstance endPortalShader = new ShaderInstance(provider, "rendertype_end_portal", DefaultVertexFormat.POSITION);
@@ -280,6 +289,7 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_lines", DefaultVertexFormat.POSITION_COLOR_NORMAL), (shaderInstance) -> {
rendertypeLinesShader = shaderInstance;
}));
//TODO Replace w/ positionColorTex
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_crumbling", DefaultVertexFormat.BLOCK), (shaderInstance) -> {
rendertypeCrumblingShader = shaderInstance;
}));
@@ -296,7 +306,7 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) {
list1.add(Pair.of(positionColor, (shaderInstance) -> {
rendertypeGuiGhostRecipeOverlayShader = shaderInstance;
}));
list1.add(Pair.of(new ShaderInstance(provider, "rendertype_energy_swirl", DefaultVertexFormat.NEW_ENTITY), (shaderInstance) -> {
list1.add(Pair.of(energySwirl, (shaderInstance) -> {
rendertypeBreezeWindShader = shaderInstance;
}));
} catch (IOException ioexception) {
@@ -347,10 +357,11 @@ public void preloadUiShader(ResourceProvider resourceProvider) {

positionShader = this.preloadShader(resourceProvider, "position", DefaultVertexFormat.POSITION);
positionColorShader = this.preloadShader(resourceProvider, "position_color", DefaultVertexFormat.POSITION_COLOR);
positionColorTexShader = this.preloadShader(resourceProvider, "position_color_tex", DefaultVertexFormat.POSITION_COLOR_TEX);
final ShaderInstance positionColorTex = this.preloadShader(resourceProvider, "position_color_tex", DefaultVertexFormat.POSITION_COLOR_TEX);
positionColorTexShader = positionColorTex;
positionTexShader = this.preloadShader(resourceProvider, "position_tex", DefaultVertexFormat.POSITION_TEX);
positionTexColorShader = this.preloadShader(resourceProvider, "position_tex_color", DefaultVertexFormat.POSITION_TEX_COLOR);
rendertypeTextShader = this.preloadShader(resourceProvider, "rendertype_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP);
rendertypeTextShader = positionColorTex;

rendertypeGuiShader = positionColorShader;
rendertypeGuiOverlayShader = positionColorShader;
Original file line number Diff line number Diff line change
@@ -6,12 +6,14 @@
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.PostChain;
import net.minecraft.resources.ResourceLocation;
import net.vulkanmod.vulkan.VRenderSystem;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.io.IOException;
@@ -53,4 +55,10 @@ public abstract class LevelRendererMixin {
//// }
// }

/* @Redirect(method = "renderSky", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;setShaderColor(FFFF)V", ordinal = 0))
private void getSkyColor(float f, float g, float h, float i)
{
VRenderSystem.setSkyColor(f, g, h, i);
}*/

}
84 changes: 57 additions & 27 deletions src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.vulkanmod.mixin.render;

import com.mojang.blaze3d.pipeline.RenderCall;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
@@ -14,19 +13,25 @@
import net.vulkanmod.interfaces.VAbstractTextureI;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.VRenderSystem;
import net.vulkanmod.vulkan.shader.Pipeline;
import net.vulkanmod.vulkan.shader.UniformState;
import net.vulkanmod.vulkan.shader.layout.Uniform;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import net.vulkanmod.vulkan.texture.VulkanImage;
import net.vulkanmod.vulkan.util.ColorUtil;
import net.vulkanmod.vulkan.util.MappedBuffer;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.lwjgl.system.MemoryStack;
import org.spongepowered.asm.mixin.*;

import java.nio.ByteBuffer;
import java.util.function.Consumer;

import static com.mojang.blaze3d.systems.RenderSystem.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.vulkan.VK10.*;

@Mixin(RenderSystem.class)
public abstract class RenderSystemMixin {
@@ -38,7 +43,7 @@ public abstract class RenderSystemMixin {
@Shadow private static Matrix4f textureMatrix;
@Shadow @Final private static int[] shaderTextures;
@Shadow @Final private static float[] shaderColor;
@Shadow @Final private static Vector3f[] shaderLightDirections;
@Shadow @Final private static final Vector3f[] shaderLightDirections = {new Vector3f(), new Vector3f()};

@Shadow
public static void assertOnGameThreadOrInit() {
@@ -51,14 +56,16 @@ public static void assertOnGameThreadOrInit() {
/**
* @author
*/
//TODO: May have potential for texture selection...
@Overwrite
public static void _setShaderTexture(int i, ResourceLocation location) {
if (i >= 0 && i < shaderTextures.length) {
//TODO: Replace w/ DescriptorAbstraction Array for Faster lookups
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
AbstractTexture abstractTexture = textureManager.getTexture(location);
VTextureSelector.bindTexture(i, ((VAbstractTextureI)abstractTexture).getVulkanImage());
VTextureSelector.bindTexture(i, ((VAbstractTextureI)abstractTexture).getVulkanImage(), abstractTexture.getId());

//shaderTextures[i] = abstractTexture.getId();
shaderTextures[i] = abstractTexture.getId();
}

}
@@ -75,7 +82,9 @@ public static void _setShaderTexture(int i, int id) {
if(vulkanImage == null)
return;

VTextureSelector.bindTexture(i, vulkanImage);
final int id1 = glTexture.getId();
VTextureSelector.bindTexture(i, vulkanImage, id1);
shaderTextures[i] = id1;
}

}
@@ -363,42 +372,63 @@ public static void clearColor(float p_69425_, float p_69426_, float p_69427_, fl
*/
@Overwrite(remap = false)
public static void _setShaderLights(Vector3f p_157174_, Vector3f p_157175_) {
shaderLightDirections[0] = p_157174_;
shaderLightDirections[1] = p_157175_;

VRenderSystem.lightDirection0.buffer.putFloat(0, p_157174_.x());
VRenderSystem.lightDirection0.buffer.putFloat(4, p_157174_.y());
VRenderSystem.lightDirection0.buffer.putFloat(8, p_157174_.z());
if(shaderLightDirections[0].hashCode() != p_157174_.hashCode() && shaderLightDirections[1].hashCode() != p_157175_.hashCode())
{
shaderLightDirections[0] = p_157174_;
shaderLightDirections[1] = p_157175_;

try(MemoryStack stack = stackPush()) {
ByteBuffer byteBuffer = stack.malloc(32);

p_157174_.get(0, byteBuffer);
p_157175_.get(16, byteBuffer);

vkCmdPushConstants(Renderer.getCommandBuffer(), Pipeline.pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, byteBuffer);

}
}

VRenderSystem.lightDirection1.buffer.putFloat(0, p_157175_.x());
VRenderSystem.lightDirection1.buffer.putFloat(4, p_157175_.y());
VRenderSystem.lightDirection1.buffer.putFloat(8, p_157175_.z());
}

/**
* @author
*/
@Overwrite(remap = false)
private static void _setShaderColor(float r, float g, float b, float a) {
shaderColor[0] = r;
shaderColor[1] = g;
shaderColor[2] = b;
shaderColor[3] = a;
if(extracted(shaderColor, r, g, b, a))
{
shaderColor[0] = r;
shaderColor[1] = g;
shaderColor[2] = b;
shaderColor[3] = a;

ColorUtil.setRGBA_Buffer(UniformState.ColorModulator.getMappedBufferPtr(), r, g, b, a);
vkCmdPushConstants(Renderer.getCommandBuffer(), Pipeline.pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 32, UniformState.ColorModulator.buffer());

VRenderSystem.setShaderColor(r, g, b, a);
}

VRenderSystem.setShaderColor(r, g, b, a);
}

/**
* @author
*/
@Overwrite(remap = false)
private static void _setShaderFogColor(float f, float g, float h, float i) {
shaderFogColor[0] = f;
shaderFogColor[1] = g;
shaderFogColor[2] = h;
shaderFogColor[3] = i;
if(extracted(shaderFogColor, f, g, h, i))
{
shaderFogColor[0] = f;
shaderFogColor[1] = g;
shaderFogColor[2] = h;
shaderFogColor[3] = i;
VRenderSystem.setShaderFogColor(f, g, h, i);
}
}

VRenderSystem.setShaderFogColor(f, g, h, i);
@Unique
private static boolean extracted(float[] shaderFogColor, float f, float g, float h, float i) {
return shaderFogColor[0] != f || shaderFogColor[1] != g || shaderFogColor[2] != h || shaderFogColor[3] != i;
}

/**
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@

import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.TextureUtil;
import com.mojang.blaze3d.systems.RenderSystem;
import net.vulkanmod.gl.GlFramebuffer;
import net.vulkanmod.gl.GlTexture;
@@ -183,9 +182,10 @@ private void _blitToScreen(int width, int height, boolean disableBlend) {
//If true it means target has not been used
return;
}

//TODO: Diff between frameBuffer and : may just use a separate Binding for Framebuffers
//edit fixed to use
Framebuffer framebuffer = GlFramebuffer.getFramebuffer(this.frameBufferId).getFramebuffer();
VTextureSelector.bindTexture(0, framebuffer.getColorAttachment());
VTextureSelector.bindTexture(0, framebuffer.getColorAttachment(), colorTextureId);

DrawUtil.blitToScreen();
}
Original file line number Diff line number Diff line change
@@ -2,11 +2,15 @@

import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.VertexBuffer;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.ShaderInstance;
import net.vulkanmod.Initializer;
import net.vulkanmod.render.VBO;
import net.vulkanmod.vulkan.VRenderSystem;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -57,15 +61,16 @@ public void upload(BufferBuilder.RenderedBuffer buffer) {
*/
@Overwrite
public void drawWithShader(Matrix4f viewMatrix, Matrix4f projectionMatrix, ShaderInstance shader) {
vbo.drawWithShader(viewMatrix, projectionMatrix, shader);

vbo.drawWithShader(viewMatrix, projectionMatrix, shader);
}

/**
* @author
*/
@Overwrite
public void draw() {
vbo.drawChunkLayer();
vbo.drawPostEffect();
}

/**
Original file line number Diff line number Diff line change
@@ -48,7 +48,12 @@ public void releaseId() {

TextureUtil.releaseTextureId(this.id);
}


public int getId2()
{
return this.id;
}

public void setId(int i) {
this.id = i;
}
@@ -71,7 +76,7 @@ public void bindTexture() {
GlTexture.bindTexture(this.id);

if (vulkanImage != null)
VTextureSelector.bindTexture(vulkanImage);
VTextureSelector.bindTexture(0, vulkanImage, id);
}

public VulkanImage getVulkanImage() {
9 changes: 7 additions & 2 deletions src/main/java/net/vulkanmod/mixin/texture/MLightTexture.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.resources.ResourceLocation;
import net.vulkanmod.interfaces.VAbstractTextureI;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import org.spongepowered.asm.mixin.Final;
@@ -15,16 +16,20 @@ public class MLightTexture {

@Shadow @Final private DynamicTexture lightTexture;

@Shadow @Final private ResourceLocation lightTextureLocation;

/**
* @author
* @reason
*/
@Overwrite
public void turnOnLightLayer() {
// RenderSystem.setShaderTexture(2, this.textureIdentifier);
//Make sure LightSampler is accessible
RenderSystem.setShaderTexture(2, this.lightTextureLocation);
// this.client.getTextureManager().bindTexture(this.textureIdentifier);
// RenderSystem.texParameter(3553, 10241, 9729);
// RenderSystem.texParameter(3553, 10240, 9729);
VTextureSelector.setLightTexture(((VAbstractTextureI)this.lightTexture).getVulkanImage());
// VTextureSelector.setLightTexture(((VAbstractTextureI)this.lightTexture).getVulkanImage());
// RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
}
}
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.vulkanmod.interfaces.VAbstractTextureI;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import org.apache.commons.lang3.Validate;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -21,7 +20,7 @@ public class MOverlayTexture {
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/DynamicTexture;bind()V"))
private void overlay(DynamicTexture instance) {

VTextureSelector.setOverlayTexture(((VAbstractTextureI)this.texture).getVulkanImage());
VTextureSelector.setOverlayTexture(texture.getId(), ((VAbstractTextureI)this.texture).getVulkanImage());
VTextureSelector.setActiveTexture(1);
}

@@ -33,7 +32,7 @@ private void overlay(CallbackInfo ci) {

@Inject(method = "setupOverlayColor", at = @At(value = "HEAD"), cancellable = true)
private void setupOverlay(CallbackInfo ci) {
VTextureSelector.setOverlayTexture(((VAbstractTextureI)this.texture).getVulkanImage());
VTextureSelector.setOverlayTexture(texture.getId(), ((VAbstractTextureI)this.texture).getVulkanImage());
ci.cancel();
}
}
16 changes: 15 additions & 1 deletion src/main/java/net/vulkanmod/mixin/texture/MTextureManager.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package net.vulkanmod.mixin.texture;

import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.Tickable;
import net.minecraft.resources.ResourceLocation;
import net.vulkanmod.interfaces.VAbstractTextureI;
import net.vulkanmod.Initializer;
import net.vulkanmod.render.texture.SpriteUtil;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.device.DeviceManager;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Set;

@@ -22,7 +30,7 @@ public abstract class MTextureManager {
*/
@Overwrite
public void tick() {
if (Renderer.skipRendering)
if (Renderer.skipRendering | !Initializer.CONFIG.enableAnimations)
return;

//Debug D
@@ -36,4 +44,10 @@ public void tick() {
DeviceManager.getGraphicsQueue().endRecordingAndSubmit();
}
}

@Inject(method = "register(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/renderer/texture/AbstractTexture;)V", at= @At(value = "RETURN", target = "Lnet/minecraft/client/renderer/texture/TextureManager;tickableTextures:Ljava/util/Set;"))
private void injectRegister(ResourceLocation resourceLocation, AbstractTexture abstractTexture, CallbackInfo ci)
{
VTextureSelector.registerTexture(((VAbstractTextureI)(abstractTexture)).getId2(), -1, resourceLocation);
}
}
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ public static void prepareImage(NativeImage.InternalGlFormat internalGlFormat, i
.createVulkanImage();

glTexture.setVulkanImage(image);
VTextureSelector.bindTexture(image);
VTextureSelector.bindTexture(0, image, id);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.vulkanmod.mixin.wayland;

import com.mojang.blaze3d.platform.InputConstants;

import net.vulkanmod.config.Platform;
import org.lwjgl.glfw.*;
import org.spongepowered.asm.mixin.Mixin;
@@ -18,4 +19,4 @@ private static void grabOrReleaseMouse(long window, double xpos, double ypos) {
if (!Platform.isWayLand())
GLFW.glfwSetCursorPos(window, xpos, ypos);
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/net/vulkanmod/render/PipelineManager.java
Original file line number Diff line number Diff line change
@@ -65,11 +65,11 @@ public static void setShaderGetter(Function<TerrainRenderType, GraphicsPipeline>
shaderGetter = consumer;
}

public static GraphicsPipeline getTerrainDirectShader(RenderType renderType) {
public static GraphicsPipeline getTerrainDirectShader() {
return terrainShader;
}

public static GraphicsPipeline getTerrainIndirectShader(RenderType renderType) {
public static GraphicsPipeline getTerrainIndirectShader() {
return terrainShaderEarlyZ;
}

20 changes: 13 additions & 7 deletions src/main/java/net/vulkanmod/render/VBO.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.ShaderInstance;
import net.vulkanmod.Initializer;
import net.vulkanmod.interfaces.ShaderMixed;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.VRenderSystem;
@@ -126,23 +127,28 @@ public void drawWithShader(Matrix4f MV, Matrix4f P, GraphicsPipeline pipeline) {

Renderer renderer = Renderer.getInstance();
renderer.bindGraphicsPipeline(pipeline);
renderer.uploadAndBindUBOs(pipeline);

if (this.indexBuffer != null)
Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount);
else
Renderer.getDrawer().draw(this.vertexBuffer, this.vertexCount);
if(Initializer.CONFIG.shouldRenderSky)
{
int textureID = pipeline.updateImageState();
if (textureID != -1) {
if (indexBuffer != null)
Renderer.getDrawer().drawIndexed(vertexBuffer, indexBuffer, indexCount, textureID);
else
Renderer.getDrawer().draw(vertexBuffer, vertexCount);
}
}

VRenderSystem.applyMVP(RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix());

}
}

public void drawChunkLayer() {
public void drawPostEffect() {
if (this.indexCount != 0) {

RenderSystem.assertOnRenderThread();
Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount);
Renderer.getDrawer().drawIndexed(this.vertexBuffer, this.indexBuffer, this.indexCount, 0);
}
}

20 changes: 14 additions & 6 deletions src/main/java/net/vulkanmod/render/chunk/ChunkArea.java
Original file line number Diff line number Diff line change
@@ -3,26 +3,29 @@
import net.minecraft.core.BlockPos;
import net.vulkanmod.render.chunk.buffer.DrawBuffers;
import net.vulkanmod.render.chunk.util.StaticQueue;
import net.vulkanmod.render.vertex.TerrainRenderType;
import org.joml.FrustumIntersection;
import org.joml.Vector3i;

import java.util.Arrays;
import java.util.EnumMap;

public class ChunkArea {
public final int index;
private final byte[] inFrustum = new byte[64];

final Vector3i position;

DrawBuffers drawBuffers;

//Help JIT optimisations by hardcoding the queue size to the max possible ChunkArea limit
public final StaticQueue<RenderSection> sectionQueue = new StaticQueue<>(512);
public final EnumMap<TerrainRenderType, StaticQueue<DrawBuffers.DrawParameters>> sectionQueue = new EnumMap<>(TerrainRenderType.class);
final DrawBuffers drawBuffers;
private final Vector3i position;

public ChunkArea(int i, Vector3i origin, int minHeight) {
this.index = i;
this.position = origin;
this.drawBuffers = new DrawBuffers(i, origin, minHeight);
for (TerrainRenderType terrainRenderType : TerrainRenderType.VALUES) {
sectionQueue.put(terrainRenderType, new StaticQueue<>(512));
}
}

public void updateFrustum(VFrustum frustum) {
@@ -118,7 +121,7 @@ public DrawBuffers getDrawBuffers() {
}

public void resetQueue() {
this.sectionQueue.clear();
this.sectionQueue.forEach((terrainRenderType, drawParameters) -> drawParameters.clear());
}

public void setPosition(int x, int y, int z) {
@@ -128,4 +131,9 @@ public void setPosition(int x, int y, int z) {
public void releaseBuffers() {
this.drawBuffers.releaseBuffers();
}

public void addDrawCmds(EnumMap<TerrainRenderType, DrawBuffers.DrawParameters> renderSection) {

renderSection.forEach((key, value) -> this.sectionQueue.get(key).add(value));
}
}
24 changes: 15 additions & 9 deletions src/main/java/net/vulkanmod/render/chunk/RenderSection.java
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import net.vulkanmod.render.vertex.TerrainRenderType;

import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;

@@ -46,7 +47,7 @@ public class RenderSection {

public int xOffset, yOffset, zOffset;

private final DrawBuffers.DrawParameters[] drawParametersArray;
private final EnumMap<TerrainRenderType, DrawBuffers.DrawParameters> drawParametersArray;

//Graph-info
public byte mainDir;
@@ -60,10 +61,8 @@ public RenderSection(int index, int x, int y, int z) {
this.yOffset = y;
this.zOffset = z;

this.drawParametersArray = new DrawBuffers.DrawParameters[TerrainRenderType.VALUES.length];
for (int i = 0; i < this.drawParametersArray.length; ++i) {
this.drawParametersArray[i] = new DrawBuffers.DrawParameters();
}

drawParametersArray = new EnumMap<>(TerrainRenderType.class);
}

public void setOrigin(int x, int y, int z) {
@@ -299,7 +298,15 @@ public int zOffset() {
}

public DrawBuffers.DrawParameters getDrawParameters(TerrainRenderType renderType) {
return drawParametersArray[renderType.ordinal()];
return drawParametersArray.get(renderType);
}

public DrawBuffers.DrawParameters getOrAllocDrawParameters(TerrainRenderType renderType) {
return drawParametersArray.computeIfAbsent(renderType, i -> new DrawBuffers.DrawParameters());
}

public EnumMap<TerrainRenderType, DrawBuffers.DrawParameters> getDrawParametersArray() {
return drawParametersArray;
}

public void setChunkArea(ChunkArea chunkArea) {
@@ -382,9 +389,8 @@ private void resetDrawParameters() {
if (this.chunkArea == null)
return;

for (TerrainRenderType r : TerrainRenderType.VALUES) {
this.getDrawParameters(r).reset(this.chunkArea, r);
}
drawParametersArray.forEach((key, value) -> value.reset(this.chunkArea, key));
drawParametersArray.clear();
}

public void setDirty(boolean playerChanged) {
4 changes: 4 additions & 0 deletions src/main/java/net/vulkanmod/render/chunk/SubCopyCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package net.vulkanmod.render.chunk;

public record SubCopyCommand(long srcOffset, int dstOffset, int bufferSize) {
}
45 changes: 23 additions & 22 deletions src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java
Original file line number Diff line number Diff line change
@@ -38,12 +38,13 @@
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.queue.Queue;
import net.vulkanmod.vulkan.shader.GraphicsPipeline;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.lwjgl.vulkan.VkCommandBuffer;

import java.util.*;

@@ -94,6 +95,7 @@ private WorldRenderer(RenderBuffers renderBuffers) {

BlockRenderer.setBlockColors(this.minecraft.getBlockColors());

Renderer.getInstance().addOnResizeCallback(Queue::trimCmdPools);
Renderer.getInstance().addOnResizeCallback(() -> {
if (this.indirectBuffers.length != Renderer.getFramesNum())
allocateIndirectBuffers();
@@ -106,12 +108,13 @@ private void allocateIndirectBuffers() {

this.indirectBuffers = new IndirectBuffer[Renderer.getFramesNum()];

for (int i = 0; i < this.indirectBuffers.length; ++i) {
this.indirectBuffers[i] = new IndirectBuffer(1000000, MemoryTypes.HOST_MEM);
// this.indirectBuffers[i] = new IndirectBuffer(1000000, MemoryTypes.GPU_MEM);

for(int i = 0; i < this.indirectBuffers.length; ++i) {
this.indirectBuffers[i] = new IndirectBuffer(1048576, MemoryTypes.RAM_MEM);
// this.indirectBuffers[i] = new IndirectBuffer(1000000, MemoryType.GPU_MEM);
}

// uniformBuffers = new UniformBuffers(100000, MemoryTypes.GPU_MEM);
// uniformBuffers = new UniformBuffers(100000, MemoryType.GPU_MEM);
}

public static WorldRenderer init(RenderBuffers renderBuffers) {
@@ -146,6 +149,7 @@ public void setupRenderer(Camera camera, Frustum frustum, boolean isCapturedFrus
this.cameraPos = camera.getPosition();
if (this.minecraft.options.getEffectiveRenderDistance() != this.renderDistance) {
this.allChanged();
Renderer.getDescriptorSetArray().forceDescriptorUpdate();
}

this.level.getProfiler().push("camera");
@@ -259,6 +263,7 @@ public void allChanged() {
this.sectionGrid.repositionCamera(entity.getX(), entity.getZ());
}


}
}

@@ -310,28 +315,30 @@ public void renderSectionLayer(RenderType renderType, PoseStack poseStack, doubl

VRenderSystem.applyMVP(poseStack.last().pose(), projection);

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<TerrainRenderType> allowedRenderTypes = Initializer.CONFIG.uniqueOpaqueLayer ? TerrainRenderType.COMPACT_RENDER_TYPES : TerrainRenderType.SEMI_COMPACT_RENDER_TYPES;
if (allowedRenderTypes.contains(terrainRenderType)) {
terrainRenderType.setCutoutUniform();
//VRenderSystem.depthMask(!isTranslucent); ////Disable Depth writes if Translucent
Renderer renderer = Renderer.getInstance();
GraphicsPipeline pipeline = PipelineManager.getTerrainShader(terrainRenderType);
renderer.bindGraphicsPipeline(pipeline);
final VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();
Renderer.getDrawer().bindIndexBuffer(commandBuffer, Renderer.getDrawer().getQuadsIndexBuffer().getIndexBuffer());


// Renderer.getDescriptorSetArray().pushDescriptorSet(currentFrame, commandBuffer);

for (Iterator<ChunkArea> iterator = this.sectionGraph.getChunkAreaQueue().iterator(isTranslucent); iterator.hasNext(); ) {
ChunkArea chunkArea = iterator.next();
var queue = chunkArea.sectionQueue;
var queue = chunkArea.sectionQueue.get(terrainRenderType);
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, terrainRenderType, camX, camY, camZ);


if (indirectDraw)
drawBuffers.buildDrawBatchesIndirect(indirectBuffers[currentFrame], queue, terrainRenderType);
@@ -341,17 +348,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();

Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ public class AreaBuffer {
private static final boolean DEBUG = false;
private static final Logger LOGGER = Initializer.LOGGER;

private static final MemoryType MEMORY_TYPE = MemoryTypes.GPU_MEM;
private static final MemoryTypes MEMORY_TYPE = MemoryTypes.GPU_MEM;

private final int usage;
private final int elementSize;
49 changes: 19 additions & 30 deletions src/main/java/net/vulkanmod/render/chunk/buffer/DrawBuffers.java
Original file line number Diff line number Diff line change
@@ -39,18 +39,20 @@ public DrawBuffers(int index, Vector3i origin, int minHeight) {
}

public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType renderType) {
DrawParameters drawParameters = section.getDrawParameters(renderType);
DrawParameters drawParameters = section.getOrAllocDrawParameters(renderType);
int vertexOffset = drawParameters.vertexOffset;
int firstIndex = -1;
int firstIndex = 0;

if (!buffer.indexOnly) {
final boolean b = !buffer.indexOnly;
final boolean b1 = !buffer.autoIndices;
if (b) {
AreaBuffer.Segment segment = this.getAreaBufferOrAlloc(renderType).upload(buffer.getVertexBuffer(), vertexOffset, drawParameters);
vertexOffset = segment.offset / VERTEX_SIZE;

drawParameters.baseInstance = encodeSectionOffset(section.xOffset(), section.yOffset(), section.zOffset());
}

if (!buffer.autoIndices) {
if (b1) {
if (this.indexBuffer == null)
this.indexBuffer = new AreaBuffer(AreaBuffer.Usage.INDEX, 786432 /*RenderType.SMALL_BUFFER_SIZE*/, INDEX_SIZE);

@@ -59,6 +61,7 @@ public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType
}

drawParameters.indexCount = buffer.indexCount;
// drawParameters.instanceCount = vertexOffset == -1 ? 0 : 1;
drawParameters.firstIndex = firstIndex;
drawParameters.vertexOffset = vertexOffset;

@@ -87,7 +90,7 @@ private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) {
return yOffset1 << 16 | zOffset1 << 8 | xOffset1;
}

private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, Pipeline pipeline, double camX, double camY, double camZ, MemoryStack stack) {
private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, double camX, double camY, double camZ, MemoryStack stack) {
float xOffset = (float) (camX - (this.origin.x));
float yOffset = (float) (camY - (this.origin.y));
float zOffset = (float) (camZ - (this.origin.z));
@@ -98,10 +101,10 @@ private void updateChunkAreaOrigin(VkCommandBuffer commandBuffer, Pipeline pipel
byteBuffer.putFloat(4, -yOffset);
byteBuffer.putFloat(8, -zOffset);

vkCmdPushConstants(commandBuffer, pipeline.getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, byteBuffer);
vkCmdPushConstants(commandBuffer, Pipeline.getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, byteBuffer);
}

public void buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, StaticQueue<RenderSection> queue, TerrainRenderType terrainRenderType) {
public void buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, StaticQueue<DrawParameters> queue, TerrainRenderType terrainRenderType) {

try (MemoryStack stack = MemoryStack.stackPush()) {

@@ -113,15 +116,10 @@ public void buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, StaticQueue<
int drawCount = 0;
for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) {

final RenderSection section = iterator.next();
final DrawParameters drawParameters = section.getDrawParameters(terrainRenderType);

if (drawParameters.indexCount <= 0)
continue;

final DrawParameters drawParameters = iterator.next();
long ptr = bufferPtr + (drawCount * 20L);
MemoryUtil.memPutInt(ptr, drawParameters.indexCount);
MemoryUtil.memPutInt(ptr + 4, 1);
MemoryUtil.memPutInt(ptr + 4, drawParameters.instanceCount);
MemoryUtil.memPutInt(ptr + 8, drawParameters.firstIndex == -1 ? 0 : drawParameters.firstIndex);
MemoryUtil.memPutInt(ptr + 12, drawParameters.vertexOffset);
MemoryUtil.memPutInt(ptr + 16, drawParameters.baseInstance);
@@ -140,28 +138,24 @@ public void buildDrawBatchesIndirect(IndirectBuffer indirectBuffer, StaticQueue<

}

public void buildDrawBatchesDirect(StaticQueue<RenderSection> queue, TerrainRenderType renderType) {
public void buildDrawBatchesDirect(StaticQueue<DrawParameters> queue, TerrainRenderType renderType) {
boolean isTranslucent = renderType == TerrainRenderType.TRANSLUCENT;
VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();

for (var iterator = queue.iterator(isTranslucent); iterator.hasNext(); ) {
final RenderSection section = iterator.next();
final DrawParameters drawParameters = section.getDrawParameters(renderType);

if (drawParameters.indexCount <= 0)
continue;
final DrawParameters drawParameters = iterator.next();

final int firstIndex = drawParameters.firstIndex == -1 ? 0 : drawParameters.firstIndex;
vkCmdDrawIndexed(commandBuffer, drawParameters.indexCount, 1, firstIndex, drawParameters.vertexOffset, drawParameters.baseInstance);
vkCmdDrawIndexed(commandBuffer, drawParameters.indexCount, drawParameters.instanceCount, firstIndex, drawParameters.vertexOffset, drawParameters.baseInstance);
}
}

public void bindBuffers(VkCommandBuffer commandBuffer, Pipeline pipeline, TerrainRenderType terrainRenderType, double camX, double camY, double camZ) {
public void bindBuffers(VkCommandBuffer commandBuffer, TerrainRenderType terrainRenderType, double camX, double camY, double camZ) {

try (MemoryStack stack = MemoryStack.stackPush()) {
var vertexBuffer = getAreaBuffer(terrainRenderType);
nvkCmdBindVertexBuffers(commandBuffer, 0, 1, stack.npointer(vertexBuffer.getId()), stack.npointer(0));
updateChunkAreaOrigin(commandBuffer, pipeline, camX, camY, camZ, stack);
updateChunkAreaOrigin(commandBuffer, camX, camY, camZ, stack);
}

if (terrainRenderType == TerrainRenderType.TRANSLUCENT) {
@@ -195,14 +189,9 @@ public EnumMap<TerrainRenderType, AreaBuffer> getVertexBuffers() {
public AreaBuffer getIndexBuffer() {
return indexBuffer;
}

//instanceCount was added to encourage memcpy optimisations _(CPU doesn't need to insert a 1, which generates better ASM + helps JIT)_
public static class DrawParameters {
int indexCount = 0;
int firstIndex = -1;
int vertexOffset = -1;
int baseInstance;

public DrawParameters() {}
public int indexCount = 0, instanceCount = 1, firstIndex = -1, vertexOffset = -1, baseInstance;

public void reset(ChunkArea chunkArea, TerrainRenderType r) {
int segmentOffset = vertexOffset * VERTEX_SIZE;
45 changes: 14 additions & 31 deletions src/main/java/net/vulkanmod/render/chunk/buffer/UploadManager.java
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
import net.vulkanmod.vulkan.memory.StagingBuffer;
import net.vulkanmod.vulkan.queue.CommandPool;
import net.vulkanmod.vulkan.queue.Queue;
import net.vulkanmod.vulkan.queue.TransferQueue;
import static net.vulkanmod.vulkan.queue.Queue.TransferQueue;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.VkCommandBuffer;
import org.lwjgl.vulkan.VkMemoryBarrier;
@@ -24,7 +24,6 @@ public static void createInstance() {
INSTANCE = new UploadManager();
}

Queue queue = DeviceManager.getTransferQueue();
CommandPool.CommandBuffer commandBuffer;

LongOpenHashSet dstBuffers = new LongOpenHashSet();
@@ -33,32 +32,24 @@ public void submitUploads() {
if (this.commandBuffer == null)
return;

queue.submitCommands(this.commandBuffer);
TransferQueue.submitCommands(this.commandBuffer);
}

public void recordUpload(long bufferId, long dstOffset, long bufferSize, ByteBuffer src) {
if (this.commandBuffer == null)
this.commandBuffer = queue.beginCommands();
this.commandBuffer = TransferQueue.beginCommands();

VkCommandBuffer commandBuffer = this.commandBuffer.getHandle();

StagingBuffer stagingBuffer = Vulkan.getStagingBuffer();
stagingBuffer.copyBuffer((int) bufferSize, src);

if (!this.dstBuffers.add(bufferId)) {
try (MemoryStack stack = MemoryStack.stackPush()) {
VkMemoryBarrier.Buffer barrier = VkMemoryBarrier.calloc(1, stack);
barrier.sType$Default();
barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT);
barrier.dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT);

vkCmdPipelineBarrier(commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
barrier,
null,
null);
}
TransferQueue.MemoryBarrier(commandBuffer,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT);

this.dstBuffers.clear();
}
@@ -72,23 +63,15 @@ public void copyBuffer(Buffer src, Buffer dst) {

public void copyBuffer(Buffer src, int srcOffset, Buffer dst, int dstOffset, int size) {
if (this.commandBuffer == null)
this.commandBuffer = queue.beginCommands();
this.commandBuffer = TransferQueue.beginCommands();

VkCommandBuffer commandBuffer = this.commandBuffer.getHandle();

try (MemoryStack stack = MemoryStack.stackPush()) {
VkMemoryBarrier.Buffer barrier = VkMemoryBarrier.calloc(1, stack);
barrier.sType$Default();
barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT);
barrier.dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT);

vkCmdPipelineBarrier(commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
barrier,
null,
null);
}
TransferQueue.MemoryBarrier(commandBuffer,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT);

this.dstBuffers.clear();
this.dstBuffers.add(dst.getId());
19 changes: 4 additions & 15 deletions src/main/java/net/vulkanmod/render/chunk/build/TaskDispatcher.java
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Map;
import java.util.Queue;

public class TaskDispatcher {
@@ -150,26 +151,14 @@ public void scheduleSectionUpdate(CompileResult compileResult) {

private void doSectionUpdate(CompileResult compileResult) {
RenderSection section = compileResult.renderSection;
ChunkArea renderArea = section.getChunkArea();
DrawBuffers drawBuffers = renderArea.getDrawBuffers();
DrawBuffers drawBuffers = section.getChunkArea().getDrawBuffers();

if(compileResult.fullUpdate) {
var renderLayers = compileResult.renderedLayers;
for(TerrainRenderType renderType : TerrainRenderType.VALUES) {
UploadBuffer uploadBuffer = renderLayers.get(renderType);

if(uploadBuffer != null) {
drawBuffers.upload(section, uploadBuffer, renderType);
} else {
section.getDrawParameters(renderType).reset(renderArea, renderType);
}
}

compileResult.renderedLayers.forEach((key, uploadBuffer) -> drawBuffers.upload(section, uploadBuffer, key));
compileResult.updateSection();
}
else {
UploadBuffer uploadBuffer = compileResult.renderedLayers.get(TerrainRenderType.TRANSLUCENT);
drawBuffers.upload(section, uploadBuffer, TerrainRenderType.TRANSLUCENT);
drawBuffers.upload(section, compileResult.renderedLayers.get(TerrainRenderType.TRANSLUCENT), TerrainRenderType.TRANSLUCENT);
}
}

12 changes: 6 additions & 6 deletions src/main/java/net/vulkanmod/render/chunk/graph/SectionGraph.java
Original file line number Diff line number Diff line change
@@ -170,7 +170,7 @@ private void updateRenderChunks() {
continue;

if (!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
renderSection.getChunkArea().addDrawCmds(renderSection.getDrawParametersArray());
this.chunkAreaQueue.add(renderSection.getChunkArea());
this.nonEmptyChunks++;
}
@@ -200,10 +200,10 @@ private boolean notInFrustum(RenderSection renderSection) {
byte frustumRes = renderSection.getChunkArea().inFrustum(renderSection.frustumIndex);
if (frustumRes > FrustumIntersection.INTERSECT) {
return true;
} else if (frustumRes == FrustumIntersection.INTERSECT) {
if (!frustum.testFrustum(renderSection.xOffset, renderSection.yOffset, renderSection.zOffset,
renderSection.xOffset + 16, renderSection.yOffset + 16, renderSection.zOffset + 16))
return true;
}
if (frustumRes == FrustumIntersection.INTERSECT) {
return !frustum.testFrustum(renderSection.xOffset, renderSection.yOffset, renderSection.zOffset,
renderSection.xOffset + 16, renderSection.yOffset + 16, renderSection.zOffset + 16);
}
return false;
}
@@ -247,7 +247,7 @@ private void updateRenderChunksSpectator() {
if (notInFrustum(renderSection)) continue;

if (!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
renderSection.getChunkArea().addDrawCmds(renderSection.getDrawParametersArray());
this.chunkAreaQueue.add(renderSection.getChunkArea());
this.nonEmptyChunks++;
}
9 changes: 3 additions & 6 deletions src/main/java/net/vulkanmod/render/util/DrawUtil.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@
import com.mojang.blaze3d.vertex.*;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.shader.GraphicsPipeline;
import net.vulkanmod.vulkan.shader.Pipeline;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import net.vulkanmod.vulkan.texture.VulkanImage;
import org.joml.Matrix4f;
@@ -27,7 +26,7 @@ public static void drawTexQuad(BufferBuilder builder, double x0, double y0, doub

BufferBuilder.RenderedBuffer renderedBuffer = bufferbuilder.end();

Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount());
Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount(), 0);

}

@@ -42,15 +41,15 @@ public static void blitQuad(double x0, double y0, double x1, double y1) {

BufferBuilder.RenderedBuffer renderedBuffer = bufferbuilder.end();

Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount());
Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount(), 0);

}

public static void drawFramebuffer(GraphicsPipeline pipeline, VulkanImage attachment) {

Renderer.getInstance().bindGraphicsPipeline(pipeline);

VTextureSelector.bindTexture(attachment);
VTextureSelector.bindTexture(0, attachment, -1);

Matrix4f matrix4f = new Matrix4f().setOrtho(0.0F, 1.0F, 0.0F, 1.0F, 0.0F, 1.0F, true);
RenderSystem.setProjectionMatrix(matrix4f, VertexSorting.DISTANCE_TO_ORIGIN);
@@ -60,8 +59,6 @@ public static void drawFramebuffer(GraphicsPipeline pipeline, VulkanImage attach
RenderSystem.applyModelViewMatrix();
posestack.popPose();

Renderer.getInstance().uploadAndBindUBOs(pipeline);

blitQuad(0.0D, 0.0D, 1.0D, 1.0D);
}
}
52 changes: 43 additions & 9 deletions src/main/java/net/vulkanmod/vulkan/Drawer.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.mojang.blaze3d.vertex.VertexFormat;
import net.vulkanmod.vulkan.memory.*;
import net.vulkanmod.vulkan.shader.UniformState;
import net.vulkanmod.vulkan.util.VUtil;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.VkCommandBuffer;
@@ -13,8 +14,8 @@
import static org.lwjgl.vulkan.VK10.*;

public class Drawer {
private static final int INITIAL_VB_SIZE = 2000000;
private static final int INITIAL_UB_SIZE = 200000;
private static final int INITIAL_VB_SIZE = 1048576;
public static final int INITIAL_UB_SIZE = 1024;

private static final int MAX_QUAD_VERTICES_UINT16 = 65536 * 2 / 3;

@@ -34,6 +35,8 @@ public class Drawer {

private int currentFrame;

private int currentUniformOffset;

public Drawer() {
// Index buffers
this.quadsIndexBuffer = new AutoIndexBuffer(MAX_QUAD_VERTICES_UINT16, AutoIndexBuffer.DrawType.QUADS);
@@ -45,6 +48,7 @@ public Drawer() {

public void setCurrentFrame(int currentFrame) {
this.currentFrame = currentFrame;
this.currentUniformOffset = 0;
}

public void createResources(int framesNum) {
@@ -56,23 +60,23 @@ public void createResources(int framesNum) {
);
}
this.vertexBuffers = new VertexBuffer[framesNum];
Arrays.setAll(this.vertexBuffers, i -> new VertexBuffer(INITIAL_VB_SIZE, MemoryTypes.HOST_MEM));
Arrays.setAll(this.vertexBuffers, i -> new VertexBuffer(INITIAL_VB_SIZE, MemoryTypes.BAR_MEM));

if (this.uniformBuffers != null) {
Arrays.stream(this.uniformBuffers).iterator().forEachRemaining(
Buffer::freeBuffer
);
}
this.uniformBuffers = new UniformBuffer[framesNum];
Arrays.setAll(this.uniformBuffers, i -> new UniformBuffer(INITIAL_UB_SIZE, MemoryTypes.HOST_MEM));
Arrays.setAll(this.uniformBuffers, i -> new UniformBuffer(INITIAL_UB_SIZE, MemoryTypes.BAR_MEM));
}

public void resetBuffers(int currentFrame) {
this.vertexBuffers[currentFrame].reset();
this.uniformBuffers[currentFrame].reset();
}

public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexFormat, int vertexCount) {
public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexFormat, int vertexCount, int textureID) {
AutoIndexBuffer autoIndexBuffer;
int indexCount;

@@ -110,22 +114,52 @@ public void draw(ByteBuffer buffer, VertexFormat.Mode mode, VertexFormat vertexF
if (indexCount > 0) {
autoIndexBuffer.checkCapacity(vertexCount);

drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount);
drawIndexed(vertexBuffer, autoIndexBuffer.getIndexBuffer(), indexCount, textureID);
} else {
draw(vertexBuffer, vertexCount);
}

}

public void drawIndexed(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int indexCount) {
public void updateUniformOffset2(int currentUniformOffset1) {


//get the basealignment/offsets of the Base/Initial Uniform on the DescriptorSet
//TODO: manage alignment w/ varing offsets/uniforms : may use a uniform block system instead, but unconfirmed if overlapping ranges are problematic otoh
// final int currentUniformOffset1 = (UniformState.MVP.getOffsetFromHash()/64);

if(currentUniformOffset1<0) return;

currentUniformOffset = currentUniformOffset1;


currentUniformOffset &= 127;
}
public void updateUniformOffset() {


//get the basealignment/offsets of the Base/Initial Uniform on the DescriptorSet
//TODO: manage alignment w/ varing offsets/uniforms : may use a uniform block system instead, but unconfirmed if overlapping ranges are problematic otoh
final int currentUniformOffset1 = (UniformState.MVP.getOffsetFromHash()/64);

if(currentUniformOffset1<0) return;

currentUniformOffset = currentUniformOffset1;


currentUniformOffset &= 127;
}

public void drawIndexed(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int indexCount, int textureID) {
VkCommandBuffer commandBuffer = Renderer.getCommandBuffer();

VUtil.UNSAFE.putLong(pBuffers, vertexBuffer.getId());
VUtil.UNSAFE.putLong(pOffsets, vertexBuffer.getOffset());
nvkCmdBindVertexBuffers(commandBuffer, 0, 1, pBuffers, pOffsets);

vkCmdBindIndexBuffer(commandBuffer, indexBuffer.getId(), indexBuffer.getOffset(), VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, 0);
final int baseInstance = textureID << 16 | currentUniformOffset;
vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, baseInstance);
}

public void draw(VertexBuffer vertexBuffer, int vertexCount) {
@@ -135,7 +169,7 @@ public void draw(VertexBuffer vertexBuffer, int vertexCount) {
VUtil.UNSAFE.putLong(pOffsets, vertexBuffer.getOffset());
nvkCmdBindVertexBuffers(commandBuffer, 0, 1, pBuffers, pOffsets);

vkCmdDraw(commandBuffer, vertexCount, 1, 0, 0);
vkCmdDraw(commandBuffer, vertexCount, 1, 0, currentUniformOffset);
}

public void bindIndexBuffer(VkCommandBuffer commandBuffer, IndexBuffer indexBuffer) {
86 changes: 39 additions & 47 deletions src/main/java/net/vulkanmod/vulkan/Renderer.java
Original file line number Diff line number Diff line change
@@ -20,12 +20,12 @@
import net.vulkanmod.vulkan.shader.Pipeline;
import net.vulkanmod.vulkan.shader.PipelineState;
import net.vulkanmod.vulkan.shader.Uniforms;
import net.vulkanmod.vulkan.shader.layout.PushConstants;
import net.vulkanmod.vulkan.shader.*;
import net.vulkanmod.vulkan.shader.descriptor.DescriptorSetArray;
import net.vulkanmod.vulkan.texture.VTextureSelector;
import net.vulkanmod.vulkan.util.VUtil;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.*;

import java.nio.ByteBuffer;
@@ -52,6 +52,8 @@ public class Renderer {
private static boolean swapChainUpdate = false;
public static boolean skipRendering = false;

private final DescriptorSetArray descriptorSetArray;
private long boundPipeline;
public static void initRenderer() {
INSTANCE = new Renderer();
INSTANCE.init();
@@ -73,8 +75,7 @@ public static int getCurrentImage() {
return imageIndex;
}

private final Set<Pipeline> usedPipelines = new ObjectOpenHashSet<>();
private long boundPipeline;
private final Set<GraphicsPipeline> usedPipelines = new ObjectOpenHashSet<>();

private Drawer drawer;

@@ -90,7 +91,6 @@ public static int getCurrentImage() {

private static int currentFrame = 0;
private static int imageIndex;
private static int lastReset = -1;
private VkCommandBuffer currentCmdBuffer;
private boolean recordingCmds = false;

@@ -102,6 +102,9 @@ public Renderer() {
device = Vulkan.getVkDevice();
framesNum = Initializer.CONFIG.frameQueueSize;
imagesNum = getSwapChain().getImagesNum();

descriptorSetArray = new DescriptorSetArray();

}

public static void setLineWidth(float width) {
@@ -194,7 +197,15 @@ public void beginFrame() {
p.pop();
p.push("Frame_fence");

if (swapChainUpdate) {
if(recomp)
{
waitIdle();
usedPipelines.forEach(graphicsPipeline -> graphicsPipeline.updateSpecConstant(SPIRVUtils.SpecConstant.USE_FOG));
recomp=false;
}


if(swapChainUpdate) {
recreateSwapChain();
swapChainUpdate = false;

@@ -221,8 +232,10 @@ public void beginFrame() {

resetDescriptors();

//TODO: Move Descriptor binds to outside renderPass: not sure if it enables specific optimisations

currentCmdBuffer = commandBuffers.get(currentFrame);
vkResetCommandBuffer(currentCmdBuffer, 0);
// vkResetCommandBuffer(currentCmdBuffer, 0);
recordingCmds = true;

try (MemoryStack stack = stackPush()) {
@@ -254,6 +267,8 @@ public void beginFrame() {
throw new RuntimeException("Failed to begin recording command buffer:" + err);
}

this.descriptorSetArray.updateAndBind(currentFrame, drawer.getUniformBuffer().getId(), commandBuffer);

mainPass.begin(commandBuffer, stack);

vkCmdSetDepthBias(commandBuffer, 0.0F, 0.0F, 0.0F);
@@ -299,12 +314,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);
}

@@ -372,13 +386,6 @@ public void preInitFrame() {
p.round();
p.push("Frame_ops");

// runTick might be called recursively,
// this check forces sync to avoid upload corruption
if (lastReset == currentFrame) {
Synchronization.INSTANCE.waitFences();
}
lastReset = currentFrame;

drawer.resetBuffers(currentFrame);

Vulkan.getStagingBuffer().reset();
@@ -388,21 +395,20 @@ public void preInitFrame() {
UploadManager.INSTANCE.waitUploads();
}

public void addUsedPipeline(Pipeline pipeline) {
public void addUsedPipeline(GraphicsPipeline pipeline) {
usedPipelines.add(pipeline);
}

public void removeUsedPipeline(Pipeline pipeline) {
public void removeUsedPipeline(GraphicsPipeline pipeline) {
usedPipelines.remove(pipeline);
}

private void resetDescriptors() {
for (Pipeline pipeline : usedPipelines) {
pipeline.resetDescriptorPool(currentFrame);
}


usedPipelines.clear();
boundPipeline=0;
UniformState.resetAll();
}

void waitForSwapChain() {
@@ -425,7 +431,7 @@ private void recreateSwapChain() {
Synchronization.INSTANCE.waitFences();
Vulkan.waitIdle();

commandBuffers.forEach(commandBuffer -> vkResetCommandBuffer(commandBuffer, 0));
vkResetCommandPool(device, Vulkan.getCommandPool(), VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);

Vulkan.getSwapChain().recreate();

@@ -444,8 +450,6 @@ private void recreateSwapChain() {
createStagingBuffers();
allocateCommandBuffers();

Pipeline.recreateDescriptorSets(framesNum);

drawer.createResources(framesNum);
}

@@ -464,6 +468,8 @@ public void cleanUpResources() {

PipelineManager.destroyPipelines();
VTextureSelector.getWhiteTexture().free();

this.descriptorSetArray.cleanup();
}

private void destroySyncObjects() {
@@ -503,35 +509,18 @@ public void bindGraphicsPipeline(GraphicsPipeline pipeline) {

PipelineState currentState = PipelineState.getCurrentPipelineState(boundRenderPass);
final long handle = pipeline.getHandle(currentState);

if (boundPipeline == handle) {
this.checkUBOs(pipeline);
if(boundPipeline==handle) {
return;
}

vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, handle);
boundPipeline = handle;

boundPipeline=handle;
addUsedPipeline(pipeline);
return;
}

public void uploadAndBindUBOs(Pipeline pipeline) {
VkCommandBuffer commandBuffer = currentCmdBuffer;
pipeline.bindDescriptorSets(commandBuffer, currentFrame);
}

public void pushConstants(Pipeline pipeline) {
VkCommandBuffer commandBuffer = currentCmdBuffer;

PushConstants pushConstants = pipeline.getPushConstants();

try (MemoryStack stack = stackPush()) {
ByteBuffer buffer = stack.malloc(pushConstants.getSize());
long ptr = MemoryUtil.memAddress0(buffer);
pushConstants.update(ptr);

nvkCmdPushConstants(commandBuffer, pipeline.getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, pushConstants.getSize(), ptr);
}

private void checkUBOs(Pipeline pipeline) {
pipeline.pushUniforms(drawer.getUniformBuffer());
}

public static void setDepthBias(float units, float factor) {
@@ -702,6 +691,8 @@ public static int getFramesNum() {
return INSTANCE.framesNum;
}

public static DescriptorSetArray getDescriptorSetArray() { return INSTANCE.descriptorSetArray; }

public static VkCommandBuffer getCommandBuffer() {
return INSTANCE.currentCmdBuffer;
}
@@ -713,4 +704,5 @@ public static boolean isRecording() {
public static void scheduleSwapChainUpdate() {
swapChainUpdate = true;
}

}
6 changes: 2 additions & 4 deletions src/main/java/net/vulkanmod/vulkan/Synchronization.java
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ public class Synchronization {
private final LongBuffer fences;
private int idx = 0;

private ObjectArrayList<CommandPool.CommandBuffer> commandBuffers = new ObjectArrayList<>();
private final ObjectArrayList<CommandPool.CommandBuffer> 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();
109 changes: 51 additions & 58 deletions src/main/java/net/vulkanmod/vulkan/VRenderSystem.java
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import net.minecraft.client.Minecraft;
import net.vulkanmod.vulkan.device.DeviceManager;
import net.vulkanmod.vulkan.shader.PipelineState;
import net.vulkanmod.vulkan.shader.UniformState;
import net.vulkanmod.vulkan.util.ColorUtil;
import net.vulkanmod.vulkan.util.MappedBuffer;
import net.vulkanmod.vulkan.util.VUtil;
@@ -20,6 +21,12 @@
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import static net.vulkanmod.vulkan.shader.UniformState.MVP;
import static net.vulkanmod.vulkan.shader.UniformState.TextureMat;
import static org.lwjgl.opengl.GL11C.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.system.MemoryUtil.memAddress;
import static org.lwjgl.vulkan.VK10.vkCmdPushConstants;

public abstract class VRenderSystem {
private static long window;

@@ -33,27 +40,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);

public static MappedBuffer modelViewMatrix = new MappedBuffer(16 * 4);
public static MappedBuffer projectionMatrix = new MappedBuffer(16 * 4);
public static MappedBuffer TextureMatrix = new MappedBuffer(16 * 4);
public static MappedBuffer MVP = new MappedBuffer(16 * 4);

public static MappedBuffer ChunkOffset = new MappedBuffer(3 * 4);
public static MappedBuffer lightDirection0 = new MappedBuffer(3 * 4);
public static MappedBuffer lightDirection1 = new MappedBuffer(3 * 4);

public static MappedBuffer shaderColor = new MappedBuffer(4 * 4);
public static MappedBuffer shaderFogColor = new MappedBuffer(4 * 4);

public static MappedBuffer screenSize = new MappedBuffer(2 * 4);

private static final float[] checkedClearColor = new float[4];
public static float alphaCutout = 0.0f;

private static final float[] depthBias = new float[2];
@@ -66,99 +59,99 @@ public static void initRenderer() {

public static MappedBuffer getScreenSize() {
updateScreenSize();
return screenSize;
return UniformState.ScreenSize.getMappedBufferPtr();
}

public static void updateScreenSize() {
Window window = Minecraft.getInstance().getWindow();

screenSize.putFloat(0, (float) window.getWidth());
screenSize.putFloat(4, (float) window.getHeight());
UniformState.ScreenSize.getMappedBufferPtr().putFloat(0, window.getWidth());
UniformState.ScreenSize.getMappedBufferPtr().putFloat(4, window.getHeight());
}

public static void setWindow(long window) {
VRenderSystem.window = window;
}

public static ByteBuffer getChunkOffset() {
return ChunkOffset.buffer;
}

public static int maxSupportedTextureSize() {
return DeviceManager.deviceProperties.limits().maxImageDimension2D();
}

public static void applyMVP(Matrix4f MV, Matrix4f P) {
applyModelViewMatrix(MV);
applyProjectionMatrix(P);
MV.get(UniformState.ModelViewMat.buffer().asFloatBuffer());//MemoryUtil.memPutFloat(MemoryUtil.memAddress(modelViewMatrix), 1);
P.get(UniformState.ProjMat.buffer().asFloatBuffer());
calculateMVP();
}

public static void applyModelViewMatrix(Matrix4f mat) {
mat.get(modelViewMatrix.buffer.asFloatBuffer());
mat.get(UniformState.ModelViewMat.buffer().asFloatBuffer());

//MemoryUtil.memPutFloat(MemoryUtil.memAddress(modelViewMatrix), 1);
}

//TODO: SKip if Hashcode Matches
public static void applyProjectionMatrix(Matrix4f mat) {
mat.get(projectionMatrix.buffer.asFloatBuffer());
mat.get(UniformState.ProjMat.buffer().asFloatBuffer());
}

public static void calculateMVP() {
org.joml.Matrix4f MV = new org.joml.Matrix4f(modelViewMatrix.buffer.asFloatBuffer());
org.joml.Matrix4f P = new org.joml.Matrix4f(projectionMatrix.buffer.asFloatBuffer());
Matrix4f MV = new Matrix4f(UniformState.ModelViewMat.buffer().asFloatBuffer());
Matrix4f P = new Matrix4f(UniformState.ProjMat.buffer().asFloatBuffer());

P.mul(MV).get(MVP.buffer);
final Matrix4f mul = P.mul(MV);
mul.get(MVP.buffer());
MVP.needsUpdate(mul.hashCode());
}

public static void setTextureMatrix(Matrix4f mat) {
mat.get(TextureMatrix.buffer.asFloatBuffer());
}

public static MappedBuffer getTextureMatrix() {
return TextureMatrix;
}

public static MappedBuffer getModelViewMatrix() {
return modelViewMatrix;
}

public static MappedBuffer getProjectionMatrix() {
return projectionMatrix;
}

public static MappedBuffer getMVP() {
return MVP;
mat.get(TextureMat.buffer());
TextureMat.needsUpdate(mat.hashCode());
//
// if(!UniformState.TextureMat.hasUniqueHash())
// {
// UniformState.TextureMat.updateBank(Renderer.getDrawer().getUniformBuffer());
// }
}

public static void setChunkOffset(float f1, float f2, float f3) {
long ptr = ChunkOffset.ptr;
long ptr = UniformState.ChunkOffset.getMappedBufferPtr().ptr;
VUtil.UNSAFE.putFloat(ptr, f1);
VUtil.UNSAFE.putFloat(ptr + 4, f2);
VUtil.UNSAFE.putFloat(ptr + 8, f3);
}

public static void setShaderColor(float f1, float f2, float f3, float f4) {
ColorUtil.setRGBA_Buffer(shaderColor, f1, f2, f3, f4);
}

}
//TOOD: Schedule update when actually unique data has been provided
public static void setShaderFogColor(float f1, float f2, float f3, float f4) {
ColorUtil.setRGBA_Buffer(shaderFogColor, f1, f2, f3, f4);
ColorUtil.setRGBA_Buffer(UniformState.FogColor.getMappedBufferPtr(), f1, f2, f3, f4);
UniformState.FogColor.setUpdateState(true);
}

public static MappedBuffer getShaderColor() {
return shaderColor;
public static MappedBuffer getShaderFogColor() {
return UniformState.FogColor.getMappedBufferPtr();
}

public static MappedBuffer getShaderFogColor() {
return shaderFogColor;
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;
}

public static void clearColor(float f1, float f2, float f3, float f4) {
ColorUtil.setRGBA_Buffer(clearColor, f1, f2, f3, f4);
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 are much much 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
21 changes: 10 additions & 11 deletions src/main/java/net/vulkanmod/vulkan/Vulkan.java
Original file line number Diff line number Diff line change
@@ -5,10 +5,11 @@
import net.vulkanmod.vulkan.framebuffer.SwapChain;
import net.vulkanmod.vulkan.memory.Buffer;
import net.vulkanmod.vulkan.memory.MemoryManager;
import net.vulkanmod.vulkan.memory.MemoryTypes;
import net.vulkanmod.vulkan.memory.StagingBuffer;
import net.vulkanmod.vulkan.queue.Queue;
import net.vulkanmod.vulkan.queue.QueueFamilyIndices;
import net.vulkanmod.vulkan.shader.Pipeline;
import net.vulkanmod.vulkan.texture.SamplerManager;
import net.vulkanmod.vulkan.util.VUtil;
import net.vulkanmod.vulkan.util.VkResult;
import org.lwjgl.PointerBuffer;
@@ -22,7 +23,6 @@
import java.util.*;

import static java.util.stream.Collectors.toSet;
import static net.vulkanmod.vulkan.queue.Queue.getQueueFamilies;
import static net.vulkanmod.vulkan.util.VUtil.asPointerBuffer;
import static org.lwjgl.glfw.GLFWVulkan.glfwCreateWindowSurface;
import static org.lwjgl.glfw.GLFWVulkan.glfwGetRequiredInstanceExtensions;
@@ -35,7 +35,7 @@
import static org.lwjgl.vulkan.KHRDynamicRendering.VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK12.VK_API_VERSION_1_2;
import static org.lwjgl.vulkan.VK13.VK_API_VERSION_1_3;

public class Vulkan {

@@ -146,7 +146,7 @@ public static void initVulkan(long window) {
DeviceManager.init(instance);

createVma();
MemoryTypes.createMemoryTypes();
// MemoryTypes.createMemoryTypes();

createCommandPool();
allocateImmediateCmdBuffer();
@@ -164,8 +164,8 @@ static void createStagingBuffers() {

stagingBuffers = new StagingBuffer[Renderer.getFramesNum()];

for (int i = 0; i < stagingBuffers.length; ++i) {
stagingBuffers[i] = new StagingBuffer(30 * 1024 * 1024);
for(int i = 0; i < stagingBuffers.length; ++i) {
stagingBuffers[i] = new StagingBuffer(33554432);
}
}

@@ -201,6 +201,7 @@ public static void cleanUp() {

vmaDestroyAllocator(allocator);

SamplerManager.cleanUp();
DeviceManager.destroy();
destroyDebugUtilsMessengerEXT(instance, debugMessenger, null);
KHRSurface.vkDestroySurfaceKHR(instance, surface, null);
@@ -228,7 +229,7 @@ private static void createInstance() {
appInfo.applicationVersion(VK_MAKE_VERSION(1, 0, 0));
appInfo.pEngineName(stack.UTF8Safe("VulkanMod Engine"));
appInfo.engineVersion(VK_MAKE_VERSION(1, 0, 0));
appInfo.apiVersion(VK_API_VERSION_1_2);
appInfo.apiVersion(VK_API_VERSION_1_3);

VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.calloc(stack);

@@ -330,7 +331,7 @@ private static void createVma() {
allocatorCreateInfo.device(DeviceManager.vkDevice);
allocatorCreateInfo.pVulkanFunctions(vulkanFunctions);
allocatorCreateInfo.instance(instance);
allocatorCreateInfo.vulkanApiVersion(VK_API_VERSION_1_2);
allocatorCreateInfo.vulkanApiVersion(VK_API_VERSION_1_3);

PointerBuffer pAllocator = stack.pointers(VK_NULL_HANDLE);

@@ -345,11 +346,9 @@ private static void createCommandPool() {

try (MemoryStack stack = stackPush()) {

Queue.QueueFamilyIndices queueFamilyIndices = getQueueFamilies();

VkCommandPoolCreateInfo poolInfo = VkCommandPoolCreateInfo.calloc(stack);
poolInfo.sType(VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO);
poolInfo.queueFamilyIndex(queueFamilyIndices.graphicsFamily);
poolInfo.queueFamilyIndex(QueueFamilyIndices.graphicsFamily);
poolInfo.flags(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);

LongBuffer pCommandPool = stack.mallocLong(1);
75 changes: 50 additions & 25 deletions src/main/java/net/vulkanmod/vulkan/device/Device.java
Original file line number Diff line number Diff line change
@@ -15,57 +15,70 @@
import static org.lwjgl.glfw.GLFW.glfwGetPlatform;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK11.vkEnumerateInstanceVersion;
import static org.lwjgl.vulkan.VK11.vkGetPhysicalDeviceFeatures2;
import static org.lwjgl.vulkan.VK11.*;

public class Device {
final VkPhysicalDevice physicalDevice;
final VkPhysicalDeviceProperties properties;
final VkPhysicalDeviceProperties2 properties;

private final int vendorId;
public final String vendorIdString;
public final String deviceName;
public final String driverVersion;
public final String vkVersion;

public final VkPhysicalDeviceFeatures2 availableFeatures;
public final VkPhysicalDeviceVulkan11Features availableFeatures11;

// public final VkPhysicalDeviceVulkan13Features availableFeatures13;
// public final VkPhysicalDeviceVulkan13Features availableFeatures13;
// public final boolean vulkan13Support;

private boolean drawIndirectSupported;
private final boolean drawIndirectSupported, hasIndexedDescriptors, hasSamplerAnisotropy, hasLogicOp;

public Device(VkPhysicalDevice device) {
this.physicalDevice = device;
try(MemoryStack stack = MemoryStack.stackPush()) {
this.physicalDevice = device;

VkPhysicalDeviceSubgroupProperties subgroupProperties = VkPhysicalDeviceSubgroupProperties.calloc(stack).sType$Default();

properties = VkPhysicalDeviceProperties.malloc();
vkGetPhysicalDeviceProperties(physicalDevice, properties);
properties = VkPhysicalDeviceProperties2.calloc().sType$Default().pNext(subgroupProperties);
VK11.vkGetPhysicalDeviceProperties2(physicalDevice, properties);

this.vendorId = properties.vendorID();
this.vendorIdString = decodeVendor(properties.vendorID());
this.deviceName = properties.deviceNameString();
this.driverVersion = decodeDvrVersion(properties.driverVersion(), properties.vendorID());
this.vkVersion = decDefVersion(getVkVer());
this.vendorId = properties.properties().vendorID();
this.vendorIdString = decodeVendor(properties.properties().vendorID());
this.deviceName = properties.properties().deviceNameString();
this.driverVersion = decodeDvrVersion(properties.properties().driverVersion(), properties.properties().vendorID());
this.vkVersion = decDefVersion(getVkVer());

this.availableFeatures = VkPhysicalDeviceFeatures2.calloc();
this.availableFeatures.sType$Default();
VkPhysicalDeviceFeatures2 availableFeatures = VkPhysicalDeviceFeatures2.calloc(stack);
availableFeatures.sType$Default();

this.availableFeatures11 = VkPhysicalDeviceVulkan11Features.malloc();
this.availableFeatures11.sType$Default();
this.availableFeatures.pNext(this.availableFeatures11);
VkPhysicalDeviceVulkan12Features availableFeatures12 = VkPhysicalDeviceVulkan12Features.malloc(stack).sType$Default();

//Vulkan 1.3
VkPhysicalDeviceVulkan11Features availableFeatures11 = VkPhysicalDeviceVulkan11Features.malloc(stack).sType$Default();
availableFeatures.pNext(availableFeatures12);
availableFeatures.pNext(availableFeatures11);

//Vulkan 1.3
// this.availableFeatures13 = VkPhysicalDeviceVulkan13Features.malloc();
// this.availableFeatures13.sType$Default();
// this.availableFeatures11.pNext(this.availableFeatures13.address());
//
// this.vulkan13Support = this.device.getCapabilities().apiVersion == VK_API_VERSION_1_3;

vkGetPhysicalDeviceFeatures2(this.physicalDevice, this.availableFeatures);
vkGetPhysicalDeviceFeatures2(this.physicalDevice, availableFeatures);


if (this.availableFeatures.features().multiDrawIndirect() && this.availableFeatures11.shaderDrawParameters())
this.drawIndirectSupported = true;
this.drawIndirectSupported = availableFeatures.features().multiDrawIndirect() && availableFeatures11.shaderDrawParameters();
this.hasIndexedDescriptors = availableFeatures12.runtimeDescriptorArray() && availableFeatures12.descriptorBindingVariableDescriptorCount() && availableFeatures12.descriptorBindingPartiallyBound();
this.hasSamplerAnisotropy = availableFeatures.features().samplerAnisotropy();
this.hasLogicOp = availableFeatures.features().logicOp();
//TODO: Handle specific Mac drivers not supporting Subgroup Ballot
//E.g. Macros/Spec Constant workarounds
final int subGroupStages = subgroupProperties.supportedStages();
final int subGroupOps = subgroupProperties.supportedOperations();
if((subGroupStages&VK_SHADER_STAGE_FRAGMENT_BIT)==0 ||(subGroupOps&VK_SUBGROUP_FEATURE_BALLOT_BIT)==0)
throw new RuntimeException("Uniform texture broadcast optimization not available!");


}

}

@@ -146,6 +159,10 @@ public boolean isDrawIndirectSupported() {
return drawIndirectSupported;
}

public boolean isHasIndexedDescriptors() {
return hasIndexedDescriptors;
}

// Added these to allow detecting GPU vendor, to allow handling vendor specific circumstances:
// (e.g. such as in case we encounter a vendor specific driver bug)
public boolean isAMD() {
@@ -159,4 +176,12 @@ public boolean isNvidia() {
public boolean isIntel() {
return vendorId == 0x8086;
}

public boolean hasSamplerAnisotropy() {
return this.hasSamplerAnisotropy;
}

public boolean hasLogicOp() {
return this.hasLogicOp;
}
}
129 changes: 62 additions & 67 deletions src/main/java/net/vulkanmod/vulkan/device/DeviceManager.java
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
import net.vulkanmod.Initializer;
import net.vulkanmod.vulkan.VRenderSystem;
import net.vulkanmod.vulkan.Vulkan;
import net.vulkanmod.vulkan.device.Device;
import net.vulkanmod.vulkan.queue.*;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
@@ -12,17 +13,18 @@
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static java.util.stream.Collectors.toSet;
import static net.vulkanmod.vulkan.queue.Queue.findQueueFamilies;
import static net.vulkanmod.vulkan.queue.Queue.*;
import static net.vulkanmod.vulkan.util.VUtil.asPointerBuffer;
import static org.lwjgl.glfw.GLFWVulkan.glfwGetRequiredInstanceExtensions;
import static org.lwjgl.system.MemoryStack.stackGet;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.vulkan.EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
import static org.lwjgl.vulkan.KHRSurface.*;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK12.VK_API_VERSION_1_2;
import static org.lwjgl.vulkan.VK13.VK_API_VERSION_1_3;

public abstract class DeviceManager {
public static List<Device> availableDevices;
@@ -38,11 +40,6 @@ public abstract class DeviceManager {

public static SurfaceProperties surfaceProperties;

static GraphicsQueue graphicsQueue;
static PresentQueue presentQueue;
static TransferQueue transferQueue;
static ComputeQueue computeQueue;

public static void init(VkInstance instance) {
try {
DeviceManager.pickPhysicalDevice(instance);
@@ -110,9 +107,9 @@ public static void pickPhysicalDevice(VkInstance instance) {
}

physicalDevice = DeviceManager.device.physicalDevice;

QueueFamilyIndices.findQueueFamilies(physicalDevice);
// Get device properties
deviceProperties = device.properties;
deviceProperties = device.properties.properties();

memoryProperties = VkPhysicalDeviceMemoryProperties.malloc();
vkGetPhysicalDeviceMemoryProperties(physicalDevice, memoryProperties);
@@ -131,7 +128,7 @@ static Device autoPickDevice() {
for (Device device : suitableDevices) {
currentDevice = device;

int deviceType = device.properties.deviceType();
int deviceType = device.properties.properties().deviceType();
if (deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
flag = true;
break;
@@ -157,9 +154,7 @@ else if (!otherDevices.isEmpty())
public static void createLogicalDevice() {
try (MemoryStack stack = stackPush()) {

net.vulkanmod.vulkan.queue.Queue.QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

int[] uniqueQueueFamilies = indices.unique();
int[] uniqueQueueFamilies = QueueFamilyIndices.unique();

VkDeviceQueueCreateInfo.Buffer queueCreateInfos = VkDeviceQueueCreateInfo.calloc(uniqueQueueFamilies.length, stack);

@@ -169,70 +164,71 @@ public static void createLogicalDevice() {
queueCreateInfo.queueFamilyIndex(uniqueQueueFamilies[i]);
queueCreateInfo.pQueuePriorities(stack.floats(1.0f));
}

VkPhysicalDeviceVulkan11Features deviceVulkan11Features = VkPhysicalDeviceVulkan11Features.calloc(stack);
deviceVulkan11Features.sType$Default();
deviceVulkan11Features.shaderDrawParameters(device.isDrawIndirectSupported());
VkPhysicalDeviceShaderDrawParameterFeatures shaderDrawParameterFeatures = VkPhysicalDeviceShaderDrawParameterFeatures.calloc(stack).sType$Default();

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().samplerAnisotropy(device.hasSamplerAnisotropy());
deviceFeatures.features().logicOp(device.hasLogicOp());
deviceFeatures.features().multiDrawIndirect(device.isDrawIndirectSupported());
shaderDrawParameterFeatures.shaderDrawParameters(device.isDrawIndirectSupported());

final boolean hasIndexedDescriptors = device.isHasIndexedDescriptors();
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = VkPhysicalDeviceDescriptorIndexingFeatures.calloc(stack)
.sType$Default()
.runtimeDescriptorArray(hasIndexedDescriptors)
.descriptorBindingPartiallyBound(hasIndexedDescriptors)
//
// .descriptorBindingSampledImageUpdateAfterBind(false)
// .descriptorBindingUniformBufferUpdateAfterBind(false)
//
.descriptorBindingVariableDescriptorCount(hasIndexedDescriptors);
// .descriptorBindingUpdateUnusedWhilePending(false)
//
// .shaderSampledImageArrayNonUniformIndexing(false);

VkPhysicalDeviceInlineUniformBlockFeatures inlineUniformBlockFeatures = VkPhysicalDeviceInlineUniformBlockFeatures.calloc(stack)
.sType$Default()
.inlineUniformBlock(true)
.descriptorBindingInlineUniformBlockUpdateAfterBind(false); //TODO: Interestingly inlineUniformBlock has wider support for Update After bind than Uniform buffers

// Must not set line width to anything other than 1.0 if this is not supported
/* // 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;
}
deviceFeatures.features().wideLines(false);
VRenderSystem.canSetLineWidth = false;
}*/

VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.calloc(stack);
createInfo.sType$Default();
createInfo.sType(VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
createInfo.pQueueCreateInfos(queueCreateInfos);
createInfo.pNext(descriptorIndexingFeatures).pNext(inlineUniformBlockFeatures).pNext(shaderDrawParameterFeatures);
createInfo.pEnabledFeatures(deviceFeatures.features());
createInfo.pNext(deviceVulkan11Features);

if (Vulkan.DYNAMIC_RENDERING) {
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeaturesKHR = VkPhysicalDeviceDynamicRenderingFeaturesKHR.calloc(stack);
dynamicRenderingFeaturesKHR.sType$Default();
dynamicRenderingFeaturesKHR.dynamicRendering(true);

deviceVulkan11Features.pNext(dynamicRenderingFeaturesKHR.address());

// //Vulkan 1.3 dynamic rendering
// VkPhysicalDeviceVulkan13Features deviceVulkan13Features = VkPhysicalDeviceVulkan13Features.calloc(stack);
// deviceVulkan13Features.sType$Default();
// if(!deviceInfo.availableFeatures13.dynamicRendering())
// throw new RuntimeException("Device does not support dynamic rendering feature.");
//
// deviceVulkan13Features.dynamicRendering(true);
// createInfo.pNext(deviceVulkan13Features);
// deviceVulkan13Features.pNext(deviceVulkan11Features.address());
}

createInfo.ppEnabledExtensionNames(asPointerBuffer(Vulkan.REQUIRED_EXTENSION));

// Configuration.DEBUG_FUNCTIONS.set(true);

createInfo.ppEnabledLayerNames(Vulkan.ENABLE_VALIDATION_LAYERS ? asPointerBuffer(Vulkan.VALIDATION_LAYERS) : null);

PointerBuffer pDevice = stack.pointers(VK_NULL_HANDLE);

int res = vkCreateDevice(physicalDevice, createInfo, null, pDevice);
Vulkan.checkResult(res, "Failed to create logical device");

vkDevice = new VkDevice(pDevice.get(0), physicalDevice, createInfo, VK_API_VERSION_1_2);
vkDevice = new VkDevice(pDevice.get(0), physicalDevice, createInfo, VK_API_VERSION_1_3);

// PointerBuffer pQueue = stack.pointers(VK_NULL_HANDLE);
//
// vkGetDeviceQueue(device, indices.graphicsFamily, 0, pQueue);
// graphicsQueue = new VkQueue(pQueue.get(0), device);
//
// vkGetDeviceQueue(device, indices.presentFamily, 0, pQueue);
// presentQueue = new VkQueue(pQueue.get(0), device);
//
// vkGetDeviceQueue(device, indices.transferFamily, 0, pQueue);
// transferQueue = new VkQueue(pQueue.get(0), device);

graphicsQueue = new GraphicsQueue(stack, indices.graphicsFamily);
transferQueue = new TransferQueue(stack, indices.transferFamily);
presentQueue = new PresentQueue(stack, indices.presentFamily);
computeQueue = new ComputeQueue(stack, indices.computeFamily);
}
}

private static PointerBuffer getRequiredExtensions() {

PointerBuffer glfwExtensions = glfwGetRequiredInstanceExtensions();

if (Vulkan.ENABLE_VALIDATION_LAYERS) {
@@ -253,7 +249,6 @@ private static PointerBuffer getRequiredExtensions() {

private static boolean isDeviceSuitable(VkPhysicalDevice device) {
try (MemoryStack stack = stackPush()) {
Queue.QueueFamilyIndices indices = findQueueFamilies(device);

VkExtensionProperties.Buffer availableExtensions = getAvailableExtension(stack, device);
boolean extensionsSupported = availableExtensions.stream()
@@ -272,7 +267,7 @@ private static boolean isDeviceSuitable(VkPhysicalDevice device) {
vkGetPhysicalDeviceFeatures(device, supportedFeatures);
boolean anisotropicFilterSupported = supportedFeatures.samplerAnisotropy();

return indices.isSuitable() && extensionsSupported && swapChainAdequate;
return extensionsSupported && swapChainAdequate;
}
}

@@ -343,28 +338,28 @@ static void logUnsupportedExtensions() {
}

public static void destroy() {
graphicsQueue.cleanUp();
transferQueue.cleanUp();
computeQueue.cleanUp();
GraphicsQueue.cleanUp();
TransferQueue.cleanUp();
PresentQueue.cleanUp();

vkDestroyDevice(vkDevice, null);
}

public static GraphicsQueue getGraphicsQueue() {
return graphicsQueue;
public static Queue getGraphicsQueue() {
return GraphicsQueue;
}

public static PresentQueue getPresentQueue() {
return presentQueue;
public static Queue getPresentQueue() {
return PresentQueue;
}

public static TransferQueue getTransferQueue() {
return transferQueue;
public static Queue getTransferQueue() {
return TransferQueue;
}

public static ComputeQueue getComputeQueue() {
return computeQueue;
}
// public static ComputeQueue getComputeQueue() {
// return computeQueue;
// }

public static SurfaceProperties querySurfaceProperties(VkPhysicalDevice device, MemoryStack stack) {

Loading