From 9c821b2fd613796541f176886d466777c65f4d55 Mon Sep 17 00:00:00 2001 From: xirreal Date: Sat, 16 Sep 2023 18:18:13 +0200 Subject: [PATCH 1/7] Support 1d/3d textures + vk binding custom texture --- .../java/me/cortex/vulkanite/client/Test.java | 6 +- .../client/rendering/VulkanPipeline.java | 18 +++- .../vulkanite/compat/IGlTextureVkGetter.java | 7 ++ .../vulkanite/lib/memory/MemoryManager.java | 58 ++++++++--- .../cortex/vulkanite/lib/memory/VGImage.java | 4 +- .../cortex/vulkanite/lib/memory/VImage.java | 17 +++- .../vulkanite/lib/other/FormatConverter.java | 44 +++++++++ .../vulkanite/lib/other/VImageView.java | 9 +- .../vulkanite/mixin/iris/MixinGlResource.java | 48 ++++++++++ .../vulkanite/mixin/iris/MixinGlTexture.java | 95 +++++++++++++++++++ .../iris/MixinNewWorldRenderingPipeline.java | 15 ++- .../mixin/iris/MixinPBRAtlasTexture.java | 1 + .../mixin/iris/MixinRenderTarget.java | 24 ++--- .../minecraft/MixinSpriteAtlasTexture.java | 1 + src/main/resources/vulkanite.mixins.json | 2 + 15 files changed, 308 insertions(+), 41 deletions(-) create mode 100644 src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java create mode 100644 src/main/java/me/cortex/vulkanite/lib/other/FormatConverter.java create mode 100644 src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlResource.java create mode 100644 src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java diff --git a/src/main/java/me/cortex/vulkanite/client/Test.java b/src/main/java/me/cortex/vulkanite/client/Test.java index 2fee9ee..c651433 100644 --- a/src/main/java/me/cortex/vulkanite/client/Test.java +++ b/src/main/java/me/cortex/vulkanite/client/Test.java @@ -110,9 +110,9 @@ public static void main(String[] args) throws IOException { context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); - context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); - context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); - context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); + context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); + context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); + context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free(); context.memory.createAcceleration(100*256,256, 0, VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR).free(); var pool = context.cmd.createSingleUsePool(); pool.createCommandBuffer(); diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java index fa9fd8c..58b87c2 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java @@ -60,6 +60,7 @@ public class VulkanPipeline { private final VSampler sampler; private final SharedImageViewTracker composite0mainView; + private final SharedImageViewTracker customTextureView; private final SharedImageViewTracker blockAtlasView; private final SharedImageViewTracker blockAtlasNormalView; private final SharedImageViewTracker blockAtlasSpecularView; @@ -76,6 +77,7 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray { this.composite0mainView = new SharedImageViewTracker(ctx, null); + this.customTextureView = new SharedImageViewTracker(ctx, null); this.blockAtlasView = new SharedImageViewTracker(ctx, ()->{ AbstractTexture blockAtlas = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier("minecraft", "textures/atlas/blocks.png")); return ((IVGImage)blockAtlas).getVGImage(); @@ -90,7 +92,7 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray PBRTextureHolder holder = PBRTextureManager.INSTANCE.getOrLoadHolder(blockAtlas.getGlId());//((TextureAtlasExtension)blockAtlas).getPBRHolder() return ((IVGImage)holder.getSpecularTexture()).getVGImage(); }); - this.placeholderImage = ctx.memory.creatImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + this.placeholderImage = ctx.memory.createImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); this.placeholderImageView = new VImageView(ctx, placeholderImage); try (var stack = stackPush()) { @@ -128,6 +130,7 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture normal .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture specular + .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//custom texture sampler .build(ctx); //TODO: use frameahead count instead of just... 10 @@ -162,7 +165,7 @@ private static void applyImageBarrier(VkImageMemoryBarrier barrier, VImage image private VSemaphore previousSemaphore; private int frameId; - public void renderPostShadows(VGImage outImg, Camera camera) { + public void renderPostShadows(VGImage outImg, VGImage customTexture, Camera camera) { this.singleUsePool.doReleases(); PBRTextureManager.notifyPBRTexturesChanged(); @@ -210,15 +213,18 @@ public void renderPostShadows(VGImage outImg, Camera camera) { bb.putInt(Float.BYTES * 40, frameId++); + System.out.println(frameId); + int flags = Uniforms.isEyeInWater()&3; bb.putInt(Float.BYTES * 41, flags); + bb.rewind(); } uboBuffer.unmap(); uboBuffer.flush(); long desc = descriptors.get(fidx); - new DescriptorUpdateBuilder(ctx, 7, placeholderImageView) + new DescriptorUpdateBuilder(ctx, 8, placeholderImageView) .set(desc) .uniform(0, uboBuffer) .acceleration(1, tlas) @@ -227,6 +233,7 @@ public void renderPostShadows(VGImage outImg, Camera camera) { .imageSampler(4, blockAtlasView.getView(), sampler) .imageSampler(5, blockAtlasNormalView.getView(), sampler) .imageSampler(6, blockAtlasSpecularView.getView(), sampler) + .imageSampler(7, customTextureView.getView(()->customTexture), sampler) .apply(); @@ -235,13 +242,15 @@ public void renderPostShadows(VGImage outImg, Camera camera) { cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); try (var stack = stackPush()) { - var barriers = VkImageMemoryBarrier.calloc(4, stack); + var barriers = VkImageMemoryBarrier.calloc(5, stack); applyImageBarrier(barriers.get(), composite0mainView.getImage(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_WRITE_BIT); applyImageBarrier(barriers.get(), blockAtlasView.getImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); var image = blockAtlasNormalView.getImage(); if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); image = blockAtlasSpecularView.getImage(); if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); + image = customTextureView.getImage(); + if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); barriers.limit(barriers.position()); barriers.rewind(); vkCmdPipelineBarrier(cmd.buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, null, null, barriers); @@ -294,6 +303,7 @@ public void destory() { previousSemaphore.free(); } composite0mainView.free(); + customTextureView.free(); blockAtlasView.free(); blockAtlasNormalView.free(); blockAtlasSpecularView.free(); diff --git a/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java b/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java new file mode 100644 index 0000000..c5fb269 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java @@ -0,0 +1,7 @@ +package me.cortex.vulkanite.compat; + +import me.cortex.vulkanite.lib.memory.VGImage; + +public interface IGlTextureVkGetter { + VGImage getImage(); +} diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java index 55bfac9..ff569a5 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/MemoryManager.java @@ -21,6 +21,8 @@ import static org.lwjgl.opengl.EXTMemoryObjectWin32.glImportMemoryWin32HandleEXT; import static org.lwjgl.opengl.EXTSemaphoreWin32.GL_HANDLE_TYPE_OPAQUE_WIN32_EXT; import static org.lwjgl.opengl.GL11C.*; +import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D; +import static org.lwjgl.opengl.GL12.GL_TEXTURE_WRAP_R; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.util.vma.Vma.*; import static org.lwjgl.vulkan.KHRAccelerationStructure.VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; @@ -125,7 +127,19 @@ public VGBuffer createSharedBuffer(long size, int usage, int properties, int ali } } - public VGImage createSharedImage(int width, int height, int mipLevels, int vkFormat, int glFormat, int usage, int properties) { + public VGImage createSharedImage(int width, int height, int depth, int mipLevels, int vkFormat, int glFormat, int usage, int properties) { + + int vkImageType = VK_IMAGE_TYPE_2D; + int glImageType = GL_TEXTURE_2D; + + if(height == 1 && depth == 1) { + vkImageType = VK_IMAGE_TYPE_1D; + glImageType = GL_TEXTURE_1D; + } else if (height != 1 && depth != 1) { + vkImageType = VK_IMAGE_TYPE_3D; + glImageType = GL_TEXTURE_3D; + } + try (var stack = stackPush()) { var createInfo = VkImageCreateInfo .calloc(stack) @@ -135,14 +149,14 @@ public VGImage createSharedImage(int width, int height, int mipLevels, int vkFor .sType$Default() .handleTypes(EXTERNAL_MEMORY_HANDLE_TYPE)) .format(vkFormat) - .imageType(VK_IMAGE_TYPE_2D) + .imageType(vkImageType) .mipLevels(mipLevels) .arrayLayers(1) .tiling(VK_IMAGE_TILING_OPTIMAL) .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED) .usage(usage) .samples(VK_SAMPLE_COUNT_1_BIT); - createInfo.extent().width(width).height(height).depth(1); + createInfo.extent().width(width).height(height).depth(depth); var alloc = shared.alloc(createInfo, VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) @@ -152,16 +166,34 @@ public VGImage createSharedImage(int width, int height, int mipLevels, int vkFor int memoryObject = glCreateMemoryObjectsEXT(); long handle = importMemory(memoryObject, alloc); - int glId = glCreateTextures(GL_TEXTURE_2D); - - glTextureStorageMem2DEXT(glId, mipLevels, glFormat, width, height, memoryObject, alloc.ai.offset()); - glTextureParameteri(glId, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTextureParameteri(glId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTextureParameteri(glId, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTextureParameteri(glId, GL_TEXTURE_WRAP_T, GL_REPEAT); + int glId = glCreateTextures(glImageType); + + switch(glImageType) { + case GL_TEXTURE_1D: + glTextureStorageMem1DEXT(glId, mipLevels, glFormat, width, memoryObject, alloc.ai.offset()); + glTextureParameteri(glId, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_WRAP_S, GL_REPEAT); + break; + case GL_TEXTURE_2D: + glTextureStorageMem2DEXT(glId, mipLevels, glFormat, width, height, memoryObject, alloc.ai.offset()); + glTextureParameteri(glId, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTextureParameteri(glId, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case GL_TEXTURE_3D: + glTextureStorageMem3DEXT(glId, mipLevels, glFormat, width, height, depth, memoryObject, alloc.ai.offset()); + glTextureParameteri(glId, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTextureParameteri(glId, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTextureParameteri(glId, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTextureParameteri(glId, GL_TEXTURE_WRAP_R, GL_REPEAT); + break; + } _CHECK_GL_ERROR_(); - return new VGImage(alloc, width, height, mipLevels, vkFormat, glFormat, glId, memoryObject, handle); + return new VGImage(alloc, width, height, depth, mipLevels, vkFormat, glFormat, glId, memoryObject, handle); } } @@ -184,7 +216,7 @@ public VBuffer createBuffer(long size, int usage, int properties, long alignment } } - public VImage creatImage2D(int width, int height, int mipLevels, int vkFormat, int usage, int properties) { + public VImage createImage2D(int width, int height, int mipLevels, int vkFormat, int usage, int properties) { try (var stack = stackPush()) { var alloc = allocator.alloc(0, VkImageCreateInfo .calloc(stack) @@ -201,7 +233,7 @@ public VImage creatImage2D(int width, int height, int mipLevels, int vkFormat, i VmaAllocationCreateInfo.calloc(stack) .usage(VMA_MEMORY_USAGE_AUTO) .requiredFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); - return new VImage(alloc, width, height, mipLevels, vkFormat); + return new VImage(alloc, width, height, 1, mipLevels, vkFormat); } } diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java b/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java index 781449e..91e5b5b 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VGImage.java @@ -10,8 +10,8 @@ public class VGImage extends VImage { public final int glFormat; private final long handle; - VGImage(VmaAllocator.ImageAllocation allocation, int width, int height, int mipLayers, int format, int glFormat, int glId, int glMemObj, long handle) { - super(allocation, width, height, mipLayers, format); + VGImage(VmaAllocator.ImageAllocation allocation, int width, int height, int depth, int mipLayers, int format, int glFormat, int glId, int glMemObj, long handle) { + super(allocation, width, height, depth, mipLayers, format); this.glId = glId; this.glMemObj = glMemObj; this.glFormat = glFormat; diff --git a/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java b/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java index dccbec1..d8606c8 100644 --- a/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java +++ b/src/main/java/me/cortex/vulkanite/lib/memory/VImage.java @@ -6,15 +6,30 @@ public class VImage { protected VmaAllocator.ImageAllocation allocation; public final int width; public final int height; + public final int depth; public final int mipLayers; public final int format; - VImage(VmaAllocator.ImageAllocation allocation, int width, int height, int mipLayers, int format) { + public final int dimensions; + + VImage(VmaAllocator.ImageAllocation allocation, int width, int height, int depth, int mipLayers, int format) { this.allocation = allocation; this.width = width; this.height = height; this.mipLayers = mipLayers; this.format = format; + this.depth = depth; + + int dimensions = 3; + + if (height == 1 && depth == 1) { + dimensions = 1; + } + else if(height != 1 && depth == 1) { + dimensions = 2; + } + + this.dimensions = dimensions; } public void free() { diff --git a/src/main/java/me/cortex/vulkanite/lib/other/FormatConverter.java b/src/main/java/me/cortex/vulkanite/lib/other/FormatConverter.java new file mode 100644 index 0000000..efafa57 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/lib/other/FormatConverter.java @@ -0,0 +1,44 @@ +package me.cortex.vulkanite.lib.other; + +import net.coderbot.iris.gl.texture.InternalTextureFormat; + +import static org.lwjgl.opengl.GL11C.GL_RGB8; +import static org.lwjgl.opengl.GL11C.GL_RGBA16; +import static org.lwjgl.opengl.GL11C.GL_RGBA8; +import static org.lwjgl.opengl.GL30C.*; +import static org.lwjgl.opengl.GL30C.GL_R16F; +import static org.lwjgl.vulkan.VK10.*; + +public class FormatConverter { + public static int getVkFormatFromGl(InternalTextureFormat format) { + // TODO: Support 3 component types + + return switch (format.getGlFormat()) { + case GL_R11F_G11F_B10F -> VK_FORMAT_B10G11R11_UFLOAT_PACK32; + + + case GL_RGB32F, GL_RGBA32F -> VK_FORMAT_R32G32B32A32_SFLOAT; + case GL_RGB16F, GL_RGBA16F -> VK_FORMAT_R16G16B16A16_SFLOAT; + case GL_R16F -> VK_FORMAT_R16_SFLOAT; + + case GL_RGB16, GL_RGBA16 -> VK_FORMAT_R16G16B16A16_UNORM; + case GL_RGBA, GL_RGB8, GL_RGBA8 -> VK_FORMAT_R8G8B8A8_UNORM; + + default -> { + throw new IllegalArgumentException("No known conversion to VK type for GL type " + format + " (" + format.getGlFormat() + ")."); + } + }; + } + + public static InternalTextureFormat findFormatFromGlFormat(int glFormat) { + InternalTextureFormat[] availableFormats = InternalTextureFormat.values(); + + for (InternalTextureFormat format : availableFormats) { + if(format.getGlFormat() == glFormat) { + return format; + } + } + + return null; + } +} diff --git a/src/main/java/me/cortex/vulkanite/lib/other/VImageView.java b/src/main/java/me/cortex/vulkanite/lib/other/VImageView.java index 5912892..665a4cb 100644 --- a/src/main/java/me/cortex/vulkanite/lib/other/VImageView.java +++ b/src/main/java/me/cortex/vulkanite/lib/other/VImageView.java @@ -19,11 +19,18 @@ public VImageView(VContext ctx, VImage image) { this.ctx = ctx; this.image = image; + int imageViewType = switch (image.dimensions) { + case 1 -> VK_IMAGE_VIEW_TYPE_1D; + case 2 -> VK_IMAGE_VIEW_TYPE_2D; + case 3 -> VK_IMAGE_VIEW_TYPE_3D; + default -> -1; + }; + try (var stack = stackPush()) { LongBuffer view = stack.callocLong(1); var vci = VkImageViewCreateInfo.calloc(stack) .sType$Default() - .viewType(VK_IMAGE_VIEW_TYPE_2D) + .viewType(imageViewType) .format(image.format) .image(image.image()); vci.subresourceRange() diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlResource.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlResource.java new file mode 100644 index 0000000..87e4d0f --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlResource.java @@ -0,0 +1,48 @@ +package me.cortex.vulkanite.mixin.iris; + +import me.cortex.vulkanite.client.Vulkanite; +import me.cortex.vulkanite.compat.IRenderTargetVkGetter; +import me.cortex.vulkanite.lib.memory.VGImage; +import net.coderbot.iris.gl.GlResource; +import net.coderbot.iris.gl.texture.InternalTextureFormat; +import net.coderbot.iris.gl.texture.PixelFormat; +import net.coderbot.iris.rendertarget.RenderTarget; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static org.lwjgl.opengl.GL11C.*; +import static org.lwjgl.opengl.GL30C.*; +import static org.lwjgl.vulkan.VK10.*; + +@Mixin(value = GlResource.class, remap = false) +public abstract class MixinGlResource { + @Shadow private boolean isValid; + + @Shadow protected abstract void assertValid(); + + @Unique private int newId; + + @Inject(method = "", at=@At("TAIL")) + protected void GlResource(int id, CallbackInfo ci) { + this.newId = id; + if(id == -1) { + isValid = false; + } + } + + protected void setGlId(int id) { + if(this.newId == -1) { + this.newId = id; + isValid = true; + } + } + + @Overwrite + protected int getGlId(){ + assertValid(); + return this.newId; + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java new file mode 100644 index 0000000..7693729 --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java @@ -0,0 +1,95 @@ +package me.cortex.vulkanite.mixin.iris; + +import com.mojang.blaze3d.systems.RenderSystem; +import me.cortex.vulkanite.client.Vulkanite; +import me.cortex.vulkanite.compat.IGlTextureVkGetter; +import me.cortex.vulkanite.lib.memory.VGImage; +import me.cortex.vulkanite.lib.other.FormatConverter; +import net.coderbot.iris.gl.IrisRenderSystem; +import net.coderbot.iris.gl.texture.GlTexture; +import net.coderbot.iris.gl.texture.InternalTextureFormat; +import net.coderbot.iris.gl.texture.TextureType; +import net.coderbot.iris.shaderpack.texture.TextureFilteringData; +import org.lwjgl.opengl.GL30; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.nio.ByteBuffer; + +import static org.lwjgl.opengl.GL11C.*; +import static org.lwjgl.vulkan.VK10.*; + +@Mixin(value = GlTexture.class, remap = false) +public abstract class MixinGlTexture extends MixinGlResource implements IGlTextureVkGetter { + @Unique private VGImage sharedImage; + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_genTexture()I")) + private static int redirectGen() { + return -1; + } + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/coderbot/iris/gl/texture/GlTexture;getGlId()I", ordinal = 0)) + private int redirectTextureCreation(GlTexture instance, TextureType target, int sizeX, int sizeY, int sizeZ, int internalFormat, int format, int pixelType, byte[] pixels, TextureFilteringData filteringData) { + // Before getting the texture id, create the texture that wasn't created earlier + + InternalTextureFormat textureFormat = FormatConverter.findFormatFromGlFormat(internalFormat); + int vkFormat = FormatConverter.getVkFormatFromGl(textureFormat); + + // Clamp y,z to 1 as per VK spec + sizeY = Math.max(sizeY, 1); + sizeZ = Math.max(sizeZ, 1); + + sharedImage = Vulkanite.INSTANCE.getCtx().memory + .createSharedImage( + sizeX, + sizeY, + sizeZ, + 1, + vkFormat, + textureFormat.getGlFormat(), + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + ); + + System.out.println("Intercepted GlTexture creation: " + sizeX + "x" + sizeY + "x" + sizeZ + ", texture ID " + sharedImage.glId + " with format " + textureFormat); + + this.setGlId(sharedImage.glId); + + return sharedImage.glId; + } + + @Redirect(method="", at = @At(value = "INVOKE", target = "Lnet/coderbot/iris/gl/texture/TextureType;apply(IIIIIIILjava/nio/ByteBuffer;)V")) + private void redirectUpload(TextureType instance, int glId, int width, int height, int depth, int internalFormat, int format, int pixelType, ByteBuffer data) { + int target = instance.getGlType(); + + RenderSystem.assertOnRenderThreadOrInit(); + IrisRenderSystem.bindTextureForSetup(target, glId); + + switch (instance) { + case TEXTURE_1D: + GL30.glTexSubImage1D(target, 0, 0, width, format, pixelType, data); + break; + case TEXTURE_2D, TEXTURE_RECTANGLE: + GL30.glTexSubImage2D(target, 0, 0, 0, width, height, format, pixelType, data); + break; + case TEXTURE_3D: + GL30.glTexSubImage3D(target, 0, 0, 0, 0, width, height, depth, format, pixelType, data); + break; + } + + InternalTextureFormat textureFormat = FormatConverter.findFormatFromGlFormat(internalFormat); + + System.out.println("Intercepted GlTexture upload: " + width + "x" + height + "x" + depth + ", texture ID " + sharedImage.glId + " with format " + textureFormat + ". Uploaded " + data.limit() + " bytes."); + } + + @Overwrite + protected void destroyInternal(){ + glFinish(); + sharedImage.free(); + } + + public VGImage getImage() { + return sharedImage; + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java index 4266d9c..a5261fc 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java @@ -3,10 +3,14 @@ import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.client.rendering.VulkanPipeline; import me.cortex.vulkanite.compat.IGetRaytracingSource; +import me.cortex.vulkanite.compat.IGlTextureVkGetter; import me.cortex.vulkanite.compat.IRenderTargetVkGetter; import me.cortex.vulkanite.compat.RaytracingShaderSet; import me.cortex.vulkanite.lib.base.VContext; +import me.cortex.vulkanite.lib.memory.VGImage; +import net.coderbot.iris.gl.texture.GlTexture; import net.coderbot.iris.mixin.LevelRendererAccessor; +import net.coderbot.iris.pipeline.CustomTextureManager; import net.coderbot.iris.pipeline.newshader.NewWorldRenderingPipeline; import net.coderbot.iris.rendertarget.RenderTargets; import net.coderbot.iris.shaderpack.ProgramSet; @@ -22,6 +26,7 @@ @Mixin(value = NewWorldRenderingPipeline.class, remap = false) public class MixinNewWorldRenderingPipeline { @Shadow @Final private RenderTargets renderTargets; + @Shadow @Final private CustomTextureManager customTextureManager; @Unique private RaytracingShaderSet[] rtShaderPasses = null; @Unique private VContext ctx; @Unique private VulkanPipeline pipeline; @@ -42,7 +47,15 @@ private void injectRTShader(ProgramSet set, CallbackInfo ci) { @Inject(method = "renderShadows", at = @At("TAIL")) private void renderShadows(LevelRendererAccessor par1, Camera par2, CallbackInfo ci) { - pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.get(0)).getMain(), par2); + GlTexture customTexture = (GlTexture) customTextureManager.getIrisCustomTextures().get("customtex0"); + + VGImage image = null; + + if(customTexture != null) { + image = ((IGlTextureVkGetter)(Object)customTexture).getImage(); + } + + pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.get(0)).getMain(), image, par2); } @Inject(method = "destroyShaders", at = @At("TAIL")) diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPBRAtlasTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPBRAtlasTexture.java index d12be60..ba1b582 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPBRAtlasTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinPBRAtlasTexture.java @@ -31,6 +31,7 @@ private void redirect(int id, int maxLevel, int width, int height) { var img = Vulkanite.INSTANCE.getCtx().memory.createSharedImage( width, height, + 1, maxLevel + 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinRenderTarget.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinRenderTarget.java index c4e4d3a..ca42a56 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinRenderTarget.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinRenderTarget.java @@ -3,6 +3,7 @@ import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.compat.IRenderTargetVkGetter; import me.cortex.vulkanite.lib.memory.VGImage; +import me.cortex.vulkanite.lib.other.FormatConverter; import net.coderbot.iris.gl.texture.InternalTextureFormat; import net.coderbot.iris.gl.texture.PixelFormat; import net.coderbot.iris.rendertarget.RenderTarget; @@ -64,26 +65,17 @@ public void resize(int width, int height) { private void setupTextures(int width, int height, boolean allowsLinear) { var ctx = Vulkanite.INSTANCE.getCtx(); + int glfmt = internalFormat.getGlFormat(); - glfmt = (glfmt==GL_RGBA)?GL_RGBA8:glfmt; - int vkfmt = gl2vkFormat(glfmt); - vgMainTexture = ctx.memory.createSharedImage(width, height, 1, vkfmt, glfmt, VK_IMAGE_USAGE_STORAGE_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - setupTexture(getMainTexture(), width, height, allowsLinear); + glfmt = (glfmt == GL_RGBA) ? GL_RGBA8 : glfmt; - vgAltTexture = ctx.memory.createSharedImage(width, height, 1, vkfmt, glfmt, VK_IMAGE_USAGE_STORAGE_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - setupTexture(getAltTexture(), width, height, allowsLinear); - } + int vkfmt = FormatConverter.getVkFormatFromGl(internalFormat); + vgMainTexture = ctx.memory.createSharedImage(width, height, 1, 1, vkfmt, glfmt, VK_IMAGE_USAGE_STORAGE_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + setupTexture(getMainTexture(), width, height, allowsLinear); - private int gl2vkFormat(int gl) { - return switch (gl) { - case GL_R11F_G11F_B10F -> VK_FORMAT_B10G11R11_UFLOAT_PACK32; - case GL_RGBA16 -> VK_FORMAT_R16G16B16A16_UNORM; - case GL_RGB32F, GL_RGBA32F -> VK_FORMAT_R32G32B32A32_SFLOAT; - case GL_RGB8, GL_RGBA8 -> VK_FORMAT_R8G8B8A8_UNORM; - case GL_R16F -> VK_FORMAT_R16_SFLOAT; - default -> {throw new IllegalArgumentException("Unknown gl2vk type: "+internalFormat+" -> "+internalFormat.getGlFormat());} - }; + vgAltTexture = ctx.memory.createSharedImage(width, height, 1, 1, vkfmt, glfmt, VK_IMAGE_USAGE_STORAGE_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + setupTexture(getAltTexture(), width, height, allowsLinear); } @Redirect(method = "destroy", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_deleteTextures([I)V")) diff --git a/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinSpriteAtlasTexture.java b/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinSpriteAtlasTexture.java index 9a261df..c9efeb3 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinSpriteAtlasTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinSpriteAtlasTexture.java @@ -30,6 +30,7 @@ private void redirect(int id, int maxLevel, int width, int height) { var img = Vulkanite.INSTANCE.getCtx().memory.createSharedImage( width, height, + 1, maxLevel + 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, diff --git a/src/main/resources/vulkanite.mixins.json b/src/main/resources/vulkanite.mixins.json index b982811..8ca1e31 100644 --- a/src/main/resources/vulkanite.mixins.json +++ b/src/main/resources/vulkanite.mixins.json @@ -4,6 +4,8 @@ "package": "me.cortex.vulkanite.mixin", "compatibilityLevel": "JAVA_17", "client": [ + "iris.MixinGlResource", + "iris.MixinGlTexture", "iris.MixinNewWorldRenderingPipeline", "iris.MixinPackRenderTargetDirectives", "iris.MixinPBRAtlasTexture", From ccfa24e5dd17e3df0a58fad6d2729e06219c6432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?aleth=C3=A9ia?= <34745171+xirreal@users.noreply.github.com> Date: Sat, 16 Sep 2023 19:18:39 +0200 Subject: [PATCH 2/7] Remove leftover debug log --- .../me/cortex/vulkanite/client/rendering/VulkanPipeline.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java index 58b87c2..9960e2c 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java @@ -213,8 +213,6 @@ public void renderPostShadows(VGImage outImg, VGImage customTexture, Camera came bb.putInt(Float.BYTES * 40, frameId++); - System.out.println(frameId); - int flags = Uniforms.isEyeInWater()&3; bb.putInt(Float.BYTES * 41, flags); bb.rewind(); From 3c563302aacac91bec982534fce089cee18ddc76 Mon Sep 17 00:00:00 2001 From: xirreal Date: Mon, 18 Sep 2023 14:18:59 +0200 Subject: [PATCH 3/7] Use a different sampler for custom textures --- .../client/rendering/VulkanPipeline.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java index 9960e2c..696e1f9 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java @@ -58,6 +58,7 @@ public class VulkanPipeline { private VDescriptorPool descriptors; private final VSampler sampler; + private final VSampler ctexSampler; private final SharedImageViewTracker composite0mainView; private final SharedImageViewTracker customTextureView; @@ -94,7 +95,7 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray }); this.placeholderImage = ctx.memory.createImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); this.placeholderImageView = new VImageView(ctx, placeholderImage); - + try (var stack = stackPush()) { var cmd = singleUsePool.createCommandBuffer(); cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); @@ -121,6 +122,17 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray .borderColor(VK_BORDER_COLOR_INT_OPAQUE_BLACK) .maxAnisotropy(1.0f)); + this.ctexSampler = new VSampler(ctx, a->a.magFilter(VK_FILTER_LINEAR) + .minFilter(VK_FILTER_LINEAR) + .mipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST) + .addressModeU(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) + .addressModeV(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) + .addressModeW(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) + .compareOp(VK_COMPARE_OP_NEVER) + .maxLod(1) + .borderColor(VK_BORDER_COLOR_INT_OPAQUE_BLACK) + .maxAnisotropy(1.0f)); + try { layout = new DescriptorSetLayoutBuilder() .binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL)//camera data @@ -231,7 +243,7 @@ public void renderPostShadows(VGImage outImg, VGImage customTexture, Camera came .imageSampler(4, blockAtlasView.getView(), sampler) .imageSampler(5, blockAtlasNormalView.getView(), sampler) .imageSampler(6, blockAtlasSpecularView.getView(), sampler) - .imageSampler(7, customTextureView.getView(()->customTexture), sampler) + .imageSampler(7, customTextureView.getView(()->customTexture), ctexSampler) .apply(); @@ -308,6 +320,7 @@ public void destory() { placeholderImageView.free(); placeholderImage.free(); sampler.free(); + ctexSampler.free(); } From 3c8450315da547d140ea273f116835f13b0a593f Mon Sep 17 00:00:00 2001 From: xirreal Date: Mon, 18 Sep 2023 23:52:55 +0200 Subject: [PATCH 4/7] Support for png custom textures --- .../vulkanite/client/rendering/Uniforms.java | 2 +- .../vulkanite/compat/IGlTextureVkGetter.java | 7 -- .../vulkanite/mixin/iris/MixinGlTexture.java | 6 +- .../iris/MixinNativeImageBackedTexture.java | 68 +++++++++++++++++++ .../iris/MixinNewWorldRenderingPipeline.java | 28 +++++--- .../mixin/minecraft/MixinAbstractTexture.java | 14 ++-- src/main/resources/vulkanite.mixins.json | 1 + 7 files changed, 100 insertions(+), 26 deletions(-) delete mode 100644 src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java create mode 100644 src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/Uniforms.java b/src/main/java/me/cortex/vulkanite/client/rendering/Uniforms.java index 6efc305..cb84719 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/Uniforms.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/Uniforms.java @@ -38,7 +38,7 @@ static Vector4f getMoonPosition() { static Vector4f getCelestialPosition(float y) { - final float sunPathRotation = 0.0f; + final float sunPathRotation = -45.0f; Vector4f position = new Vector4f(0.0F, y, 0.0F, 0.0F); diff --git a/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java b/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java deleted file mode 100644 index c5fb269..0000000 --- a/src/main/java/me/cortex/vulkanite/compat/IGlTextureVkGetter.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.cortex.vulkanite.compat; - -import me.cortex.vulkanite.lib.memory.VGImage; - -public interface IGlTextureVkGetter { - VGImage getImage(); -} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java index 7693729..86e1b8a 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java @@ -2,7 +2,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import me.cortex.vulkanite.client.Vulkanite; -import me.cortex.vulkanite.compat.IGlTextureVkGetter; +import me.cortex.vulkanite.compat.IVGImage; import me.cortex.vulkanite.lib.memory.VGImage; import me.cortex.vulkanite.lib.other.FormatConverter; import net.coderbot.iris.gl.IrisRenderSystem; @@ -21,7 +21,7 @@ import static org.lwjgl.vulkan.VK10.*; @Mixin(value = GlTexture.class, remap = false) -public abstract class MixinGlTexture extends MixinGlResource implements IGlTextureVkGetter { +public abstract class MixinGlTexture extends MixinGlResource implements IVGImage { @Unique private VGImage sharedImage; @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/GlStateManager;_genTexture()I")) @@ -89,7 +89,7 @@ protected void destroyInternal(){ sharedImage.free(); } - public VGImage getImage() { + public VGImage getVGImage() { return sharedImage; } } diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java new file mode 100644 index 0000000..3fea0ce --- /dev/null +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java @@ -0,0 +1,68 @@ +package me.cortex.vulkanite.mixin.iris; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.platform.TextureUtil; +import com.mojang.blaze3d.systems.RenderSystem; +import me.cortex.vulkanite.client.Vulkanite; +import me.cortex.vulkanite.compat.IVGImage; +import me.cortex.vulkanite.mixin.minecraft.MixinAbstractTexture; +import net.coderbot.iris.gl.IrisRenderSystem; +import net.coderbot.iris.rendertarget.NativeImageBackedCustomTexture; +import net.minecraft.client.texture.AbstractTexture; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.NativeImageBackedTexture; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL30; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import static org.lwjgl.opengl.GL11C.*; +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + +@Mixin(value = NativeImageBackedTexture.class, remap = false) +public abstract class MixinNativeImageBackedTexture extends AbstractTexture implements IVGImage { + + @Shadow @Nullable private NativeImage image; + + @Redirect(method = "(Lnet/minecraft/client/texture/NativeImage;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/texture/NativeImageBackedTexture;getGlId()I")) + private int redirectGetId(NativeImageBackedTexture instance){ + if(!((Object) this instanceof NativeImageBackedCustomTexture)) { + return instance.getGlId(); + } + return -1; + } + + @Redirect(method = "(Lnet/minecraft/client/texture/NativeImage;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(III)V")) + private void redirectGen(int id, int width, int height) { + if(!((Object) this instanceof NativeImageBackedCustomTexture)) { + TextureUtil.prepareImage(id, width, height); + return; + } + + RenderSystem.assertOnRenderThreadOrInit(); + + if (getVGImage() != null) { + System.err.println("Vulkan image already allocated, releasing"); + Vulkanite.INSTANCE.addSyncedCallback(getVGImage()::free); + setVGImage(null); + } + + var img = Vulkanite.INSTANCE.getCtx().memory.createSharedImage( + width, + height, + 1, + 1, + VK_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + setVGImage(img); + + GlStateManager._bindTexture(img.glId); + } +} diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java index a5261fc..5b681c3 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java @@ -3,18 +3,20 @@ import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.client.rendering.VulkanPipeline; import me.cortex.vulkanite.compat.IGetRaytracingSource; -import me.cortex.vulkanite.compat.IGlTextureVkGetter; import me.cortex.vulkanite.compat.IRenderTargetVkGetter; +import me.cortex.vulkanite.compat.IVGImage; import me.cortex.vulkanite.compat.RaytracingShaderSet; import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.memory.VGImage; -import net.coderbot.iris.gl.texture.GlTexture; +import net.coderbot.iris.gl.texture.TextureAccess; import net.coderbot.iris.mixin.LevelRendererAccessor; import net.coderbot.iris.pipeline.CustomTextureManager; import net.coderbot.iris.pipeline.newshader.NewWorldRenderingPipeline; import net.coderbot.iris.rendertarget.RenderTargets; import net.coderbot.iris.shaderpack.ProgramSet; +import net.coderbot.iris.shaderpack.texture.TextureStage; import net.minecraft.client.render.Camera; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -45,16 +47,26 @@ private void injectRTShader(ProgramSet set, CallbackInfo ci) { } } - @Inject(method = "renderShadows", at = @At("TAIL")) - private void renderShadows(LevelRendererAccessor par1, Camera par2, CallbackInfo ci) { - GlTexture customTexture = (GlTexture) customTextureManager.getIrisCustomTextures().get("customtex0"); + @Unique + private @Nullable VGImage getCustomtexOrNull() { + // Try getting the custom texture from the list of binary textures + TextureAccess customTexture = customTextureManager.getIrisCustomTextures().get("customtex0"); - VGImage image = null; + // If none were found, try getting it from the png custom texture list + if (customTexture == null) { + customTexture = customTextureManager.getCustomTextureIdMap(TextureStage.GBUFFERS_AND_SHADOW).get("customtex0"); + } - if(customTexture != null) { - image = ((IGlTextureVkGetter)(Object)customTexture).getImage(); + if (customTexture != null) { + return ((IVGImage) customTexture).getVGImage(); } + return null; + } + + @Inject(method = "renderShadows", at = @At("TAIL")) + private void renderShadows(LevelRendererAccessor par1, Camera par2, CallbackInfo ci) { + VGImage image = getCustomtexOrNull(); pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.get(0)).getMain(), image, par2); } diff --git a/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinAbstractTexture.java b/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinAbstractTexture.java index 5385724..3e91b37 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinAbstractTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/minecraft/MixinAbstractTexture.java @@ -15,33 +15,33 @@ @Mixin(AbstractTexture.class) public class MixinAbstractTexture implements IVGImage { @Shadow protected int glId; - @Unique private VGImage image; + @Unique private VGImage vgImage; @Override public void setVGImage(VGImage image) { - this.image = image; + this.vgImage = image; } @Override public VGImage getVGImage() { - return image; + return vgImage; } @Inject(method = "getGlId", at = @At("HEAD"), cancellable = true) private void redirectGetId(CallbackInfoReturnable cir) { - if (image != null) { + if (vgImage != null) { if (glId != -1) { throw new IllegalStateException("glId != -1 while VGImage is set"); } - cir.setReturnValue(image.glId); + cir.setReturnValue(vgImage.glId); cir.cancel(); } } @Inject(method = "clearGlId", at = @At("HEAD"), cancellable = true) private void redirectClear(CallbackInfo ci) { - if (image != null) { - Vulkanite.INSTANCE.addSyncedCallback(image::free); + if (vgImage != null) { + Vulkanite.INSTANCE.addSyncedCallback(vgImage::free); ci.cancel(); } } diff --git a/src/main/resources/vulkanite.mixins.json b/src/main/resources/vulkanite.mixins.json index 8ca1e31..1478181 100644 --- a/src/main/resources/vulkanite.mixins.json +++ b/src/main/resources/vulkanite.mixins.json @@ -4,6 +4,7 @@ "package": "me.cortex.vulkanite.mixin", "compatibilityLevel": "JAVA_17", "client": [ + "iris.MixinNativeImageBackedTexture", "iris.MixinGlResource", "iris.MixinGlTexture", "iris.MixinNewWorldRenderingPipeline", From b37c7db0bb0adcd50a7977629f42c13abb15cd94 Mon Sep 17 00:00:00 2001 From: xirreal Date: Mon, 18 Sep 2023 23:54:11 +0200 Subject: [PATCH 5/7] Remove debug logging --- .../java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java index 86e1b8a..5cefd2f 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinGlTexture.java @@ -52,8 +52,6 @@ private int redirectTextureCreation(GlTexture instance, TextureType target, int VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ); - System.out.println("Intercepted GlTexture creation: " + sizeX + "x" + sizeY + "x" + sizeZ + ", texture ID " + sharedImage.glId + " with format " + textureFormat); - this.setGlId(sharedImage.glId); return sharedImage.glId; @@ -77,10 +75,6 @@ private void redirectUpload(TextureType instance, int glId, int width, int heigh GL30.glTexSubImage3D(target, 0, 0, 0, 0, width, height, depth, format, pixelType, data); break; } - - InternalTextureFormat textureFormat = FormatConverter.findFormatFromGlFormat(internalFormat); - - System.out.println("Intercepted GlTexture upload: " + width + "x" + height + "x" + depth + ", texture ID " + sharedImage.glId + " with format " + textureFormat + ". Uploaded " + data.limit() + " bytes."); } @Overwrite From b42de7e0ca9032608302f16e5656bb523403ec1e Mon Sep 17 00:00:00 2001 From: xirreal Date: Tue, 19 Sep 2023 00:01:49 +0200 Subject: [PATCH 6/7] Cleanup, use 1 less mixin --- .../iris/MixinNativeImageBackedTexture.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java index 3fea0ce..03e5606 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNativeImageBackedTexture.java @@ -26,17 +26,6 @@ @Mixin(value = NativeImageBackedTexture.class, remap = false) public abstract class MixinNativeImageBackedTexture extends AbstractTexture implements IVGImage { - - @Shadow @Nullable private NativeImage image; - - @Redirect(method = "(Lnet/minecraft/client/texture/NativeImage;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/texture/NativeImageBackedTexture;getGlId()I")) - private int redirectGetId(NativeImageBackedTexture instance){ - if(!((Object) this instanceof NativeImageBackedCustomTexture)) { - return instance.getGlId(); - } - return -1; - } - @Redirect(method = "(Lnet/minecraft/client/texture/NativeImage;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/TextureUtil;prepareImage(III)V")) private void redirectGen(int id, int width, int height) { if(!((Object) this instanceof NativeImageBackedCustomTexture)) { @@ -44,8 +33,10 @@ private void redirectGen(int id, int width, int height) { return; } - RenderSystem.assertOnRenderThreadOrInit(); - + if (glId != -1) { + glDeleteTextures(glId); + glId = -1; + } if (getVGImage() != null) { System.err.println("Vulkan image already allocated, releasing"); Vulkanite.INSTANCE.addSyncedCallback(getVGImage()::free); From 7268687690e8206c6b6617937d2354595a071f1b Mon Sep 17 00:00:00 2001 From: xirreal Date: Wed, 20 Sep 2023 17:39:11 +0200 Subject: [PATCH 7/7] Move custom tex and ssbo to their own sets --- .../client/rendering/VulkanPipeline.java | 112 ++++++++++++------ .../lib/descriptors/VDescriptorPool.java | 26 ++-- .../iris/MixinNewWorldRenderingPipeline.java | 54 +++++---- 3 files changed, 126 insertions(+), 66 deletions(-) diff --git a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java index c40d40c..7eb8037 100644 --- a/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java +++ b/src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java @@ -58,14 +58,16 @@ public class VulkanPipeline { private final VCommandPool singleUsePool; private VRaytracePipeline[] raytracePipelines; - private VDescriptorSetLayout layout; + private VDescriptorSetLayout commonLayout; + private VDescriptorSetLayout customtexLayout; + private VDescriptorSetLayout storageBufferLayout; private VDescriptorPool descriptors; private final VSampler sampler; private final VSampler ctexSampler; private final SharedImageViewTracker composite0mainView; - private final SharedImageViewTracker customTextureView; + private final SharedImageViewTracker[] customTextureViews; private final SharedImageViewTracker blockAtlasView; private final SharedImageViewTracker blockAtlasNormalView; private final SharedImageViewTracker blockAtlasSpecularView; @@ -75,14 +77,19 @@ public class VulkanPipeline { private int fidx; - public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, RaytracingShaderSet[] passes, int[] ssboIds) { + public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, RaytracingShaderSet[] passes, int[] ssboIds, VGImage[] customTextures) { this.ctx = ctx; this.accelerationManager = accelerationManager; this.singleUsePool = ctx.cmd.createSingleUsePool(); { + this.customTextureViews = new SharedImageViewTracker[customTextures.length]; + for(int i = 0; i < customTextures.length; i++) { + int index = i; + this.customTextureViews[i] = new SharedImageViewTracker(ctx, ()->customTextures[index]); + } + this.composite0mainView = new SharedImageViewTracker(ctx, null); - this.customTextureView = new SharedImageViewTracker(ctx, null); this.blockAtlasView = new SharedImageViewTracker(ctx, ()->{ AbstractTexture blockAtlas = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier("minecraft", "textures/atlas/blocks.png")); return ((IVGImage)blockAtlas).getVGImage(); @@ -138,30 +145,46 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray .maxAnisotropy(1.0f)); try { - var layoutBuilder = new DescriptorSetLayoutBuilder() - .binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL)//camera data - .binding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL)//funni acceleration buffer - .binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL)//funni buffer buffer - .binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL)//output texture + commonLayout = new DescriptorSetLayoutBuilder() + .binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL)// camera data + .binding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL)// funni acceleration buffer + .binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL)// funni buffer buffer .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture normal - .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL);//block texture specular + .binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture specular + // Reordered these so output texture is last... this means you can dynamically add more output textures without messing other ids + .binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL)// output texture + .build(ctx); + + DescriptorSetLayoutBuilder ctexLayoutBuilder = new DescriptorSetLayoutBuilder(); + for (int i = 0; i < customTextureViews.length; i++) { + ctexLayoutBuilder.binding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL); + } + customtexLayout = ctexLayoutBuilder.build(ctx); + + DescriptorSetLayoutBuilder ssboLayoutBuilder = new DescriptorSetLayoutBuilder(); for (int id : ssboIds) { - //NOTE:FIXME: the + 7 is cause of all the other bindings - layoutBuilder.binding(id + 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); + ssboLayoutBuilder.binding(id, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); } + storageBufferLayout = ssboLayoutBuilder.build(ctx); - layout = layoutBuilder.build(ctx); - + // Using commonLayout.types is good enough because both VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER are used there already... //TODO: use frameahead count instead of just... 10 - descriptors = new VDescriptorPool(ctx, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 10, layout.types); - descriptors.allocateSets(layout); + descriptors = new VDescriptorPool(ctx, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 10, commonLayout.types); + descriptors.allocateSets(new VDescriptorSetLayout[]{ + commonLayout, + customtexLayout, + storageBufferLayout + }); raytracePipelines = new VRaytracePipeline[passes.length]; for (int i = 0; i < passes.length; i++) { - var builder = new RaytracePipelineBuilder().addLayout(layout); + var builder = new RaytracePipelineBuilder() + .addLayout(commonLayout) + .addLayout(customtexLayout) + .addLayout(storageBufferLayout); passes[i].apply(builder); raytracePipelines[i] = builder.build(ctx, 1); } @@ -180,14 +203,13 @@ private static void applyImageBarrier(VkImageMemoryBarrier barrier, VImage image .srcAccessMask(0) .dstAccessMask(targetAccess) .subresourceRange(e->e.levelCount(1).layerCount(1).aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)); - } private VSemaphore previousSemaphore; private int frameId; - + public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer[] ssbos) { this.singleUsePool.doReleases(); PBRTextureManager.notifyPBRTexturesChanged(); @@ -243,19 +265,34 @@ public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer uboBuffer.unmap(); uboBuffer.flush(); - long desc = descriptors.get(fidx); + long commonSet = descriptors.get(0); + long ctexSet = descriptors.get(1); + long ssboSet = descriptors.get(2); - var updater = new DescriptorUpdateBuilder(ctx, 7 + ssbos.length, placeholderImageView) - .set(desc) + var updater = new DescriptorUpdateBuilder(ctx, 7, placeholderImageView) + .set(commonSet) .uniform(0, uboBuffer) .acceleration(1, tlas) .buffer(2, accelerationManager.getReferenceBuffer()) - .imageStore(3, composite0mainView.getView(()->outImg)) - .imageSampler(4, blockAtlasView.getView(), sampler) - .imageSampler(5, blockAtlasNormalView.getView(), sampler) - .imageSampler(6, blockAtlasSpecularView.getView(), sampler); + .imageSampler(3, blockAtlasView.getView(), sampler) + .imageSampler(4, blockAtlasNormalView.getView(), sampler) + .imageSampler(5, blockAtlasSpecularView.getView(), sampler) + .imageStore(6, composite0mainView.getView(()->outImg)); + updater.apply(); + + updater = new DescriptorUpdateBuilder(ctx, customTextureViews.length, placeholderImageView) + .set(ctexSet); + + for (int i = 0; i < customTextureViews.length; i++) { + updater.imageSampler(i, customTextureViews[i].getView(), ctexSampler); + } + updater.apply(); + + updater = new DescriptorUpdateBuilder(ctx, ssbos.length, placeholderImageView) + .set(ssboSet); + for (ShaderStorageBuffer ssbo : ssbos) { - updater.buffer(ssbo.getIndex() + 7, ((IVGBuffer) ssbo).getBuffer()); + updater.buffer(ssbo.getIndex(), ((IVGBuffer) ssbo).getBuffer()); } updater.apply(); @@ -264,15 +301,18 @@ public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); try (var stack = stackPush()) { - var barriers = VkImageMemoryBarrier.calloc(5, stack); + var barriers = VkImageMemoryBarrier.calloc(4 + customTextureViews.length, stack); applyImageBarrier(barriers.get(), composite0mainView.getImage(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_WRITE_BIT); applyImageBarrier(barriers.get(), blockAtlasView.getImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); var image = blockAtlasNormalView.getImage(); if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); image = blockAtlasSpecularView.getImage(); if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); - image = customTextureView.getImage(); - if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); + + for(SharedImageViewTracker customtexView : customTextureViews) { + applyImageBarrier(barriers.get(), customtexView.getImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT); + } + barriers.limit(barriers.position()); barriers.rewind(); vkCmdPipelineBarrier(cmd.buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, null, null, barriers); @@ -280,7 +320,7 @@ public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer for (var pipeline : raytracePipelines) { pipeline.bind(cmd); - pipeline.bindDSet(cmd, desc); + pipeline.bindDSet(cmd, new long[]{commonSet, ctexSet, ssboSet}); pipeline.trace(cmd, outImg.width, outImg.height, 1); } @@ -316,7 +356,9 @@ public void destory() { for (var pass : raytracePipelines) { pass.free(); } - layout.free(); + commonLayout.free(); + customtexLayout.free(); + storageBufferLayout.free(); descriptors.free(); ctx.sync.checkFences(); singleUsePool.doReleases(); @@ -324,8 +366,12 @@ public void destory() { if (previousSemaphore != null) { previousSemaphore.free(); } + + for (SharedImageViewTracker customTexView : customTextureViews) { + customTexView.free(); + } + composite0mainView.free(); - customTextureView.free(); blockAtlasView.free(); blockAtlasNormalView.free(); blockAtlasSpecularView.free(); diff --git a/src/main/java/me/cortex/vulkanite/lib/descriptors/VDescriptorPool.java b/src/main/java/me/cortex/vulkanite/lib/descriptors/VDescriptorPool.java index a717281..9d1869d 100644 --- a/src/main/java/me/cortex/vulkanite/lib/descriptors/VDescriptorPool.java +++ b/src/main/java/me/cortex/vulkanite/lib/descriptors/VDescriptorPool.java @@ -17,46 +17,50 @@ public class VDescriptorPool extends TrackedResourceObject { private final long pool; private final long[] sets; + private int usedSets = 0; - public VDescriptorPool(VContext ctx, int flags, int numSets, int... types) { + public VDescriptorPool(VContext ctx, int flags, int maxSets, int... types) { this.ctx = ctx; - this.sets = new long[numSets]; + this.sets = new long[maxSets]; try (var stack = stackPush()) { var sizes = VkDescriptorPoolSize.calloc(types.length, stack); for (int i = 0; i < types.length; i++) { - sizes.get(i).type(types[i]).descriptorCount(numSets); + sizes.get(i).type(types[i]).descriptorCount(maxSets); } LongBuffer pPool = stack.mallocLong(1); _CHECK_(vkCreateDescriptorPool(ctx.device, VkDescriptorPoolCreateInfo.calloc(stack) .sType$Default() .flags(flags) - .maxSets(numSets) + .maxSets(maxSets) .pPoolSizes(sizes), null, pPool)); pool = pPool.get(0); } } - - public void allocateSets(VDescriptorSetLayout layout) { + public void allocateSets(VDescriptorSetLayout[] layouts) { try (var stack = stackPush()) { - var layouts = stack.mallocLong(sets.length); - for (int i = 0; i < sets.length; i++) { - layouts.put(layout.layout); + usedSets = layouts.length; + var pLayouts = stack.mallocLong(usedSets); + for (int i = 0; i < usedSets; i++) { + pLayouts.put(layouts[i].layout); } - layouts.rewind(); + pLayouts.rewind(); LongBuffer pDescriptorSets = stack.mallocLong(sets.length); _CHECK_(vkAllocateDescriptorSets(ctx.device, VkDescriptorSetAllocateInfo .calloc(stack) .sType$Default() .descriptorPool(pool) - .pSetLayouts(layouts), pDescriptorSets), + .pSetLayouts(pLayouts), pDescriptorSets), "Failed to allocate descriptor set"); pDescriptorSets.get(sets); } } public long get(int idx) { + if(idx < 0 || idx >= usedSets) { + throw new IllegalArgumentException("Descriptor set out of range: " + idx); + } return sets[idx]; } diff --git a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java index c3bf630..a54d78c 100644 --- a/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java +++ b/src/main/java/me/cortex/vulkanite/mixin/iris/MixinNewWorldRenderingPipeline.java @@ -1,5 +1,7 @@ package me.cortex.vulkanite.mixin.iris; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap.Entry; import me.cortex.vulkanite.client.Vulkanite; import me.cortex.vulkanite.client.rendering.VulkanPipeline; import me.cortex.vulkanite.compat.IGetRaytracingSource; @@ -8,10 +10,9 @@ import me.cortex.vulkanite.compat.RaytracingShaderSet; import me.cortex.vulkanite.lib.base.VContext; import me.cortex.vulkanite.lib.memory.VGImage; -import net.coderbot.iris.gl.texture.TextureAccess; import net.coderbot.iris.gl.buffer.ShaderStorageBuffer; +import net.coderbot.iris.gl.texture.TextureAccess; import net.coderbot.iris.gl.buffer.ShaderStorageBufferHolder; -import net.coderbot.iris.gl.buffer.ShaderStorageInfo; import net.coderbot.iris.mixin.LevelRendererAccessor; import net.coderbot.iris.pipeline.CustomTextureManager; import net.coderbot.iris.pipeline.newshader.NewWorldRenderingPipeline; @@ -28,6 +29,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + @Mixin(value = NewWorldRenderingPipeline.class, remap = false) public class MixinNewWorldRenderingPipeline { @@ -39,6 +44,24 @@ public class MixinNewWorldRenderingPipeline { @Unique private VContext ctx; @Unique private VulkanPipeline pipeline; + @Unique + private VGImage[] getCustomTextures() { + Object2ObjectMap texturesBinary = customTextureManager.getIrisCustomTextures(); + Object2ObjectMap texturesPNGs = customTextureManager.getCustomTextureIdMap(TextureStage.GBUFFERS_AND_SHADOW); + + List> entryList = new ArrayList<>(); + entryList.addAll(texturesBinary.object2ObjectEntrySet()); + entryList.addAll(texturesPNGs.object2ObjectEntrySet()); + + entryList.sort(Comparator.comparing(Entry::getKey)); + + VGImage[] sortedTextures = entryList.stream() + .map(entry -> ((IVGImage) entry.getValue()).getVGImage()) + .toArray(VGImage[]::new); + + return sortedTextures; + } + @Inject(method = "", at = @At("TAIL")) private void injectRTShader(ProgramSet set, CallbackInfo ci) { ctx = Vulkanite.INSTANCE.getCtx(); @@ -49,32 +72,19 @@ private void injectRTShader(ProgramSet set, CallbackInfo ci) { rtShaderPasses[i] = new RaytracingShaderSet(ctx, passes[i]); } - pipeline = new VulkanPipeline(ctx, Vulkanite.INSTANCE.getAccelerationManager(), rtShaderPasses, set.getPackDirectives().getBufferObjects().keySet().toArray(new int[0])); + pipeline = new VulkanPipeline(ctx, Vulkanite.INSTANCE.getAccelerationManager(), rtShaderPasses, set.getPackDirectives().getBufferObjects().keySet().toArray(new int[0]), getCustomTextures()); } } - @Unique - private @Nullable VGImage getCustomtexOrNull() { - // Try getting the custom texture from the list of binary textures - TextureAccess customTexture = customTextureManager.getIrisCustomTextures().get("customtex0"); - - // If none were found, try getting it from the png custom texture list - if (customTexture == null) { - customTexture = customTextureManager.getCustomTextureIdMap(TextureStage.GBUFFERS_AND_SHADOW).get("customtex0"); - } + @Inject(method = "renderShadows", at = @At("TAIL")) + private void renderShadows(LevelRendererAccessor par1, Camera par2, CallbackInfo ci) { + ShaderStorageBuffer[] buffers = new ShaderStorageBuffer[0]; - if (customTexture != null) { - return ((IVGImage) customTexture).getVGImage(); + if(shaderStorageBufferHolder != null) { + buffers = ((ShaderStorageBufferHolderAccessor)shaderStorageBufferHolder).getBuffers(); } - return null; - } - - @Inject(method = "renderShadows", at = @At("TAIL")) - private void renderShadows(LevelRendererAccessor par1, Camera par2, CallbackInfo ci) { - VGImage image = getCustomtexOrNull(); - // pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.get(0)).getMain(), image, par2); - pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.getOrCreate(0)).getMain(), par2, ((ShaderStorageBufferHolderAccessor)shaderStorageBufferHolder).getBuffers()); + pipeline.renderPostShadows(((IRenderTargetVkGetter)renderTargets.getOrCreate(0)).getMain(), par2, buffers); } @Inject(method = "destroyShaders", at = @At("TAIL"))