Skip to content

Commit

Permalink
Merge branch 'CaffeineMC:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
hfhhfhzx authored Jan 16, 2025
2 parents 980490a + d74e421 commit be95d9e
Show file tree
Hide file tree
Showing 39 changed files with 1,121 additions and 825 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/BuildConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.12.07"

// https://semver.org/
var MOD_VERSION: String = "0.6.5"
var MOD_VERSION: String = "0.6.6"

fun createVersionString(project: Project): String {
val builder = StringBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public class ColorAttribute {
public static void set(long ptr, int color) {
MemoryUtil.memPutInt(ptr + 0, color);
MemoryUtil.memPutInt(ptr, color);
}

public static int get(long ptr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public class NormalAttribute {
public static void set(long ptr, int normal) {
MemoryUtil.memPutInt(ptr + 0, normal);
MemoryUtil.memPutInt(ptr, normal);
}

public static int get(long ptr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@

public class PositionAttribute {
public static void put(long ptr, float x, float y, float z) {
MemoryUtil.memPutFloat(ptr + 0, x);
MemoryUtil.memPutFloat(ptr + 4, y);
MemoryUtil.memPutFloat(ptr + 8, z);
MemoryUtil.memPutFloat(ptr + 0L, x);
MemoryUtil.memPutFloat(ptr + 4L, y);
MemoryUtil.memPutFloat(ptr + 8L, z);
}

public static float getX(long ptr) {
return MemoryUtil.memGetFloat(ptr + 0);
return MemoryUtil.memGetFloat(ptr + 0L);
}

public static float getY(long ptr) {
return MemoryUtil.memGetFloat(ptr + 4);
return MemoryUtil.memGetFloat(ptr + 4L);
}

public static float getZ(long ptr) {
return MemoryUtil.memGetFloat(ptr + 8);
return MemoryUtil.memGetFloat(ptr + 8L);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL20C;

import java.util.Arrays;

/**
* A compiled OpenGL shader object.
*/
Expand All @@ -15,17 +17,18 @@ public class GlShader extends GlObject {

private final ResourceLocation name;

public GlShader(ShaderType type, ResourceLocation name, String src) {
public GlShader(ShaderType type, ResourceLocation name, ShaderParser.ParsedShader parsedShader) {
this.name = name;

int handle = GL20C.glCreateShader(type.id);
ShaderWorkarounds.safeShaderSource(handle, src);
ShaderWorkarounds.safeShaderSource(handle, parsedShader.src());
GL20C.glCompileShader(handle);

String log = GL20C.glGetShaderInfoLog(handle);

if (!log.isEmpty()) {
LOGGER.warn("Shader compilation log for " + this.name + ": " + log);
LOGGER.warn("Shader compilation log for {}: {}", this.name, log);
LOGGER.warn("Include table: {}", Arrays.toString(parsedShader.includeIds()));
}

int result = GlStateManager.glGetShaderi(handle, GL20C.GL_COMPILE_STATUS);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package net.caffeinemc.mods.sodium.client.gl.shader;

import net.caffeinemc.mods.sodium.client.services.PlatformRuntimeInformation;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ShaderLoader {
private static final Logger LOGGER = LoggerFactory.getLogger("Sodium-ShaderLoader");

/**
* Creates an OpenGL shader from GLSL sources. The GLSL source file should be made available on the classpath at the
* path of `/assets/{namespace}/shaders/{path}`. User defines can be used to declare variables in the shader source
Expand All @@ -19,7 +24,12 @@ public class ShaderLoader {
* @return An OpenGL shader object compiled with the given user defines
*/
public static GlShader loadShader(ShaderType type, ResourceLocation name, ShaderConstants constants) {
return new GlShader(type, name, ShaderParser.parseShader(getShaderSource(name), constants));
var parsedShader = ShaderParser.parseShader(getShaderSource(name), constants);
if (PlatformRuntimeInformation.INSTANCE.isDevelopmentEnvironment()) {
LOGGER.info("Loaded shader {} with constants {}", name, constants);
LOGGER.info(parsedShader.src());
}
return new GlShader(type, name, parsedShader);
}

public static String getShaderSource(ResourceLocation name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,87 @@
package net.caffeinemc.mods.sodium.client.gl.shader;

import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.resources.ResourceLocation;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.resources.ResourceLocation;

public class ShaderParser {
public static String parseShader(String src, ShaderConstants constants) {
List<String> lines = parseShader(src);
lines.addAll(1, constants.getDefineStrings());
public record ParsedShader(String src, String[] includeIds) {
}

public static ParsedShader parseShader(String src, ShaderConstants constants) {
var parser = new ShaderParser();
parser.parseShader("_root", src);
parser.prependDefineStrings(constants);

return String.join("\n", lines);
return parser.finish();
}

public static List<String> parseShader(String src) {
List<String> builder = new LinkedList<>();
private final Object2IntMap<String> includeIds = new Object2IntArrayMap<>();
private final List<String> lines = new LinkedList<>();

private ShaderParser() {
}

public void parseShader(String name, String src) {
String line;
int lineNumber = 0;

try (BufferedReader reader = new BufferedReader(new StringReader(src))) {
while ((line = reader.readLine()) != null) {
if (line.startsWith("#import")) {
builder.addAll(resolveImport(line));
lineNumber++;
if (line.startsWith("#version")) {
this.lines.add(line);
this.lines.add(lineDirectiveFor(name, lineNumber));
} else if (line.startsWith("#import")) {
// add the original import statement as a comment for reference
this.lines.add("// START " + line);

processImport(line);

// reset the line directive to the current file
this.lines.add("// END " + line);
this.lines.add(lineDirectiveFor(name, lineNumber));
} else {
builder.add(line);
this.lines.add(line);
}
}
} catch (IOException e) {
throw new RuntimeException("Failed to read shader sources", e);
}
}

private String lineDirectiveFor(String name, int line) {
int idNumber;
if (!this.includeIds.containsKey(name)) {
idNumber = this.includeIds.size();
this.includeIds.put(name, idNumber);
} else {
idNumber = this.includeIds.getInt(name);
}
return "#line " + (line + 1) + " " + idNumber;
}

private void processImport(String line) {
ResourceLocation name = parseImport(line);

return builder;
// mark the start of the imported file
var nameString = name.toString();
this.lines.add(lineDirectiveFor(nameString, 0));

parseShader(nameString, ShaderLoader.getShaderSource(name));
}

private static final Pattern IMPORT_PATTERN = Pattern.compile("#import <(?<namespace>.*):(?<path>.*)>");

private static List<String> resolveImport(String line) {
private ResourceLocation parseImport(String line) {
Matcher matcher = IMPORT_PATTERN.matcher(line);

if (!matcher.matches()) {
Expand All @@ -48,9 +91,20 @@ private static List<String> resolveImport(String line) {
String namespace = matcher.group("namespace");
String path = matcher.group("path");

ResourceLocation name = ResourceLocation.fromNamespaceAndPath(namespace, path);
String source = ShaderLoader.getShaderSource(name);
return ResourceLocation.fromNamespaceAndPath(namespace, path);
}

private void prependDefineStrings(ShaderConstants constants) {
this.lines.addAll(1, constants.getDefineStrings());
}

private ParsedShader finish() {
// convert include id map to a list ordered by id
var includeIds = new String[this.includeIds.size()];
this.includeIds.forEach((name, id) -> {
includeIds[id] = name;
});

return ShaderParser.parseShader(source);
return new ParsedShader(String.join("\n", this.lines), includeIds);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.caffeinemc.mods.sodium.client.util.BitwiseMath;
import net.caffeinemc.mods.sodium.client.util.UInt32;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.Pointer;

import java.util.Iterator;

Expand Down Expand Up @@ -172,7 +173,7 @@ private static void addNonIndexedDrawCommands(MultiDrawBatch batch, long pMeshDa
// Uint32 -> Int32 cast is always safe and should be optimized away
MemoryUtil.memPutInt(pBaseVertex + (size << 2), (int) SectionRenderDataUnsafe.getVertexOffset(pMeshData, facing));
MemoryUtil.memPutInt(pElementCount + (size << 2), (int) SectionRenderDataUnsafe.getElementCount(pMeshData, facing));
MemoryUtil.memPutAddress(pElementPointer + (size << 3), 0 /* using a shared index buffer */);
MemoryUtil.memPutAddress(pElementPointer + (size << Pointer.POINTER_SHIFT), 0 /* using a shared index buffer */);

size += (mask >> facing) & 1;
}
Expand Down Expand Up @@ -204,7 +205,7 @@ private static void addIndexedDrawCommands(MultiDrawBatch batch, long pMeshData,

// * 4 to convert to bytes (the index buffer contains integers)
// the section render data storage for the indices stores the offset in indices (also called elements)
MemoryUtil.memPutAddress(pElementPointer + (size << 3), elementOffset << 2);
MemoryUtil.memPutAddress(pElementPointer + (size << Pointer.POINTER_SHIFT), elementOffset << 2);

// adding the number of elements works because the index data has one index per element (which are the indices)
elementOffset += elementCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,23 @@ private boolean validateQuadUVs(TextureAtlasSprite atlasSprite) {
}

private static TerrainRenderPass getDowngradedPass(TextureAtlasSprite sprite, TerrainRenderPass pass) {
if (sprite.contents() instanceof SpriteContentsExtension contents) {
if (pass == DefaultTerrainRenderPasses.TRANSLUCENT && !contents.sodium$hasTranslucentPixels()) {
pass = DefaultTerrainRenderPasses.CUTOUT;
if (sprite instanceof TextureAtlasSpriteExtension spriteExt) {
// Some mods may use a custom ticker which we cannot look into. To avoid problems with these mods,
// do not attempt to downgrade the render pass.
if (spriteExt.sodium$hasUnknownImageContents()) {
return pass;
}
if (pass == DefaultTerrainRenderPasses.CUTOUT && !contents.sodium$hasTransparentPixels()) {
pass = DefaultTerrainRenderPasses.SOLID;

if (sprite.contents() instanceof SpriteContentsExtension contentsExt) {
if (pass == DefaultTerrainRenderPasses.TRANSLUCENT && !contentsExt.sodium$hasTranslucentPixels()) {
pass = DefaultTerrainRenderPasses.CUTOUT;
}
if (pass == DefaultTerrainRenderPasses.CUTOUT && !contentsExt.sodium$hasTransparentPixels()) {
pass = DefaultTerrainRenderPasses.SOLID;
}
}
}

return pass;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline;

public interface TextureAtlasSpriteExtension {
boolean sodium$hasUnknownImageContents();
}
Original file line number Diff line number Diff line change
Expand Up @@ -530,43 +530,25 @@ static private BSPNode buildTopoMultiLeafNode(BSPWorkspace workspace, IntArrayLi
}

static private BSPNode buildSNRLeafNodeFromQuads(BSPWorkspace workspace, IntArrayList indexes, LongArrayList points) {
// in this case the points array is wrong, but its allocation can be reused
final var indexBuffer = indexes.elements();
final var indexCount = indexes.size();

int[] quadIndexes;
final var keys = new int[indexCount];
final var perm = new int[indexCount];

// adapted from SNR sorting code
if (RadixSort.useRadixSort(indexes.size())) {
final var keys = new int[indexes.size()];

for (int i = 0; i < indexes.size(); i++) {
var quadIndex = indexes.getInt(i);
keys[i] = MathUtil.floatToComparableInt(workspace.quads[quadIndex].getAccurateDotProduct());
}

quadIndexes = RadixSort.sort(keys);

for (int i = 0; i < indexes.size(); i++) {
quadIndexes[i] = indexes.getInt(quadIndexes[i]);
}
} else {
final var sortData = points.elements();

for (int i = 0; i < indexes.size(); i++) {
var quadIndex = indexes.getInt(i);
int dotProductComponent = MathUtil.floatToComparableInt(workspace.quads[quadIndex].getAccurateDotProduct());
sortData[i] = (long) dotProductComponent << 32 | quadIndex;
}

Arrays.sort(sortData, 0, indexes.size());
for (int i = 0; i < indexCount; i++) {
TQuad quad = workspace.quads[indexBuffer[i]];
keys[i] = MathUtil.floatToComparableInt(quad.getAccurateDotProduct());
perm[i] = i;
}

quadIndexes = new int[indexes.size()];
RadixSort.sortIndirect(perm, keys);

for (int i = 0; i < indexes.size(); i++) {
quadIndexes[i] = (int) sortData[i];
}
for (int i = 0; i < indexCount; i++) {
perm[i] = indexBuffer[perm[i]];
}

return new LeafMultiBSPNode(BSPSortState.compressIndexes(IntArrayList.wrap(quadIndexes), false));
return new LeafMultiBSPNode(BSPSortState.compressIndexes(IntArrayList.wrap(perm), false));
}

static private BSPNode buildSNRLeafNodeFromPoints(BSPWorkspace workspace, LongArrayList points) {
Expand Down
Loading

0 comments on commit be95d9e

Please sign in to comment.