/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.common.collect.ImmutableList * com.google.common.collect.ImmutableMap * com.google.common.collect.ImmutableMap$Builder * it.unimi.dsi.fastutil.ints.IntArrayList * it.unimi.dsi.fastutil.ints.IntList * org.jspecify.annotations.Nullable */ package com.mojang.blaze3d.vertex; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.GraphicsWorkarounds; import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.VertexFormatElement; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; import org.jspecify.annotations.Nullable; public class VertexFormat { public static final int UNKNOWN_ELEMENT = -1; private final List elements; private final List names; private final int vertexSize; private final int elementsMask; private final int[] offsetsByElement = new int[32]; private @Nullable GpuBuffer immediateDrawVertexBuffer; private @Nullable GpuBuffer immediateDrawIndexBuffer; private VertexFormat(List elements, List names, IntList offsets, int vertexSize) { this.elements = elements; this.names = names; this.vertexSize = vertexSize; this.elementsMask = elements.stream().mapToInt(VertexFormatElement::mask).reduce(0, (left, right) -> left | right); for (int id = 0; id < this.offsetsByElement.length; ++id) { VertexFormatElement element = VertexFormatElement.byId(id); int index = element != null ? elements.indexOf(element) : -1; this.offsetsByElement[id] = index != -1 ? offsets.getInt(index) : -1; } } public static Builder builder() { return new Builder(); } public String toString() { return "VertexFormat" + String.valueOf(this.names); } public int getVertexSize() { return this.vertexSize; } public List getElements() { return this.elements; } public List getElementAttributeNames() { return this.names; } public int[] getOffsetsByElement() { return this.offsetsByElement; } public int getOffset(VertexFormatElement element) { return this.offsetsByElement[element.id()]; } public boolean contains(VertexFormatElement element) { return (this.elementsMask & element.mask()) != 0; } public int getElementsMask() { return this.elementsMask; } public String getElementName(VertexFormatElement element) { int index = this.elements.indexOf(element); if (index == -1) { throw new IllegalArgumentException(String.valueOf(element) + " is not contained in format"); } return this.names.get(index); } /* * Enabled force condition propagation * Lifted jumps to return sites */ public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof VertexFormat)) return false; VertexFormat format = (VertexFormat)o; if (this.elementsMask != format.elementsMask) return false; if (this.vertexSize != format.vertexSize) return false; if (!this.names.equals(format.names)) return false; if (!Arrays.equals(this.offsetsByElement, format.offsetsByElement)) return false; return true; } public int hashCode() { return this.elementsMask * 31 + Arrays.hashCode(this.offsetsByElement); } private static GpuBuffer uploadToBuffer(@Nullable GpuBuffer target, ByteBuffer buffer, @GpuBuffer.Usage int usage, Supplier label) { GpuDevice device = RenderSystem.getDevice(); if (GraphicsWorkarounds.get(device).alwaysCreateFreshImmediateBuffer()) { if (target != null) { target.close(); } return device.createBuffer(label, usage, buffer); } if (target == null) { target = device.createBuffer(label, usage, buffer); } else { CommandEncoder encoder = device.createCommandEncoder(); if (target.size() < buffer.remaining()) { target.close(); target = device.createBuffer(label, usage, buffer); } else { encoder.writeToBuffer(target.slice(), buffer); } } return target; } public GpuBuffer uploadImmediateVertexBuffer(ByteBuffer buffer) { this.immediateDrawVertexBuffer = VertexFormat.uploadToBuffer(this.immediateDrawVertexBuffer, buffer, 40, () -> "Immediate vertex buffer for " + String.valueOf(this)); return this.immediateDrawVertexBuffer; } public GpuBuffer uploadImmediateIndexBuffer(ByteBuffer buffer) { this.immediateDrawIndexBuffer = VertexFormat.uploadToBuffer(this.immediateDrawIndexBuffer, buffer, 72, () -> "Immediate index buffer for " + String.valueOf(this)); return this.immediateDrawIndexBuffer; } public static class Builder { private final ImmutableMap.Builder elements = ImmutableMap.builder(); private final IntList offsets = new IntArrayList(); private int offset; private Builder() { } public Builder add(String name, VertexFormatElement element) { this.elements.put((Object)name, (Object)element); this.offsets.add(this.offset); this.offset += element.byteSize(); return this; } public Builder padding(int bytes) { this.offset += bytes; return this; } public VertexFormat build() { ImmutableMap elementMap = this.elements.buildOrThrow(); ImmutableList elements = elementMap.values().asList(); ImmutableList names = elementMap.keySet().asList(); return new VertexFormat((List)elements, (List)names, this.offsets, this.offset); } } public static enum Mode { LINES(2, 2, false), DEBUG_LINES(2, 2, false), DEBUG_LINE_STRIP(2, 1, true), POINTS(1, 1, false), TRIANGLES(3, 3, false), TRIANGLE_STRIP(3, 1, true), TRIANGLE_FAN(3, 1, true), QUADS(4, 4, false); public final int primitiveLength; public final int primitiveStride; public final boolean connectedPrimitives; private Mode(int primitiveLength, int primitiveStride, boolean connectedPrimitives) { this.primitiveLength = primitiveLength; this.primitiveStride = primitiveStride; this.connectedPrimitives = connectedPrimitives; } public int indexCount(int vertexCount) { return switch (this.ordinal()) { case 1, 2, 3, 4, 5, 6 -> vertexCount; case 0, 7 -> vertexCount / 4 * 6; default -> 0; }; } } public static enum IndexType { SHORT(2), INT(4); public final int bytes; private IndexType(int bytes) { this.bytes = bytes; } public static IndexType least(int length) { if ((length & 0xFFFF0000) != 0) { return INT; } return SHORT; } } }