diff --git a/src/main/java/net/vulkanmod/config/widget/OptionWidget.java b/src/main/java/net/vulkanmod/config/widget/OptionWidget.java index ff87ba126..34e3d1db3 100644 --- a/src/main/java/net/vulkanmod/config/widget/OptionWidget.java +++ b/src/main/java/net/vulkanmod/config/widget/OptionWidget.java @@ -12,7 +12,6 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.navigation.ScreenRectangle; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.client.sounds.SoundManager; @@ -21,7 +20,6 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; import net.vulkanmod.vulkan.util.ColorUtil; -import net.vulkanmod.vulkan.util.VUtil; import java.util.Objects; import java.util.function.Consumer; @@ -76,7 +74,7 @@ public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float RenderSystem.defaultBlendFunc(); RenderSystem.enableDepthTest(); - int color = this.controlHovered ? ColorUtil.packColorInt(0.0f, 0.0f, 0.0f, 0.45f) : ColorUtil.packColorInt(0.0f, 0.0f, 0.0f, 0.3f); + int color = this.controlHovered ? ColorUtil.packColorIntRGBA(0.0f, 0.0f, 0.0f, 0.45f) : ColorUtil.packColorIntRGBA(0.0f, 0.0f, 0.0f, 0.3f); if(this.hovered) guiGraphics.fill(this.x - 2, this.y - 2, this.x + this.width + 2, this.y + this.height + 2, 0x28000000); diff --git a/src/main/java/net/vulkanmod/config/widget/RangeOptionWidget.java b/src/main/java/net/vulkanmod/config/widget/RangeOptionWidget.java index 1800725db..57579d01d 100644 --- a/src/main/java/net/vulkanmod/config/widget/RangeOptionWidget.java +++ b/src/main/java/net/vulkanmod/config/widget/RangeOptionWidget.java @@ -1,7 +1,6 @@ package net.vulkanmod.config.widget; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.sounds.SoundManager; @@ -9,7 +8,6 @@ import net.minecraft.util.Mth; import net.vulkanmod.config.RangeOption; import net.vulkanmod.vulkan.util.ColorUtil; -import net.vulkanmod.vulkan.util.VUtil; import org.lwjgl.glfw.GLFW; public class RangeOptionWidget extends OptionWidget { @@ -40,7 +38,7 @@ protected void renderBackground(GuiGraphics guiGraphics, Minecraft client, int m // this.drawTexture(matrices, this.controlX + (int)(this.value * (this.controlWidth - 8)), this.y, 0, 46 + i, 4, 20); // this.drawTexture(matrices, this.controlX + (int)(this.value * (this.controlWidth - 8)) + 4, this.y, 196, 46 + i, 4, 20); - int color = this.controlHovered ? ColorUtil.packColorInt(1.0f, 1.0f, 1.0f, 1.0f) : ColorUtil.packColorInt(1.0f, 1.0f, 1.0f, 0.8f); + int color = this.controlHovered ? ColorUtil.packColorIntRGBA(1.0f, 1.0f, 1.0f, 1.0f) : ColorUtil.packColorIntRGBA(1.0f, 1.0f, 1.0f, 0.8f); guiGraphics.fill(this.controlX + (int)(this.value * (this.controlWidth - 8)), this.y + 20, this.controlX + (int)(this.value * (this.controlWidth - 8)) + 8, this.y, color); } diff --git a/src/main/java/net/vulkanmod/gl/GlFramebuffer.java b/src/main/java/net/vulkanmod/gl/GlFramebuffer.java index 415799b21..8737aedd2 100644 --- a/src/main/java/net/vulkanmod/gl/GlFramebuffer.java +++ b/src/main/java/net/vulkanmod/gl/GlFramebuffer.java @@ -3,23 +3,23 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.framebuffer.Framebuffer; -import org.apache.commons.lang3.Validate; +import net.vulkanmod.vulkan.framebuffer.RenderPass; +import net.vulkanmod.vulkan.texture.VulkanImage; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL30C; -public class GlFramebuffer { +import static org.lwjgl.vulkan.VK11.*; - private static int ID_COUNT = 0; +public class GlFramebuffer { + private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundId = 0; private static GlFramebuffer boundFramebuffer; - private static GlFramebuffer boundRenderbuffer; public static int genFramebufferId() { - int id = ID_COUNT; + int id = ID_COUNTER; map.put(id, new GlFramebuffer(id)); - ID_COUNT++; + ID_COUNTER++; return id; } @@ -28,21 +28,52 @@ public static void bindFramebuffer(int target, int id) { // 36160 GL_FRAMEBUFFER // 36161 GL_RENDERBUFFER - if(target != GL30C.GL_FRAMEBUFFER) { - throw new IllegalArgumentException("target is not GL_FRAMEBUFFER"); +// if(target != GL30.GL_FRAMEBUFFER) { +// throw new IllegalArgumentException("target is not GL_FRAMEBUFFER"); +// } + + if(boundId == id) + return; + + if(id == 0) { + Renderer.getInstance().endRenderPass(); + +// RenderTarget renderTarget = Minecraft.getInstance().getMainRenderTarget(); +// if(renderTarget != null) +// renderTarget.bindWrite(true); + boundFramebuffer = null; + boundId = 0; + return; } - boundId = id; boundFramebuffer = map.get(id); if(boundFramebuffer == null) throw new NullPointerException("bound framebuffer is null"); - if(boundFramebuffer.framebuffer != null) - boundFramebuffer.beginRendering(); + if(boundFramebuffer.framebuffer != null) { + if(boundFramebuffer.beginRendering()) + boundId = id; + else + boundId = -1; + } + } + + public static void deleteFramebuffer(int id) { + if(id == 0) { + return; + } + + boundFramebuffer = map.remove(id); + + if(boundFramebuffer == null) + throw new NullPointerException("bound framebuffer is null"); + + boundFramebuffer.cleanUp(); + boundFramebuffer = null; } - public static void glFramebufferTexture2D(int target, int attachment, int texTarget, int texture, int level) { + public static void framebufferTexture2D(int target, int attachment, int texTarget, int texture, int level) { // GL30C.glFramebufferTexture2D(target, attachment, texTarget, texture, level); // attachment @@ -52,7 +83,7 @@ public static void glFramebufferTexture2D(int target, int attachment, int texTar // texTarget // 3553 texture2D - if(attachment != GL30C.GL_COLOR_ATTACHMENT0 && attachment != GL30C.GL_DEPTH_ATTACHMENT) { + if(attachment != GL30.GL_COLOR_ATTACHMENT0 && attachment != GL30.GL_DEPTH_ATTACHMENT) { throw new UnsupportedOperationException(); } if(texTarget != GL11.GL_TEXTURE_2D) { @@ -65,83 +96,152 @@ public static void glFramebufferTexture2D(int target, int attachment, int texTar boundFramebuffer.setAttachmentTexture(attachment, texture); } - public static void glFramebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer) { + public static void framebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer) { // GL30C.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); - if(target != GL30C.GL_FRAMEBUFFER) { - throw new IllegalArgumentException("target is not GL_FRAMEBUFFER"); - } - if(renderbuffertarget != GL30C.GL_RENDERBUFFER) { - throw new UnsupportedOperationException(); - } +// if(target != GL30.GL_FRAMEBUFFER) { +// throw new IllegalArgumentException("target is not GL_FRAMEBUFFER"); +// } +// if(renderbuffertarget != GL30.GL_RENDERBUFFER) { +// throw new UnsupportedOperationException(); +// } -// boundFramebuffer.setAttachmentTexture(attachment, texture); + boundFramebuffer.setAttachmentRenderbuffer(attachment, renderbuffer); //TODO } - public static void bindRenderbuffer(int target, int id) { - // target - // 36160 GL_FRAMEBUFFER - // 36161 GL_RENDERBUFFER - - if(target != GL30C.GL_RENDERBUFFER) { - throw new IllegalArgumentException("target is not GL_RENDERBUFFER"); - } - - boundRenderbuffer = map.get(id); - - if(boundRenderbuffer == null) - throw new NullPointerException("bound renderbuffer is null"); + public static int glCheckFramebufferStatus(int target) { + //TODO + return GL30.GL_FRAMEBUFFER_COMPLETE; } - public static void glRenderbufferStorage(int target, int internalformat, int width, int height) { - //TODO -// GL30C.glRenderbufferStorage(target, internalformat, width, height); + public static GlFramebuffer getBoundFramebuffer() { + return boundFramebuffer; } - public static int glCheckFramebufferStatus(int target) { - //TODO - return GL30.GL_FRAMEBUFFER_COMPLETE; + public static GlFramebuffer getFramebuffer(int id) { + return map.get(id); } private final int id; Framebuffer framebuffer; - GlTexture colorAttachment; - GlTexture depthAttachment; + RenderPass renderPass; + + VulkanImage colorAttachment; + VulkanImage depthAttachment; GlFramebuffer(int i) { this.id = i; } - void beginRendering() { - Renderer.getInstance().beginRendering(this.framebuffer); + boolean beginRendering() { + return Renderer.getInstance().beginRendering(this.renderPass, this.framebuffer); } void setAttachmentTexture(int attachment, int texture) { GlTexture glTexture = GlTexture.getTexture(texture); - Validate.notNull(glTexture); + + if(glTexture == null) + throw new NullPointerException(String.format("Texture %d is null", texture)); if(glTexture.vulkanImage == null) return; switch (attachment) { - case(GL30C.GL_COLOR_ATTACHMENT0) -> + case(GL30.GL_COLOR_ATTACHMENT0) -> this.setColorAttachment(glTexture); - case(GL30C.GL_DEPTH_ATTACHMENT) -> - this.depthAttachment = glTexture; + case(GL30.GL_DEPTH_ATTACHMENT) -> + this.setDepthAttachment(glTexture); + + default -> throw new IllegalStateException("Unexpected value: " + attachment); + } + } + + void setAttachmentRenderbuffer(int attachment, int texture) { + GlRenderbuffer renderbuffer = GlRenderbuffer.getRenderbuffer(texture); + + if(renderbuffer == null) + throw new NullPointerException(String.format("Texture %d is null", texture)); + + if(renderbuffer.vulkanImage == null) + return; + + switch (attachment) { + case(GL30.GL_COLOR_ATTACHMENT0) -> + this.setColorAttachment(renderbuffer); + + case(GL30.GL_DEPTH_ATTACHMENT) -> + this.setDepthAttachment(renderbuffer); default -> throw new IllegalStateException("Unexpected value: " + attachment); } } void setColorAttachment(GlTexture texture) { - this.colorAttachment = texture; + this.colorAttachment = texture.vulkanImage; + createAndBind(); + } + + void setDepthAttachment(GlTexture texture) { + //TODO check if texture is in depth format + this.depthAttachment = texture.vulkanImage; + createAndBind(); + } + + void setColorAttachment(GlRenderbuffer texture) { + this.colorAttachment = texture.vulkanImage; + createAndBind(); + } + + void setDepthAttachment(GlRenderbuffer texture) { + //TODO check if texture is in depth format + this.depthAttachment = texture.vulkanImage; + createAndBind(); + } + + void createAndBind() { + //Cannot create without color attachment + if(this.colorAttachment == null) + return; - if(this.framebuffer == null) { - this.framebuffer = new Framebuffer(this.colorAttachment.vulkanImage); + if(this.framebuffer != null) { + this.cleanUp(); } + boolean hasDepthImage = this.depthAttachment != null; + VulkanImage depthImage = this.depthAttachment; +// hasDepthImage = false; +// VulkanImage depthImage = null; + + this.framebuffer = Framebuffer.builder(this.colorAttachment, depthImage).build(); + RenderPass.Builder builder = RenderPass.builder(this.framebuffer); + + builder.getColorAttachmentInfo() + .setLoadOp(VK_ATTACHMENT_LOAD_OP_LOAD) + .setFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + if(hasDepthImage) + builder.getDepthAttachmentInfo().setOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + + this.renderPass = builder.build(); + this.beginRendering(); } + + public Framebuffer getFramebuffer() { + return framebuffer; + } + + public RenderPass getRenderPass() { + return renderPass; + } + + void cleanUp() { + this.framebuffer.cleanUp(false); + this.renderPass.cleanUp(); + + this.framebuffer = null; + this.renderPass = null; + } } diff --git a/src/main/java/net/vulkanmod/gl/GlRenderbuffer.java b/src/main/java/net/vulkanmod/gl/GlRenderbuffer.java new file mode 100644 index 000000000..39634ff9b --- /dev/null +++ b/src/main/java/net/vulkanmod/gl/GlRenderbuffer.java @@ -0,0 +1,237 @@ +package net.vulkanmod.gl; + +import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; +import net.vulkanmod.vulkan.texture.SamplerManager; +import net.vulkanmod.vulkan.texture.ImageUtil; +import net.vulkanmod.vulkan.texture.VTextureSelector; +import net.vulkanmod.vulkan.texture.VulkanImage; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL30; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; + +import static org.lwjgl.vulkan.VK10.*; + +public class GlRenderbuffer { + private static int ID_COUNTER = 1; + private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); + private static int boundId = 0; + private static GlRenderbuffer bound; + + public static int genId() { + int id = ID_COUNTER; + map.put(id, new GlRenderbuffer(id)); + ID_COUNTER++; + return id; + } + + public static void bindRenderbuffer(int target, int id) { + boundId = id; + bound = map.get(id); + + if(id <= 0) + return; + + if(bound == null) + throw new NullPointerException("bound texture is null"); + + VulkanImage vulkanImage = bound.vulkanImage; + if(vulkanImage != null) + VTextureSelector.bindTexture(vulkanImage); + } + + public static void deleteRenderbuffer(int i) { + map.remove(i); + } + + public static GlRenderbuffer getRenderbuffer(int id) { + return map.get(id); + } + + public static void renderbufferStorage(int target, int internalFormat, int width, int height) { + if(width == 0 || height == 0) + return; + + bound.internalFormat = internalFormat; + + bound.allocateIfNeeded(width, height, internalFormat); + } + + public static void texParameteri(int target, int pName, int param) { + if(target != GL11.GL_TEXTURE_2D) + throw new UnsupportedOperationException(); + + switch (pName) { + case GL30.GL_TEXTURE_MAX_LEVEL -> bound.setMaxLevel(param); + case GL30.GL_TEXTURE_MAX_LOD -> bound.setMaxLod(param); + case GL30.GL_TEXTURE_MIN_LOD -> {} + case GL30.GL_TEXTURE_LOD_BIAS -> {} + + case GL11.GL_TEXTURE_MAG_FILTER -> bound.setMagFilter(param); + case GL11.GL_TEXTURE_MIN_FILTER -> bound.setMinFilter(param); + + default -> {} + } + + //TODO + } + + public static int getTexLevelParameter(int target, int level, int pName) { + if(bound == null || target == GL11.GL_TEXTURE_2D) + return -1; + + return switch (pName) { + case GL11.GL_TEXTURE_INTERNAL_FORMAT -> GlUtil.getGlFormat(bound.vulkanImage.format); + case GL11.GL_TEXTURE_WIDTH -> bound.vulkanImage.width; + case GL11.GL_TEXTURE_HEIGHT -> bound.vulkanImage.height; + + default -> -1; + }; + } + + public static void generateMipmap(int target) { + if(target != GL11.GL_TEXTURE_2D) + throw new UnsupportedOperationException(); + + bound.generateMipmaps(); + } + + public static void setVulkanImage(int id, VulkanImage vulkanImage) { + GlRenderbuffer texture = map.get(id); + + texture.vulkanImage = vulkanImage; + } + + public static GlRenderbuffer getBound() { + return bound; + } + + final int id; + VulkanImage vulkanImage; + int internalFormat; + + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + + public GlRenderbuffer(int id) { + this.id = id; + } + + void allocateIfNeeded(int width, int height, int format) { + int vkFormat = GlUtil.vulkanFormat(format); + + needsUpdate |= vulkanImage == null || + vulkanImage.width != width || vulkanImage.height != height || + vkFormat != vulkanImage.format; + + if(needsUpdate) { + allocateImage(width, height, vkFormat); + updateSampler(); + + needsUpdate = false; + } + } + + void allocateImage(int width, int height, int vkFormat) { + if(this.vulkanImage != null) + this.vulkanImage.free(); + + if(VulkanImage.isDepthFormat(vkFormat)) + this.vulkanImage = VulkanImage.createDepthImage(vkFormat, + width, height, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + false, true); + else + this.vulkanImage = new VulkanImage.Builder(width, height) + .setMipLevels(maxLevel + 1) + .setFormat(vkFormat) + .addUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + .createVulkanImage(); + + VTextureSelector.bindTexture(this.vulkanImage); + } + + void updateSampler() { + if(vulkanImage == null) + return; + + byte samplerFlags = magFilter == GL11.GL_LINEAR ? SamplerManager.LINEAR_FILTERING_BIT : 0; + samplerFlags |= minFilter == GL11.GL_LINEAR_MIPMAP_LINEAR ? SamplerManager.USE_MIPMAPS_BIT : 0; + vulkanImage.updateTextureSampler(maxLod, samplerFlags); + } + + private void uploadImage(ByteBuffer pixels) { + int width = this.vulkanImage.width; + int height = this.vulkanImage.height; + + if(internalFormat == GL11.GL_RGB && vulkanImage.format == VK_FORMAT_R8G8B8A8_UNORM) { + ByteBuffer RGBA_buffer = GlUtil.RGBtoRGBA_buffer(pixels); + this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, RGBA_buffer); + MemoryUtil.memFree(RGBA_buffer); + } else + this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, pixels); + + } + + void generateMipmaps() { + //TODO test + ImageUtil.generateMipmaps(vulkanImage); + } + + void setMaxLevel(int l) { + if(l < 0) + throw new IllegalStateException("max level cannot be < 0."); + + if(maxLevel != l) { + maxLevel = l; + needsUpdate = true; + } + } + + void setMaxLod(int l) { + if(l < 0) + throw new IllegalStateException("max level cannot be < 0."); + + if(maxLod != l) { + maxLod = l; + updateSampler(); + } + } + + void setMagFilter(int v) { + switch (v) { + case GL11.GL_LINEAR, GL11.GL_NEAREST + -> {} + + default -> throw new IllegalArgumentException("illegal mag filter value: " + v); + } + + this.magFilter = v; + updateSampler(); + } + + void setMinFilter(int v) { + switch (v) { + case GL11.GL_LINEAR, GL11.GL_NEAREST, + GL11.GL_LINEAR_MIPMAP_LINEAR, GL11.GL_NEAREST_MIPMAP_LINEAR, + GL11.GL_LINEAR_MIPMAP_NEAREST, GL11.GL_NEAREST_MIPMAP_NEAREST + -> {} + + default -> throw new IllegalArgumentException("illegal min filter value: " + v); + } + + this.magFilter = v; + updateSampler(); + } + + public VulkanImage getVulkanImage() { + return vulkanImage; + } + + public void setVulkanImage(VulkanImage vulkanImage) { + this.vulkanImage = vulkanImage; + } +} diff --git a/src/main/java/net/vulkanmod/gl/GlTexture.java b/src/main/java/net/vulkanmod/gl/GlTexture.java index 3177b092f..c0017e264 100644 --- a/src/main/java/net/vulkanmod/gl/GlTexture.java +++ b/src/main/java/net/vulkanmod/gl/GlTexture.java @@ -1,40 +1,40 @@ package net.vulkanmod.gl; -import com.mojang.blaze3d.platform.NativeImage; -import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.texture.SamplerManager; +import net.vulkanmod.vulkan.texture.ImageUtil; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; -import org.lwjgl.system.MemoryStack; +import org.lwjgl.opengl.GL30; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; -import java.nio.IntBuffer; import static org.lwjgl.vulkan.VK10.*; public class GlTexture { - private static int ID_COUNT = 0; + private static int ID_COUNTER = 1; private static final Int2ReferenceOpenHashMap map = new Int2ReferenceOpenHashMap<>(); private static int boundTextureId = 0; private static GlTexture boundTexture; public static int genTextureId() { - int id = ID_COUNT; + int id = ID_COUNTER; map.put(id, new GlTexture(id)); - ID_COUNT++; + ID_COUNTER++; return id; } public static void bindTexture(int id) { - if(id == -1) - return; - boundTextureId = id; boundTexture = map.get(id); + if(id <= 0) + return; + if(boundTexture == null) throw new NullPointerException("bound texture is null"); @@ -44,10 +44,16 @@ public static void bindTexture(int id) { } public static void glDeleteTextures(int i) { - map.remove(i); + GlTexture glTexture = map.remove(i); + VulkanImage image = glTexture != null ? glTexture.vulkanImage : null; + if(image != null) + MemoryManager.getInstance().addToFreeable(image); } public static GlTexture getTexture(int id) { + if (id == 0) + return null; + return map.get(id); } @@ -55,13 +61,16 @@ public static void texImage2D(int target, int level, int internalFormat, int wid if(width == 0 || height == 0) return; + //TODO levels + if(level != 0) + throw new UnsupportedOperationException(); + boundTexture.internalFormat = internalFormat; - if(width != boundTexture.vulkanImage.width || height != boundTexture.vulkanImage.height || vulkanFormat(format, type) != boundTexture.vulkanImage.format) { - boundTexture.allocateVulkanImage(width, height); - } + boundTexture.allocateIfNeeded(width, height, format, type); - boundTexture.uploadImage(pixels); + if(pixels != null) + boundTexture.uploadImage(pixels); } public static void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, @Nullable ByteBuffer pixels) { @@ -71,12 +80,31 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset VTextureSelector.uploadSubTexture(level, width, height, xOffset, yOffset,0, 0, width, pixels); } + public static void texParameteri(int target, int pName, int param) { + if(target != GL11.GL_TEXTURE_2D) + throw new UnsupportedOperationException(); + + switch (pName) { + case GL30.GL_TEXTURE_MAX_LEVEL -> boundTexture.setMaxLevel(param); + case GL30.GL_TEXTURE_MAX_LOD -> boundTexture.setMaxLod(param); + case GL30.GL_TEXTURE_MIN_LOD -> {} + case GL30.GL_TEXTURE_LOD_BIAS -> {} + + case GL11.GL_TEXTURE_MAG_FILTER -> boundTexture.setMagFilter(param); + case GL11.GL_TEXTURE_MIN_FILTER -> boundTexture.setMinFilter(param); + + default -> {} + } + + //TODO + } + public static int getTexLevelParameter(int target, int level, int pName) { if(boundTexture == null || target == GL11.GL_TEXTURE_2D) return -1; return switch (pName) { - case GL11.GL_TEXTURE_INTERNAL_FORMAT -> getGlFormat(boundTexture.vulkanImage.format); + case GL11.GL_TEXTURE_INTERNAL_FORMAT -> GlUtil.getGlFormat(boundTexture.vulkanImage.format); case GL11.GL_TEXTURE_WIDTH -> boundTexture.vulkanImage.width; case GL11.GL_TEXTURE_HEIGHT -> boundTexture.vulkanImage.height; @@ -84,6 +112,18 @@ public static int getTexLevelParameter(int target, int level, int pName) { }; } + public static void generateMipmap(int target) { + if(target != GL11.GL_TEXTURE_2D) + throw new UnsupportedOperationException(); + + boundTexture.generateMipmaps(); + } + + public static void getTexImage(int tex, int level, int format, int type, long pixels) { + VulkanImage image = boundTexture.vulkanImage; + ImageUtil.downloadTexture(image, pixels); + } + public static void setVulkanImage(int id, VulkanImage vulkanImage) { GlTexture texture = map.get(id); @@ -98,73 +138,128 @@ public static GlTexture getBoundTexture() { VulkanImage vulkanImage; int internalFormat; + boolean needsUpdate = false; + int maxLevel = 0; + int maxLod = 0; + int minFilter, magFilter = GL11.GL_LINEAR; + public GlTexture(int id) { this.id = id; } - private void allocateVulkanImage(int width, int height) { + void allocateIfNeeded(int width, int height, int format, int type) { + int vkFormat = GlUtil.vulkanFormat(format, type); + + needsUpdate |= vulkanImage == null || + vulkanImage.width != width || vulkanImage.height != height || + vkFormat != vulkanImage.format; + + if(needsUpdate) { + allocateImage(width, height, vkFormat); + updateSampler(); + + needsUpdate = false; + } + } + + void allocateImage(int width, int height, int vkFormat) { if(this.vulkanImage != null) this.vulkanImage.free(); - this.vulkanImage = new VulkanImage.Builder(width, height).createVulkanImage(); + if(VulkanImage.isDepthFormat(vkFormat)) + this.vulkanImage = VulkanImage.createDepthImage(vkFormat, + width, height, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + false, true); + else + this.vulkanImage = new VulkanImage.Builder(width, height) + .setMipLevels(maxLevel + 1) + .setFormat(vkFormat) + .addUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + .createVulkanImage(); + VTextureSelector.bindTexture(this.vulkanImage); } - private void uploadImage(@Nullable ByteBuffer pixels) { + void updateSampler() { + if(vulkanImage == null) + return; + + byte samplerFlags = magFilter == GL11.GL_LINEAR ? SamplerManager.LINEAR_FILTERING_BIT : 0; + samplerFlags |= minFilter == GL11.GL_LINEAR_MIPMAP_LINEAR ? SamplerManager.USE_MIPMAPS_BIT : 0; + vulkanImage.updateTextureSampler(maxLod, samplerFlags); + } + + private void uploadImage(ByteBuffer pixels) { int width = this.vulkanImage.width; int height = this.vulkanImage.height; - if(pixels != null) { + if(internalFormat == GL11.GL_RGB && vulkanImage.format == VK_FORMAT_R8G8B8A8_UNORM) { + ByteBuffer RGBA_buffer = GlUtil.RGBtoRGBA_buffer(pixels); + this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, RGBA_buffer); + MemoryUtil.memFree(RGBA_buffer); + } else + this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, pixels); - if(internalFormat == GL11.GL_RGB && vulkanImage.format == VK_FORMAT_R8G8B8A8_UNORM) { + } - ByteBuffer RGBA_buffer = Util.RGBtoRGBA_buffer(pixels); - this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, RGBA_buffer); - MemoryUtil.memFree(RGBA_buffer); + void generateMipmaps() { + //TODO test + ImageUtil.generateMipmaps(vulkanImage); + } - return; - } + void setMaxLevel(int l) { + if(l < 0) + throw new IllegalStateException("max level cannot be < 0."); - this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, pixels); + if(maxLevel != l) { + maxLevel = l; + needsUpdate = true; } - else { - pixels = MemoryUtil.memCalloc(width * height * 4); - this.vulkanImage.uploadSubTextureAsync(0, width, height, 0, 0, 0, 0, 0, pixels); - MemoryUtil.memFree(pixels); + } + + void setMaxLod(int l) { + if(l < 0) + throw new IllegalStateException("max level cannot be < 0."); + + if(maxLod != l) { + maxLod = l; + updateSampler(); } } - public VulkanImage getVulkanImage() { - return vulkanImage; + void setMagFilter(int v) { + switch (v) { + case GL11.GL_LINEAR, GL11.GL_NEAREST + -> {} + + default -> throw new IllegalArgumentException("illegal mag filter value: " + v); + } + + this.magFilter = v; + updateSampler(); } - public void setVulkanImage(VulkanImage vulkanImage) { - this.vulkanImage = vulkanImage; + void setMinFilter(int v) { + switch (v) { + case GL11.GL_LINEAR, GL11.GL_NEAREST, + GL11.GL_LINEAR_MIPMAP_LINEAR, GL11.GL_NEAREST_MIPMAP_LINEAR, + GL11.GL_LINEAR_MIPMAP_NEAREST, GL11.GL_NEAREST_MIPMAP_NEAREST + -> {} + + default -> throw new IllegalArgumentException("illegal min filter value: " + v); + } + + this.magFilter = v; + updateSampler(); } - private static int vulkanFormat(int glFormat, int type) { - return switch (glFormat) { - case GL11.GL_RGBA -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; - default -> throw new IllegalStateException("Unexpected value: " + type); - }; - case GL11.GL_RED -> - switch (type) { - case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; - default -> throw new IllegalStateException("Unexpected value: " + type); - }; - - default -> throw new IllegalStateException("Unexpected value: " + glFormat); - }; + public VulkanImage getVulkanImage() { + return vulkanImage; } - public static int getGlFormat(int vFormat) { - return switch (vFormat) { - case VK_FORMAT_R8G8B8A8_UNORM -> GL11.GL_RGBA; - case VK_FORMAT_R8_UNORM -> GL11.GL_RED; - default -> throw new IllegalStateException("Unexpected value: " + vFormat); - }; + public void setVulkanImage(VulkanImage vulkanImage) { + this.vulkanImage = vulkanImage; } } diff --git a/src/main/java/net/vulkanmod/gl/GlUtil.java b/src/main/java/net/vulkanmod/gl/GlUtil.java new file mode 100644 index 000000000..a5e232eb5 --- /dev/null +++ b/src/main/java/net/vulkanmod/gl/GlUtil.java @@ -0,0 +1,100 @@ +package net.vulkanmod.gl; + +import net.vulkanmod.vulkan.framebuffer.SwapChain; +import net.vulkanmod.vulkan.shader.SPIRVUtils; +import org.apache.commons.lang3.Validate; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL30; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; + +import static org.lwjgl.vulkan.VK10.*; + +public abstract class GlUtil { + + public static SPIRVUtils.ShaderKind extToShaderKind(String ext) { + return switch (ext) { + case ".vsh" -> SPIRVUtils.ShaderKind.VERTEX_SHADER; + case ".fsh" -> SPIRVUtils.ShaderKind.FRAGMENT_SHADER; + default -> throw new RuntimeException("unknown shader type: " + ext); + }; + } + + //Created buffer will need to be freed + public static ByteBuffer RGBtoRGBA_buffer(ByteBuffer in) { + Validate.isTrue(in.remaining() % 3 == 0, "bytebuffer is not RGB"); + + int outSize = in.remaining() * 4 / 3; + ByteBuffer out = MemoryUtil.memAlloc(outSize); + + int j = 0; + for(int i = 0; i < outSize; i+=4, j+=3) { + out.put(i, in.get(j)); + out.put(i + 1, in.get(j + 1)); + out.put(i + 2, in.get(j + 2)); + out.put(i + 3, (byte) 0xFF); + } + + return out; + } + + public static int vulkanFormat(int glFormat, int type) { + return switch (glFormat) { + case GL11.GL_RGBA -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_BGRA -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL11.GL_BYTE -> VK_FORMAT_B8G8R8A8_UNORM; + case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UINT; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8G8B8A8_UINT; + case GL11.GL_BYTE -> VK_FORMAT_R8G8B8A8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL11.GL_RED -> + switch (type) { + case GL11.GL_UNSIGNED_BYTE -> VK_FORMAT_R8_UNORM; + default -> throw new IllegalStateException("Unexpected type: " + type); + }; + case GL11.GL_DEPTH_COMPONENT -> +// switch (type) { +// case GL11.GL_FLOAT -> VK_FORMAT_D32_SFLOAT; +// default -> throw new IllegalStateException("Unexpected value: " + type); +// }; + SwapChain.getDefaultDepthFormat(); + + default -> throw new IllegalStateException("Unexpected format: " + glFormat); + }; + } + + public static int vulkanFormat(int glInternalFormat) { + return switch (glInternalFormat) { + case GL30.GL_UNSIGNED_INT_8_8_8_8_REV -> VK_FORMAT_R8G8B8A8_UINT; + case GL11.GL_DEPTH_COMPONENT, GL30.GL_DEPTH_COMPONENT32F, GL30.GL_DEPTH_COMPONENT24 -> +// switch (type) { +// case GL11.GL_FLOAT -> VK_FORMAT_D32_SFLOAT; +// default -> throw new IllegalStateException("Unexpected value: " + type); +// }; + SwapChain.getDefaultDepthFormat(); + + default -> throw new IllegalStateException("Unexpected value: " + glInternalFormat); + }; + } + + public static int getGlFormat(int vFormat) { + return switch (vFormat) { + case VK_FORMAT_R8G8B8A8_UNORM -> GL11.GL_RGBA; + case VK_FORMAT_R8_UNORM -> GL11.GL_RED; + default -> throw new IllegalStateException("Unexpected value: " + vFormat); + }; + } +} diff --git a/src/main/java/net/vulkanmod/gl/Util.java b/src/main/java/net/vulkanmod/gl/Util.java deleted file mode 100644 index 58695af8b..000000000 --- a/src/main/java/net/vulkanmod/gl/Util.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.vulkanmod.gl; - -import net.vulkanmod.vulkan.shader.SPIRVUtils; -import org.apache.commons.lang3.Validate; -import org.lwjgl.system.MemoryUtil; - -import java.nio.ByteBuffer; - -public class Util { - - public static SPIRVUtils.ShaderKind extToShaderKind(String in) { - return switch (in) { - case ".vsh" -> SPIRVUtils.ShaderKind.VERTEX_SHADER; - case ".fsh" -> SPIRVUtils.ShaderKind.FRAGMENT_SHADER; - default -> throw new RuntimeException("unknown shader type: " + in); - }; - } - - //Created buffer will need to be freed - public static ByteBuffer RGBtoRGBA_buffer(ByteBuffer in) { - Validate.isTrue(in.remaining() % 3 == 0, "bytebuffer is not RGB"); - - int outSize = in.remaining() * 4 / 3; - ByteBuffer out = MemoryUtil.memAlloc(outSize); - - int j = 0; - for(int i = 0; i < outSize; i+=4, j+=3) { - out.put(i, in.get(j)); - out.put(i + 1, in.get(j + 1)); - out.put(i + 2, in.get(j + 2)); - out.put(i + 3, (byte) 0xFF); - } - - return out; - } -} diff --git a/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java b/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java new file mode 100644 index 000000000..f5da47f6d --- /dev/null +++ b/src/main/java/net/vulkanmod/interfaces/ExtendedRenderTarget.java @@ -0,0 +1,10 @@ +package net.vulkanmod.interfaces; + +import net.vulkanmod.vulkan.framebuffer.RenderPass; + +public interface ExtendedRenderTarget { + + boolean isBound(); + + RenderPass getRenderPass(); +} diff --git a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java index 0c1979758..a69402ea1 100644 --- a/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java +++ b/src/main/java/net/vulkanmod/interfaces/ExtendedVertexBuilder.java @@ -1,8 +1,9 @@ package net.vulkanmod.interfaces; -import net.vulkanmod.render.vertex.VertexUtil; - public interface ExtendedVertexBuilder { void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal); + + //Particles + default void vertex(float x, float y, float z, float u, float v, int packedColor, int light) {} } diff --git a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java index eaa178a2c..99209ef7d 100644 --- a/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/chunk/LevelRendererMixin.java @@ -4,11 +4,13 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectListIterator; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; +import net.minecraft.client.renderer.chunk.SectionRenderDispatcher; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.core.BlockPos; @@ -171,13 +173,31 @@ public String getSectionStatistics() { return this.worldRenderer.getChunkStatistics(); } + /** + * @author + * @reason + */ + @Overwrite + public boolean hasRenderedAllSections() { + return this.worldRenderer.needsUpdate(); + } + + /** + * @author + * @reason + */ + @Overwrite + public int countRenderedSections() { + return this.worldRenderer.getVisibleSectionsCount(); + } + @Inject(method = "renderClouds", at = @At("HEAD")) private void pushProfiler2(PoseStack poseStack, Matrix4f matrix4f, float f, double d, double e, double g, CallbackInfo ci) { Profiler2 profiler = Profiler2.getMainProfiler(); profiler.push("clouds"); } - @Inject(method = "renderClouds", at = @At("TAIL")) + @Inject(method = "renderClouds", at = @At("RETURN")) private void popProfiler2(PoseStack poseStack, Matrix4f matrix4f, float f, double d, double e, double g, CallbackInfo ci) { Profiler2 profiler = Profiler2.getMainProfiler(); profiler.pop(); diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java b/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java index 12c2eadd3..73c45ec07 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/EffectInstanceM.java @@ -1,17 +1,24 @@ package net.vulkanmod.mixin.compatibility; import com.google.gson.JsonObject; +import com.mojang.blaze3d.shaders.BlendMode; import com.mojang.blaze3d.shaders.EffectProgram; import com.mojang.blaze3d.shaders.Program; -import com.mojang.blaze3d.shaders.Uniform; +import com.mojang.blaze3d.shaders.ProgramManager; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import net.minecraft.client.renderer.EffectInstance; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; +import net.vulkanmod.interfaces.ShaderMixed; +import net.vulkanmod.vulkan.Renderer; +import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.shader.layout.Field; +import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.shader.descriptor.UBO; +import net.vulkanmod.vulkan.shader.layout.Vec1f; +import net.vulkanmod.vulkan.shader.layout.Vec1i; import net.vulkanmod.vulkan.shader.parser.GlslConverter; import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.io.IOUtils; @@ -32,17 +39,31 @@ 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; import java.util.function.Supplier; @Mixin(EffectInstance.class) public class EffectInstanceM { - @Shadow @Final private Map uniformMap; - @Shadow @Final private List uniforms; + @Shadow @Final private Map uniformMap; + @Shadow @Final private List uniforms; - private Pipeline pipeline; + @Shadow private boolean dirty; + @Shadow private static EffectInstance lastAppliedEffect; + @Shadow @Final private BlendMode blend; + @Shadow private static int lastProgramId; + @Shadow @Final private int programId; + @Shadow @Final private List samplerLocations; + @Shadow @Final private List samplerNames; + @Shadow @Final private Map samplerMap; + + @Shadow @Final private String name; + private static GraphicsPipeline lastPipeline; + + private GraphicsPipeline pipeline; @Inject(method = "", at = @At(value = "INVOKE", @@ -68,7 +89,7 @@ private EffectProgram redirectShader(ResourceManager resourceManager, Program.Ty @Overwrite public void close() { - for (Uniform uniform : this.uniforms) { + for (com.mojang.blaze3d.shaders.Uniform uniform : this.uniforms) { uniform.close(); } @@ -93,14 +114,14 @@ private void createShaders(ResourceManager resourceManager, String vertexShader, //TODO GlslConverter converter = new GlslConverter(); - Pipeline.Builder builder = new Pipeline.Builder(DefaultVertexFormat.POSITION_TEX_COLOR); - converter.process(DefaultVertexFormat.POSITION_TEX_COLOR, vshSrc, fshSrc); + converter.process(vshSrc, fshSrc); UBO ubo = converter.getUBO(); this.setUniformSuppliers(ubo); + Pipeline.Builder builder = new Pipeline.Builder(DefaultVertexFormat.POSITION); builder.setUniforms(Collections.singletonList(ubo), converter.getSamplerList()); - builder.compileShaders(converter.getVshConverted(), converter.getFshConverted()); + builder.compileShaders(this.name, converter.getVshConverted(), converter.getFshConverted()); this.pipeline = builder.createGraphicsPipeline(); @@ -112,8 +133,8 @@ private void createShaders(ResourceManager resourceManager, String vertexShader, private void setUniformSuppliers(UBO ubo) { - for(Field field : ubo.getFields()) { - Uniform uniform = this.uniformMap.get(field.getName()); + for(Uniform v_uniform : ubo.getUniforms()) { + com.mojang.blaze3d.shaders.Uniform uniform = this.uniformMap.get(v_uniform.getName()); Supplier supplier; ByteBuffer byteBuffer; @@ -128,11 +149,18 @@ else if (uniform.getType() <= 10) { throw new RuntimeException("out of bounds value for uniform " + uniform); } +// if(v_uniform instanceof Vec1f) { +// ((Vec1f)v_uniform).setSupplier(); +// } +// else if(v_uniform instanceof Vec1i) { +// +// } + MappedBuffer mappedBuffer = MappedBuffer.createFromBuffer(byteBuffer); supplier = () -> mappedBuffer; - //TODO vec1 + //TODO vec1 - maybe done - field.setSupplier(supplier); + v_uniform.setSupplier(supplier); } } @@ -150,41 +178,41 @@ private String[] decompose(String string, char c) { return strings; } -// /** -// * @author -// * @reason -// */ -// @Overwrite -// public void apply() { -// RenderSystem.assertOnGameThread(); -// this.dirty = false; -// lastAppliedEffect = this; -// this.blend.apply(); -// if (this.programId != lastProgramId) { -// ProgramManager.glUseProgram(this.programId); -// lastProgramId = this.programId; -// } -// -// for(int i = 0; i < this.samplerLocations.size(); ++i) { -// String string = (String)this.samplerNames.get(i); -// IntSupplier intSupplier = (IntSupplier)this.samplerMap.get(string); -// if (intSupplier != null) { -// RenderSystem.activeTexture('蓀' + i); -// RenderSystem.enableTexture(); -// int j = intSupplier.getAsInt(); -// if (j != -1) { -// RenderSystem.bindTexture(j); -// Uniform.uploadInteger((Integer)this.samplerLocations.get(i), i); -// } -// } -// } -// -// Iterator var5 = this.uniforms.iterator(); -// -// while(var5.hasNext()) { -// Uniform uniform = (Uniform)var5.next(); -// uniform.upload(); -// } -// -// } + /** + * @author + * @reason + */ + @Overwrite + public void apply() { + RenderSystem.assertOnGameThread(); + this.dirty = false; + this.blend.apply(); + + Renderer renderer = Renderer.getInstance(); + + if (this.pipeline != lastPipeline) { + renderer.bindGraphicsPipeline(pipeline); + lastPipeline = this.pipeline; + } + + for(int i = 0; i < this.samplerLocations.size(); ++i) { + String string = this.samplerNames.get(i); + IntSupplier intSupplier = this.samplerMap.get(string); + if (intSupplier != null) { + RenderSystem.activeTexture('蓀' + i); + int j = intSupplier.getAsInt(); + if (j != -1) { + RenderSystem.bindTexture(j); + com.mojang.blaze3d.shaders.Uniform.uploadInteger(this.samplerLocations.get(i), i); + } + } + } + + for (com.mojang.blaze3d.shaders.Uniform uniform : this.uniforms) { + uniform.upload(); + } + + renderer.uploadAndBindUBOs(pipeline); + + } } diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/PostChainM.java b/src/main/java/net/vulkanmod/mixin/compatibility/PostChainM.java new file mode 100644 index 000000000..1ac35aa91 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/compatibility/PostChainM.java @@ -0,0 +1,285 @@ +package net.vulkanmod.mixin.compatibility; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.renderer.PostChain; +import net.minecraft.client.renderer.PostPass; +import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.ChainedJsonException; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.GsonHelper; +import org.jetbrains.annotations.Nullable; +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 java.io.IOException; +import java.io.Reader; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@Mixin(PostChain.class) +public abstract class PostChainM { + + @Shadow @Final private ResourceManager resourceManager; + + @Shadow public abstract void addTempTarget(String string, int i, int j); + + @Shadow private int screenWidth; + + @Shadow private int screenHeight; + + @Shadow @Final private Map customRenderTargets; + + @Shadow @Final private RenderTarget screenTarget; + + @Shadow @Final private List passes; + + @Shadow protected abstract void parseUniformNode(JsonElement jsonElement) throws ChainedJsonException; + + @Shadow private float lastStamp; + + @Shadow private float time; + + @Shadow protected abstract void parseTargetNode(JsonElement jsonElement) throws ChainedJsonException; + +// /** +// * @author +// * @reason +// */ +// @Overwrite +// private void load(TextureManager textureManager, ResourceLocation resourceLocation) throws IOException, JsonSyntaxException { +// Resource resource = this.resourceManager.getResourceOrThrow(resourceLocation); +// +// try { +// Reader reader = resource.openAsReader(); +// +// try { +// JsonObject jsonObject = GsonHelper.parse(reader); +// JsonArray jsonArray; +// int i; +// JsonElement jsonElement; +// if (GsonHelper.isArrayNode(jsonObject, "targets")) { +// jsonArray = jsonObject.getAsJsonArray("targets"); +// i = 0; +// +// Iterator iterator; +// for(iterator = jsonArray.iterator(); iterator.hasNext(); ++i) { +// jsonElement = iterator.next(); +// +// try { +// this.parseTargetNode(jsonElement); +// } catch (Exception var14) { +// ChainedJsonException chainedJsonException = ChainedJsonException.forException(var14); +// chainedJsonException.prependJsonKey("targets[" + i + "]"); +// throw chainedJsonException; +// } +// } +// } +// +// if (GsonHelper.isArrayNode(jsonObject, "passes")) { +// jsonArray = jsonObject.getAsJsonArray("passes"); +// i = 0; +// +// Iterator iterator; +// for(iterator = jsonArray.iterator(); iterator.hasNext(); ++i) { +// jsonElement = iterator.next(); +// +// try { +// this.parsePassNode(textureManager, jsonElement); +// } catch (Exception var13) { +// ChainedJsonException chainedJsonException = ChainedJsonException.forException(var13); +// chainedJsonException.prependJsonKey("passes[" + i + "]"); +// throw chainedJsonException; +// } +// } +// } +// } catch (Throwable var15) { +// try { +// reader.close(); +// } catch (Throwable var12) { +// var15.addSuppressed(var12); +// } +// +// throw var15; +// } +// +// reader.close(); +// +// } catch (Exception var16) { +// ChainedJsonException chainedJsonException2 = ChainedJsonException.forException(var16); +// String var10001 = resourceLocation.getPath(); +// chainedJsonException2.setFilenameAndFlush(var10001 + " (" + resource.sourcePackId() + ")"); +// throw chainedJsonException2; +// } +// } + +// /** +// * @author +// * @reason +// */ +// @Overwrite +// private void parseTargetNode(JsonElement jsonElement) throws ChainedJsonException { +// if (GsonHelper.isStringValue(jsonElement)) { +// this.addTempTarget(jsonElement.getAsString(), this.screenWidth, this.screenHeight); +// } else { +// JsonObject jsonObject = GsonHelper.convertToJsonObject(jsonElement, "target"); +// String string = GsonHelper.getAsString(jsonObject, "name"); +// int i = GsonHelper.getAsInt(jsonObject, "width", this.screenWidth); +// int j = GsonHelper.getAsInt(jsonObject, "height", this.screenHeight); +// if (this.customRenderTargets.containsKey(string)) { +// throw new ChainedJsonException(string + " is already defined"); +// } +// +// this.addTempTarget(string, i, j); +// } +// +// } + + /** + * @author + * @reason + */ + @Overwrite + private void parsePassNode(TextureManager textureManager, JsonElement jsonElement) throws IOException { + JsonObject jsonObject = GsonHelper.convertToJsonObject(jsonElement, "pass"); + String string = GsonHelper.getAsString(jsonObject, "name"); + String string2 = GsonHelper.getAsString(jsonObject, "intarget"); + String string3 = GsonHelper.getAsString(jsonObject, "outtarget"); + RenderTarget renderTarget = this.getRenderTarget(string2); + RenderTarget renderTarget2 = this.getRenderTarget(string3); + if (renderTarget == null) { + throw new ChainedJsonException("Input target '" + string2 + "' does not exist"); + } else if (renderTarget2 == null) { + throw new ChainedJsonException("Output target '" + string3 + "' does not exist"); + } else { + PostPass postPass = this.addPass(string, renderTarget, renderTarget2); + JsonArray jsonArray = GsonHelper.getAsJsonArray(jsonObject, "auxtargets", null); + if (jsonArray != null) { + int i = 0; + + for(Iterator var12 = jsonArray.iterator(); var12.hasNext(); ++i) { + JsonElement jsonElement2 = (JsonElement)var12.next(); + + try { + JsonObject jsonObject2 = GsonHelper.convertToJsonObject(jsonElement2, "auxtarget"); + String string4 = GsonHelper.getAsString(jsonObject2, "name"); + String string5 = GsonHelper.getAsString(jsonObject2, "id"); + boolean bl; + String string6; + if (string5.endsWith(":depth")) { + bl = true; + string6 = string5.substring(0, string5.lastIndexOf(58)); + } else { + bl = false; + string6 = string5; + } + + RenderTarget renderTarget3 = this.getRenderTarget(string6); + if (renderTarget3 == null) { + if (bl) { + throw new ChainedJsonException("Render target '" + string6 + "' can't be used as depth buffer"); + } + + ResourceLocation resourceLocation = new ResourceLocation("textures/effect/" + string6 + ".png"); + this.resourceManager.getResource(resourceLocation).orElseThrow(() -> { + return new ChainedJsonException("Render target or texture '" + string6 + "' does not exist"); + }); + RenderSystem.setShaderTexture(0, resourceLocation); + textureManager.bindForSetup(resourceLocation); + AbstractTexture abstractTexture = textureManager.getTexture(resourceLocation); + int j = GsonHelper.getAsInt(jsonObject2, "width"); + int k = GsonHelper.getAsInt(jsonObject2, "height"); + boolean bl2 = GsonHelper.getAsBoolean(jsonObject2, "bilinear"); + if (bl2) { + RenderSystem.texParameter(3553, 10241, 9729); + RenderSystem.texParameter(3553, 10240, 9729); + } else { + RenderSystem.texParameter(3553, 10241, 9728); + RenderSystem.texParameter(3553, 10240, 9728); + } + + Objects.requireNonNull(abstractTexture); + postPass.addAuxAsset(string4, abstractTexture::getId, j, k); + } else if (bl) { + Objects.requireNonNull(renderTarget3); + postPass.addAuxAsset(string4, renderTarget3::getDepthTextureId, renderTarget3.width, renderTarget3.height); + } else { + Objects.requireNonNull(renderTarget3); + postPass.addAuxAsset(string4, renderTarget3::getColorTextureId, renderTarget3.width, renderTarget3.height); + } + } catch (Exception e) { + ChainedJsonException chainedJsonException = ChainedJsonException.forException(e); + chainedJsonException.prependJsonKey("auxtargets[" + i + "]"); + throw chainedJsonException; + } + } + } + + JsonArray jsonArray2 = GsonHelper.getAsJsonArray(jsonObject, "uniforms", null); + if (jsonArray2 != null) { + int l = 0; + + for(Iterator var29 = jsonArray2.iterator(); var29.hasNext(); ++l) { + JsonElement jsonElement3 = var29.next(); + + try { + this.parseUniformNode(jsonElement3); + } catch (Exception var25) { + ChainedJsonException chainedJsonException2 = ChainedJsonException.forException(var25); + chainedJsonException2.prependJsonKey("uniforms[" + l + "]"); + throw chainedJsonException2; + } + } + } + + } + } + + private RenderTarget getRenderTarget(@Nullable String string) { + if (string == null) { + return null; + } else { + return string.equals("minecraft:main") ? this.screenTarget : this.customRenderTargets.get(string); + } + } + + public PostPass addPass(String string, RenderTarget renderTarget, RenderTarget renderTarget2) throws IOException { + PostPass postPass = new PostPass(this.resourceManager, string, renderTarget, renderTarget2); + this.passes.add(this.passes.size(), postPass); + return postPass; + } + + /** + * @author + * @reason + */ + @Overwrite + public void process(float f) { + if (f < this.lastStamp) { + this.time += 1.0F - this.lastStamp; + this.time += f; + } else { + this.time += f - this.lastStamp; + } + + for(this.lastStamp = f; this.time > 20.0F; this.time -= 20.0F) { + } + + for (PostPass postPass : this.passes) { + postPass.process(this.time / 20.0F); + } + + } + +} diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java new file mode 100644 index 000000000..cf5722766 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/compatibility/PostPassM.java @@ -0,0 +1,91 @@ +package net.vulkanmod.mixin.compatibility; + +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.EffectInstance; +import net.minecraft.client.renderer.PostPass; +import org.joml.Matrix4f; +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 java.util.List; +import java.util.Objects; +import java.util.function.IntSupplier; + +@Mixin(PostPass.class) +public class PostPassM { + + @Shadow @Final public RenderTarget inTarget; + + @Shadow @Final public RenderTarget outTarget; + + @Shadow @Final private EffectInstance effect; + + @Shadow @Final private List auxAssets; + + @Shadow @Final private List auxNames; + + @Shadow @Final private List auxWidths; + + @Shadow @Final private List auxHeights; + + @Shadow private Matrix4f shaderOrthoMatrix; + + /** + * @author + * @reason + */ + @Overwrite + public void process(float f) { + this.inTarget.unbindWrite(); + float g = (float)this.outTarget.width; + float h = (float)this.outTarget.height; + RenderSystem.viewport(0, 0, (int)g, (int)h); + + Objects.requireNonNull(this.inTarget); + this.effect.setSampler("DiffuseSampler", this.inTarget::getColorTextureId); + + for(int i = 0; i < this.auxAssets.size(); ++i) { + this.effect.setSampler(this.auxNames.get(i), this.auxAssets.get(i)); + this.effect.safeGetUniform("AuxSize" + i).set((float) this.auxWidths.get(i), (float) this.auxHeights.get(i)); + } + + this.effect.safeGetUniform("ProjMat").set(this.shaderOrthoMatrix); + this.effect.safeGetUniform("InSize").set((float)this.inTarget.width, (float)this.inTarget.height); + this.effect.safeGetUniform("OutSize").set(g, h); + this.effect.safeGetUniform("Time").set(f); + Minecraft minecraft = Minecraft.getInstance(); + this.effect.safeGetUniform("ScreenSize").set((float)minecraft.getWindow().getWidth(), (float)minecraft.getWindow().getHeight()); + + this.outTarget.clear(Minecraft.ON_OSX); + this.outTarget.bindWrite(false); + + this.effect.apply(); + + RenderSystem.depthFunc(519); + + BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder(); + bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION); + bufferBuilder.vertex(0.0, 0.0, 500.0).endVertex(); + bufferBuilder.vertex(g, 0.0, 500.0).endVertex(); + bufferBuilder.vertex(g, h, 500.0).endVertex(); + bufferBuilder.vertex(0.0, h, 500.0).endVertex(); + BufferUploader.draw(bufferBuilder.end()); + RenderSystem.depthFunc(515); + + this.effect.clear(); + this.outTarget.unbindWrite(); + this.inTarget.unbindRead(); + + for (Object object : this.auxAssets) { + if (object instanceof RenderTarget) { + ((RenderTarget) object).unbindRead(); + } + } + + } +} diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/ProgramM.java b/src/main/java/net/vulkanmod/mixin/compatibility/ProgramM.java index 2eed96df2..7771c43f9 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/ProgramM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/ProgramM.java @@ -2,7 +2,7 @@ import com.mojang.blaze3d.preprocessor.GlslPreprocessor; import com.mojang.blaze3d.shaders.Program; -import net.vulkanmod.gl.Util; +import net.vulkanmod.gl.GlUtil; import net.vulkanmod.vulkan.shader.SPIRVUtils; import org.apache.commons.io.IOUtils; import org.spongepowered.asm.mixin.Mixin; @@ -35,9 +35,9 @@ public static int compileShaderInternal(Program.Type type, String string, InputS // return i; // } - //TODO + //TODO maybe not needed? glslPreprocessor.process(string3); - SPIRVUtils.compileShader(string2 + ":" + string, string3, Util.extToShaderKind(type.getExtension())); + SPIRVUtils.compileShader(string2 + ":" + string, string3, GlUtil.extToShaderKind(type.getExtension())); } return 0; } diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/UniformM.java b/src/main/java/net/vulkanmod/mixin/compatibility/UniformM.java index 0fa7f00e4..75c2985cd 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/UniformM.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/UniformM.java @@ -1,6 +1,7 @@ package net.vulkanmod.mixin.compatibility; import com.mojang.blaze3d.shaders.Uniform; +import com.mojang.blaze3d.systems.RenderSystem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.At; @@ -33,4 +34,9 @@ public static int glGetAttribLocation(int i, CharSequence charSequence) { public void cancelUpload(CallbackInfo ci) { ci.cancel(); } + + @Inject(method = "uploadInteger", at = @At("HEAD"), cancellable = true) + private static void cancelUploadInteger(int i, int j, CallbackInfo ci) { + ci.cancel(); + } } diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java index 949c112a3..a0f160406 100644 --- a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL11M.java @@ -1,14 +1,15 @@ package net.vulkanmod.mixin.compatibility.gl; import net.vulkanmod.gl.GlTexture; -import net.vulkanmod.vulkan.Drawer; -import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.VRenderSystem; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11C; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.NativeType; +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 javax.annotation.Nullable; import java.nio.ByteBuffer; @@ -61,7 +62,7 @@ public static boolean glIsEnabled(@NativeType("GLenum") int cap) { */ @Overwrite(remap = false) public static void glClear(@NativeType("GLbitfield") int mask) { - //TODO + VRenderSystem.clear(mask); } /** @@ -80,7 +81,7 @@ public static int glGetError() { */ @Overwrite(remap = false) public static void glClearColor(@NativeType("GLfloat") float red, @NativeType("GLfloat") float green, @NativeType("GLfloat") float blue, @NativeType("GLfloat") float alpha) { - //TODO + VRenderSystem.clearColor(red, green, blue, alpha); } /** @@ -126,7 +127,7 @@ public static void glTexSubImage2D(int target, int level, int xOffset, int yOffs */ @Overwrite(remap = false) public static void glTexParameteri(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint") int param) { - //TODO + GlTexture.texParameteri(target, pname, param); } /** @@ -154,4 +155,22 @@ public static void glEnable(@NativeType("GLenum") int target) { @Overwrite(remap = false) public static void glDisable(@NativeType("GLenum") int target) { } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") long pixels) { + GlTexture.getTexImage(tex, level, format, type, pixels); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glCopyTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { + //TODO + } } diff --git a/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java new file mode 100644 index 000000000..1a34e6bb9 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/compatibility/gl/GL30M.java @@ -0,0 +1,117 @@ +package net.vulkanmod.mixin.compatibility.gl; + +import net.vulkanmod.gl.GlFramebuffer; +import net.vulkanmod.gl.GlRenderbuffer; +import net.vulkanmod.gl.GlTexture; +import org.lwjgl.opengl.GL30; +import org.lwjgl.system.NativeType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(GL30.class) +public class GL30M { + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glGenerateMipmap(@NativeType("GLenum") int target) { + GlTexture.generateMipmap(target); + } + + /** + * @author + * @reason + */ + @NativeType("void") + @Overwrite(remap = false) + public static int glGenFramebuffers() { + return GlFramebuffer.genFramebufferId(); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glBindFramebuffer(@NativeType("GLenum") int target, @NativeType("GLuint") int framebuffer) { + GlFramebuffer.bindFramebuffer(target, framebuffer); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glFramebufferTexture2D(@NativeType("GLenum") int target, @NativeType("GLenum") int attachment, @NativeType("GLenum") int textarget, @NativeType("GLuint") int texture, @NativeType("GLint") int level) { + GlFramebuffer.framebufferTexture2D(target, attachment, textarget, texture, level); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glFramebufferRenderbuffer(@NativeType("GLenum") int target, @NativeType("GLenum") int attachment, @NativeType("GLenum") int renderbuffertarget, @NativeType("GLuint") int renderbuffer) { +// GL30C.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glDeleteFramebuffers(@NativeType("GLuint const *") int framebuffer) { + GlFramebuffer.deleteFramebuffer(framebuffer); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + @NativeType("GLenum") + public static int glCheckFramebufferStatus(@NativeType("GLenum") int target) { + return GlFramebuffer.glCheckFramebufferStatus(target); + } + + //RENDER BUFFER + + /** + * @author + * @reason + */ + @NativeType("void") + @Overwrite(remap = false) + public static int glGenRenderbuffers() { + return GlRenderbuffer.genId(); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glBindRenderbuffer(@NativeType("GLenum") int target, @NativeType("GLuint") int framebuffer) { + GlRenderbuffer.bindRenderbuffer(target, framebuffer); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glRenderbufferStorage(@NativeType("GLenum") int target, @NativeType("GLenum") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { + GlRenderbuffer.renderbufferStorage(target, internalformat, width, height); + } + + /** + * @author + * @reason + */ + @Overwrite(remap = false) + public static void glDeleteRenderbuffers(@NativeType("GLuint const *") int renderbuffer) { + GlRenderbuffer.deleteRenderbuffer(renderbuffer); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java index 1d3cc0ade..e1bdea153 100644 --- a/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/BufferUploaderM.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.BufferUploader; +import net.minecraft.client.renderer.ShaderInstance; import net.vulkanmod.interfaces.ShaderMixed; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.shader.GraphicsPipeline; @@ -34,7 +35,12 @@ public static void drawWithShader(BufferBuilder.RenderedBuffer buffer) { if(parameters.vertexCount() <= 0) return; - GraphicsPipeline pipeline = ((ShaderMixed)(RenderSystem.getShader())).getPipeline(); + ShaderInstance shaderInstance = RenderSystem.getShader(); + //Used to update legacy shader uniforms + //TODO it would be faster to allocate a buffer from stack and set all values + shaderInstance.apply(); + + GraphicsPipeline pipeline = ((ShaderMixed)(shaderInstance)).getPipeline(); renderer.bindGraphicsPipeline(pipeline); renderer.uploadAndBindUBOs(pipeline); Renderer.getDrawer().draw(buffer.vertexBuffer(), parameters.mode(), parameters.format(), parameters.vertexCount()); diff --git a/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java index 9fc5a1624..6b9c97315 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/GameRendererMixin.java @@ -89,7 +89,9 @@ public abstract class GameRendererMixin { @Shadow private static @Nullable ShaderInstance rendertypeGuiTextHighlightShader; @Shadow private static @Nullable ShaderInstance rendertypeGuiGhostRecipeOverlayShader; - @Shadow protected abstract void shutdownShaders(); + @Shadow private @Nullable static ShaderInstance positionColorLightmapShader; + @Shadow private @Nullable static ShaderInstance positionColorTexLightmapShader; + @Shadow private @Nullable static ShaderInstance positionTexLightmapColorShader; @Shadow public ShaderInstance blitShader; @@ -116,14 +118,14 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { ShaderInstance positionColor = new ShaderInstance(provider, "position_color", DefaultVertexFormat.POSITION_COLOR); list1.add(Pair.of(positionColor, (shaderInstance) -> positionColorShader = shaderInstance)); -// list1.add(Pair.of(new ShaderInstance(provider, "position_color_lightmap", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), (p_172705_) -> { -// positionColorLightmapShader = p_172705_; +// 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) -> { positionColorTexShader = shaderInstance; })); -// list1.add(Pair.of(new ShaderInstance(provider, "position_color_tex_lightmap", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (p_172699_) -> { -// positionColorTexLightmapShader = p_172699_; +// list1.add(Pair.of(new ShaderInstance(provider, "position_color_tex_lightmap", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> { +// positionColorTexLightmapShader = shaderInstance; // })); list1.add(Pair.of(new ShaderInstance(provider, "position_tex", DefaultVertexFormat.POSITION_TEX), (shaderInstance) -> { positionTexShader = shaderInstance; @@ -134,8 +136,8 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { list1.add(Pair.of(new ShaderInstance(provider, "position_tex_color_normal", DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL), (shaderInstance) -> { positionTexColorNormalShader = shaderInstance; })); -// list1.add(Pair.of(new ShaderInstance(provider, "position_tex_lightmap_color", DefaultVertexFormat.POSITION_TEX_LIGHTMAP_COLOR), (p_172687_) -> { -// positionTexLightmapColorShader = p_172687_; +// 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) -> { rendertypeSolidShader = shaderInstance; @@ -254,12 +256,9 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> { rendertypeTextSeeThroughShader = shaderInstance; })); - list1.add(Pair.of(positionColor, (shaderInstance) -> { + list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_background_see_through", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), (shaderInstance) -> { rendertypeTextBackgroundSeeThroughShader = shaderInstance; })); -// list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_background_see_through", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP), (shaderInstance) -> { -// rendertypeTextBackgroundSeeThroughShader = shaderInstance; -// })); list1.add(Pair.of(new ShaderInstance(provider, "rendertype_text_intensity_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), (shaderInstance) -> { rendertypeTextIntensitySeeThroughShader = shaderInstance; })); @@ -303,10 +302,7 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { throw new RuntimeException("could not reload shaders", ioexception); } - final var clearList = ImmutableList.copyOf(this.shaders.values()); - MemoryManager.getInstance().addFrameOp(() -> clearList.forEach((ShaderInstance::close))); - //this.shutdownShaders(); - //TODO: clear shaders + this.shutdownShaders(); list1.forEach((pair) -> { ShaderInstance shaderinstance = pair.getFirst(); this.shaders.put(shaderinstance.getName(), shaderinstance); @@ -316,6 +312,20 @@ public void reloadShaders(ResourceProvider provider, CallbackInfo ci) { ci.cancel(); } + /** + * @author + * @reason + */ + @Overwrite + private void shutdownShaders() { + RenderSystem.assertOnRenderThread(); + + final var clearList = ImmutableList.copyOf(this.shaders.values()); + MemoryManager.getInstance().addFrameOp(() -> clearList.forEach((ShaderInstance::close))); + + this.shaders.clear(); + } + /** * @author * @reason @@ -326,7 +336,7 @@ public void preloadUiShader(ResourceProvider resourceProvider) { throw new RuntimeException("Blit shader already preloaded"); } else { try { - this.blitShader = new ShaderInstance(resourceProvider, "blit_screen", DefaultVertexFormat.BLIT_SCREEN); + this.blitShader = new ShaderInstance(resourceProvider, "blit_screen", DefaultVertexFormat.POSITION_TEX); } catch (IOException var3) { throw new RuntimeException("could not preload blit shader", var3); } @@ -348,8 +358,8 @@ public void preloadUiShader(ResourceProvider resourceProvider) { // Renderer.clearAttachments(0x100); // } - @Redirect(method = "render", at = @At(value="INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V", ordinal = 0)) - private void remClear(int i, boolean bl) {} +// @Redirect(method = "render", at = @At(value="INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V", ordinal = 0)) +// private void remClear(int i, boolean bl) {} /** * @author diff --git a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java index afa6a94b6..c9b070fd7 100644 --- a/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java +++ b/src/main/java/net/vulkanmod/mixin/render/GlStateManagerM.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.gl.GlFramebuffer; +import net.vulkanmod.gl.GlRenderbuffer; import net.vulkanmod.gl.GlTexture; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; @@ -122,7 +123,7 @@ public static void _texSubImage2D(int target, int level, int offsetX, int offset */ @Overwrite(remap = false) public static void _texParameter(int i, int j, int k) { - //TODO + GlTexture.texParameteri(i, j, k); } /** @@ -146,7 +147,7 @@ public static int _getTexLevelParameter(int i, int j, int k) { */ @Overwrite(remap = false) public static void _pixelStore(int pname, int param) { - + //Used during upload to set copy offsets } /** @@ -194,6 +195,12 @@ public static void _clearColor(float f, float g, float h, float i) { VRenderSystem.clearColor(f, g, h, i); } + /** + * @author + */ + @Overwrite(remap = false) + public static void _clearDepth(double d) {} + /** * @author */ @@ -251,9 +258,8 @@ public static int glGenFramebuffers() { */ @Overwrite(remap = false) public static int glGenRenderbuffers() { - //TODO RenderSystem.assertOnRenderThreadOrInit(); - return GlFramebuffer.genFramebufferId(); + return GlRenderbuffer.genId(); } /** @@ -271,7 +277,7 @@ public static void _glBindFramebuffer(int i, int j) { @Overwrite(remap = false) public static void _glFramebufferTexture2D(int i, int j, int k, int l, int m) { RenderSystem.assertOnRenderThreadOrInit(); - GlFramebuffer.glFramebufferTexture2D(i, j, k, l, m); + GlFramebuffer.framebufferTexture2D(i, j, k, l, m); } /** @@ -280,7 +286,7 @@ public static void _glFramebufferTexture2D(int i, int j, int k, int l, int m) { @Overwrite(remap = false) public static void _glBindRenderbuffer(int i, int j) { RenderSystem.assertOnRenderThreadOrInit(); - GlFramebuffer.bindRenderbuffer(i, j); + GlRenderbuffer.bindRenderbuffer(i, j); } /** @@ -288,9 +294,8 @@ public static void _glBindRenderbuffer(int i, int j) { */ @Overwrite(remap = false) public static void _glFramebufferRenderbuffer(int i, int j, int k, int l) { - //TODO RenderSystem.assertOnRenderThreadOrInit(); - GlFramebuffer.glFramebufferRenderbuffer(i, j, k, l); + GlFramebuffer.framebufferRenderbuffer(i, j, k, l); } /** @@ -299,8 +304,7 @@ public static void _glFramebufferRenderbuffer(int i, int j, int k, int l) { @Overwrite(remap = false) public static void _glRenderbufferStorage(int i, int j, int k, int l) { RenderSystem.assertOnRenderThreadOrInit(); -// GL30.glRenderbufferStorage(i, j, k, l); - GlFramebuffer.glRenderbufferStorage(i, j, k, l); + GlRenderbuffer.renderbufferStorage(i, j, k, l); } /** diff --git a/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java b/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java index c5966fd0f..f397ee81f 100644 --- a/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/LevelRendererMixin.java @@ -1,40 +1,56 @@ package net.vulkanmod.mixin.render; +import com.google.gson.JsonSyntaxException; +import com.mojang.blaze3d.pipeline.RenderTarget; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.PostChain; +import net.minecraft.resources.ResourceLocation; 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.Redirect; + +import java.io.IOException; @Mixin(LevelRenderer.class) public abstract class LevelRendererMixin { @Shadow private @Nullable PostChain entityEffect; - /** - * @author - */ - @Overwrite - public void initOutline() { - if (this.entityEffect != null) { - this.entityEffect.close(); - } -// Identifier identifier = new Identifier("shaders/post/entity_outline.json"); -// try { -// this.entityOutlineShader = new ShaderEffect(this.minecraft.getTextureManager(), this.minecraft.getResourceManager(), this.minecraft.getFramebuffer(), identifier); -// this.entityOutlineShader.setupDimensions(this.minecraft.getWindow().getFramebufferWidth(), this.minecraft.getWindow().getFramebufferHeight()); -// this.entityOutlinesFramebuffer = this.entityOutlineShader.getSecondaryTarget("final"); -// } -// catch (IOException iOException) { -// LOGGER.warn("Failed to load shader: {}", (Object)identifier, (Object)iOException); -// this.entityOutlineShader = null; -// this.entityOutlinesFramebuffer = null; -// } -// catch (JsonSyntaxException iOException) { -// LOGGER.warn("Failed to parse shader: {}", (Object)identifier, (Object)iOException); -// this.entityOutlineShader = null; -// this.entityOutlinesFramebuffer = null; + @Shadow @Final private Minecraft minecraft; + + @Shadow @Nullable private RenderTarget entityTarget; + + @Shadow @Final private static Logger LOGGER; + +// /** +// * @author +// */ +// @Overwrite +// public void initOutline() { +// if (this.entityEffect != null) { +// this.entityEffect.close(); // } - } +// +//// ResourceLocation resourceLocation = new ResourceLocation("shaders/post/entity_outline.json"); +//// +//// try { +//// this.entityEffect = new PostChain(this.minecraft.getTextureManager(), this.minecraft.getResourceManager(), this.minecraft.getMainRenderTarget(), resourceLocation); +//// this.entityEffect.resize(this.minecraft.getWindow().getWidth(), this.minecraft.getWindow().getHeight()); +//// this.entityTarget = this.entityEffect.getTempTarget("final"); +//// } catch (IOException var3) { +//// LOGGER.warn("Failed to load shader: {}", resourceLocation, var3); +//// this.entityEffect = null; +//// this.entityTarget = null; +//// } catch (JsonSyntaxException var4) { +//// LOGGER.warn("Failed to parse shader: {}", resourceLocation, var4); +//// this.entityEffect = null; +//// this.entityTarget = null; +//// } +// } + } \ No newline at end of file diff --git a/src/main/java/net/vulkanmod/mixin/render/MainTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/MainTargetMixin.java deleted file mode 100644 index 2806c2cda..000000000 --- a/src/main/java/net/vulkanmod/mixin/render/MainTargetMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.vulkanmod.mixin.render; - -import com.mojang.blaze3d.pipeline.MainTarget; -import com.mojang.blaze3d.pipeline.RenderTarget; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; - -@Mixin(MainTarget.class) -public class MainTargetMixin extends RenderTarget { - - public MainTargetMixin(boolean useDepth) { - super(useDepth); - } - - /** - * @author - */ - @Overwrite - private void createFrameBuffer(int width, int height) { - - this.viewWidth = width; - this.viewHeight = height; - this.width = width; - this.height = height; - } - - - public void bindWrite(boolean updateViewport) { -// Drawer.getInstance().beginRendering(framebuffer); - } - - public void unbindWrite() { - - } -} diff --git a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java index 670ff1615..29bf5d96a 100644 --- a/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/MinecraftMixin.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.TimerQuery; import net.minecraft.Util; import net.minecraft.client.GraphicsStatus; @@ -40,8 +41,10 @@ private void forceGraphicsMode(GameConfig gameConfig, CallbackInfo ci) { } } + //Main target (framebuffer) ops @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;clear(IZ)V")) private void beginRender(int i, boolean bl) { + RenderSystem.clear(i, bl); Renderer.getInstance().beginFrame(); } @@ -52,16 +55,19 @@ private void submitRender(boolean tick, CallbackInfo ci) { @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;bindWrite(Z)V")) private void redirectMainTarget1(RenderTarget instance, boolean bl) { + Renderer.getInstance().getMainPass().mainTargetBindWrite(); } @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;unbindWrite()V")) private void redirectMainTarget2(RenderTarget instance) { + Renderer.getInstance().getMainPass().mainTargetUnbindWrite(); } @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/pipeline/RenderTarget;blitToScreen(II)V")) private void removeBlit(RenderTarget instance, int i, int j) { } + @Redirect(method = "runTick", at = @At(value = "INVOKE", target = "Ljava/lang/Thread;yield()V")) private void removeThreadYield() { } diff --git a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java index 6683425bb..5b5bef87b 100644 --- a/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java +++ b/src/main/java/net/vulkanmod/mixin/render/RenderSystemMixin.java @@ -9,10 +9,12 @@ import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.resources.ResourceLocation; +import net.vulkanmod.gl.GlTexture; import net.vulkanmod.interfaces.VAbstractTextureI; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.texture.VTextureSelector; +import net.vulkanmod.vulkan.texture.VulkanImage; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import org.joml.Vector3f; @@ -60,6 +62,20 @@ public static void _setShaderTexture(int i, ResourceLocation location) { } + /** + * @author + */ + @Overwrite(remap = false) + public static void _setShaderTexture(int i, int id) { + if (i >= 0 && i < VTextureSelector.SIZE) { + GlTexture glTexture = GlTexture.getTexture(id); + VulkanImage vulkanImage = glTexture != null ? glTexture.getVulkanImage() : null; + + VTextureSelector.bindTexture(i, vulkanImage); + } + + } + /** * @author */ diff --git a/src/main/java/net/vulkanmod/mixin/render/RenderTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/RenderTargetMixin.java deleted file mode 100644 index 1bae0fd9c..000000000 --- a/src/main/java/net/vulkanmod/mixin/render/RenderTargetMixin.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.vulkanmod.mixin.render; - -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.systems.RenderSystem; -import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.framebuffer.Framebuffer; -import net.vulkanmod.vulkan.util.DrawUtil; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(RenderTarget.class) -public class RenderTargetMixin { - - @Shadow public int viewWidth; - @Shadow public int viewHeight; - @Shadow public int width; - @Shadow public int height; - - Framebuffer framebuffer; - - /** - * @author - */ - @Overwrite - public void clear(boolean getError) {} - - /** - * @author - */ - @Overwrite - public void resize(int i, int j, boolean bl) { - if(this.framebuffer != null) { - this.framebuffer.cleanUp(); - } - - this.viewWidth = i; - this.viewHeight = j; - this.width = i; - this.height = j; - - //TODO -// this.framebuffer = new Framebuffer(this.width, this.height, Framebuffer.DEFAULT_FORMAT); - } - - /** - * @author - */ - @Overwrite - public void bindWrite(boolean updateViewport) { - Renderer.getInstance().beginRendering(framebuffer); - } - - /** - * @author - */ - @Overwrite - public void unbindWrite() { - - } - - /** - * @author - */ - @Overwrite - private void _blitToScreen(int width, int height, boolean disableBlend) { - RenderSystem.depthMask(false); - - DrawUtil.drawFramebuffer(this.framebuffer); - - RenderSystem.depthMask(true); - } -} diff --git a/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java b/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java index 954ff5744..ca625d7d1 100644 --- a/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java +++ b/src/main/java/net/vulkanmod/mixin/render/ShaderInstanceM.java @@ -1,20 +1,20 @@ package net.vulkanmod.mixin.render; import com.google.gson.JsonObject; +import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.shaders.Program; -import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.VertexFormat; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceProvider; import net.minecraft.util.GsonHelper; -import net.vulkanmod.Initializer; import net.vulkanmod.interfaces.ShaderMixed; import net.vulkanmod.vulkan.shader.GraphicsPipeline; import net.vulkanmod.vulkan.shader.Pipeline; -import net.vulkanmod.vulkan.shader.layout.Field; +import net.vulkanmod.vulkan.shader.layout.Uniform; import net.vulkanmod.vulkan.shader.descriptor.UBO; import net.vulkanmod.vulkan.shader.parser.GlslConverter; import net.vulkanmod.vulkan.util.MappedBuffer; @@ -31,6 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.nio.ByteBuffer; @@ -42,14 +43,23 @@ @Mixin(ShaderInstance.class) public class ShaderInstanceM implements ShaderMixed { - @Shadow @Final private Map uniformMap; + @Shadow @Final private Map uniformMap; @Shadow @Final private String name; - @Shadow @Final @Nullable public Uniform MODEL_VIEW_MATRIX; - @Shadow @Final @Nullable public Uniform PROJECTION_MATRIX; - @Shadow @Final @Nullable public Uniform COLOR_MODULATOR; - @Shadow @Final @Nullable public Uniform LINE_WIDTH; - + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform MODEL_VIEW_MATRIX; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform PROJECTION_MATRIX; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform COLOR_MODULATOR; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform LINE_WIDTH; + + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform INVERSE_VIEW_ROTATION_MATRIX; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform GLINT_ALPHA; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_START; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_END; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_COLOR; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform FOG_SHAPE; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform TEXTURE_MATRIX; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform GAME_TIME; + @Shadow @Final @Nullable public com.mojang.blaze3d.shaders.Uniform SCREEN_SIZE; private GraphicsPipeline pipeline; boolean isLegacy = false; @@ -60,16 +70,23 @@ public GraphicsPipeline getPipeline() { @Inject(method = "", at = @At("RETURN")) private void create(ResourceProvider resourceProvider, String name, VertexFormat format, CallbackInfo ci) { - if(Pipeline.class.getResourceAsStream(String.format("/assets/vulkanmod/shaders/minecraft/core/%s/%s.json", name, name)) == null) { - createLegacyShader(resourceProvider, new ResourceLocation("shaders/core/" + name + ".json"), format); - return; + + try { + if(Pipeline.class.getResourceAsStream(String.format("/assets/vulkanmod/shaders/minecraft/core/%s/%s.json", name, name)) == null) { + createLegacyShader(resourceProvider, new ResourceLocation("shaders/core/" + name + ".json"), format); + return; + } + + String path = String.format("minecraft/core/%s/%s", name, name); + Pipeline.Builder pipelineBuilder = new Pipeline.Builder(format, path); + pipelineBuilder.parseBindingsJSON(); + pipelineBuilder.compileShaders(); + this.pipeline = pipelineBuilder.createGraphicsPipeline(); + } catch (Exception e) { + System.out.printf("Error on shader %s creation\n", name); + throw e; } - String path = String.format("minecraft/core/%s/%s", name, name); - Pipeline.Builder pipelineBuilder = new Pipeline.Builder(format, path); - pipelineBuilder.parseBindingsJSON(); - pipelineBuilder.compileShaders(); - this.pipeline = pipelineBuilder.createGraphicsPipeline(); } @Inject(method = "getOrCreate", at = @At("HEAD"), cancellable = true) @@ -94,29 +111,64 @@ public void close() { */ @Overwrite public void apply() { - RenderSystem.setShader(() -> (ShaderInstance)(Object)this); + if(!this.isLegacy) + return; - if(this.isLegacy) { - if (this.MODEL_VIEW_MATRIX != null) { - this.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); - } + if (this.MODEL_VIEW_MATRIX != null) { + this.MODEL_VIEW_MATRIX.set(RenderSystem.getModelViewMatrix()); + } - if (this.PROJECTION_MATRIX != null) { - this.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); - } + if (this.PROJECTION_MATRIX != null) { + this.PROJECTION_MATRIX.set(RenderSystem.getProjectionMatrix()); + } - if (this.COLOR_MODULATOR != null) { - this.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); - } + if (this.COLOR_MODULATOR != null) { + this.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); + } -// if (shaderInstance.SCREEN_SIZE != null) { -// Window window = Minecraft.getInstance().getWindow(); -// shaderInstance.SCREEN_SIZE.set((float)window.getWidth(), (float)window.getHeight()); -// } + if (this.INVERSE_VIEW_ROTATION_MATRIX != null) { + this.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix()); + } + + if (this.COLOR_MODULATOR != null) { + this.COLOR_MODULATOR.set(RenderSystem.getShaderColor()); + } -// if (this.LINE_WIDTH != null) { -// this.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); -// } + if (this.GLINT_ALPHA != null) { + this.GLINT_ALPHA.set(RenderSystem.getShaderGlintAlpha()); + } + + if (this.FOG_START != null) { + this.FOG_START.set(RenderSystem.getShaderFogStart()); + } + + if (this.FOG_END != null) { + this.FOG_END.set(RenderSystem.getShaderFogEnd()); + } + + if (this.FOG_COLOR != null) { + this.FOG_COLOR.set(RenderSystem.getShaderFogColor()); + } + + if (this.FOG_SHAPE != null) { + this.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex()); + } + + if (this.TEXTURE_MATRIX != null) { + this.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix()); + } + + if (this.GAME_TIME != null) { + this.GAME_TIME.set(RenderSystem.getShaderGameTime()); + } + + if (this.SCREEN_SIZE != null) { + Window window = Minecraft.getInstance().getWindow(); + this.SCREEN_SIZE.set((float)window.getWidth(), (float)window.getHeight()); + } + + if (this.LINE_WIDTH != null) { + this.LINE_WIDTH.set(RenderSystem.getShaderLineWidth()); } } @@ -128,31 +180,22 @@ public void clear() {} private void setUniformSuppliers(UBO ubo) { - for(Field field : ubo.getFields()) { - Uniform uniform = this.uniformMap.get(field.getName()); + for(Uniform v_uniform : ubo.getUniforms()) { + com.mojang.blaze3d.shaders.Uniform uniform = this.uniformMap.get(v_uniform.getName()); if(uniform == null) { - throw new NullPointerException(String.format("Field: %s not present in map: %s", field.getName(), this.uniformMap)); + throw new NullPointerException(String.format("Field: %s not present in map: %s", v_uniform.getName(), this.uniformMap)); } Supplier supplier; ByteBuffer byteBuffer; - if(uniform != null) { - if (uniform.getType() <= 3) { - byteBuffer = MemoryUtil.memByteBuffer(uniform.getIntBuffer()); - } - else if (uniform.getType() <= 10) { - byteBuffer = MemoryUtil.memByteBuffer(uniform.getFloatBuffer()); - } - else { - throw new RuntimeException("out of bounds value for uniform " + uniform); - } + if (uniform.getType() <= 3) { + byteBuffer = MemoryUtil.memByteBuffer(uniform.getIntBuffer()); + } else if (uniform.getType() <= 10) { + byteBuffer = MemoryUtil.memByteBuffer(uniform.getFloatBuffer()); } else { - Initializer.LOGGER.warn(String.format("Shader: %s field: %s not present in uniform map", this.name, field.getName())); - - //TODO - byteBuffer = null; + throw new RuntimeException("out of bounds value for uniform " + uniform); } @@ -160,7 +203,7 @@ else if (uniform.getType() <= 10) { supplier = () -> mappedBuffer; //TODO vec1 - field.setSupplier(supplier); + v_uniform.setSupplier(supplier); } } @@ -187,18 +230,18 @@ private void createLegacyShader(ResourceProvider resourceProvider, ResourceLocat GlslConverter converter = new GlslConverter(); Pipeline.Builder builder = new Pipeline.Builder(format); - converter.process(format, vshSrc, fshSrc); + converter.process(vshSrc, fshSrc); UBO ubo = converter.getUBO(); this.setUniformSuppliers(ubo); builder.setUniforms(Collections.singletonList(ubo), converter.getSamplerList()); - builder.compileShaders(converter.getVshConverted(), converter.getFshConverted()); + builder.compileShaders(this.name, converter.getVshConverted(), converter.getFshConverted()); this.pipeline = builder.createGraphicsPipeline(); this.isLegacy = true; - } catch (Throwable throwable) { - throwable.printStackTrace(); + } catch (IOException e) { + throw new RuntimeException(e); } } } diff --git a/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java b/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java new file mode 100644 index 000000000..73b32202d --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/particle/SingleQuadParticleM.java @@ -0,0 +1,106 @@ +package net.vulkanmod.mixin.render.particle; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.Camera; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SingleQuadParticle; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; +import net.vulkanmod.interfaces.ExtendedVertexBuilder; +import net.vulkanmod.render.chunk.RenderSection; +import net.vulkanmod.render.chunk.WorldRenderer; +import net.vulkanmod.vulkan.util.ColorUtil; +import org.joml.Quaternionf; +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; + +@Mixin(SingleQuadParticle.class) +public abstract class SingleQuadParticleM extends Particle { + + @Shadow protected float quadSize; + + @Shadow protected abstract float getU0(); + @Shadow protected abstract float getU1(); + @Shadow protected abstract float getV0(); + @Shadow protected abstract float getV1(); + + @Shadow public abstract float getQuadSize(float f); + + protected SingleQuadParticleM(ClientLevel clientLevel, double d, double e, double f, double g, double h, double i) { + super(clientLevel, d, e, f, g, h, i); + this.quadSize = 0.1F * (this.random.nextFloat() * 0.5F + 0.5F) * 2.0F; + } + + /** + * @author + * @reason + */ + @Overwrite + public void render(VertexConsumer vertexConsumer, Camera camera, float f) { + float xOffset = (float)(Mth.lerp(f, this.xo, this.x)); + float yOffset = (float)(Mth.lerp(f, this.yo, this.y)); + float zOffset = (float)(Mth.lerp(f, this.zo, this.z)); + + if(cull(WorldRenderer.getInstance(), xOffset, yOffset, zOffset)) + return; + + Vec3 vec3 = camera.getPosition(); + xOffset -= (float) vec3.x(); + yOffset -= (float) vec3.y(); + zOffset -= (float) vec3.z(); + + Quaternionf quaternionf; + if (this.roll != 0.0F) { + quaternionf = new Quaternionf(camera.rotation()); + quaternionf.rotateZ(Mth.lerp(f, this.oRoll, this.roll)); + } else { + quaternionf = camera.rotation(); + } + + Vector3f[] vector3fs = new Vector3f[]{new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F)}; + float j = this.getQuadSize(f); + + for(int k = 0; k < 4; ++k) { + Vector3f vector3f = vector3fs[k]; + vector3f.rotate(quaternionf); + vector3f.mul(j); + vector3f.add(xOffset, yOffset, zOffset); + } + + float u0 = this.getU0(); + float u1 = this.getU1(); + float v0 = this.getV0(); + float v1 = this.getV1(); + int light = this.getLightColor(f); + + ExtendedVertexBuilder vertexBuilder = (ExtendedVertexBuilder)vertexConsumer; + int packedColor = ColorUtil.packColorIntRGBA(this.rCol, this.gCol, this.bCol, this.alpha); + + vertexBuilder.vertex(vector3fs[0].x(), vector3fs[0].y(), vector3fs[0].z(), u1, v1, packedColor, light); + vertexBuilder.vertex(vector3fs[1].x(), vector3fs[1].y(), vector3fs[1].z(), u1, v0, packedColor, light); + vertexBuilder.vertex(vector3fs[2].x(), vector3fs[2].y(), vector3fs[2].z(), u0, v0, packedColor, light); + vertexBuilder.vertex(vector3fs[3].x(), vector3fs[3].y(), vector3fs[3].z(), u0, v1, packedColor, light); + } + + protected int getLightColor(float f) { + BlockPos blockPos = BlockPos.containing(this.x, this.y, this.z); + return this.level.hasChunkAt(blockPos) ? LevelRenderer.getLightColor(this.level, blockPos) : 0; + } + + private boolean cull(WorldRenderer worldRenderer, float x, float y, float z) { + RenderSection section = worldRenderer.getSectionGrid().getSectionAtBlockPos((int) x, (int) y, (int) z); + return section != null && section.getLastFrame() != worldRenderer.getLastFrame(); + } + + @Override + public ParticleRenderType getRenderType() { + return null; + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java new file mode 100644 index 000000000..4954b8e5e --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/target/MainTargetMixin.java @@ -0,0 +1,13 @@ +package net.vulkanmod.mixin.render.target; + +import com.mojang.blaze3d.pipeline.MainTarget; +import com.mojang.blaze3d.pipeline.RenderTarget; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(MainTarget.class) +public class MainTargetMixin extends RenderTarget { + + public MainTargetMixin(boolean useDepth) { + super(useDepth); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java new file mode 100644 index 000000000..366d05705 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/render/target/RenderTargetMixin.java @@ -0,0 +1,182 @@ +package net.vulkanmod.mixin.render.target; + +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; +import net.vulkanmod.interfaces.ExtendedRenderTarget; +import net.vulkanmod.vulkan.Renderer; +import net.vulkanmod.vulkan.framebuffer.Framebuffer; +import net.vulkanmod.vulkan.framebuffer.RenderPass; +import net.vulkanmod.vulkan.texture.VTextureSelector; +import net.vulkanmod.vulkan.util.DrawUtil; +import org.lwjgl.opengl.GL30; +import org.lwjgl.system.MemoryStack; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(RenderTarget.class) +public abstract class RenderTargetMixin implements ExtendedRenderTarget { + + @Shadow public int viewWidth; + @Shadow public int viewHeight; + @Shadow public int width; + @Shadow public int height; + + @Shadow protected int depthBufferId; + @Shadow protected int colorTextureId; + @Shadow public int frameBufferId; + + @Shadow @Final private float[] clearChannels; + @Shadow @Final public boolean useDepth; + + Framebuffer framebuffer; + + boolean needClear = false; + boolean bound = false; + + private static int boundTarget = 0; + + /** + * @author + */ + @Overwrite + public void clear(boolean getError) { + RenderSystem.assertOnRenderThreadOrInit(); + + if(!Renderer.isRecording()) + return; + + if(!bound) { + needClear = true; + return; + } + +// this.bindWrite(true); + GlStateManager._clearColor(this.clearChannels[0], this.clearChannels[1], this.clearChannels[2], this.clearChannels[3]); + int i = 16384; + if (this.useDepth) { + GlStateManager._clearDepth(1.0); + i |= 256; + } + + GlStateManager._clear(i, getError); +// this.unbindWrite(); + needClear = false; + } + +// /** +// * @author +// */ +// @Overwrite +// public void destroyBuffers() { +// RenderSystem.assertOnRenderThreadOrInit(); +// this.unbindRead(); +// this.unbindWrite(); +// if (this.depthBufferId > -1) { +// TextureUtil.releaseTextureId(this.depthBufferId); +// this.depthBufferId = -1; +// } +// +// if (this.colorTextureId > -1) { +// TextureUtil.releaseTextureId(this.colorTextureId); +// this.colorTextureId = -1; +// } +// +// if (this.frameBufferId > -1) { +// GlStateManager._glBindFramebuffer(36160, 0); +// GlStateManager._glDeleteFramebuffers(this.frameBufferId); +// this.frameBufferId = -1; +// } +// +// } + + public void bindRead() { + RenderSystem.assertOnRenderThread(); +// GlStateManager._bindTexture(this.colorTextureId); + + GlTexture.bindTexture(this.colorTextureId); + + try (MemoryStack stack = MemoryStack.stackPush()) { + GlTexture.getBoundTexture().getVulkanImage() + .readOnlyLayout(stack, Renderer.getCommandBuffer()); + } + } + + public void unbindRead() { + RenderSystem.assertOnRenderThreadOrInit(); + GlTexture.bindTexture(0); + } + + public void bindWrite(boolean bl) { + if (!RenderSystem.isOnRenderThread()) { + RenderSystem.recordRenderCall(() -> { + this._bindWrite(bl); + }); + } else { + this._bindWrite(bl); + } + + } + + private void _bindWrite(boolean bl) { + RenderSystem.assertOnRenderThreadOrInit(); + +// if(this.frameBufferId == boundTarget) +// return; + + GlFramebuffer.bindFramebuffer(GL30.GL_FRAMEBUFFER, this.frameBufferId); + if (bl) { + GlStateManager._viewport(0, 0, this.viewWidth, this.viewHeight); + } + + this.bound = true; + boundTarget = this.frameBufferId; + if(needClear) + clear(false); + } + + public void unbindWrite() { + if (!RenderSystem.isOnRenderThread()) { + RenderSystem.recordRenderCall(() -> { + GlStateManager._glBindFramebuffer(36160, 0); + this.bound = false; + boundTarget = 0; + }); + } else { + GlStateManager._glBindFramebuffer(36160, 0); + this.bound = false; + boundTarget = 0; + } + } + + /** + * @author + */ + @Overwrite + private void _blitToScreen(int width, int height, boolean disableBlend) { + if(needClear) { + //If true it means target has not been used + return; + } + + Framebuffer framebuffer = GlFramebuffer.getFramebuffer(this.frameBufferId).getFramebuffer(); + VTextureSelector.bindTexture(0, framebuffer.getColorAttachment()); + + DrawUtil.blitToScreen(); + } + + @Override + public boolean isBound() { + return bound; + } + + @Override + public RenderPass getRenderPass() { + return GlFramebuffer.getFramebuffer(this.frameBufferId).getRenderPass(); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java index 12b125579..c09b73b6c 100644 --- a/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java +++ b/src/main/java/net/vulkanmod/mixin/render/vertex/BufferBuilderM.java @@ -3,10 +3,8 @@ import com.mojang.blaze3d.vertex.*; import net.vulkanmod.interfaces.ExtendedVertexBuilder; import net.vulkanmod.interfaces.VertexFormatMixed; -import net.vulkanmod.render.util.SortUtil; import net.vulkanmod.render.vertex.VertexUtil; import org.jetbrains.annotations.Nullable; -import org.joml.Vector3f; import org.lwjgl.system.MemoryUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -17,7 +15,6 @@ import java.nio.ByteBuffer; import java.util.List; -import java.util.function.IntConsumer; @Mixin(BufferBuilder.class) public abstract class BufferBuilderM extends DefaultedVertexConsumer @@ -79,7 +76,7 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, } else { - this.vertex(x, y, z); + this.position(x, y, z); this.fastColor(packedColor); this.fastUv(u, v); this.fastOverlay(overlay); @@ -91,7 +88,26 @@ public void vertex(float x, float y, float z, int packedColor, float u, float v, } - public void vertex(float x, float y, float z) { + public void vertex(float x, float y, float z, float u, float v, int packedColor, int light) { + this.ptr = this.nextElementPtr(); + + MemoryUtil.memPutFloat(ptr + 0, x); + MemoryUtil.memPutFloat(ptr + 4, y); + MemoryUtil.memPutFloat(ptr + 8, z); + + MemoryUtil.memPutFloat(ptr + 12, u); + MemoryUtil.memPutFloat(ptr + 16, v); + + MemoryUtil.memPutInt(ptr + 20, packedColor); + + MemoryUtil.memPutInt(ptr + 24, light); + + this.nextElementByte += 28; + this.endVertex(); + + } + + public void position(float x, float y, float z) { MemoryUtil.memPutFloat(ptr + 0, x); MemoryUtil.memPutFloat(ptr + 4, y); MemoryUtil.memPutFloat(ptr + 8, z); @@ -100,15 +116,17 @@ public void vertex(float x, float y, float z) { } public void fastColor(int packedColor) { - if (this.currentElement.getUsage() != VertexFormatElement.Usage.COLOR) return; + if (this.currentElement.getUsage() != VertexFormatElement.Usage.COLOR) + return; - MemoryUtil.memPutFloat(ptr + 12, packedColor); + MemoryUtil.memPutInt(ptr + 12, packedColor); this.nextElement(); } public void fastUv(float u, float v) { - if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) return; + if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) + return; MemoryUtil.memPutFloat(ptr + 16, u); MemoryUtil.memPutFloat(ptr + 20, v); @@ -117,7 +135,8 @@ public void fastUv(float u, float v) { } public void fastOverlay(int o) { - if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) return; + if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) + return; MemoryUtil.memPutInt(ptr + 24, o); @@ -125,7 +144,8 @@ public void fastOverlay(int o) { } public void light(int l) { - if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) return; + if (this.currentElement.getUsage() != VertexFormatElement.Usage.UV) + return; MemoryUtil.memPutInt(ptr + 28, l); @@ -133,7 +153,8 @@ public void light(int l) { } public void fastNormal(int packedNormal) { - if (this.currentElement.getUsage() != VertexFormatElement.Usage.NORMAL) return; + if (this.currentElement.getUsage() != VertexFormatElement.Usage.NORMAL) + return; MemoryUtil.memPutInt(ptr + 32, packedNormal); diff --git a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java index c632e976e..b192873f7 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java +++ b/src/main/java/net/vulkanmod/mixin/texture/MTextureUtil.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.TextureUtil; +import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.gl.GlTexture; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; @@ -16,6 +17,7 @@ public class MTextureUtil { */ @Overwrite(remap = false) public static int generateTextureId() { + RenderSystem.assertOnRenderThreadOrInit(); return GlTexture.genTextureId(); } @@ -24,6 +26,7 @@ public static int generateTextureId() { */ @Overwrite(remap = false) public static void prepareImage(NativeImage.InternalGlFormat internalGlFormat, int id, int mipLevels, int width, int height) { + RenderSystem.assertOnRenderThreadOrInit(); GlTexture.bindTexture(id); GlTexture glTexture = GlTexture.getBoundTexture(); VulkanImage image = glTexture.getVulkanImage(); diff --git a/src/main/java/net/vulkanmod/mixin/texture/MNativeImage.java b/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java similarity index 76% rename from src/main/java/net/vulkanmod/mixin/texture/MNativeImage.java rename to src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java index ac76870bb..cc4537bcd 100644 --- a/src/main/java/net/vulkanmod/mixin/texture/MNativeImage.java +++ b/src/main/java/net/vulkanmod/mixin/texture/image/MNativeImage.java @@ -1,8 +1,9 @@ -package net.vulkanmod.mixin.texture; +package net.vulkanmod.mixin.texture.image; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.texture.ImageUtil; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import net.vulkanmod.vulkan.util.ColorUtil; @@ -16,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.nio.ByteBuffer; +import java.util.Locale; @Mixin(NativeImage.class) public abstract class MNativeImage { @@ -39,6 +41,8 @@ public abstract class MNativeImage { @Shadow public abstract int getPixelRGBA(int i, int j); + @Shadow protected abstract void checkAllocated(); + private ByteBuffer buffer; @Inject(method = "(Lcom/mojang/blaze3d/platform/NativeImage$Format;IIZ)V", at = @At("RETURN")) @@ -76,18 +80,22 @@ private void _upload(int level, int xOffset, int yOffset, int unpackSkipPixels, public void downloadTexture(int level, boolean removeAlpha) { RenderSystem.assertOnRenderThread(); - VulkanImage.downloadTexture(this.width, this.height, 4, this.buffer, Vulkan.getSwapChain().getColorAttachment().getId()); + ImageUtil.downloadTexture(VTextureSelector.getBoundTexture(0), this.pixels); if (removeAlpha && this.format.hasAlpha()) { - for (int i = 0; i < this.height; ++i) { - for (int j = 0; j < this.getWidth(); ++j) { - int v = this.getPixelRGBA(j, i); + if (this.format != NativeImage.Format.RGBA) { + throw new IllegalArgumentException(String.format(Locale.ROOT, "getPixelRGBA only works on RGBA images; have %s", this.format)); + } + + for (long l = 0; l < this.width * this.height * 4L; l+=4) { + int v = MemoryUtil.memGetInt(this.pixels + l); - if(Vulkan.getSwapChain().isBGRAformat) - v = ColorUtil.BGRAtoRGBA(v); + //TODO + if(Vulkan.getSwapChain().isBGRAformat) + v = ColorUtil.BGRAtoRGBA(v); - this.setPixelRGBA(j, i, v | 255 << this.format.alphaOffset()); - } + v = v | 255 << this.format.alphaOffset(); + MemoryUtil.memPutInt(this.pixels + l, v); } } diff --git a/src/main/java/net/vulkanmod/mixin/texture/image/NativeImageAccessor.java b/src/main/java/net/vulkanmod/mixin/texture/image/NativeImageAccessor.java new file mode 100644 index 000000000..8281cbe21 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/texture/image/NativeImageAccessor.java @@ -0,0 +1,12 @@ +package net.vulkanmod.mixin.texture.image; + +import com.mojang.blaze3d.platform.NativeImage; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(NativeImage.class) +public interface NativeImageAccessor { + + @Accessor + long getPixels(); +} diff --git a/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java new file mode 100644 index 000000000..fd71aa695 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/texture/mip/MipmapGeneratorM.java @@ -0,0 +1,201 @@ +package net.vulkanmod.mixin.texture.mip; + +import com.mojang.blaze3d.platform.NativeImage; +import net.minecraft.Util; +import net.minecraft.client.renderer.texture.MipmapGenerator; +import net.vulkanmod.mixin.texture.image.NativeImageAccessor; +import org.lwjgl.opengl.GL30; +import org.lwjgl.system.MemoryUtil; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(MipmapGenerator.class) +public abstract class MipmapGeneratorM { + private static final int ALPHA_CUTOFF = 50; + private static final int[] INV_POW22 = Util.make(new int[256], (fs) -> { + for(int i = 0; i < fs.length; ++i) { + //TODO + fs[i] = (int)(Math.pow((float)i / 255.0F, 0.45454545454545453) * 255.0f); + } + + }); + + @Shadow + private static float getPow22(int i) { + return 0; + } + + /** + * @author + * @reason + */ + @Overwrite + public static NativeImage[] generateMipLevels(NativeImage[] nativeImages, int i) { + if (i + 1 <= nativeImages.length) { + return nativeImages; + } else { + NativeImage[] nativeImages2 = new NativeImage[i + 1]; + nativeImages2[0] = nativeImages[0]; + + long srcPtr = ((NativeImageAccessor)(Object)nativeImages2[0]).getPixels(); + boolean bl = hasTransparentPixel(srcPtr, nativeImages2[0].getWidth(), nativeImages2[0].getHeight()); + + if(bl) { + int avg = calculateAverage(nativeImages2[0]); + avg = avg & 0x00FFFFFF; //mask out alpha + + for(int j = 1; j <= i; ++j) { + if (j < nativeImages.length) { + nativeImages2[j] = nativeImages[j]; + } else { + NativeImage nativeImage = nativeImages2[j - 1]; + NativeImage nativeImage2 = new NativeImage(nativeImage.getWidth() >> 1, nativeImage.getHeight() >> 1, false); + int width = nativeImage2.getWidth(); + int height = nativeImage2.getHeight(); + + srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); + long dstPtr = ((NativeImageAccessor)(Object)nativeImage2).getPixels(); + final int width2 = width * 2; + + for(int m = 0; m < width; ++m) { + for(int n = 0; n < height; ++n) { + int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 0) * width2)) * 4L); + int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 0) * width2)) * 4L); + int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 1) * width2)) * 4L); + int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 1) * width2)) * 4L); + + boolean b0 = ((p0 >> 24) & 0xFF) >= ALPHA_CUTOFF; + boolean b1 = ((p1 >> 24) & 0xFF) >= ALPHA_CUTOFF; + boolean b2 = ((p2 >> 24) & 0xFF) >= ALPHA_CUTOFF; + boolean b3 = ((p3 >> 24) & 0xFF) >= ALPHA_CUTOFF; + +// p0 = b0 ? p0 : avg; +// p1 = b1 ? p1 : avg; +// p2 = b2 ? p2 : avg; +// p3 = b3 ? p3 : avg; + + p0 = b0 ? p0 : avg | p0 & 0xFF000000; + p1 = b1 ? p1 : avg | p1 & 0xFF000000; + p2 = b2 ? p2 : avg | p2 & 0xFF000000; + p3 = b3 ? p3 : avg | p3 & 0xFF000000; + + int outColor = blend(p0, p1, p2, p3); + MemoryUtil.memPutInt(dstPtr + (m + (long) n * width) * 4L, outColor); + } + } + + nativeImages2[j] = nativeImage2; + } + } + } else { + for(int j = 1; j <= i; ++j) { + if (j < nativeImages.length) { + nativeImages2[j] = nativeImages[j]; + } else { + NativeImage nativeImage = nativeImages2[j - 1]; + NativeImage nativeImage2 = new NativeImage(nativeImage.getWidth() >> 1, nativeImage.getHeight() >> 1, false); + int width = nativeImage2.getWidth(); + int height = nativeImage2.getHeight(); + + srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); + long dstPtr = ((NativeImageAccessor)(Object)nativeImage2).getPixels(); + final int width2 = width * 2; + + for(int m = 0; m < width; ++m) { + for(int n = 0; n < height; ++n) { + int p0 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 0) * width2)) * 4L); + int p1 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 0) * width2)) * 4L); + int p2 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 0) + ((n * 2 + 1) * width2)) * 4L); + int p3 = MemoryUtil.memGetInt(srcPtr + ((m * 2 + 1) + ((n * 2 + 1) * width2)) * 4L); + + int outColor = blend(p0, p1, p2, p3); + MemoryUtil.memPutInt(dstPtr + (m + (long) n * width) * 4L, outColor); + } + } + + nativeImages2[j] = nativeImage2; + } + } + } + + return nativeImages2; + } + } + + private static boolean hasTransparentPixel(long ptr, int width, int height) { + for(int i = 0; i < width; ++i) { + for(int j = 0; j < height; ++j) { + if (getPixelA(MemoryUtil.memGetInt(ptr + (i + j * width) * 4L)) == 0) { + return true; + } + } + } + + return false; + } + + private static int blend(int p0, int p1, int p2, int p3) { + int a = gammaBlend(p0, p1, p2, p3, 24); +// int a = ((p0 >> 24 & 0xFF) + (p1 >> 24 & 0xFF) + (p2 >> 24 & 0xFF) + (p3 >> 24 & 0xFF)) >> 2; + int b = gammaBlend(p0, p1, p2, p3, 16); + int g = gammaBlend(p0, p1, p2, p3, 8); + int r = gammaBlend(p0, p1, p2, p3, 0); + return a << 24 | b << 16 | g << 8 | r; + } + + private static int getMax(int i0, int i1, int i2, int i3) { + return Math.max(Math.max(Math.max(i0, i1), i2), i3); + } + + private static int gammaBlend(int i, int j, int k, int l, int m) { + float f = getPow22(i >> m); + float g = getPow22(j >> m); + float h = getPow22(k >> m); + float n = getPow22(l >> m); + float o = (float)((double)((float)Math.pow((double)(f + g + h + n) * 0.25, 0.45454545454545453))); + return (int)((double)o * 255.0); + } + + private static int getPixelA(int rgba) { + return rgba >> 24; + } + + private static int calculateAverage(NativeImage nativeImage) { + final int width = nativeImage.getWidth(); + final int height = nativeImage.getHeight(); + + final int[] values = new int[width * height]; + int count = 0; + long srcPtr = ((NativeImageAccessor)(Object)nativeImage).getPixels(); + + for(int i = 0; i < width; ++i) { + for(int j = 0; j < height; ++j) { +// int value = nativeImage.getPixelRGBA(i, j); + int value = MemoryUtil.memGetInt(srcPtr + (i + (long) j * width) * 4L); + if (((value >> 24) & 0xFF) > 0) { + values[count] = value; + count++; + } + } + } + + int sumR = 0; + int sumG = 0; + int sumB = 0; + for (int i = 0; i < count; i++) { + sumR += values[i] & 0xFF; + sumG += (values[i] >> 8) & 0xFF; + sumB += (values[i] >> 16) & 0xFF; + } + + if(count == 0) + return 0; + + sumR /= count; + sumG /= count; + sumB /= count; + + return (sumR & 0xFF) | ((sumG & 0xFF) << 8) | ((sumB & 0xFF) << 16) | (0xFF << 24); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/util/ScreenshotRecorderM.java b/src/main/java/net/vulkanmod/mixin/util/ScreenshotRecorderM.java index c84047be8..2a2639fc5 100644 --- a/src/main/java/net/vulkanmod/mixin/util/ScreenshotRecorderM.java +++ b/src/main/java/net/vulkanmod/mixin/util/ScreenshotRecorderM.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.NativeImage; import net.minecraft.client.Screenshot; +import net.vulkanmod.gl.GlTexture; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -13,13 +14,21 @@ public class ScreenshotRecorderM { * @author */ @Overwrite - public static NativeImage takeScreenshot(RenderTarget framebuffer) { - int i = framebuffer.width; - int j = framebuffer.height; + public static NativeImage takeScreenshot(RenderTarget target) { + int i = target.width; + int j = target.height; NativeImage nativeimage = new NativeImage(i, j, false); - //RenderSystem.bindTexture(p_92282_.getColorTextureId()); + GlTexture.bindTexture(target.getColorTextureId()); + + //TODO screenshot might be requested when cmds have not been submitted yet +// RenderPass renderPass = ((ExtendedRenderTarget)target).getRenderPass(); +// +// Renderer renderer = Renderer.getInstance(); +// boolean b = renderer.getBoundRenderPass() == renderPass; + nativeimage.downloadTexture(0, true); + //nativeimage.flipY(); return nativeimage; } diff --git a/src/main/java/net/vulkanmod/mixin/vertex/EntityOutlineGeneratorM.java b/src/main/java/net/vulkanmod/mixin/vertex/EntityOutlineGeneratorM.java new file mode 100644 index 000000000..4b5d0ec66 --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/vertex/EntityOutlineGeneratorM.java @@ -0,0 +1,26 @@ +package net.vulkanmod.mixin.vertex; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.OutlineBufferSource; +import net.vulkanmod.interfaces.ExtendedVertexBuilder; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(OutlineBufferSource.EntityOutlineGenerator.class) +public class EntityOutlineGeneratorM implements ExtendedVertexBuilder { + + private ExtendedVertexBuilder extDelegate; + + @Inject(method = "", at = @At("RETURN")) + private void getExtBuilder(VertexConsumer vertexConsumer, int i, int j, int k, int l, CallbackInfo ci) { + this.extDelegate = (ExtendedVertexBuilder) vertexConsumer; + } + + @Override + public void vertex(float x, float y, float z, int packedColor, float u, float v, int overlay, int light, int packedNormal) { + this.extDelegate.vertex(x, y, z, packedColor, u, v, overlay, light, packedNormal); +// this.delegate.vertex((double)f, (double)g, (double)h).color(this.defaultR, this.defaultG, this.defaultB, this.defaultA).uv(m, n); + } +} diff --git a/src/main/java/net/vulkanmod/mixin/window/WindowAccessor.java b/src/main/java/net/vulkanmod/mixin/window/WindowAccessor.java new file mode 100644 index 000000000..aba6c541e --- /dev/null +++ b/src/main/java/net/vulkanmod/mixin/window/WindowAccessor.java @@ -0,0 +1,13 @@ +package net.vulkanmod.mixin.window; + +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.platform.WindowEventHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Window.class) +public interface WindowAccessor { + + @Accessor + WindowEventHandler getEventHandler(); +} diff --git a/src/main/java/net/vulkanmod/mixin/WindowMixin.java b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java similarity index 95% rename from src/main/java/net/vulkanmod/mixin/WindowMixin.java rename to src/main/java/net/vulkanmod/mixin/window/WindowMixin.java index 296144834..6d52da470 100644 --- a/src/main/java/net/vulkanmod/mixin/WindowMixin.java +++ b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java @@ -1,4 +1,4 @@ -package net.vulkanmod.mixin; +package net.vulkanmod.mixin.window; import com.mojang.blaze3d.platform.*; import com.mojang.blaze3d.systems.RenderSystem; @@ -17,6 +17,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -212,19 +213,19 @@ else if(config.windowedFullscreen) { @Overwrite private void onFramebufferResize(long window, int width, int height) { if (window == this.window) { - int k = this.getWidth(); - int m = this.getHeight(); - if (width != 0 && height != 0) { + int prevWidth = this.getWidth(); + int prevHeight = this.getHeight(); + + if(width > 0 && height > 0) { this.framebufferWidth = width; this.framebufferHeight = height; - if (this.framebufferWidth != k || this.framebufferHeight != m) { - this.eventHandler.resizeDisplay(); - } +// if (this.framebufferWidth != prevWidth || this.framebufferHeight != prevHeight) { +// this.eventHandler.resizeDisplay(); +// } + Renderer.scheduleSwapChainUpdate(); } - if(width > 0 && height > 0) - Renderer.scheduleSwapChainUpdate(); } } diff --git a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java index d779dafb5..f44f37347 100644 --- a/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java +++ b/src/main/java/net/vulkanmod/render/chunk/WorldRenderer.java @@ -124,8 +124,9 @@ private void allocateIndirectBuffers() { public static WorldRenderer init(RenderBuffers renderBuffers) { if(INSTANCE != null) - throw new RuntimeException("WorldRenderer re-initialization"); - return INSTANCE = new WorldRenderer(renderBuffers); + return INSTANCE; + else + return INSTANCE = new WorldRenderer(renderBuffers); } public static WorldRenderer getInstance() { @@ -398,48 +399,40 @@ private void updateRenderChunksSpectator() { } private void addNode(RenderSection renderSection, RenderSection relativeChunk, Direction direction) { - if (relativeChunk.setLastFrame(this.lastFrame)) { - - int d; - if (renderSection.mainDir != direction && !renderSection.isCompletelyEmpty()) - d = renderSection.directionChanges + 1; - else - d = renderSection.directionChanges; + if (relativeChunk.getChunkArea().inFrustum(relativeChunk.frustumIndex) >= 0) { + return; + } + else if (relativeChunk.getLastFrame() == this.lastFrame) { + int d = renderSection.mainDir != direction && !renderSection.isCompletelyEmpty() ? + renderSection.directionChanges + 1 : renderSection.directionChanges; relativeChunk.addDir(direction); - if(d < relativeChunk.directionChanges) - relativeChunk.directionChanges = (byte) d; + relativeChunk.directionChanges = d < relativeChunk.directionChanges ? (byte) d : relativeChunk.directionChanges; + return; + } + else if(relativeChunk.getChunkArea().inFrustum(relativeChunk.frustumIndex) == FrustumIntersection.INTERSECT) { + if(frustum.cubeInFrustum(relativeChunk.xOffset, relativeChunk.yOffset, relativeChunk.zOffset, + relativeChunk.xOffset + 16 , relativeChunk.yOffset + 16, relativeChunk.zOffset + 16) >= 0) + return; } - else if (relativeChunk.getChunkArea().inFrustum(relativeChunk.frustumIndex) < 0 ) { - - if(relativeChunk.getChunkArea().inFrustum(relativeChunk.frustumIndex) == FrustumIntersection.INTERSECT) { - if(frustum.cubeInFrustum(relativeChunk.xOffset, relativeChunk.yOffset, relativeChunk.zOffset, - relativeChunk.xOffset + 16 , relativeChunk.yOffset + 16, relativeChunk.zOffset + 16) >= 0) - return; - } - relativeChunk.setGraphInfo(direction, (byte) (renderSection.step + 1)); - relativeChunk.setDirections(renderSection.directions, direction); - this.chunkQueue.add(relativeChunk); + relativeChunk.setLastFrame(this.lastFrame); - byte d; - if ((renderSection.sourceDirs & (1 << direction.ordinal())) == 0 && !renderSection.isCompletelyEmpty()) - { - if(renderSection.step > 4) { - d = (byte) (renderSection.directionChanges + 1); - } - else { - d = 0; - } + relativeChunk.setGraphInfo(direction, (byte) (renderSection.step + 1)); + relativeChunk.setDirections(renderSection.directions, direction); + this.chunkQueue.add(relativeChunk); - } - else - d = renderSection.directionChanges; - - relativeChunk.directionChanges = d; + byte d; + if ((renderSection.sourceDirs & (1 << direction.ordinal())) == 0 && !renderSection.isCompletelyEmpty()) + { + d = renderSection.step > 4 ? (byte) (renderSection.directionChanges + 1) : 0; } + else + d = renderSection.directionChanges; + + relativeChunk.directionChanges = d; } public boolean scheduleUpdate(RenderSection section, int limit) { @@ -716,6 +709,14 @@ public void setNeedsUpdate() { this.needsUpdate = true; } + public boolean needsUpdate() { + return this.needsUpdate; + } + + public int getVisibleSectionsCount() { + return this.chunkQueue.size(); + } + public void setSectionDirty(int x, int y, int z, boolean flag) { this.sectionGrid.setDirty(x, y, z, flag); } diff --git a/src/main/java/net/vulkanmod/render/chunk/util/Util.java b/src/main/java/net/vulkanmod/render/chunk/util/Util.java index 90314fd61..ca5c0897f 100644 --- a/src/main/java/net/vulkanmod/render/chunk/util/Util.java +++ b/src/main/java/net/vulkanmod/render/chunk/util/Util.java @@ -44,6 +44,9 @@ public static int flooredLog(int v) { } public static int align(int i, int alignment) { + if(alignment == 0) + return i; + int r = i % alignment; return r != 0 ? i + alignment - r : i; } diff --git a/src/main/java/net/vulkanmod/render/util/DrawUtil.java b/src/main/java/net/vulkanmod/render/util/DrawUtil.java new file mode 100644 index 000000000..76858e772 --- /dev/null +++ b/src/main/java/net/vulkanmod/render/util/DrawUtil.java @@ -0,0 +1,67 @@ +package net.vulkanmod.render.util; + +import com.mojang.blaze3d.systems.RenderSystem; +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; + +public class DrawUtil { + + public static void blitQuad() { + blitQuad(0.0, 1.0, 1.0, 0.0); + } + + public static void drawTexQuad(BufferBuilder builder, double x0, double y0, double x1, double y1, double z, + float u0, float v0, float u1, float v1) { + Tesselator tesselator = RenderSystem.renderThreadTesselator(); + BufferBuilder bufferbuilder = tesselator.getBuilder(); + bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + bufferbuilder.vertex(x0, y0, z).uv(0.0F, 1.0F).endVertex(); + bufferbuilder.vertex(x1, y0, z).uv(1.0F, 1.0F).endVertex(); + bufferbuilder.vertex(x1, y1, z).uv(1.0F, 0.0F).endVertex(); + bufferbuilder.vertex(x0, y1, z).uv(0.0F, 0.0F).endVertex(); + + BufferBuilder.RenderedBuffer renderedBuffer = bufferbuilder.end(); + + Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount()); + + } + + public static void blitQuad(double x0, double y0, double x1, double y1) { + Tesselator tesselator = RenderSystem.renderThreadTesselator(); + BufferBuilder bufferbuilder = tesselator.getBuilder(); + bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + bufferbuilder.vertex(x0, y0, 0.0D).uv(0.0F, 1.0F).endVertex(); + bufferbuilder.vertex(x1, y0, 0.0D).uv(1.0F, 1.0F).endVertex(); + bufferbuilder.vertex(x1, y1, 0.0D).uv(1.0F, 0.0F).endVertex(); + bufferbuilder.vertex(x0, y1, 0.0D).uv(0.0F, 0.0F).endVertex(); + + BufferBuilder.RenderedBuffer renderedBuffer = bufferbuilder.end(); + + Renderer.getDrawer().draw(renderedBuffer.vertexBuffer(), VertexFormat.Mode.QUADS, renderedBuffer.drawState().format(), renderedBuffer.drawState().vertexCount()); + + } + + public static void drawFramebuffer(GraphicsPipeline pipeline, VulkanImage attachment) { + + Renderer.getInstance().bindGraphicsPipeline(pipeline); + + VTextureSelector.bindTexture(attachment); + + 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); + PoseStack posestack = RenderSystem.getModelViewStack(); + posestack.pushPose(); + posestack.setIdentity(); + RenderSystem.applyModelViewMatrix(); + posestack.popPose(); + + Renderer.getInstance().uploadAndBindUBOs(pipeline); + + blitQuad(0.0D, 0.0D, 1.0D, 1.0D); + } +} diff --git a/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java b/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java index 3d7545ccb..8d093ea6a 100644 --- a/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java +++ b/src/main/java/net/vulkanmod/render/vertex/VertexUtil.java @@ -1,17 +1,14 @@ package net.vulkanmod.render.vertex; +import net.vulkanmod.vulkan.util.ColorUtil; + public class VertexUtil { private static final float NORM_INV = 1.0f / 127.0f; private static final float COLOR_INV = 1.0f / 255.0f; public static int packColor(float r, float g, float b, float a) { - r *= 255.0f; - g *= 255.0f; - b *= 255.0f; - a *= 255.0f; - - return ((int)r & 0xFF) | ((int)g & 0xFF) << 8 | ((int)b & 0xFF) << 16 | ((int)a & 0xFF) << 24; + return ColorUtil.packColorIntRGBA(r, g, b, a); } public static int packNormal(float x, float y, float z) { diff --git a/src/main/java/net/vulkanmod/vulkan/Renderer.java b/src/main/java/net/vulkanmod/vulkan/Renderer.java index 2fe8e9a9b..faeb8afaa 100644 --- a/src/main/java/net/vulkanmod/vulkan/Renderer.java +++ b/src/main/java/net/vulkanmod/vulkan/Renderer.java @@ -4,13 +4,14 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.client.Minecraft; import net.vulkanmod.Initializer; +import net.vulkanmod.mixin.window.WindowAccessor; import net.vulkanmod.render.chunk.AreaUploadManager; import net.vulkanmod.render.chunk.TerrainShaderManager; import net.vulkanmod.render.profiling.Profiler2; import net.vulkanmod.vulkan.framebuffer.Framebuffer; import net.vulkanmod.vulkan.framebuffer.RenderPass; import net.vulkanmod.vulkan.memory.MemoryManager; -import net.vulkanmod.vulkan.passes.DefaultMainPass; +import net.vulkanmod.vulkan.passes.LegacyMainPass; import net.vulkanmod.vulkan.passes.MainPass; import net.vulkanmod.vulkan.shader.*; import net.vulkanmod.vulkan.shader.layout.PushConstants; @@ -31,7 +32,6 @@ import static com.mojang.blaze3d.platform.GlConst.GL_COLOR_BUFFER_BIT; import static com.mojang.blaze3d.platform.GlConst.GL_DEPTH_BUFFER_BIT; import static net.vulkanmod.vulkan.Vulkan.*; -import static org.lwjgl.system.MemoryStack.stackGet; import static org.lwjgl.system.MemoryStack.stackPush; import static org.lwjgl.vulkan.EXTDebugUtils.*; import static org.lwjgl.vulkan.KHRSwapchain.*; @@ -74,8 +74,10 @@ public static void initRenderer() { private static int currentFrame = 0; private static int imageIndex; private VkCommandBuffer currentCmdBuffer; + private boolean recordingCmds = false; - MainPass mainPass = DefaultMainPass.PASS; +// MainPass mainPass = DefaultMainPass.PASS; + MainPass mainPass = LegacyMainPass.PASS; private final List onResizeCallbacks = new ObjectArrayList<>(); @@ -208,6 +210,7 @@ public void beginFrame() { currentCmdBuffer = commandBuffers.get(currentFrame); vkResetCommandBuffer(currentCmdBuffer, 0); + recordingCmds = true; try(MemoryStack stack = stackPush()) { @@ -257,47 +260,93 @@ public void endFrame() { mainPass.end(currentCmdBuffer); submitFrame(); + recordingCmds = false; p.pop(); } + private void submitFrame() { + if(swapChainUpdate) + return; + + try(MemoryStack stack = stackPush()) { + + int vkResult; + + VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); + submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); + + submitInfo.waitSemaphoreCount(1); + submitInfo.pWaitSemaphores(stack.longs(imageAvailableSemaphores.get(currentFrame))); + submitInfo.pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)); + + submitInfo.pSignalSemaphores(stack.longs(renderFinishedSemaphores.get(currentFrame))); + + submitInfo.pCommandBuffers(stack.pointers(currentCmdBuffer)); + + vkResetFences(device, stack.longs(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); + } + + VkPresentInfoKHR presentInfo = VkPresentInfoKHR.calloc(stack); + presentInfo.sType(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR); + + presentInfo.pWaitSemaphores(stack.longs(renderFinishedSemaphores.get(currentFrame))); + + presentInfo.swapchainCount(1); + presentInfo.pSwapchains(stack.longs(Vulkan.getSwapChain().getId())); + + presentInfo.pImageIndices(stack.ints(imageIndex)); + + vkResult = vkQueuePresentKHR(DeviceManager.getPresentQueue().queue(), presentInfo); + + if(vkResult == VK_ERROR_OUT_OF_DATE_KHR || vkResult == VK_SUBOPTIMAL_KHR || swapChainUpdate) { + swapChainUpdate = true; + return; + } else if(vkResult != VK_SUCCESS) { + throw new RuntimeException("Failed to present swap chain image"); + } + + currentFrame = (currentFrame + 1) % framesNum; + } + } + public void endRenderPass() { endRenderPass(currentCmdBuffer); } public void endRenderPass(VkCommandBuffer commandBuffer) { + if(skipRendering || this.boundFramebuffer == null) + return; + if(!DYNAMIC_RENDERING) this.boundRenderPass.endRenderPass(currentCmdBuffer); else KHRDynamicRendering.vkCmdEndRenderingKHR(commandBuffer); this.boundRenderPass = null; + this.boundFramebuffer = null; } - //TODO - public void beginRendering(Framebuffer framebuffer) { - if(skipRendering) - return; + public boolean beginRendering(RenderPass renderPass, Framebuffer framebuffer) { + if(skipRendering || !recordingCmds) + return false; if(this.boundFramebuffer != framebuffer) { - this.endRendering(); + this.endRenderPass(currentCmdBuffer); try (MemoryStack stack = stackPush()) { -// framebuffer.beginRenderPass(currentCmdBuffer, stack); + framebuffer.beginRenderPass(currentCmdBuffer, renderPass, stack); } this.boundFramebuffer = framebuffer; } - } - - public void endRendering() { - if(skipRendering) - return; - - this.boundRenderPass.endRenderPass(currentCmdBuffer); - - this.boundFramebuffer = null; - this.boundRenderPass = null; + return true; } public void setBoundFramebuffer(Framebuffer framebuffer) { @@ -328,57 +377,6 @@ private void resetDescriptors() { usedPipelines.clear(); } - private void submitFrame() { - if(swapChainUpdate) - return; - - try(MemoryStack stack = stackPush()) { - - int vkResult; - - VkSubmitInfo submitInfo = VkSubmitInfo.calloc(stack); - submitInfo.sType(VK_STRUCTURE_TYPE_SUBMIT_INFO); - - submitInfo.waitSemaphoreCount(1); - submitInfo.pWaitSemaphores(stackGet().longs(imageAvailableSemaphores.get(currentFrame))); - submitInfo.pWaitDstStageMask(stack.ints(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)); - - submitInfo.pSignalSemaphores(stackGet().longs(renderFinishedSemaphores.get(currentFrame))); - - submitInfo.pCommandBuffers(stack.pointers(currentCmdBuffer)); - - vkResetFences(device, stackGet().longs(inFlightFences.get(currentFrame))); - - Synchronization.INSTANCE.waitFences(); - - if((vkResult = vkQueueSubmit(DeviceManager.getGraphicsQueue().queue(), submitInfo, inFlightFences.get(currentFrame))) != VK_SUCCESS) { - vkResetFences(device, stackGet().longs(inFlightFences.get(currentFrame))); - throw new RuntimeException("Failed to submit draw command buffer: " + vkResult); - } - - VkPresentInfoKHR presentInfo = VkPresentInfoKHR.calloc(stack); - presentInfo.sType(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR); - - presentInfo.pWaitSemaphores(stackGet().longs(renderFinishedSemaphores.get(currentFrame))); - - presentInfo.swapchainCount(1); - presentInfo.pSwapchains(stack.longs(Vulkan.getSwapChain().getId())); - - presentInfo.pImageIndices(stack.ints(imageIndex)); - - vkResult = vkQueuePresentKHR(DeviceManager.getPresentQueue().queue(), presentInfo); - - if(vkResult == VK_ERROR_OUT_OF_DATE_KHR || vkResult == VK_SUBOPTIMAL_KHR || swapChainUpdate) { - swapChainUpdate = true; - return; - } else if(vkResult != VK_SUCCESS) { - throw new RuntimeException("Failed to present swap chain image"); - } - - currentFrame = (currentFrame + 1) % framesNum; - } - } - void waitForSwapChain() { vkResetFences(device, inFlightFences.get(currentFrame)); @@ -425,6 +423,7 @@ private void recreateSwapChain() { createSyncObjects(); this.onResizeCallbacks.forEach(Runnable::run); + ((WindowAccessor)(Object)Minecraft.getInstance().getWindow()).getEventHandler().resizeDisplay(); currentFrame = 0; } @@ -456,6 +455,8 @@ public RenderPass getBoundRenderPass() { public void setMainPass(MainPass mainPass) { this.mainPass = mainPass; } + public MainPass getMainPass() { return this.mainPass; } + public void addOnResizeCallback(Runnable runnable) { this.onResizeCallbacks.add(runnable); } @@ -463,6 +464,10 @@ public void addOnResizeCallback(Runnable runnable) { public void bindGraphicsPipeline(GraphicsPipeline pipeline) { VkCommandBuffer commandBuffer = currentCmdBuffer; + //Debug + if(boundRenderPass == null) + mainPass.mainTargetBindWrite(); + PipelineState currentState = PipelineState.getCurrentPipelineState(boundRenderPass); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getHandle(currentState)); @@ -508,7 +513,8 @@ public static void clearAttachments(int v, int width, int height) { return; try(MemoryStack stack = stackPush()) { - //ClearValues have to be different for each attachment to clear, it seems it works like a buffer: color and depth attributes override themselves + //ClearValues have to be different for each attachment to clear, + //it seems it uses the same buffer: color and depth values override themselves VkClearValue colorValue = VkClearValue.calloc(stack); colorValue.color().float32(VRenderSystem.clearColor); @@ -522,6 +528,7 @@ public static void clearAttachments(int v, int width, int height) { VkClearAttachment clearDepth = pAttachments.get(0); clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); clearDepth.clearValue(depthValue); } case GL_COLOR_BUFFER_BIT -> { @@ -540,6 +547,7 @@ public static void clearAttachments(int v, int width, int height) { VkClearAttachment clearDepth = pAttachments.get(1); clearDepth.aspectMask(VK_IMAGE_ASPECT_DEPTH_BIT); + clearDepth.colorAttachment(0); clearDepth.clearValue(depthValue); } default -> throw new RuntimeException("unexpected value"); @@ -560,6 +568,9 @@ public static void clearAttachments(int v, int width, int height) { } public static void setViewport(int x, int y, int width, int height) { + if(!INSTANCE.recordingCmds) + return; + try(MemoryStack stack = stackPush()) { VkViewport.Buffer viewport = VkViewport.malloc(1, stack); viewport.x(x); @@ -579,6 +590,9 @@ public static void setViewport(int x, int y, int width, int height) { } public static void setScissor(int x, int y, int width, int height) { + if(INSTANCE.boundFramebuffer == null) + return; + try(MemoryStack stack = stackPush()) { int framebufferHeight = INSTANCE.boundFramebuffer.getHeight(); @@ -591,7 +605,7 @@ public static void setScissor(int x, int y, int width, int height) { } public static void resetScissor() { - if(Renderer.getInstance().boundFramebuffer == null) + if(INSTANCE.boundFramebuffer == null) return; try(MemoryStack stack = stackPush()) { @@ -631,5 +645,7 @@ public static void popPushDebugSection(String s) { public static VkCommandBuffer getCommandBuffer() { return INSTANCE.currentCmdBuffer; } + public static boolean isRecording() { return INSTANCE.recordingCmds; } + public static void scheduleSwapChainUpdate() { swapChainUpdate = true; } } diff --git a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java index cbc04e9d2..ae327436b 100644 --- a/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java +++ b/src/main/java/net/vulkanmod/vulkan/VRenderSystem.java @@ -261,8 +261,8 @@ public static void setWindow(long window) { VRenderSystem.window = window; } - public static void depthFunc(int p_69457_) { - depthFun = p_69457_; + public static void depthFunc(int depthFun) { + VRenderSystem.depthFun = depthFun; } public static void enableBlend() { diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java index 3210d28df..2289ca287 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/Framebuffer.java @@ -1,9 +1,11 @@ package net.vulkanmod.vulkan.framebuffer; +import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.memory.MemoryManager; import net.vulkanmod.vulkan.texture.VTextureSelector; import net.vulkanmod.vulkan.texture.VulkanImage; import org.apache.commons.lang3.Validate; @@ -11,6 +13,7 @@ import org.lwjgl.vulkan.*; import java.nio.LongBuffer; +import java.util.Arrays; import static net.vulkanmod.vulkan.Vulkan.*; import static org.lwjgl.vulkan.VK10.*; @@ -37,19 +40,6 @@ public class Framebuffer { private final Reference2LongArrayMap framebufferIds = new Reference2LongArrayMap<>(); - //GL compatibility - public Framebuffer(VulkanImage colorAttachment) { - this.width = colorAttachment.width; - this.height = colorAttachment.height; - - this.colorAttachment = colorAttachment; - - this.depthFormat = SwapChain.getDefaultDepthFormat(); - this.depthAttachment = VulkanImage.createDepthImage(depthFormat, this.width, this.height, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - false, false); - } - //SwapChain protected Framebuffer() {} @@ -63,7 +53,12 @@ public Framebuffer(Builder builder) { this.hasColorAttachment = builder.hasColorAttachment; this.hasDepthAttachment = builder.hasDepthAttachment; - this.createImages(); + if(builder.createImages) + this.createImages(); + else { + this.colorAttachment = builder.colorAttachment; + this.depthAttachment = builder.depthAttachment; + } } public void addRenderPass(RenderPass renderPass) { @@ -108,12 +103,12 @@ private long createFramebuffer(RenderPass renderPass) { } else if(colorAttachment != null) { attachments = stack.longs(colorAttachment.getImageView()); } else { - attachments = stack.longs(depthAttachment.getImageView()); + throw new IllegalStateException(); } LongBuffer pFramebuffer = stack.mallocLong(1); - VkFramebufferCreateInfo framebufferInfo = VkFramebufferCreateInfo.callocStack(stack); + VkFramebufferCreateInfo framebufferInfo = VkFramebufferCreateInfo.calloc(stack); framebufferInfo.sType$Default(); framebufferInfo.renderPass(renderPass.getId()); framebufferInfo.width(this.width); @@ -141,11 +136,6 @@ public void beginRenderPass(VkCommandBuffer commandBuffer, RenderPass renderPass Renderer.getInstance().setBoundFramebuffer(this); } - public void bindAsTexture(VkCommandBuffer commandBuffer, MemoryStack stack) { - this.colorAttachment.transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - VTextureSelector.bindTexture(3, this.colorAttachment); - } - public VkViewport.Buffer viewport(MemoryStack stack) { VkViewport.Buffer viewport = VkViewport.malloc(1, stack); viewport.x(0.0f); @@ -167,20 +157,29 @@ public VkRect2D.Buffer scissor(MemoryStack stack) { } public void cleanUp() { - if(this.colorAttachment != null) - this.colorAttachment.free(); + cleanUp(true); + } + + public void cleanUp(boolean cleanImages) { + if(cleanImages) { + if(this.colorAttachment != null) + this.colorAttachment.free(); - if(this.depthAttachment != null) - this.depthAttachment.free(); + if(this.depthAttachment != null) + this.depthAttachment.free(); + } final VkDevice device = Vulkan.getDevice(); + final var ids = framebufferIds.values().toLongArray(); + + MemoryManager.getInstance().addFrameOp( + () -> Arrays.stream(ids).forEach(id -> + vkDestroyFramebuffer(device, id, null)) + ); - framebufferIds.forEach((renderPass, id) -> { - vkDestroyFramebuffer(device, id, null); - }); - framebufferIds.clear(); + framebufferIds.clear(); } public long getDepthImageView() { return depthAttachment.getImageView(); } @@ -197,10 +196,22 @@ public void cleanUp() { public int getDepthFormat() { return this.depthFormat; } + public static Builder builder(int width, int height, int colorAttachments, boolean hasDepthAttachment) { + return new Builder(width, height, colorAttachments, hasDepthAttachment); + } + + public static Builder builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { + return new Builder(colorAttachment, depthAttachment); + } + public static class Builder { + final boolean createImages; final int width, height; int format, depthFormat; + VulkanImage colorAttachment; + VulkanImage depthAttachment; + // int colorAttachments; boolean hasColorAttachment; boolean hasDepthAttachment; @@ -214,6 +225,7 @@ public Builder(int width, int height, int colorAttachments, boolean hasDepthAtta //TODO multi color attachments Validate.isTrue(colorAttachments <= 1, "Not supported"); + this.createImages = true; this.format = DEFAULT_FORMAT; this.depthFormat = SwapChain.getDefaultDepthFormat(); this.linearFiltering = true; @@ -225,6 +237,23 @@ public Builder(int width, int height, int colorAttachments, boolean hasDepthAtta this.hasDepthAttachment = hasDepthAttachment; } + public Builder(VulkanImage colorAttachment, VulkanImage depthAttachment) { + this.createImages = false; + this.colorAttachment = colorAttachment; + this.depthAttachment = depthAttachment; + + this.format = colorAttachment.format; + + this.width = colorAttachment.width; + this.height = colorAttachment.height; + this.hasColorAttachment = true; + this.hasDepthAttachment = depthAttachment != null; + + this.depthFormat = this.hasDepthAttachment ? depthAttachment.format : 0; + this.linearFiltering = true; + this.depthLinearFiltering = false; + } + public Framebuffer build() { return new Framebuffer(this); } diff --git a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java index 6456a2a91..4ae21ba85 100644 --- a/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java +++ b/src/main/java/net/vulkanmod/vulkan/framebuffer/RenderPass.java @@ -3,6 +3,7 @@ import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.VRenderSystem; import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.memory.MemoryManager; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.*; @@ -218,7 +219,9 @@ public void cleanUp() { //TODO if(!Vulkan.DYNAMIC_RENDERING) - vkDestroyRenderPass(Vulkan.getDevice(), this.id, null); + MemoryManager.getInstance().addFrameOp( + () -> vkDestroyRenderPass(Vulkan.getDevice(), this.id, null)); + } public long getId() { diff --git a/src/main/java/net/vulkanmod/vulkan/passes/LegacyMainPass.java b/src/main/java/net/vulkanmod/vulkan/passes/LegacyMainPass.java new file mode 100644 index 000000000..16f4d5edc --- /dev/null +++ b/src/main/java/net/vulkanmod/vulkan/passes/LegacyMainPass.java @@ -0,0 +1,72 @@ +package net.vulkanmod.vulkan.passes; + +import com.mojang.blaze3d.pipeline.RenderTarget; +import net.minecraft.client.Minecraft; +import net.vulkanmod.vulkan.Renderer; +import net.vulkanmod.vulkan.VRenderSystem; +import net.vulkanmod.vulkan.Vulkan; +import net.vulkanmod.vulkan.framebuffer.SwapChain; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.vulkan.VkCommandBuffer; +import org.lwjgl.vulkan.VkRect2D; +import org.lwjgl.vulkan.VkViewport; + +import static org.lwjgl.vulkan.VK10.*; + +public class LegacyMainPass implements MainPass { + public static LegacyMainPass PASS = new LegacyMainPass(); + + private RenderTarget mainTarget; + + LegacyMainPass() { + this.mainTarget = Minecraft.getInstance().getMainRenderTarget(); + } + + @Override + public void begin(VkCommandBuffer commandBuffer, MemoryStack stack) { + } + + @Override + public void mainTargetBindWrite() { + RenderTarget mainTarget = Minecraft.getInstance().getMainRenderTarget(); + mainTarget.bindWrite(true); + } + + @Override + public void mainTargetUnbindWrite() { + RenderTarget mainTarget = Minecraft.getInstance().getMainRenderTarget(); + mainTarget.unbindWrite(); + } + + @Override + public void end(VkCommandBuffer commandBuffer) { + try(MemoryStack stack = MemoryStack.stackPush()) { + Renderer.getInstance().endRenderPass(commandBuffer); + + RenderTarget mainTarget = Minecraft.getInstance().getMainRenderTarget(); + mainTarget.bindRead(); + + SwapChain swapChain = Vulkan.getSwapChain(); + swapChain.colorAttachmentLayout(stack, commandBuffer, Renderer.getCurrentImage()); + + swapChain.beginRenderPass(commandBuffer, stack); + Renderer.getInstance().setBoundFramebuffer(swapChain); + + VkViewport.Buffer pViewport = swapChain.viewport(stack); + vkCmdSetViewport(commandBuffer, 0, pViewport); + + VkRect2D.Buffer pScissor = swapChain.scissor(stack); + vkCmdSetScissor(commandBuffer, 0, pScissor); + + VRenderSystem.disableBlend(); + Minecraft.getInstance().getMainRenderTarget().blitToScreen(swapChain.getWidth(), swapChain.getHeight()); + } + + Renderer.getInstance().endRenderPass(commandBuffer); + + int result = vkEndCommandBuffer(commandBuffer); + if(result != VK_SUCCESS) { + throw new RuntimeException("Failed to record command buffer:" + result); + } + } +} diff --git a/src/main/java/net/vulkanmod/vulkan/passes/MainPass.java b/src/main/java/net/vulkanmod/vulkan/passes/MainPass.java index 5399e1c73..2c32bf56c 100644 --- a/src/main/java/net/vulkanmod/vulkan/passes/MainPass.java +++ b/src/main/java/net/vulkanmod/vulkan/passes/MainPass.java @@ -1,5 +1,6 @@ package net.vulkanmod.vulkan.passes; +import com.mojang.blaze3d.pipeline.RenderTarget; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.VkCommandBuffer; @@ -7,4 +8,8 @@ public interface MainPass { void begin(VkCommandBuffer commandBuffer, MemoryStack stack); void end(VkCommandBuffer commandBuffer); + + default void mainTargetBindWrite() {} + + default void mainTargetUnbindWrite() {} } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java index 757b5596f..e75106ebe 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/Pipeline.java @@ -498,9 +498,9 @@ public void compileShaders() { this.fragShaderSPIRV = compileShaderAbsoluteFile(String.format("%s%s.fsh", resourcePath, this.shaderPath), ShaderKind.FRAGMENT_SHADER); } - public void compileShaders(String vsh, String fsh) { - this.vertShaderSPIRV = compileShader("vertex shader", vsh, ShaderKind.VERTEX_SHADER); - this.fragShaderSPIRV = compileShader("fragment shader", fsh, ShaderKind.FRAGMENT_SHADER); + public void compileShaders(String name, String vsh, String fsh) { + this.vertShaderSPIRV = compileShader(String.format("%s.vsh", name), vsh, ShaderKind.VERTEX_SHADER); + this.fragShaderSPIRV = compileShader(String.format("%s.fsh", name), fsh, ShaderKind.FRAGMENT_SHADER); } public void parseBindingsJSON() { @@ -560,7 +560,7 @@ private void parseUboNode(JsonElement jsonelement) { String type2 = GsonHelper.getAsString(jsonobject2, "type"); int j = GsonHelper.getAsInt(jsonobject2, "count"); - builder.addFieldInfo(type2, name, j); + builder.addUniformInfo(type2, name, j); } UBO ubo = builder.buildUBO(binding, type); @@ -602,7 +602,7 @@ private void parsePushConstantNode(JsonArray jsonArray) { String type2 = GsonHelper.getAsString(jsonobject2, "type"); int j = GsonHelper.getAsInt(jsonobject2, "count"); - builder.addFieldInfo(type2, name, j); + builder.addUniformInfo(type2, name, j); } this.pushConstants = builder.buildPushConstant(); diff --git a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java index 039b14799..351ff5283 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/descriptor/UBO.java @@ -1,7 +1,7 @@ package net.vulkanmod.vulkan.shader.descriptor; import net.vulkanmod.vulkan.shader.layout.AlignedStruct; -import net.vulkanmod.vulkan.shader.layout.Field; +import net.vulkanmod.vulkan.shader.layout.Uniform; import java.util.List; @@ -11,7 +11,7 @@ public class UBO extends AlignedStruct implements Descriptor { private final int binding; private final int stages; - public UBO(int binding, int stages, int size, List infoList) { + public UBO(int binding, int stages, int size, List infoList) { super(infoList, size); this.binding = binding; this.stages = stages; diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java index 9daf680a4..89c015da5 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/AlignedStruct.java @@ -7,30 +7,30 @@ public abstract class AlignedStruct { - protected List fields = new ArrayList<>(); + protected List uniforms = new ArrayList<>(); protected int size; - protected AlignedStruct(List infoList, int size) { + protected AlignedStruct(List infoList, int size) { this.size = size; if(infoList == null) return; - for(Field.FieldInfo fieldInfo : infoList) { + for(Uniform.Info info : infoList) { - Field field = Field.createField(fieldInfo); - this.fields.add(field); + Uniform uniform = Uniform.createField(info); + this.uniforms.add(uniform); } } public void update(long ptr) { - for(Field field : this.fields) { - field.update(ptr); + for(Uniform uniform : this.uniforms) { + uniform.update(ptr); } } - public List getFields() { - return this.fields; + public List getUniforms() { + return this.uniforms; } public int getSize() { @@ -39,33 +39,33 @@ public int getSize() { public static class Builder { - final List fields = new ArrayList<>(); + final List uniformsInfo = new ArrayList<>(); protected int currentOffset = 0; - public void addFieldInfo(String type, String name, int count) { - Field.FieldInfo fieldInfo = Field.createFieldInfo(type, name, count); + public void addUniformInfo(String type, String name, int count) { + Uniform.Info info = Uniform.createUniformInfo(type, name, count); - this.currentOffset = fieldInfo.computeAlignmentOffset(this.currentOffset); - this.currentOffset += fieldInfo.size; - this.fields.add(fieldInfo); + this.currentOffset = info.computeAlignmentOffset(this.currentOffset); + this.currentOffset += info.size; + this.uniformsInfo.add(info); } - public void addFieldInfo(String type, String name) { - Field.FieldInfo fieldInfo = Field.createFieldInfo(type, name); + public void addUniformInfo(String type, String name) { + Uniform.Info info = Uniform.createUniformInfo(type, name); - this.currentOffset = fieldInfo.computeAlignmentOffset(this.currentOffset); - this.currentOffset += fieldInfo.size; - this.fields.add(fieldInfo); + this.currentOffset = info.computeAlignmentOffset(this.currentOffset); + this.currentOffset += info.size; + this.uniformsInfo.add(info); } public UBO buildUBO(int binding, int stages) { //offset is expressed in floats/ints - return new UBO(binding, stages, this.currentOffset * 4, this.fields); + return new UBO(binding, stages, this.currentOffset * 4, this.uniformsInfo); } public PushConstants buildPushConstant() { - if(this.fields.isEmpty()) return null; - return new PushConstants(this.fields, this.currentOffset * 4); + if(this.uniformsInfo.isEmpty()) return null; + return new PushConstants(this.uniformsInfo, this.currentOffset * 4); } } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Field.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Field.java deleted file mode 100644 index 47a49f04f..000000000 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Field.java +++ /dev/null @@ -1,108 +0,0 @@ -package net.vulkanmod.vulkan.shader.layout; - -import net.vulkanmod.vulkan.util.MappedBuffer; -import org.lwjgl.system.MemoryUtil; - -import java.util.function.Supplier; - -public abstract class Field { - protected Supplier values; - - FieldInfo fieldInfo; - protected long offset; - protected int size; - - Field(FieldInfo fieldInfo) { - this.fieldInfo = fieldInfo; - this.offset = fieldInfo.offset * 4L; - this.size = fieldInfo.size * 4; - this.setSupplier(); - } - - abstract void setSupplier(); - - public void setSupplier(Supplier supplier) { - this.values = supplier; - } - - public String getName() { - return this.fieldInfo.name; - } - - void update(long ptr) { - MappedBuffer src = values.get(); - - MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); - } - - public static Field createField(FieldInfo info) { - return switch (info.type) { - case "mat4" -> new Mat4f(info); - case "vec4" -> new Vec4f(info); - case "vec3" -> new Vec3f(info); - case "vec2" -> new Vec2f(info); - case "float" -> new Vec1f(info); - case "int" -> new Vec1i(info); - default -> throw new RuntimeException("not admitted type: " + info.type); - }; - } - - public int getOffset() { - return fieldInfo.offset; - } - - public int getSize() { return fieldInfo.size; } - - //TODO - public static FieldInfo createFieldInfo(String type, String name, int count) { - return switch (type) { - case "matrix4x4" -> new FieldInfo("mat4", name, 4, 16); - case "float" -> switch (count) { - case 4 -> new FieldInfo("vec4", name, 4, 4); - case 3 -> new FieldInfo("vec3", name, 4, 3); - case 2 -> new FieldInfo("vec2", name, 4, 2); - case 1 -> new FieldInfo("float", name, 1, 1); - - default -> throw new IllegalStateException("Unexpected value: " + count); - }; - case "int" -> new FieldInfo("int", name, 1, 1); - default -> throw new RuntimeException("not admitted type.."); - }; - } - - public static FieldInfo createFieldInfo(String type, String name) { - return switch (type) { - case "mat4" -> new FieldInfo(type, name, 4, 16); - case "mat3" -> new FieldInfo(type, name, 4, 9); - - case "vec4" -> new FieldInfo(type, name, 4, 4); - case "vec3" -> new FieldInfo(type, name, 4, 3); - case "vec2" -> new FieldInfo(type, name, 4, 2); - - case "float", "int" -> new FieldInfo(type, name, 1, 1); - - default -> throw new RuntimeException("not admitted type: " + type); - }; - } - - public static class FieldInfo { - final String type; - final String name; - final int align; - final int size; - int offset; - - FieldInfo(String type, String name, int align, int size) { - this.type = type; - this.name = name; - this.align = align; - this.size = size; - } - - int getSizeBytes() { return 4 * this.size; } - - int computeAlignmentOffset(int builderOffset) { - return this.offset = builderOffset + ((align - (builderOffset % align)) % align); - } - } -} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat4f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat4f.java deleted file mode 100644 index 503cf8b19..000000000 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Mat4f.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.vulkanmod.vulkan.shader.layout; - -import net.vulkanmod.vulkan.shader.Uniforms; -import org.apache.commons.lang3.Validate; - -public class Mat4f extends Field { - public Mat4f(FieldInfo info) { - super(info); - } - - protected void setSupplier() { - this.values = Uniforms.mat4f_uniformMap.get(this.fieldInfo.name); - - Validate.notNull(this.values, "Field name not found: " + this.fieldInfo.name); - } - -} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/PushConstants.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/PushConstants.java index b0f4da565..2e37c1a53 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/PushConstants.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/PushConstants.java @@ -4,7 +4,7 @@ public class PushConstants extends AlignedStruct { - protected PushConstants(List infoList, int size) { + protected PushConstants(List infoList, int size) { super(infoList, size); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java new file mode 100644 index 000000000..dec970668 --- /dev/null +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Uniform.java @@ -0,0 +1,119 @@ +package net.vulkanmod.vulkan.shader.layout; + +import net.vulkanmod.vulkan.shader.Uniforms; +import net.vulkanmod.vulkan.util.MappedBuffer; +import org.lwjgl.system.MemoryUtil; + +import java.util.function.Supplier; + +public class Uniform { + protected Supplier values; + + Info info; + protected long offset; + protected int size; + + Uniform(Info info) { + this.info = info; + this.offset = info.offset * 4L; + this.size = info.size * 4; + this.setSupplier(); + } + + void setSupplier() { + this.values = switch (info.type) { + case "mat4" -> Uniforms.mat4f_uniformMap.get(info.name); + case "vec4" -> Uniforms.vec4f_uniformMap.get(info.name); + case "vec3" -> Uniforms.vec3f_uniformMap.get(info.name); + case "vec2" -> Uniforms.vec2f_uniformMap.get(info.name); + + default -> null; + }; + } + + public void setSupplier(Supplier supplier) { + this.values = supplier; + } + + public String getName() { + return this.info.name; + } + + void update(long ptr) { + MappedBuffer src = values.get(); + + MemoryUtil.memCopy(src.ptr, ptr + this.offset, this.size); + } + + public static Uniform createField(Info info) { + return switch (info.type) { + case "mat4", "vec3", "vec4", "vec2" -> new Uniform(info); + case "float" -> new Vec1f(info); + case "int" -> new Vec1i(info); + default -> throw new RuntimeException("not admitted type: " + info.type); + }; + } + + public int getOffset() { + return info.offset; + } + + public int getSize() { return info.size; } + + public String toString() { + return String.format("%s: %s offset: %d", info.type, info.name, info.offset); + } + + //TODO + public static Info createUniformInfo(String type, String name, int count) { + return switch (type) { + case "matrix4x4" -> new Info("mat4", name, 4, 16); + case "float" -> switch (count) { + case 4 -> new Info("vec4", name, 4, 4); + case 3 -> new Info("vec3", name, 4, 3); + case 2 -> new Info("vec2", name, 2, 2); + case 1 -> new Info("float", name, 1, 1); + + default -> throw new IllegalStateException("Unexpected value: " + count); + }; + case "int" -> new Info("int", name, 1, 1); + default -> throw new RuntimeException("not admitted type.."); + }; + } + + public static Info createUniformInfo(String type, String name) { + return switch (type) { + case "mat4" -> new Info(type, name, 4, 16); + case "mat3" -> new Info(type, name, 4, 9); + + case "vec4" -> new Info(type, name, 4, 4); + case "vec3" -> new Info(type, name, 4, 3); + case "vec2" -> new Info(type, name, 2, 2); + + case "float", "int" -> new Info(type, name, 1, 1); + + default -> throw new RuntimeException("not admitted type: " + type); + }; + } + + public static class Info { + final String type; + final String name; + final int align; + final int size; + int offset; + + Info(String type, String name, int align, int size) { + this.type = type; + this.name = name; + this.align = align; + this.size = size; + } + + int getSizeBytes() { return 4 * this.size; } + + int computeAlignmentOffset(int builderOffset) { + return this.offset = builderOffset + ((align - (builderOffset % align)) % align); + } + } +} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java index 2207f9ed3..4e9a2084c 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1f.java @@ -1,22 +1,26 @@ package net.vulkanmod.vulkan.shader.layout; import net.vulkanmod.vulkan.shader.Uniforms; +import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.lang3.Validate; import org.lwjgl.system.MemoryUtil; import java.util.function.Supplier; -public class Vec1f extends Field { +public class Vec1f extends Uniform { private Supplier floatSupplier; - public Vec1f(FieldInfo fieldInfo) { - super(fieldInfo); + public Vec1f(Info info) { + super(info); } void setSupplier() { - this.floatSupplier = Uniforms.vec1f_uniformMap.get(this.fieldInfo.name); + this.floatSupplier = Uniforms.vec1f_uniformMap.get(this.info.name); + } - Validate.notNull(this.floatSupplier, "Field name not found: " + this.fieldInfo.name); + @Override + public void setSupplier(Supplier supplier) { + this.floatSupplier = () -> supplier.get().getFloat(0); } void update(long ptr) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java index a63fdc146..995076cb2 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec1i.java @@ -1,22 +1,26 @@ package net.vulkanmod.vulkan.shader.layout; import net.vulkanmod.vulkan.shader.Uniforms; +import net.vulkanmod.vulkan.util.MappedBuffer; import org.apache.commons.lang3.Validate; import org.lwjgl.system.MemoryUtil; import java.util.function.Supplier; -public class Vec1i extends Field { +public class Vec1i extends Uniform { private Supplier intSupplier; - public Vec1i(FieldInfo fieldInfo) { - super(fieldInfo); + public Vec1i(Info info) { + super(info); } void setSupplier() { - this.intSupplier = Uniforms.vec1i_uniformMap.get(this.fieldInfo.name); + this.intSupplier = Uniforms.vec1i_uniformMap.get(this.info.name); + } - Validate.notNull(this.intSupplier, "Field name not found: " + this.fieldInfo.name); + @Override + public void setSupplier(Supplier supplier) { + this.intSupplier = () -> supplier.get().getInt(0); } void update(long ptr) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec2f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec2f.java deleted file mode 100644 index f7143c760..000000000 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec2f.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.vulkanmod.vulkan.shader.layout; - -import net.vulkanmod.vulkan.shader.Uniforms; -import org.apache.commons.lang3.Validate; - -public class Vec2f extends Field { - - public Vec2f(FieldInfo fieldInfo) { - super(fieldInfo); - } - - void setSupplier() { - this.values = Uniforms.vec2f_uniformMap.get(this.fieldInfo.name); - - Validate.notNull(this.values, "Field name not found: " + this.fieldInfo.name); - } - -} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec3f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec3f.java deleted file mode 100644 index f4c31e1c4..000000000 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec3f.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.vulkanmod.vulkan.shader.layout; - -import net.vulkanmod.vulkan.shader.Uniforms; -import org.apache.commons.lang3.Validate; - -public class Vec3f extends Field { - - public Vec3f(FieldInfo fieldInfo) { - super(fieldInfo); - } - - void setSupplier() { - this.values = Uniforms.vec3f_uniformMap.get(this.fieldInfo.name); - - Validate.notNull(this.values, "Field name not found: " + this.fieldInfo.name); - } - -} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec4f.java b/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec4f.java deleted file mode 100644 index b75a747a5..000000000 --- a/src/main/java/net/vulkanmod/vulkan/shader/layout/Vec4f.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.vulkanmod.vulkan.shader.layout; - -import net.vulkanmod.vulkan.shader.Uniforms; -import org.apache.commons.lang3.Validate; - -public class Vec4f extends Field { - - public Vec4f(FieldInfo fieldInfo) { - super(fieldInfo); - } - - void setSupplier() { - this.values = Uniforms.vec4f_uniformMap.get(this.fieldInfo.name); - - Validate.notNull(this.values, "Field name not found: " + this.fieldInfo.name); - } - -} diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java b/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java index 78d6f2915..ca1e56a11 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/parser/GlslConverter.java @@ -10,7 +10,7 @@ public class GlslConverter { -// private Queue stack = new ArrayDeque<>(); + // private Queue stack = new ArrayDeque<>(); private int count; ShaderStage shaderStage; private State state; @@ -21,9 +21,9 @@ public class GlslConverter { private String vshConverted; private String fshConverted; - public void process(VertexFormat vertexFormat, String vertShader, String fragShader) { + public void process(String vertShader, String fragShader) { this.uniformParser = new UniformParser(this); - this.inOutParser = new InputOutputParser(this, vertexFormat); + this.inOutParser = new InputOutputParser(this); StringBuilder vshOut = new StringBuilder(); StringBuilder fshOut = new StringBuilder(); @@ -34,7 +34,6 @@ public void process(VertexFormat vertexFormat, String vertShader, String fragSha var iterator = Arrays.stream(lines).iterator(); - //TODO version while (iterator.hasNext()) { String line = iterator.next(); @@ -79,8 +78,6 @@ public void process(VertexFormat vertexFormat, String vertShader, String fragSha vshOut.insert(0, "#version 450\n\n"); fshOut.insert(0, "#version 450\n\n"); - //TODO check - //TODO ubo this.vshConverted = vshOut.toString(); this.fshConverted = fshOut.toString(); @@ -95,20 +92,23 @@ private String parseLine(String line) { String token = tokenizer.nextToken(); - if(token.matches("uniform")) { - this.state = State.MATCHING_UNIFORM; - } - else if(token.matches("in")) { - this.state = State.MATCHING_IN_OUT; - } - else if(token.matches("out")) { - this.state = State.MATCHING_IN_OUT; - } - else if(token.matches("#version")) { - return null; - } - else { - return line; + switch (token) { + case "uniform" -> this.state = State.MATCHING_UNIFORM; + case "in", "out" -> this.state = State.MATCHING_IN_OUT; + case "#version" -> { + return null; + } + case "#moj_import" -> { + if(tokenizer.countTokens() != 1) { + throw new IllegalArgumentException("Token count != 1"); + } + + return String.format("#include %s", tokenizer.nextToken()); + } + + default -> { + return line; + } } if(tokenizer.countTokens() < 2) { diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java b/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java index 3607af6eb..aa8c5c0fe 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/parser/InputOutputParser.java @@ -10,10 +10,10 @@ public class InputOutputParser { private final GlslConverter converterInstance; - private final VertexFormat vertexFormat; + private VertexFormat vertexFormat; - private AttributeSet vertInAttributes = new AttributeSet(); - private AttributeSet vertOutAttributes = new AttributeSet(); + private final AttributeSet vertInAttributes = new AttributeSet(); + private final AttributeSet vertOutAttributes = new AttributeSet(); private GlslConverter.ShaderStage shaderStage; @@ -22,9 +22,8 @@ public class InputOutputParser { private String type; private String name; - public InputOutputParser(GlslConverter converterInstance, VertexFormat vertexFormat) { + public InputOutputParser(GlslConverter converterInstance) { this.converterInstance = converterInstance; - this.vertexFormat = vertexFormat; } public boolean parseToken(String token) { @@ -92,7 +91,7 @@ public String createInOutCode() { } builder.append("\n"); - //TODO + //TODO multi attachments? builder.append(String.format("layout(location = 0) out vec4 fragColor;\n\n")); } diff --git a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java b/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java index d9aeec8df..eb1fc2a60 100644 --- a/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java +++ b/src/main/java/net/vulkanmod/vulkan/shader/parser/UniformParser.java @@ -101,7 +101,7 @@ private UBO createUBO() { AlignedStruct.Builder builder = new AlignedStruct.Builder(); for(Uniform uniform : this.globalUniforms) { - builder.addFieldInfo(uniform.type, uniform.name); + builder.addUniformInfo(uniform.type, uniform.name); } //hardcoded 0 binding as it should always be 0 in this case diff --git a/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java new file mode 100644 index 000000000..b7444dc56 --- /dev/null +++ b/src/main/java/net/vulkanmod/vulkan/texture/ImageUtil.java @@ -0,0 +1,194 @@ +package net.vulkanmod.vulkan.texture; + +import net.vulkanmod.vulkan.DeviceManager; +import net.vulkanmod.vulkan.memory.MemoryManager; +import net.vulkanmod.vulkan.queue.CommandPool; +import net.vulkanmod.vulkan.util.VUtil; +import org.lwjgl.PointerBuffer; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.vulkan.*; + +import java.nio.LongBuffer; + +import static org.lwjgl.system.MemoryStack.stackPush; +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.vkWaitForFences; + +public abstract class ImageUtil { + + public static void copyBufferToImageCmd(VkCommandBuffer commandBuffer, long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { + + try(MemoryStack stack = stackPush()) { + + VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); + region.bufferOffset(bufferOffset); + region.bufferRowLength(bufferRowLenght); // Tightly packed + region.bufferImageHeight(bufferImageHeight); // Tightly packed + region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + region.imageSubresource().mipLevel(mipLevel); + region.imageSubresource().baseArrayLayer(0); + region.imageSubresource().layerCount(1); + region.imageOffset().set(xOffset, yOffset, 0); + region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); + + vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); + } + } + + public static void downloadTexture(VulkanImage image, long ptr) { + try(MemoryStack stack = stackPush()) { + int prevLayout = image.getCurrentLayout(); + CommandPool.CommandBuffer commandBuffer = DeviceManager.getGraphicsQueue().beginCommands(); + image.transitionImageLayout(stack, commandBuffer.getHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + long imageSize = (long) image.width * image.height * image.formatSize; + + LongBuffer pStagingBuffer = stack.mallocLong(1); + PointerBuffer pStagingAllocation = stack.pointers(0L); + MemoryManager.getInstance().createBuffer(imageSize, + VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + pStagingBuffer, + pStagingAllocation); + + copyImageToBuffer(commandBuffer.getHandle(), pStagingBuffer.get(0), image.getId(), 0, image.width, image.height, 0, 0, 0, 0, 0); + image.transitionImageLayout(stack, commandBuffer.getHandle(), prevLayout); + + long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); + vkWaitForFences(DeviceManager.device, fence, true, VUtil.UINT64_MAX); + + MemoryManager.MapAndCopy(pStagingAllocation.get(0), + (data) -> VUtil.memcpy(data.getByteBuffer(0, (int)imageSize), ptr) + ); + + MemoryManager.freeBuffer(pStagingBuffer.get(0), pStagingAllocation.get(0)); + } + } + + public static void copyImageToBuffer(VkCommandBuffer commandBuffer, long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { + + try(MemoryStack stack = stackPush()) { + + VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); + region.bufferOffset(bufferOffset); + region.bufferRowLength(bufferRowLenght); // Tightly packed + region.bufferImageHeight(bufferImageHeight); // Tightly packed + region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); + region.imageSubresource().mipLevel(mipLevel); + region.imageSubresource().baseArrayLayer(0); + region.imageSubresource().layerCount(1); + region.imageOffset().set(xOffset, yOffset, 0); + region.imageExtent().set(width, height, 1); + + vkCmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, region); + } + } + + public static void generateMipmaps(VulkanImage image) { + try(MemoryStack stack = stackPush()) { + + CommandPool.CommandBuffer commandBuffer = DeviceManager.getGraphicsQueue().beginCommands(); + + image.transitionImageLayout(stack, commandBuffer.getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + int level, prevLevel; + + for (level = 1; level < image.mipLevels; level++) { + prevLevel = level - 1; + + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); + barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + barrier.oldLayout(VK_IMAGE_USAGE_TRANSFER_DST_BIT); + barrier.newLayout(VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + barrier.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.image(image.getId()); + + barrier.subresourceRange().baseMipLevel(prevLevel); + barrier.subresourceRange().levelCount(1); + barrier.subresourceRange().baseArrayLayer(0); + barrier.subresourceRange().layerCount(VK_REMAINING_ARRAY_LAYERS); + + barrier.subresourceRange().aspectMask(image.aspect); + + barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); + barrier.dstAccessMask(VK_ACCESS_TRANSFER_READ_BIT); + + vkCmdPipelineBarrier(commandBuffer.getHandle(), + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, + null, + null, + barrier); + + prevLevel = level - 1; + + VkImageBlit.Buffer blit = VkImageBlit.calloc(1, stack); + blit.srcOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); + blit.srcOffsets(1, VkOffset3D.calloc(stack).set(image.width >> prevLevel, image.height >> prevLevel, 1)); + blit.srcSubresource() + .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .mipLevel(prevLevel) + .baseArrayLayer(0) + .layerCount(1); + + blit.dstOffsets(0, VkOffset3D.calloc(stack).set(0, 0, 0)); + blit.dstOffsets(1, VkOffset3D.calloc(stack).set(image.width >> level, image.height >> level, 1)); + blit.dstSubresource() + .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .mipLevel(level) + .baseArrayLayer(0) + .layerCount(1); + + vkCmdBlitImage(commandBuffer.getHandle(), + image.getId(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + image.getId(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + blit, + VK_FILTER_LINEAR); + + } + + VkImageMemoryBarrier.Buffer barrier = VkImageMemoryBarrier.calloc(1, stack); + barrier.sType(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + barrier.oldLayout(VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + barrier.newLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + barrier.srcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.dstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED); + barrier.image(image.getId()); + + barrier.subresourceRange().baseMipLevel(0); + barrier.subresourceRange().levelCount(image.mipLevels - 1); + barrier.subresourceRange().baseArrayLayer(0); + barrier.subresourceRange().layerCount(VK_REMAINING_ARRAY_LAYERS); + + barrier.subresourceRange().aspectMask(image.aspect); + + barrier.srcAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT); + barrier.dstAccessMask(VK_ACCESS_SHADER_READ_BIT); + + vkCmdPipelineBarrier(commandBuffer.getHandle(), + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + null, + null, + barrier); + + barrier.oldLayout(VK_IMAGE_USAGE_TRANSFER_DST_BIT); + barrier.subresourceRange().baseMipLevel(image.mipLevels - 1); + barrier.subresourceRange().levelCount(1); + + vkCmdPipelineBarrier(commandBuffer.getHandle(), + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + null, + null, + barrier); + + image.setCurrentLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); + + vkWaitForFences(DeviceManager.device, fence, true, VUtil.UINT64_MAX); + } + } +} diff --git a/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java index 513ec2735..d29c91939 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/SamplerManager.java @@ -21,19 +21,19 @@ public abstract class SamplerManager { static final Short2LongMap SAMPLERS = new Short2LongOpenHashMap(); - public static long getTextureSampler(byte mipLevels, byte flags) { - short key = (short) (flags | (mipLevels << 8)); + public static long getTextureSampler(byte maxLod, byte flags) { + short key = (short) (flags | (maxLod << 8)); long sampler = SAMPLERS.getOrDefault(key, 0L); if(sampler == 0L) { - sampler = createTextureSampler(mipLevels, flags); + sampler = createTextureSampler(maxLod, flags); SAMPLERS.put(key, sampler); } return sampler; } - private static long createTextureSampler(byte mipLevels, byte flags) { + private static long createTextureSampler(byte maxLod, byte flags) { Validate.isTrue( (flags & (REDUCTION_MIN_BIT | REDUCTION_MAX_BIT)) != (REDUCTION_MIN_BIT | REDUCTION_MAX_BIT) ); @@ -70,7 +70,7 @@ private static long createTextureSampler(byte mipLevels, byte flags) { if((flags & USE_MIPMAPS_BIT) != 0) { samplerInfo.mipmapMode(VK_SAMPLER_MIPMAP_MODE_LINEAR); - samplerInfo.maxLod(mipLevels); + samplerInfo.maxLod(maxLod); samplerInfo.minLod(0.0F); samplerInfo.mipLodBias(MIP_BIAS); } else { diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java index 3d627f4fa..a6586a3ce 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VTextureSelector.java @@ -5,7 +5,7 @@ import java.nio.ByteBuffer; public abstract class VTextureSelector { - private static final int SIZE = 8; + public static final int SIZE = 8; private static final VulkanImage[] boundTextures = new VulkanImage[SIZE]; @@ -50,7 +50,7 @@ public static void uploadSubTexture(int mipLevel, int width, int height, int xOf public static VulkanImage getTexture(String name) { return switch (name) { - case "Sampler0" -> boundTextures[0]; + case "Sampler0", "DiffuseSampler" -> boundTextures[0]; case "Sampler1" -> boundTextures[1]; case "Sampler2" -> boundTextures[2]; case "Sampler3" -> boundTextures[3]; diff --git a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java index 5d3750aef..8c617327b 100644 --- a/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java +++ b/src/main/java/net/vulkanmod/vulkan/texture/VulkanImage.java @@ -13,6 +13,7 @@ import java.nio.ByteBuffer; import java.nio.LongBuffer; +import java.util.Arrays; import static net.vulkanmod.vulkan.texture.SamplerManager.*; import static org.lwjgl.system.MemoryStack.stackPush; @@ -135,7 +136,15 @@ private void createImage(int mipLevels, int width, int height, int format, int u } public static int getAspect(int format) { - return format == SwapChain.getDefaultDepthFormat() ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + return isDepthFormat(format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + } + + public static boolean isDepthFormat(int format) { + return switch (format) { + case VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT_S8_UINT -> true; + default -> false; + }; } public static long createImageView(long image, int format, int aspectFlags, int mipLevels) { @@ -180,7 +189,7 @@ public void uploadSubTextureAsync(int mipLevel, int width, int height, int xOffs stagingBuffer.copyBuffer((int)imageSize, buffer); - copyBufferToImageCmd(commandBuffer, stagingBuffer.getId(), id, mipLevel, width, height, xOffset, yOffset, + ImageUtil.copyBufferToImageCmd(commandBuffer.getHandle(), stagingBuffer.getId(), id, mipLevel, width, height, xOffset, yOffset, (int) (stagingBuffer.getOffset() + (unpackRowLength * unpackSkipRows + unpackSkipPixels) * this.formatSize), unpackRowLength, height); long fence = DeviceManager.getGraphicsQueue().endIfNeeded(commandBuffer); @@ -189,29 +198,6 @@ public void uploadSubTextureAsync(int mipLevel, int width, int height, int xOffs Synchronization.INSTANCE.addCommandBuffer(commandBuffer); } - public static void downloadTexture(int width, int height, int formatSize, ByteBuffer buffer, long image) { - try(MemoryStack stack = stackPush()) { - long imageSize = width * height * formatSize; - - LongBuffer pStagingBuffer = stack.mallocLong(1); - PointerBuffer pStagingAllocation = stack.pointers(0L); - MemoryManager.getInstance().createBuffer(imageSize, - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - pStagingBuffer, - pStagingAllocation); - - copyImageToBuffer(pStagingBuffer.get(0), image, 0, width, height, 0, 0, 0, 0, 0); - - MemoryManager.MapAndCopy(pStagingAllocation.get(0), - (data) -> VUtil.memcpy(data.getByteBuffer(0, (int)imageSize), buffer) - ); - - MemoryManager.freeBuffer(pStagingBuffer.get(0), pStagingAllocation.get(0)); - } - - } - private void transferDstLayout(MemoryStack stack, VkCommandBuffer commandBuffer) { transitionImageLayout(stack, commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); } @@ -241,51 +227,11 @@ public void updateTextureSampler(boolean blur, boolean clamp, boolean mipmaps) { } public void updateTextureSampler(byte flags) { - this.sampler = SamplerManager.getTextureSampler((byte) this.mipLevels, flags); + updateTextureSampler(this.mipLevels - 1, flags); } - private void copyBufferToImageCmd(CommandPool.CommandBuffer commandBuffer, long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { - - try(MemoryStack stack = stackPush()) { - - VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); - region.bufferOffset(bufferOffset); - region.bufferRowLength(bufferRowLenght); // Tightly packed - region.bufferImageHeight(bufferImageHeight); // Tightly packed - region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - region.imageSubresource().mipLevel(mipLevel); - region.imageSubresource().baseArrayLayer(0); - region.imageSubresource().layerCount(1); - region.imageOffset().set(xOffset, yOffset, 0); - region.imageExtent(VkExtent3D.calloc(stack).set(width, height, 1)); - - vkCmdCopyBufferToImage(commandBuffer.getHandle(), buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); - } - } - - private static void copyImageToBuffer(long buffer, long image, int mipLevel, int width, int height, int xOffset, int yOffset, int bufferOffset, int bufferRowLenght, int bufferImageHeight) { - - try(MemoryStack stack = stackPush()) { - - CommandPool.CommandBuffer commandBuffer = DeviceManager.getGraphicsQueue().beginCommands(); - - VkBufferImageCopy.Buffer region = VkBufferImageCopy.calloc(1, stack); - region.bufferOffset(bufferOffset); - region.bufferRowLength(bufferRowLenght); // Tightly packed - region.bufferImageHeight(bufferImageHeight); // Tightly packed - region.imageSubresource().aspectMask(VK_IMAGE_ASPECT_COLOR_BIT); - region.imageSubresource().mipLevel(mipLevel); - region.imageSubresource().baseArrayLayer(0); - region.imageSubresource().layerCount(1); - region.imageOffset().set(xOffset, yOffset, 0); - region.imageExtent().set(width, height, 1); - - vkCmdCopyImageToBuffer(commandBuffer.getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, region); - - long fence = DeviceManager.getGraphicsQueue().submitCommands(commandBuffer); - - vkWaitForFences(DEVICE, fence, true, VUtil.UINT64_MAX); - } + public void updateTextureSampler(int maxLod, byte flags) { + this.sampler = SamplerManager.getTextureSampler((byte) maxLod, flags); } public void transitionImageLayout(MemoryStack stack, VkCommandBuffer commandBuffer, int newLayout) { @@ -309,6 +255,10 @@ public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer comm srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; } + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL -> { + srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL -> { srcAccessMask = VK_ACCESS_SHADER_READ_BIT; sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; @@ -329,6 +279,10 @@ public static void transitionImageLayout(MemoryStack stack, VkCommandBuffer comm dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; } + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL -> { + dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL -> { dstAccessMask = VK_ACCESS_SHADER_READ_BIT; destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; @@ -394,9 +348,18 @@ public void free() { } public void doFree() { + if(this.id == 0L) + return; + MemoryManager.freeImage(this.id, this.allocation); vkDestroyImageView(Vulkan.getDevice(), this.mainImageView, null); + + if(this.levelImageViews != null) + Arrays.stream(this.levelImageViews).forEach( + imageView -> vkDestroyImageView(Vulkan.getDevice(), this.mainImageView, null)); + + this.id = 0L; } public int getCurrentLayout() { @@ -432,7 +395,7 @@ public static class Builder { int format = VulkanImage.DefaultFormat; int formatSize; byte mipLevels = 1; - int usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + int usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; byte samplerFlags = 0; @@ -467,6 +430,11 @@ public Builder setUsage(int usage) { return this; } + public Builder addUsage(int usage) { + this.usage |= usage; + return this; + } + public Builder setLinearFiltering(boolean b) { this.samplerFlags |= b ? LINEAR_FILTERING_BIT : 0; return this; @@ -503,7 +471,9 @@ private static int convertFormat(NativeImage.InternalGlFormat format) { private static int formatSize(int format) { return switch (format) { - case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB -> 4; + case VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_SINT-> 4; case VK_FORMAT_R8_UNORM -> 1; // default -> throw new IllegalArgumentException(String.format("Unxepcted format: %s", format)); diff --git a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java index 09427ef9b..4e583e5a6 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/ColorUtil.java @@ -11,23 +11,17 @@ public static void useGammaCorrection(boolean b) { colorConsumer = b ? new GammaColorConsumer() : new DefaultColorConsumer(); } - public static int packColorInt(float r, float g, float b, float a) { - int color = 0; - color += (int)(a * 255) << 24; - color += (int)(r * 255) << 16; - color += (int)(g * 255) << 8; - color += (int)(b * 255); + public static int packColorIntRGBA(float r, float g, float b, float a) { +// int color = ((int)(r * 255.0f) & 0xFF) << 24 | ((int)(g * 255.0f) & 0xFF) << 16 | ((int)(b * 255.0f) & 0xFF) << 8 | ((int)(a * 255.0f) & 0xFF); + int color = ((int)(a * 255.0f) & 0xFF) << 24 | ((int)(b * 255.0f) & 0xFF) << 16 | ((int)(g * 255.0f) & 0xFF) << 8 | ((int)(r * 255.0f) & 0xFF); return color; } public static int BGRAtoRGBA(int v) { byte r = (byte) (v >> 16); - byte g = (byte) (v >> 8); byte b = (byte) (v); - byte a = (byte) (v >> 24); - - return r & 0xFF | (g << 8) & 0xFF00 | (b << 16) & 0xFF0000 | (a << 24) & 0xFF000000; + return r & 0xFF | (b << 16) & 0xFF0000 | v & 0xFF00FF00; } public static float gamma(float f) { diff --git a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java index 4093333b5..eebd803e8 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/DrawUtil.java @@ -4,18 +4,12 @@ import com.mojang.blaze3d.vertex.*; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ShaderInstance; -import net.vulkanmod.vulkan.Renderer; -import net.vulkanmod.vulkan.framebuffer.Framebuffer; import org.joml.Matrix4f; -import org.lwjgl.system.MemoryStack; public class DrawUtil { - public static void drawFramebuffer(Framebuffer framebuffer) { - Renderer renderer = Renderer.getInstance(); - + public static void blitToScreen() { Matrix4f matrix4f = new Matrix4f().setOrtho(0.0F, 1.0F, 1.0F, 0.0F, 0.0F, 1.0F); -// matrix4f.setIdentity(); RenderSystem.setProjectionMatrix(matrix4f, VertexSorting.ORTHOGRAPHIC_Z); PoseStack posestack = RenderSystem.getModelViewStack(); posestack.pushPose(); @@ -23,38 +17,18 @@ public static void drawFramebuffer(Framebuffer framebuffer) { RenderSystem.applyModelViewMatrix(); posestack.popPose(); -// drawer.uploadAndBindUBOs(drawer.blitShader); - - try (MemoryStack stack = MemoryStack.stackPush()) { - framebuffer.bindAsTexture(Renderer.getCommandBuffer(), stack); - } - ShaderInstance shaderInstance = Minecraft.getInstance().gameRenderer.blitShader; RenderSystem.setShader(() -> shaderInstance); Tesselator tesselator = RenderSystem.renderThreadTesselator(); BufferBuilder bufferBuilder = tesselator.getBuilder(); -// bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); -// bufferBuilder.vertex(0.0D, 0.0D, 0.0D).uv(0.0F, 1.0F).endVertex(); -// bufferBuilder.vertex(1.0D, 0.0D, 0.0D).uv(1.0F, 1.0F).endVertex(); -// bufferBuilder.vertex(1.0D, 1.0D, 0.0D).uv(1.0F, 0.0F).endVertex(); -// bufferBuilder.vertex(0.0D, 1.0D, 0.0D).uv(0.0F, 0.0F).endVertex(); - bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); - bufferBuilder.vertex(0.0D, 0.0D, 0.0D).uv(0.0F, 0.0F).color(255, 255, 255, 255).endVertex(); - bufferBuilder.vertex(1.0D, 0.0D, 0.0D).uv(1.0F, 0.0F).color(255, 255, 255, 255).endVertex(); - bufferBuilder.vertex(1.0D, 1.0D, 0.0D).uv(1.0F, 0.0F).color(255, 255, 255, 255).endVertex(); - bufferBuilder.vertex(0.0D, 1.0D, 0.0D).uv(0.0F, 0.0F).color(255, 255, 255, 255).endVertex(); -// bufferBuilder.end(); -// BufferUploader._endInternal(bufferBuilder); + bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + bufferBuilder.vertex(-1.0D, -1.0D, 0.0D).uv(0.0F, 1.0F).endVertex(); + bufferBuilder.vertex(1.0D, -1.0D, 0.0D).uv(1.0F, 1.0F).endVertex(); + bufferBuilder.vertex(1.0D, 1.0D, 0.0D).uv(1.0F, 0.0F).endVertex(); + bufferBuilder.vertex(-1.0D, 1.0D, 0.0D).uv(0.0F, 0.0F).endVertex(); BufferUploader.drawWithShader(bufferBuilder.end()); - //Draw buffer -// Pair pair = bufferBuilder.popNextBuffer(); -// BufferBuilder.DrawState drawstate = pair.getFirst(); - -// drawer.draw(pair.getSecond(), 7, drawstate.format(), drawstate.vertexCount()); - -// drawer.drawWithoutBinding(pair.getSecond(), 7, drawstate.format(), drawstate.vertexCount()); } } diff --git a/src/main/java/net/vulkanmod/vulkan/util/VUtil.java b/src/main/java/net/vulkanmod/vulkan/util/VUtil.java index e6c8d5ed0..46ffadeb3 100644 --- a/src/main/java/net/vulkanmod/vulkan/util/VUtil.java +++ b/src/main/java/net/vulkanmod/vulkan/util/VUtil.java @@ -63,16 +63,16 @@ public static void memcpy(ByteBuffer buffer, short[] indices, long offset) { } public static void memcpy(ByteBuffer src, ByteBuffer dst) { - //src.limit((int)size); -// dst.put(src); - MemoryUtil.memCopy(src, dst); src.limit(src.capacity()).rewind(); } + public static void memcpy(ByteBuffer src, long dstPtr) { + MemoryUtil.memCopy(MemoryUtil.memAddress0(src), dstPtr, src.capacity()); + } + public static void memcpy(ByteBuffer src, ByteBuffer dst, long offset) { dst.position((int)offset); -// dst.put(src); MemoryUtil.memCopy(src, dst); src.limit(src.capacity()).rewind(); @@ -81,7 +81,6 @@ public static void memcpy(ByteBuffer src, ByteBuffer dst, long offset) { public static void memcpy(ByteBuffer src, ByteBuffer dst, int size, long offset) { dst.position((int)offset); src.limit(size); -// dst.put(src); MemoryUtil.memCopy(src, dst); src.limit(src.capacity()).rewind(); diff --git a/src/main/resources/assets/vulkanmod/shaders/include/fog.glsl b/src/main/resources/assets/vulkanmod/shaders/include/fog.glsl new file mode 100644 index 000000000..f5c38b5cb --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/include/fog.glsl @@ -0,0 +1,28 @@ +vec4 linear_fog(vec4 inColor, float vertexDistance, float fogStart, float fogEnd, vec4 fogColor) { + if (vertexDistance <= fogStart) { + return inColor; + } + + float fogValue = vertexDistance < fogEnd ? smoothstep(fogStart, fogEnd, vertexDistance) : 1.0; + return vec4(mix(inColor.rgb, fogColor.rgb, fogValue * fogColor.a), inColor.a); +} + +float linear_fog_fade(float vertexDistance, float fogStart, float fogEnd) { + if (vertexDistance <= fogStart) { + return 1.0; + } else if (vertexDistance >= fogEnd) { + return 0.0; + } + + return smoothstep(fogEnd, fogStart, vertexDistance); +} + +float fog_distance(mat4 modelViewMat, vec3 pos, int shape) { + if (shape == 0) { + return length((modelViewMat * vec4(pos, 1.0)).xyz); + } else { + float distXZ = length((modelViewMat * vec4(pos.x, 0.0, pos.z, 1.0)).xyz); + float distY = length((modelViewMat * vec4(0.0, pos.y, 0.0, 1.0)).xyz); + return max(distXZ, distY); + } +} diff --git a/src/main/resources/assets/vulkanmod/shaders/include/matrix.glsl b/src/main/resources/assets/vulkanmod/shaders/include/matrix.glsl new file mode 100644 index 000000000..0262add4c --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/include/matrix.glsl @@ -0,0 +1,6 @@ +mat2 mat2_rotate_z(float radians) { + return mat2( + cos(radians), -sin(radians), + sin(radians), cos(radians) + ); +} diff --git a/src/main/resources/assets/vulkanmod/shaders/include/projection.glsl b/src/main/resources/assets/vulkanmod/shaders/include/projection.glsl new file mode 100644 index 000000000..c976cb825 --- /dev/null +++ b/src/main/resources/assets/vulkanmod/shaders/include/projection.glsl @@ -0,0 +1,6 @@ +vec4 projection_from_position(vec4 position) { + vec4 projection = position * 0.5; + projection.xy = vec2(projection.x + projection.w, projection.y + projection.w); + projection.zw = position.zw; + return projection; +} diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh index ca01f415f..be1711e59 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.fsh @@ -1,19 +1,14 @@ #version 450 -layout(binding = 2) uniform sampler2D DiffuseSampler; - -layout(binding = 1) uniform UBO { - vec4 ColorModulator; -}; +layout(binding = 1) uniform sampler2D DiffuseSampler; layout(location = 0) in vec2 texCoord; -layout(location = 1) in vec4 vertexColor; layout(location = 0) out vec4 fragColor; void main() { - vec4 color = texture(DiffuseSampler, texCoord) * vertexColor; + vec4 color = texture(DiffuseSampler, texCoord); // blit final output of compositor into displayed back buffer - fragColor = color * ColorModulator; + fragColor = color; } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json index 279229b03..eabf13afd 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.json @@ -12,7 +12,7 @@ "Color" ], "samplers": [ - { "name": "DiffuseSampler" } + { "name": "Sampler0" } ], "uniforms": [ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, @@ -22,9 +22,6 @@ "UBOs": [ { "type": "vertex", "binding": 0, "fields": [ { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } - ] }, - { "type": "fragment", "binding": 1, "fields": [ - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh index bf0f4394d..f00f78af7 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/blit_screen/blit_screen.vsh @@ -2,7 +2,6 @@ layout(location = 0) in vec3 Position; layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Color; layout(binding = 0) uniform UniformBufferObject { mat4 MVP; @@ -16,5 +15,4 @@ void main() { gl_Position = vec4(Position, 1.0); texCoord = UV; - vertexColor = Color; } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh index 49a182cb7..a94ccfc2e 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.fsh @@ -1,13 +1,15 @@ -#version 150 +#version 450 -uniform sampler2D Sampler2; +layout(location = 0) in vec4 vertexColor; +layout(location = 1) in vec2 texCoord2; -uniform vec4 ColorModulator; +layout(binding = 1) uniform UBO { + vec4 ColorModulator; +}; -in vec4 vertexColor; -in vec2 texCoord2; +layout(binding = 2) uniform sampler2D Sampler2; -out vec4 fragColor; +layout(location = 0) out vec4 fragColor; void main() { vec4 color = texture(Sampler2, texCoord2) * vertexColor; diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh index 7aab39285..78f3e6d99 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_lightmap/position_color_lightmap.vsh @@ -1,14 +1,15 @@ -#version 150 +#version 450 -in vec3 Position; -in vec4 Color; -in vec2 UV2; +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; +layout(location = 2) in vec2 UV2; -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; +}; -out vec4 vertexColor; -out vec2 texCoord2; +layout(location = 0) out vec4 vertexColor; +layout(location = 1) out vec2 texCoord2; void main() { gl_Position = MVP * vec4(Position, 1.0); diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh index 8962a028f..cf7099c9f 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.fsh @@ -1,17 +1,44 @@ -#version 150 +//#version 150 +// +//#moj_import +// +//uniform vec4 ColorModulator; +//uniform float FogStart; +//uniform float FogEnd; +//uniform vec4 FogColor; +// +//in float vertexDistance; +//in vec4 vertexColor; +//in vec4 normal; +// +//out vec4 fragColor; +// +//void main() { +// vec4 color = vertexColor * ColorModulator; +// if (color.a < 0.1) { +// discard; +// } +// fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); +//} -#moj_import +#version 450 -uniform vec4 ColorModulator; -uniform float FogStart; -uniform float FogEnd; -uniform vec4 FogColor; +#include -in float vertexDistance; -in vec4 vertexColor; -in vec4 normal; +layout(binding = 2) uniform sampler2D Sampler0; -out vec4 fragColor; +layout(binding = 1) uniform UBO{ + vec4 ColorModulator; + float FogStart; + float FogEnd; + vec4 FogColor; +}; + +layout(location = 0) in float vertexDistance; +layout(location = 1) in vec4 vertexColor; +layout(location = 2) in vec4 normal; + +layout(location = 0) out vec4 fragColor; void main() { vec4 color = vertexColor * ColorModulator; @@ -19,4 +46,4 @@ void main() { discard; } fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json index 33b601867..a96423462 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.json @@ -20,5 +20,14 @@ { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh index 7f15a9d93..89ce1d373 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_normal/position_color_normal.vsh @@ -1,20 +1,22 @@ -#version 150 +#version 450 -in vec3 Position; -in vec4 Color; -in vec3 Normal; +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; +layout(location = 2) in vec3 Normal; -uniform mat4 ModelViewMat; -uniform mat4 ModelViewProjMat; +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; + mat4 ModelViewMat; +}; -out float vertexDistance; -out vec4 vertexColor; -out vec4 normal; +layout(location = 0) out float vertexDistance; +layout(location = 1) out vec4 vertexColor; +layout(location = 2) out vec4 normal; void main() { - gl_Position = ModelViewProjMat * vec4(Position, 1.0); + gl_Position = MVP * vec4(Position, 1.0); vertexDistance = length((ModelViewMat * vec4(Position, 1.0)).xyz); vertexColor = Color; - normal = ModelViewProjMat * vec4(Normal, 0.0); + normal = MVP * vec4(Normal, 0.0); } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh index d04bdec49..2b102ebd8 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.fsh @@ -1,14 +1,16 @@ -#version 150 +#version 450 -uniform sampler2D Sampler0; +layout(binding = 2) uniform sampler2D Sampler0; -uniform vec4 ColorModulator; +layout(binding = 1) uniform UBO{ + vec4 ColorModulator; +}; -in vec4 vertexColor; -in vec2 texCoord0; -in vec2 texCoord2; +layout(location = 0) in vec4 vertexColor; +layout(location = 1) in vec2 texCoord0; +layout(location = 2) in vec2 texCoord2; -out vec4 fragColor; +layout(location = 0) out vec4 fragColor; void main() { vec4 color = texture(Sampler0, texCoord0) * vertexColor; diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json index 8df21642c..aa38dd4b9 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.json @@ -19,5 +19,13 @@ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh index 62895b6df..26114a1f9 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_color_tex_lightmap/position_color_tex_lightmap.vsh @@ -1,16 +1,17 @@ -#version 150 +#version 450 -in vec3 Position; -in vec4 Color; -in vec2 UV0; -in vec2 UV2; +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; +layout(location = 2) in vec2 UV0; +layout(location = 3) in vec2 UV2; -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; +}; -out vec4 vertexColor; -out vec2 texCoord0; -out vec2 texCoord2; +layout(location = 0) out vec4 vertexColor; +layout(location = 1) out vec2 texCoord0; +layout(location = 2) out vec2 texCoord2; void main() { gl_Position = MVP * vec4(Position, 1.0); diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh index 35ce11190..0afbda31a 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.fsh @@ -33,24 +33,4 @@ void main() { fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); } -/* -#version 150 - -#moj_import - -uniform sampler2D Sampler0; - -uniform vec4 ColorModulator; -uniform float FogStart; -uniform float FogEnd; -uniform vec4 FogColor; - -in vec2 texCoord0; -in float vertexDistance; -in vec4 vertexColor; -in vec4 normal; - -out vec4 fragColor; -*/ - diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh index 7a5f0246b..1482e45c3 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/position_tex_color_normal/position_tex_color_normal.vsh @@ -24,21 +24,4 @@ void main() { //normal = (MVP * vec4(Normal, 0.0)).xyz; } -/* -#version 150 - -in vec3 Position; -in vec2 UV0; -in vec4 Color; -in vec3 Normal; - -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; - -out vec2 texCoord0; -out float vertexDistance; -out vec4 vertexColor; -out vec4 normal; -*/ - diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh index 35f9567ff..b3581c386 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.fsh @@ -37,27 +37,3 @@ void main() { color *= lightMapColor; fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); } - -/* -#version 150 - -#moj_import - -uniform sampler2D Sampler0; - -uniform vec4 ColorModulator; -uniform float FogStart; -uniform float FogEnd; -uniform vec4 FogColor; - -in float vertexDistance; -in vec4 vertexColor; -in vec4 lightMapColor; -in vec4 overlayColor; -in vec2 texCoord0; -in vec4 normal; - -out vec4 fragColor; -*/ - - diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh index b5d730727..a850d58c7 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull/rendertype_entity_cutout_no_cull.vsh @@ -33,47 +33,6 @@ void main() { vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); overlayColor = texelFetch(Sampler1, UV1, 0); -// overlayColor = vec4(1.0f); texCoord0 = UV0; normal = (MVP * vec4(Normal, 0.0)).xyz; -} - -/* -#version 150 - -#moj_import - -in vec3 Position; -in vec4 Color; -in vec2 UV0; -in ivec2 UV1; -in ivec2 UV2; -in vec3 Normal; - -uniform sampler2D Sampler1; -uniform sampler2D Sampler2; - -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; - -uniform vec3 Light0_Direction; -uniform vec3 Light1_Direction; - -out float vertexDistance; -out vec4 vertexColor; -out vec4 lightMapColor; -out vec4 overlayColor; -out vec2 texCoord0; -out vec4 normal; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = length((ModelViewMat * vec4(Position, 1.0)).xyz); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; - normal = MVP * vec4(Normal, 0.0); -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh index 8fe992d43..08f7dc26a 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.fsh @@ -36,37 +36,4 @@ void main() { color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); color *= lightMapColor; fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} - -/* -#version 150 - -#moj_import - -uniform sampler2D Sampler0; - -uniform vec4 ColorModulator; -uniform float FogStart; -uniform float FogEnd; -uniform vec4 FogColor; - -in float vertexDistance; -in vec4 vertexColor; -in vec4 lightMapColor; -in vec4 overlayColor; -in vec2 texCoord0; -in vec4 normal; - -out vec4 fragColor; - -void main() { - vec4 color = texture(Sampler0, texCoord0); - if (color.a < 0.1) { - discard; - } - color *= vertexColor * ColorModulator; - color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); - color *= lightMapColor; - fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor); -} -*/ +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json index 29a4b7e6d..a684dbdad 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.json @@ -28,5 +28,19 @@ { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }, + { "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, + { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, + { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] } + ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh index 9c44100f6..2fb066fe1 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_entity_cutout_no_cull_z_offset/rendertype_entity_cutout_no_cull_z_offset.vsh @@ -10,10 +10,10 @@ layout(location = 4) in ivec2 UV2; layout(location = 5) in vec3 Normal; layout(binding = 0) uniform UniformBufferObject { - mat4 MVP; - mat4 ModelViewMat; - vec3 Light0_Direction; - vec3 Light1_Direction; + mat4 MVP; + mat4 ModelViewMat; + vec3 Light0_Direction; + vec3 Light1_Direction; }; layout(binding = 3) uniform sampler2D Sampler1; @@ -33,47 +33,6 @@ void main() { vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); overlayColor = texelFetch(Sampler1, UV1, 0); -// overlayColor = vec4(1.0f); texCoord0 = UV0; normal = (MVP * vec4(Normal, 0.0)).xyz; -} - -/* -#version 150 - -#moj_import - -in vec3 Position; -in vec4 Color; -in vec2 UV0; -in ivec2 UV1; -in ivec2 UV2; -in vec3 Normal; - -uniform sampler2D Sampler1; -uniform sampler2D Sampler2; - -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; - -uniform vec3 Light0_Direction; -uniform vec3 Light1_Direction; - -out float vertexDistance; -out vec4 vertexColor; -out vec4 lightMapColor; -out vec4 overlayColor; -out vec2 texCoord0; -out vec4 normal; - -void main() { - gl_Position = MVP * vec4(Position, 1.0); - - vertexDistance = length((ModelViewMat * vec4(Position, 1.0)).xyz); - vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color); - lightMapColor = texelFetch(Sampler2, UV2 / 16, 0); - overlayColor = texelFetch(Sampler1, UV1, 0); - texCoord0 = UV0; - normal = MVP * vec4(Normal, 0.0); -} -*/ +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh index 6b1c565fe..3d175e2cc 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.fsh @@ -1,10 +1,12 @@ -#version 150 +#version 450 -uniform vec4 ColorModulator; +layout(location = 0) in vec4 vertexColor; -in vec4 vertexColor; +layout(binding = 1) uniform UBO{ + vec4 ColorModulator; +}; -out vec4 fragColor; +layout(location = 0) out vec4 fragColor; void main() { vec4 color = vertexColor; @@ -12,4 +14,4 @@ void main() { discard; } fragColor = color * ColorModulator; -} +} \ No newline at end of file diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json index 42c0d58df..a9c589624 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.json @@ -16,5 +16,13 @@ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ], + "UBOs": [ + { "type": "vertex", "binding": 0, "fields": [ + { "name": "MVP", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] } + ] }, + { "type": "fragment", "binding": 1, "fields": [ + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] } ] } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh index 19d3fdbae..5fd8ccf2b 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_background_see_through/rendertype_text_background_see_through.vsh @@ -1,15 +1,16 @@ -#version 150 +#version 450 -in vec3 Position; -in vec4 Color; +layout(location = 0) in vec3 Position; +layout(location = 1) in vec4 Color; -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; +layout(binding = 0) uniform UniformBufferObject { + mat4 MVP; +}; -out vec4 vertexColor; +layout(location = 0) out vec4 vertexColor; void main() { - gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0); + gl_Position = MVP * vec4(Position, 1.0); vertexColor = Color; } diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh index 036db0524..9083d7665 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.fsh @@ -19,16 +19,3 @@ void main() { fragColor = color * ColorModulator; } -/* -#version 150 - -uniform sampler2D Sampler0; - -uniform vec4 ColorModulator; - -in vec4 vertexColor; -in vec2 texCoord0; - -out vec4 fragColor; -*/ - diff --git a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh index 7e7e928e6..b203fb509 100644 --- a/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh +++ b/src/main/resources/assets/vulkanmod/shaders/minecraft/core/rendertype_text_see_through/rendertype_text_see_through.vsh @@ -18,17 +18,3 @@ void main() { texCoord0 = UV0; } -/* -#version 150 - -in vec3 Position; -in vec4 Color; -in vec2 UV0; - -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; - -out vec4 vertexColor; -out vec2 texCoord0; -*/ - diff --git a/src/main/resources/vulkanmod.accesswidener b/src/main/resources/vulkanmod.accesswidener index 98bcc5e7b..89da0b18b 100644 --- a/src/main/resources/vulkanmod.accesswidener +++ b/src/main/resources/vulkanmod.accesswidener @@ -7,6 +7,8 @@ accessible class net/minecraft/client/model/geom/ModelPart$Polygon accessible class net/minecraft/client/model/geom/ModelPart$Vertex accessible class net/minecraft/client/gui/Gui$HeartType +accessible class net/minecraft/client/renderer/OutlineBufferSource$EntityOutlineGenerator + #1.20 accessible field com/mojang/blaze3d/systems/RenderSystem vertexSorting Lcom/mojang/blaze3d/vertex/VertexSorting; accessible field net/minecraft/client/renderer/RenderStateShard name Ljava/lang/String; \ No newline at end of file diff --git a/src/main/resources/vulkanmod.mixins.json b/src/main/resources/vulkanmod.mixins.json index 424cdb72c..55df3a523 100644 --- a/src/main/resources/vulkanmod.mixins.json +++ b/src/main/resources/vulkanmod.mixins.json @@ -7,7 +7,8 @@ "mixins": [ ], "client": [ - "WindowMixin", + "window.WindowMixin", + "window.WindowAccessor", "chunk.DirectionMixin", "chunk.FrustumMixin", @@ -18,6 +19,7 @@ "compatibility.ProgramM", "compatibility.UniformM", "compatibility.gl.GL11M", + "compatibility.gl.GL30M", "debug.ChunkBorderRendererM", "debug.DebugScreenOverlayM", @@ -38,14 +40,15 @@ "render.GlProgramManagerMixin", "render.GlStateManagerM", "render.LevelRendererMixin", - "render.MainTargetMixin", "render.MinecraftMixin", "render.RenderSystemMixin", - "render.RenderTargetMixin", "render.ShaderInstanceM", "render.entity.EntityRendererM", "render.model.ModelPartCubeM", "render.model.ModelPartM", + "render.particle.SingleQuadParticleM", + "render.target.MainTargetMixin", + "render.target.RenderTargetMixin", "render.vertex.BufferBuilderM", "render.vertex.FaceBakeryM", "render.vertex.IndexTypeMixin", @@ -56,11 +59,13 @@ "screen.OptionsScreenM", + "texture.mip.MipmapGeneratorM", + "texture.image.MNativeImage", + "texture.image.NativeImageAccessor", "texture.MAbstractTexture", "texture.MDynamicTexture", "texture.MFontTexture", "texture.MLightTexture", - "texture.MNativeImage", "texture.MOverlayTexture", "texture.MPlayerSkinTexture", "texture.MSimpleTexture", @@ -71,13 +76,19 @@ "util.ScreenshotRecorderM", + "vertex.EntityOutlineGeneratorM", "vertex.SpriteCoordinateExpanderM", "vertex.VertexMultiConsumersM$DoubleM", "vertex.VertexMultiConsumersM$MultipleM", "vertex.VertexMultiConsumersM$SheetDecalM", "wayland.InputConstantsM", - "wayland.MinecraftMixin" + "wayland.MinecraftMixin", + + "texture.mip.MipmapGeneratorM", + + "compatibility.PostChainM", + "compatibility.PostPassM" ], "injectors": { "defaultRequire": 1