Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Multiple misc changes to shader interfaces #2690

Merged
merged 2 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ static VertexSerializerRegistry instance() {
}

VertexSerializer get(VertexFormatDescription srcFormat, VertexFormatDescription dstFormat);

void registerSerializer(VertexFormatDescription srcFormat, VertexFormatDescription dstFormat, VertexSerializer serializer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
*/
public record GlVertexAttributeFormat(int typeId, int size) {
public static final GlVertexAttributeFormat FLOAT = new GlVertexAttributeFormat(GL33C.GL_FLOAT, 4);
public static final GlVertexAttributeFormat INT = new GlVertexAttributeFormat(GL33C.GL_INT, 4);
public static final GlVertexAttributeFormat SHORT = new GlVertexAttributeFormat(GL33C.GL_SHORT, 2);
public static final GlVertexAttributeFormat BYTE = new GlVertexAttributeFormat(GL33C.GL_BYTE, 1);
public static final GlVertexAttributeFormat UNSIGNED_SHORT = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_SHORT, 2);
public static final GlVertexAttributeFormat UNSIGNED_BYTE = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_BYTE, 1);
public static final GlVertexAttributeFormat UNSIGNED_INT = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_INT, 4);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
package net.caffeinemc.mods.sodium.client.gl.attribute;

import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.caffeinemc.mods.sodium.client.render.vertex.VertexFormatAttribute;

import java.util.EnumMap;
import java.util.Map;

/**
* Provides a generic vertex format which contains the attributes defined by {@param T}. Other code can then retrieve
* Provides a generic vertex format which contains the attributes defined by a {@link VertexFormatAttribute}. Other code can then retrieve
* the attributes and work with encoded data in a generic manner without needing to rely on a specific format.
*
* @param <T> The enumeration over the vertex attributes
*/
public class GlVertexFormat<T extends Enum<T>> {
private final Class<T> attributeEnum;
private final EnumMap<T, GlVertexAttribute> attributesKeyed;
public class GlVertexFormat {
private final Map<VertexFormatAttribute, GlVertexAttribute> attributesKeyed;

private final int stride;
private final GlVertexAttributeBinding[] bindings;

public GlVertexFormat(Class<T> attributeEnum, EnumMap<T, GlVertexAttribute> attributesKeyed, int stride) {
this.attributeEnum = attributeEnum;
public GlVertexFormat(Map<VertexFormatAttribute, GlVertexAttribute> attributesKeyed, GlVertexAttributeBinding[] bindings, int stride) {
this.attributesKeyed = attributesKeyed;
this.bindings = bindings;
this.stride = stride;
}

public static <T extends Enum<T>> Builder<T> builder(Class<T> type, int stride) {
return new Builder<>(type, stride);
public static Builder builder(int stride) {
return new Builder(stride);
}

/**
* Returns the {@link GlVertexAttribute} of this vertex format bound to the type {@param name}.
* @throws NullPointerException If the attribute does not exist in this format
*/
public GlVertexAttribute getAttribute(T name) {
public GlVertexAttribute getAttribute(VertexFormatAttribute name) {
GlVertexAttribute attr = this.attributesKeyed.get(name);

if (attr == null) {
Expand All @@ -47,23 +51,27 @@ public int getStride() {

@Override
public String toString() {
return String.format("GlVertexFormat<%s>{attributes=%d,stride=%d}", this.attributeEnum.getName(),
return String.format("GlVertexFormat{attributes=%d,stride=%d}",
this.attributesKeyed.size(), this.stride);
}

public static class Builder<T extends Enum<T>> {
private final EnumMap<T, GlVertexAttribute> attributes;
private final Class<T> type;
public GlVertexAttributeBinding[] getShaderBindings() {
return bindings;
}

public static class Builder {
private final Map<VertexFormatAttribute, GlVertexAttribute> attributes;
private final Object2IntMap<GlVertexAttribute> bindings;
private final int stride;

public Builder(Class<T> type, int stride) {
this.type = type;
this.attributes = new EnumMap<>(type);
public Builder(int stride) {
this.attributes = new Object2ObjectArrayMap<>();
this.bindings = new Object2IntArrayMap<>();
this.stride = stride;
}

public Builder<T> addElement(T type, int pointer, GlVertexAttributeFormat format, int count, boolean normalized, boolean intType) {
return this.addElement(type, new GlVertexAttribute(format, count, normalized, pointer, this.stride, intType));
public Builder addElement(VertexFormatAttribute attribute, int binding, int pointer) {
return this.addElement(attribute, binding, new GlVertexAttribute(attribute.format(), attribute.count(), attribute.normalized(), pointer, this.stride, attribute.intType()));
}

/**
Expand All @@ -73,7 +81,7 @@ public Builder<T> addElement(T type, int pointer, GlVertexAttributeFormat format
* @param attribute The attribute to bind
* @throws IllegalStateException If an attribute is already bound to the generic type
*/
private Builder<T> addElement(T type, GlVertexAttribute attribute) {
private Builder addElement(VertexFormatAttribute type, int binding, GlVertexAttribute attribute) {
if (attribute.getPointer() >= this.stride) {
throw new IllegalArgumentException("Element starts outside vertex format");
}
Expand All @@ -86,22 +94,20 @@ private Builder<T> addElement(T type, GlVertexAttribute attribute) {
throw new IllegalStateException("Generic attribute " + type.name() + " already defined in vertex format");
}

if (binding != -1) {
this.bindings.put(attribute, binding);
}

return this;
}

/**
* Creates a {@link GlVertexFormat} from the current builder.
*/
public GlVertexFormat<T> build() {
public GlVertexFormat build() {
int size = 0;

for (T key : this.type.getEnumConstants()) {
GlVertexAttribute attribute = this.attributes.get(key);

if (attribute == null) {
throw new NullPointerException("Generic attribute not assigned to enumeration " + key.name());
}

for (GlVertexAttribute attribute : this.attributes.values()) {
size = Math.max(size, attribute.getPointer() + attribute.getSize());
}

Expand All @@ -111,7 +117,11 @@ public GlVertexFormat<T> build() {
throw new IllegalArgumentException("Stride is too small");
}

return new GlVertexFormat<>(this.type, this.attributes, this.stride);
GlVertexAttributeBinding[] bindings = this.bindings.object2IntEntrySet().stream()
.map(entry -> new GlVertexAttributeBinding(entry.getIntValue(), entry.getKey()))
.toArray(GlVertexAttributeBinding[]::new);

return new GlVertexFormat(this.attributes, bindings, this.stride);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* Helper type for tagging the vertex format alongside the raw buffer data.
*/
public record IndexedVertexData(GlVertexFormat<?> vertexFormat,
public record IndexedVertexData(GlVertexFormat vertexFormat,
NativeBuffer vertexBuffer,
NativeBuffer indexBuffer) {
public void delete() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL20C;
import org.lwjgl.opengl.GL30C;
import org.lwjgl.opengl.GL32C;
Expand Down Expand Up @@ -51,7 +52,7 @@ public void delete() {
}

@Override
public <U extends GlUniform<?>> U bindUniform(String name, IntFunction<U> factory) {
public <U extends GlUniform<?>> @NotNull U bindUniform(String name, IntFunction<U> factory) {
int index = GL20C.glGetUniformLocation(this.handle(), name);

if (index < 0) {
Expand All @@ -62,7 +63,18 @@ public <U extends GlUniform<?>> U bindUniform(String name, IntFunction<U> factor
}

@Override
public GlUniformBlock bindUniformBlock(String name, int bindingPoint) {
public <U extends GlUniform<?>> U bindUniformOptional(String name, IntFunction<U> factory) {
int index = GL20C.glGetUniformLocation(this.handle(), name);

if (index < 0) {
return null;
}

return factory.apply(index);
}

@Override
public @NotNull GlUniformBlock bindUniformBlock(String name, int bindingPoint) {
int index = GL32C.glGetUniformBlockIndex(this.handle(), name);

if (index < 0) {
Expand All @@ -74,6 +86,19 @@ public GlUniformBlock bindUniformBlock(String name, int bindingPoint) {
return new GlUniformBlock(bindingPoint);
}

@Override
public GlUniformBlock bindUniformBlockOptional(String name, int bindingPoint) {
int index = GL32C.glGetUniformBlockIndex(this.handle(), name);

if (index < 0) {
return null;
}

GL32C.glUniformBlockBinding(this.handle(), index, bindingPoint);

return new GlUniformBlock(bindingPoint);
}

public static class Builder {
private final ResourceLocation name;
private final int program;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
package net.caffeinemc.mods.sodium.client.gl.shader;

import org.lwjgl.opengl.GL20C;
import org.lwjgl.opengl.GL32C;
import org.lwjgl.opengl.GL40C;

/**
* An enumeration over the supported OpenGL shader types.
*/
public enum ShaderType {
VERTEX(GL20C.GL_VERTEX_SHADER),
GEOMETRY(GL32C.GL_GEOMETRY_SHADER),
TESS_CONTROL(GL40C.GL_TESS_CONTROL_SHADER),
TESS_EVALUATION(GL40C.GL_TESS_EVALUATION_SHADER),
FRAGMENT(GL20C.GL_FRAGMENT_SHADER);

public final int id;

ShaderType(int id) {
this.id = id;
}

public static ShaderType fromGlShaderType(int id) {
for (ShaderType type : values()) {
if (type.id == id) {
return type;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package net.caffeinemc.mods.sodium.client.gl.tessellation;

import org.lwjgl.opengl.GL20C;
import org.lwjgl.opengl.GL40C;

public enum GlPrimitiveType {
TRIANGLES(GL20C.GL_TRIANGLES);
POINTS(GL20C.GL_POINTS),
LINES(GL20C.GL_LINES),
TRIANGLES(GL20C.GL_TRIANGLES),
PATCHES(GL40C.GL_PATCHES);

private final int id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ public static OptionPage performance() {
.setControl(TickBoxControl::new)
.setImpact(OptionImpact.LOW)
.setBinding((opts, value) -> opts.performance.useNoErrorGLContext = value, opts -> opts.performance.useNoErrorGLContext)
.setEnabled(supportsNoErrorContext())
.setEnabled(SodiumGameOptionPages::supportsNoErrorContext)
.setFlags(OptionFlag.REQUIRES_GAME_RESTART)
.build())
.build());
Expand Down Expand Up @@ -338,13 +338,15 @@ private static boolean supportsNoErrorContext() {
public static OptionPage advanced() {
List<OptionGroup> groups = new ArrayList<>();

boolean isPersistentMappingSupported = MappedStagingBuffer.isSupported(RenderDevice.INSTANCE);

groups.add(OptionGroup.createBuilder()
.add(OptionImpl.createBuilder(boolean.class, sodiumOpts)
.setName(Component.translatable("sodium.options.use_persistent_mapping.name"))
.setTooltip(Component.translatable("sodium.options.use_persistent_mapping.tooltip"))
.setControl(TickBoxControl::new)
.setImpact(OptionImpact.MEDIUM)
.setEnabled(MappedStagingBuffer.isSupported(RenderDevice.INSTANCE))
.setEnabled(() -> isPersistentMappingSupported)
.setBinding((opts, value) -> opts.advanced.useAdvancedStagingBuffers = value, opts -> opts.advanced.useAdvancedStagingBuffers)
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.function.BiConsumer;
import java.util.function.BooleanSupplier;
import java.util.function.Function;

public class OptionImpl<S, T> implements Option<T> {
Expand All @@ -29,7 +30,7 @@ public class OptionImpl<S, T> implements Option<T> {
private T value;
private T modifiedValue;

private final boolean enabled;
private final BooleanSupplier enabled;

private OptionImpl(OptionStorage<S> storage,
Component name,
Expand All @@ -38,7 +39,7 @@ private OptionImpl(OptionStorage<S> storage,
Function<OptionImpl<S, T>, Control<T>> control,
EnumSet<OptionFlag> flags,
OptionImpact impact,
boolean enabled) {
BooleanSupplier enabled) {
this.storage = storage;
this.name = name;
this.tooltip = tooltip;
Expand Down Expand Up @@ -94,7 +95,7 @@ public OptionStorage<?> getStorage() {

@Override
public boolean isAvailable() {
return this.enabled;
return this.enabled.getAsBoolean();
}

@Override
Expand Down Expand Up @@ -125,7 +126,7 @@ public static class Builder<S, T> {
private Function<OptionImpl<S, T>, Control<T>> control;
private OptionImpact impact;
private final EnumSet<OptionFlag> flags = EnumSet.noneOf(OptionFlag.class);
private boolean enabled = true;
private BooleanSupplier enabled = () -> true;

private Builder(OptionStorage<S> storage) {
this.storage = storage;
Expand Down Expand Up @@ -179,7 +180,7 @@ public Builder<S, T> setImpact(OptionImpact impact) {
return this;
}

public Builder<S, T> setEnabled(boolean value) {
public Builder<S, T> setEnabled(BooleanSupplier value) {
this.enabled = value;

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterface;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior;
import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute;
import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType;
import net.caffeinemc.mods.sodium.client.render.viewport.CameraTransform;
import net.caffeinemc.mods.sodium.client.util.BitwiseMath;
Expand Down Expand Up @@ -316,18 +315,7 @@ private GlTessellation prepareIndexedTessellation(CommandList commandList, Rende

private GlTessellation createRegionTessellation(CommandList commandList, RenderRegion.DeviceResources resources, boolean useSharedIndexBuffer) {
return commandList.createTessellation(GlPrimitiveType.TRIANGLES, new TessellationBinding[] {
TessellationBinding.forVertexBuffer(resources.getGeometryBuffer(), new GlVertexAttributeBinding[] {
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_HI,
this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_HI)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_LO,
this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_LO)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR,
this.vertexFormat.getAttribute(ChunkMeshAttribute.COLOR)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_TEXTURE,
this.vertexFormat.getAttribute(ChunkMeshAttribute.TEXTURE)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX,
this.vertexFormat.getAttribute(ChunkMeshAttribute.LIGHT_MATERIAL_INDEX))
}),
TessellationBinding.forVertexBuffer(resources.getGeometryBuffer(), this.vertexFormat.getShaderBindings()),
TessellationBinding.forElementBuffer(useSharedIndexBuffer
? this.sharedIndexBuffer.getBufferObject()
: resources.getIndexBuffer())
Expand Down
Loading
Loading