From 2ee3944ca691ce90d9a309e7576908300aedf076 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Sun, 31 Mar 2024 15:53:23 -0700 Subject: [PATCH] GLSL to the max - Always compile with highest supported GLSL version - Allow indirect shaders to compile with as low as GLSL 420 - Fix GL extension checks for indirect - Explicitly initialize GlCompat as early as possible to avoid invalid initialization off render thread --- .../jozufozu/flywheel/backend/Backends.java | 4 +- .../backend/compile/IndirectPrograms.java | 37 +++- .../backend/compile/InstancingPrograms.java | 5 + .../flywheel/backend/compile/Pipeline.java | 13 +- .../backend/compile/PipelineCompiler.java | 15 +- .../flywheel/backend/compile/Pipelines.java | 3 - .../backend/compile/core/Compile.java | 172 ++++++++++-------- .../flywheel/backend/gl/GlCompat.java | 153 +++++++++------- .../flywheel/backend/glsl/GlslVersion.java | 1 - .../backend/mixin/RenderSystemMixin.java | 6 + .../flywheel/internal/indirect/main.vert | 8 + 11 files changed, 251 insertions(+), 166 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index dc668de74..fa0ce5ac2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -17,7 +17,7 @@ public final class Backends { */ public static final Backend INSTANCING = SimpleBackend.builder() .engineFactory(level -> new EngineImpl(new InstancedDrawManager(InstancingPrograms.get()), 256)) - .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsInstancing() && InstancingPrograms.allLoaded()) + .supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse()) .register(Flywheel.rl("instancing")); /** @@ -26,7 +26,7 @@ public final class Backends { public static final Backend INDIRECT = SimpleBackend.builder() .engineFactory(level -> new EngineImpl(new IndirectDrawManager(IndirectPrograms.get()), 256)) .fallback(() -> Backends.INSTANCING) - .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsIndirect() && IndirectPrograms.allLoaded()) + .supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse()) .register(Flywheel.rl("indirect")); private Backends() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java index ba7cb6a08..3806b07d7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.compile; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -33,6 +34,9 @@ public class IndirectPrograms extends AtomicReferenceCounted { private static final Compile> CULL = new Compile<>(); private static final Compile UTIL = new Compile<>(); + private static final List EXTENSIONS = getExtensions(GlCompat.MAX_GLSL_VERSION); + private static final List COMPUTE_EXTENSIONS = getComputeExtensions(GlCompat.MAX_GLSL_VERSION); + @Nullable private static IndirectPrograms instance; @@ -48,10 +52,33 @@ public class IndirectPrograms extends AtomicReferenceCounted { this.scatter = scatter; } + private static List getExtensions(GlslVersion glslVersion) { + List extensions = new ArrayList<>(); + if (glslVersion.compareTo(GlslVersion.V430) < 0) { + extensions.add("GL_ARB_shader_storage_buffer_object"); + } + if (glslVersion.compareTo(GlslVersion.V460) < 0) { + extensions.add("GL_ARB_shader_draw_parameters"); + } + return extensions; + } + + private static List getComputeExtensions(GlslVersion glslVersion) { + List extensions = new ArrayList<>(); + if (glslVersion.compareTo(GlslVersion.V430) < 0) { + extensions.add("GL_ARB_compute_shader"); + } + return extensions; + } + static void reload(ShaderSources sources, ImmutableList pipelineKeys, List vertexComponents, List fragmentComponents) { + if (!GlCompat.SUPPORTS_INDIRECT) { + return; + } + IndirectPrograms newInstance = null; - var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, vertexComponents, fragmentComponents); + var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, vertexComponents, fragmentComponents, EXTENSIONS); var cullingCompiler = createCullingCompiler(sources); var applyCompiler = createUtilCompiler(sources); @@ -76,8 +103,10 @@ public class IndirectPrograms extends AtomicReferenceCounted { private static CompilationHarness> createCullingCompiler(ShaderSources sources) { return CULL.program() - .link(CULL.shader(GlslVersion.V460, ShaderType.COMPUTE) + .link(CULL.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.COMPUTE) .nameMapper(instanceType -> "culling/" + ResourceUtil.toDebugFileNameNoExtension(instanceType.cullShader())) + .enableExtensions(EXTENSIONS) + .enableExtensions(COMPUTE_EXTENSIONS) .define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE) .withResource(CULL_SHADER_API_IMPL) .withComponent(InstanceStructComponent::new) @@ -96,8 +125,10 @@ public class IndirectPrograms extends AtomicReferenceCounted { private static CompilationHarness createUtilCompiler(ShaderSources sources) { return UTIL.program() - .link(UTIL.shader(GlslVersion.V460, ShaderType.COMPUTE) + .link(UTIL.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.COMPUTE) .nameMapper(resourceLocation -> "utilities/" + ResourceUtil.toDebugFileNameNoExtension(resourceLocation)) + .enableExtensions(EXTENSIONS) + .enableExtensions(COMPUTE_EXTENSIONS) .define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE) .withResource(s -> s)) .harness("utilities", sources); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java index 5a8589a66..8109f872c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.backend.gl.GlCompat; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; @@ -23,6 +24,10 @@ public class InstancingPrograms extends AtomicReferenceCounted { } static void reload(ShaderSources sources, ImmutableList pipelineKeys, List vertexComponents, List fragmentComponents) { + if (!GlCompat.SUPPORTS_INSTANCING) { + return; + } + InstancingPrograms newInstance = null; var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCING, vertexComponents, fragmentComponents); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipeline.java b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipeline.java index a73962f00..a1b5edcec 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipeline.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipeline.java @@ -8,12 +8,11 @@ import org.jetbrains.annotations.Nullable; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; -import com.jozufozu.flywheel.backend.glsl.GlslVersion; import com.jozufozu.flywheel.backend.glsl.SourceComponent; import net.minecraft.resources.ResourceLocation; -public record Pipeline(GlslVersion glslVersion, ResourceLocation vertexMain, ResourceLocation fragmentMain, +public record Pipeline(ResourceLocation vertexMain, ResourceLocation fragmentMain, InstanceAssembler assembler, String compilerMarker, Consumer onLink) { @FunctionalInterface @@ -31,8 +30,6 @@ public record Pipeline(GlslVersion glslVersion, ResourceLocation vertexMain, Res } public static class Builder { - @Nullable - private GlslVersion glslVersion; @Nullable private ResourceLocation vertexMain; @Nullable @@ -44,11 +41,6 @@ public record Pipeline(GlslVersion glslVersion, ResourceLocation vertexMain, Res @Nullable private Consumer onLink; - public Builder glslVersion(GlslVersion glslVersion) { - this.glslVersion = glslVersion; - return this; - } - public Builder vertexMain(ResourceLocation shader) { this.vertexMain = shader; return this; @@ -75,13 +67,12 @@ public record Pipeline(GlslVersion glslVersion, ResourceLocation vertexMain, Res } public Pipeline build() { - Objects.requireNonNull(glslVersion); Objects.requireNonNull(vertexMain); Objects.requireNonNull(fragmentMain); Objects.requireNonNull(assembler); Objects.requireNonNull(compilerMarker); Objects.requireNonNull(onLink); - return new Pipeline(glslVersion, vertexMain, fragmentMain, assembler, compilerMarker, onLink); + return new Pipeline(vertexMain, fragmentMain, assembler, compilerMarker, onLink); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java index 3a86d9f87..a7dc27e3a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.backend.compile; +import java.util.Collection; +import java.util.Collections; import java.util.List; import com.jozufozu.flywheel.Flywheel; @@ -9,6 +11,7 @@ import com.jozufozu.flywheel.backend.compile.component.InstanceStructComponent; import com.jozufozu.flywheel.backend.compile.core.CompilationHarness; import com.jozufozu.flywheel.backend.compile.core.Compile; import com.jozufozu.flywheel.backend.engine.uniform.Uniforms; +import com.jozufozu.flywheel.backend.gl.GlCompat; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.glsl.ShaderSources; @@ -23,9 +26,9 @@ public final class PipelineCompiler { private static final ResourceLocation API_IMPL_VERT = Flywheel.rl("internal/api_impl.vert"); private static final ResourceLocation API_IMPL_FRAG = Flywheel.rl("internal/api_impl.frag"); - static CompilationHarness create(ShaderSources sources, Pipeline pipeline, List vertexComponents, List fragmentComponents) { + static CompilationHarness create(ShaderSources sources, Pipeline pipeline, List vertexComponents, List fragmentComponents, Collection extensions) { return PIPELINE.program() - .link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX) + .link(PIPELINE.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.VERTEX) .nameMapper(key -> { var instance = ResourceUtil.toDebugFileNameNoExtension(key.instanceType() .vertexShader()); @@ -34,6 +37,7 @@ public final class PipelineCompiler { .nameLowerCase(); return "pipeline/" + pipeline.compilerMarker() + "/" + instance + "_" + context; }) + .enableExtensions(extensions) .onCompile((key, comp) -> key.contextShader() .onCompile(comp)) .withResource(API_IMPL_VERT) @@ -45,12 +49,13 @@ public final class PipelineCompiler { .withComponent(key -> pipeline.assembler() .assemble(key.instanceType())) .withResource(pipeline.vertexMain())) - .link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.FRAGMENT) + .link(PIPELINE.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.FRAGMENT) .nameMapper(key -> { var context = key.contextShader() .nameLowerCase(); return "pipeline/" + pipeline.compilerMarker() + "/" + context; }) + .enableExtensions(extensions) .enableExtension("GL_ARB_conservative_depth") .onCompile((key, comp) -> key.contextShader() .onCompile(comp)) @@ -86,4 +91,8 @@ public final class PipelineCompiler { }) .harness(pipeline.compilerMarker(), sources); } + + static CompilationHarness create(ShaderSources sources, Pipeline pipeline, List vertexComponents, List fragmentComponents) { + return create(sources, pipeline, vertexComponents, fragmentComponents, Collections.emptyList()); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java index 3dca51fd7..29978c1de 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/Pipelines.java @@ -4,12 +4,10 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.backend.Samplers; import com.jozufozu.flywheel.backend.compile.component.BufferTextureInstanceComponent; import com.jozufozu.flywheel.backend.compile.component.SsboInstanceComponent; -import com.jozufozu.flywheel.backend.glsl.GlslVersion; public final class Pipelines { public static final Pipeline INSTANCING = Pipeline.builder() .compilerMarker("instancing") - .glslVersion(GlslVersion.V330) .vertexMain(Flywheel.rl("internal/instancing/main.vert")) .fragmentMain(Flywheel.rl("internal/instancing/main.frag")) .assembler(BufferTextureInstanceComponent::new) @@ -18,7 +16,6 @@ public final class Pipelines { public static final Pipeline INDIRECT = Pipeline.builder() .compilerMarker("indirect") - .glslVersion(GlslVersion.V460) .vertexMain(Flywheel.rl("internal/indirect/main.vert")) .fragmentMain(Flywheel.rl("internal/indirect/main.frag")) .assembler(SsboInstanceComponent::new) diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java index e087e1cdd..b74b71ff0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java @@ -40,6 +40,100 @@ public class Compile { return new ProgramStitcher<>(); } + public static class ShaderCompiler { + private final GlslVersion glslVersion; + private final ShaderType shaderType; + private final List> fetchers = new ArrayList<>(); + private BiConsumer compilationCallbacks = ($, $$) -> { + }; + private Function nameMapper = Object::toString; + + public ShaderCompiler(GlslVersion glslVersion, ShaderType shaderType) { + this.glslVersion = glslVersion; + this.shaderType = shaderType; + } + + public ShaderCompiler nameMapper(Function nameMapper) { + this.nameMapper = nameMapper; + return this; + } + + public ShaderCompiler with(BiFunction fetch) { + fetchers.add(fetch); + return this; + } + + public ShaderCompiler withComponents(Collection<@Nullable SourceComponent> components) { + components.forEach(this::withComponent); + return this; + } + + public ShaderCompiler withComponent(@Nullable SourceComponent component) { + return withComponent($ -> component); + } + + public ShaderCompiler withComponent(Function sourceFetcher) { + return with((key, $) -> sourceFetcher.apply(key)); + } + + public ShaderCompiler withResource(Function sourceFetcher) { + return with((key, loader) -> loader.find(sourceFetcher.apply(key))); + } + + public ShaderCompiler withResource(ResourceLocation resourceLocation) { + return withResource($ -> resourceLocation); + } + + public ShaderCompiler onCompile(BiConsumer cb) { + compilationCallbacks = compilationCallbacks.andThen(cb); + return this; + } + + public ShaderCompiler define(String def, int value) { + return onCompile(($, ctx) -> ctx.define(def, String.valueOf(value))); + } + + public ShaderCompiler enableExtension(String extension) { + return onCompile(($, ctx) -> ctx.enableExtension(extension)); + } + + public ShaderCompiler enableExtensions(String... extensions) { + return onCompile(($, ctx) -> { + for (String extension : extensions) { + ctx.enableExtension(extension); + } + }); + } + + public ShaderCompiler enableExtensions(Collection extensions) { + return onCompile(($, ctx) -> { + for (String extension : extensions) { + ctx.enableExtension(extension); + } + }); + } + + @Nullable + private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) { + var components = new ArrayList(); + boolean ok = true; + for (var fetcher : fetchers) { + SourceComponent apply = fetcher.apply(key, loader); + if (apply == null) { + ok = false; + } + components.add(apply); + } + + if (!ok) { + return null; + } + + Consumer cb = ctx -> compilationCallbacks.accept(key, ctx); + return compiler.compile(glslVersion, shaderType, nameMapper.apply(key), cb, components); + } + } + public static class ProgramStitcher implements CompilationHarness.KeyCompiler { private final Map> compilers = new EnumMap<>(ShaderType.class); private BiConsumer postLink = (k, p) -> { @@ -100,82 +194,4 @@ public class Compile { return out; } } - - public static class ShaderCompiler { - private final GlslVersion glslVersion; - private final ShaderType shaderType; - private final List> fetchers = new ArrayList<>(); - private BiConsumer compilationCallbacks = ($, $$) -> { - }; - private Function nameMapper = Object::toString; - - public ShaderCompiler(GlslVersion glslVersion, ShaderType shaderType) { - this.glslVersion = glslVersion; - this.shaderType = shaderType; - } - - public ShaderCompiler nameMapper(Function nameMapper) { - this.nameMapper = nameMapper; - return this; - } - - public ShaderCompiler with(BiFunction fetch) { - fetchers.add(fetch); - return this; - } - - public ShaderCompiler withComponents(Collection<@Nullable SourceComponent> components) { - components.forEach(this::withComponent); - return this; - } - - public ShaderCompiler withComponent(@Nullable SourceComponent component) { - return withComponent($ -> component); - } - - public ShaderCompiler withComponent(Function sourceFetcher) { - return with((key, $) -> sourceFetcher.apply(key)); - } - - public ShaderCompiler withResource(Function sourceFetcher) { - return with((key, loader) -> loader.find(sourceFetcher.apply(key))); - } - - public ShaderCompiler withResource(ResourceLocation resourceLocation) { - return withResource($ -> resourceLocation); - } - - public ShaderCompiler onCompile(BiConsumer cb) { - compilationCallbacks = compilationCallbacks.andThen(cb); - return this; - } - - public ShaderCompiler define(String def, int value) { - return onCompile(($, ctx) -> ctx.define(def, String.valueOf(value))); - } - - public ShaderCompiler enableExtension(String extension) { - return onCompile(($, ctx) -> ctx.enableExtension(extension)); - } - - @Nullable - private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) { - var components = new ArrayList(); - boolean ok = true; - for (var fetcher : fetchers) { - SourceComponent apply = fetcher.apply(key, loader); - if (apply == null) { - ok = false; - } - components.add(apply); - } - - if (!ok) { - return null; - } - - Consumer cb = ctx -> compilationCallbacks.accept(key, ctx); - return compiler.compile(glslVersion, shaderType, nameMapper.apply(key), cb, components); - } - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlCompat.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlCompat.java index 4704134fc..fcf56a471 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlCompat.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlCompat.java @@ -10,78 +10,23 @@ import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.opengl.KHRShaderSubgroup; import org.lwjgl.system.MemoryStack; +import com.jozufozu.flywheel.backend.glsl.GlslVersion; import com.jozufozu.flywheel.lib.math.MoreMath; -import net.minecraft.Util; - -/** - * An instance of this class stores information about what OpenGL features are available. - *
- * Each field stores an enum variant that provides access to the most appropriate version of a feature for the current - * system. - */ public final class GlCompat { - public static final GLCapabilities CAPABILITIES = GL.createCapabilities(); - public static final boolean WINDOWS = _decideIfWeAreWindows(); + public static final GLCapabilities CAPABILITIES = GL.getCapabilities(); + public static final Driver DRIVER = readVendorString(); + public static final int SUBGROUP_SIZE = subgroupSize(); public static final boolean ALLOW_DSA = true; - public static final boolean SUPPORTS_INDIRECT = _decideIfWeSupportIndirect(); - public static final int SUBGROUP_SIZE = _subgroupSize(); - public static final Driver DRIVER = _readVendorString(); + public static final GlslVersion MAX_GLSL_VERSION = maxGlslVersion(); + + public static final boolean SUPPORTS_INSTANCING = isInstancingSupported(); + public static final boolean SUPPORTS_INDIRECT = isIndirectSupported(); private GlCompat() { } - public static boolean onAMDWindows() { - return DRIVER == Driver.AMD && WINDOWS; - } - - public static boolean supportsInstancing() { - return true; - } - - public static boolean supportsIndirect() { - return SUPPORTS_INDIRECT; - } - - private static Driver _readVendorString() { - String vendor = GL20C.glGetString(GL20C.GL_VENDOR); - - if (vendor == null) { - return Driver.UNKNOWN; - } - - // vendor string I got was "ATI Technologies Inc." - if (vendor.contains("ATI") || vendor.contains("AMD")) { - return Driver.AMD; - } else if (vendor.contains("NVIDIA")) { - return Driver.NVIDIA; - } else if (vendor.contains("Intel")) { - return Driver.INTEL; - } else if (vendor.contains("Mesa")) { - return Driver.MESA; - } - - return Driver.UNKNOWN; - } - - private static boolean _decideIfWeAreWindows() { - return Util.getPlatform() == Util.OS.WINDOWS; - } - - private static boolean _decideIfWeSupportIndirect() { - return CAPABILITIES.OpenGL46 || (CAPABILITIES.GL_ARB_compute_shader && CAPABILITIES.GL_ARB_shader_draw_parameters && CAPABILITIES.GL_ARB_base_instance && CAPABILITIES.GL_ARB_multi_draw_indirect && CAPABILITIES.GL_ARB_direct_state_access); - } - - private static int _subgroupSize() { - if (CAPABILITIES.GL_KHR_shader_subgroup) { - return GL31C.glGetInteger(KHRShaderSubgroup.GL_SUBGROUP_SIZE_KHR); - } - // Try to guess. - // Newer (RDNA) AMD cards have 32 threads in a wavefront, older ones have 64. - // I assume the newer drivers will implement the above extension, so 64 is a - // reasonable guess for AMD hardware. In the worst case we'll just spread - // load across multiple SIMDs - return DRIVER == Driver.AMD || DRIVER == Driver.MESA ? 64 : 32; + public static void init() { } public static int getComputeGroupCount(int invocations) { @@ -108,5 +53,83 @@ public final class GlCompat { GL20C.nglShaderSource(glId, 1, pointers.address0(), 0); } } -} + private static Driver readVendorString() { + String vendor = GL20C.glGetString(GL20C.GL_VENDOR); + + if (vendor == null) { + return Driver.UNKNOWN; + } + + // vendor string I got was "ATI Technologies Inc." + if (vendor.contains("ATI") || vendor.contains("AMD")) { + return Driver.AMD; + } else if (vendor.contains("NVIDIA")) { + return Driver.NVIDIA; + } else if (vendor.contains("Intel")) { + return Driver.INTEL; + } else if (vendor.contains("Mesa")) { + return Driver.MESA; + } + + return Driver.UNKNOWN; + } + + private static int subgroupSize() { + if (CAPABILITIES.GL_KHR_shader_subgroup) { + return GL31C.glGetInteger(KHRShaderSubgroup.GL_SUBGROUP_SIZE_KHR); + } + + // Try to guess. + // Newer (RDNA) AMD cards have 32 threads in a wavefront, older ones have 64. + // I assume the newer drivers will implement the above extension, so 64 is a + // reasonable guess for AMD hardware. In the worst case we'll just spread + // load across multiple SIMDs + return DRIVER == Driver.AMD || DRIVER == Driver.MESA ? 64 : 32; + } + + private static GlslVersion maxGlslVersion() { + if (CAPABILITIES.OpenGL46) { + return GlslVersion.V460; + } else if (CAPABILITIES.OpenGL45) { + return GlslVersion.V450; + } else if (CAPABILITIES.OpenGL44) { + return GlslVersion.V440; + } else if (CAPABILITIES.OpenGL43) { + return GlslVersion.V430; + } else if (CAPABILITIES.OpenGL42) { + return GlslVersion.V420; + } else if (CAPABILITIES.OpenGL41) { + return GlslVersion.V410; + } else if (CAPABILITIES.OpenGL40) { + return GlslVersion.V400; + } else if (CAPABILITIES.OpenGL33) { + return GlslVersion.V330; + } else { + return GlslVersion.V150; + } + } + + private static boolean isInstancingSupported() { + if (!CAPABILITIES.OpenGL33) { + return false; + } + return true; + } + + private static boolean isIndirectSupported() { + // The GL requirement cannot be lower because GL_ARB_compute_shader requires at least GL 4.2. + if (!CAPABILITIES.OpenGL42) { + return false; + } + if (CAPABILITIES.OpenGL46) { + return true; + } + return CAPABILITIES.GL_ARB_compute_shader + && CAPABILITIES.GL_ARB_direct_state_access + && CAPABILITIES.GL_ARB_multi_bind + && CAPABILITIES.GL_ARB_multi_draw_indirect + && CAPABILITIES.GL_ARB_shader_draw_parameters + && CAPABILITIES.GL_ARB_shader_storage_buffer_object; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/glsl/GlslVersion.java b/src/main/java/com/jozufozu/flywheel/backend/glsl/GlslVersion.java index aae047dcb..e12d29bd5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/glsl/GlslVersion.java +++ b/src/main/java/com/jozufozu/flywheel/backend/glsl/GlslVersion.java @@ -26,5 +26,4 @@ public enum GlslVersion { public String toString() { return Integer.toString(version); } - } diff --git a/src/main/java/com/jozufozu/flywheel/backend/mixin/RenderSystemMixin.java b/src/main/java/com/jozufozu/flywheel/backend/mixin/RenderSystemMixin.java index 07c786b45..62abbfc1b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/mixin/RenderSystemMixin.java +++ b/src/main/java/com/jozufozu/flywheel/backend/mixin/RenderSystemMixin.java @@ -6,10 +6,16 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.jozufozu.flywheel.backend.engine.uniform.Uniforms; +import com.jozufozu.flywheel.backend.gl.GlCompat; import com.mojang.blaze3d.systems.RenderSystem; @Mixin(RenderSystem.class) abstract class RenderSystemMixin { + @Inject(method = "initRenderer(IZ)V", at = @At("RETURN")) + private static void flywheel$onInitRenderer(CallbackInfo ci) { + GlCompat.init(); + } + @Inject(method = "setShaderFogStart(F)V", at = @At("RETURN")) private static void flywheel$onSetFogStart(CallbackInfo ci) { Uniforms.onFogUpdate(); diff --git a/src/main/resources/assets/flywheel/flywheel/internal/indirect/main.vert b/src/main/resources/assets/flywheel/flywheel/internal/indirect/main.vert index d7ac82016..55bd8fc0f 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/indirect/main.vert +++ b/src/main/resources/assets/flywheel/flywheel/internal/indirect/main.vert @@ -16,7 +16,11 @@ uniform uint _flw_baseDraw; flat out uvec3 _flw_packedMaterial; void main() { +#if __VERSION__ < 460 + uint drawIndex = gl_DrawIDARB + _flw_baseDraw; +#else uint drawIndex = gl_DrawID + _flw_baseDraw; +#endif MeshDrawCommand draw = _flw_drawCommands[drawIndex]; _flw_uberMaterialVertexIndex = draw.materialVertexIndex; @@ -24,7 +28,11 @@ void main() { _flw_unpackMaterialProperties(packedMaterialProperties, flw_material); _flw_packedMaterial = uvec3(draw.materialFragmentIndex, draw.packedFogAndCutout, packedMaterialProperties); +#if __VERSION__ < 460 + uint instanceIndex = _flw_instanceIndices[gl_BaseInstanceARB + gl_InstanceID]; +#else uint instanceIndex = _flw_instanceIndices[gl_BaseInstance + gl_InstanceID]; +#endif FlwInstance instance = _flw_unpackInstance(instanceIndex); _flw_main(instance, instanceIndex);