mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
AMD driver workaround
- Just don't pool models
This commit is contained in:
parent
d094595f2e
commit
d9fd668bbb
7 changed files with 103 additions and 76 deletions
|
@ -9,6 +9,8 @@ import org.lwjgl.opengl.GLCapabilities;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import net.minecraft.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of this class stores information about what OpenGL features are available.
|
* An instance of this class stores information about what OpenGL features are available.
|
||||||
* <br>
|
* <br>
|
||||||
|
@ -19,13 +21,27 @@ public class GlCompat {
|
||||||
|
|
||||||
public final InstancedArrays instancedArrays;
|
public final InstancedArrays instancedArrays;
|
||||||
public final BufferStorage bufferStorage;
|
public final BufferStorage bufferStorage;
|
||||||
|
public final boolean amd;
|
||||||
|
|
||||||
public GlCompat(GLCapabilities caps) {
|
public GlCompat(GLCapabilities caps) {
|
||||||
instancedArrays = getLatest(InstancedArrays.class, caps);
|
instancedArrays = getLatest(InstancedArrays.class, caps);
|
||||||
bufferStorage = getLatest(BufferStorage.class, caps);
|
bufferStorage = getLatest(BufferStorage.class, caps);
|
||||||
|
|
||||||
|
|
||||||
|
if (Util.getPlatform() == Util.OS.WINDOWS) {
|
||||||
|
String vendor = GL20C.glGetString(GL20C.GL_VENDOR);
|
||||||
|
// vendor string I got was "ATI Technologies Inc."
|
||||||
|
amd = vendor.contains("ATI") || vendor.contains("AMD");
|
||||||
|
} else {
|
||||||
|
amd = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean instancedArraysSupported() {
|
public boolean onAMDWindows() {
|
||||||
|
return amd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean instancedArraysSupported() {
|
||||||
return instancedArrays != InstancedArrays.UNSUPPORTED;
|
return instancedArrays != InstancedArrays.UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||||
model = modelAllocator.alloc(modelData, arenaModel -> {
|
model = modelAllocator.alloc(modelData, arenaModel -> {
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
||||||
model.setupState();
|
arenaModel.setupState();
|
||||||
});
|
});
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
|
@ -5,10 +5,13 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.Material;
|
||||||
|
import com.jozufozu.flywheel.backend.model.ImmediateAllocator;
|
||||||
|
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
||||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
import com.jozufozu.flywheel.core.Formats;
|
||||||
|
@ -20,14 +23,18 @@ import com.jozufozu.flywheel.core.model.Model;
|
||||||
*/
|
*/
|
||||||
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
|
|
||||||
final ModelPool modelPool;
|
final ModelAllocator allocator;
|
||||||
protected final Cache<Object, GPUInstancer<D>> models;
|
protected final Cache<Object, GPUInstancer<D>> models;
|
||||||
protected final StructType<D> type;
|
protected final StructType<D> type;
|
||||||
|
|
||||||
public InstancedMaterial(StructType<D> spec) {
|
public InstancedMaterial(StructType<D> spec) {
|
||||||
this.type = spec;
|
this.type = spec;
|
||||||
|
|
||||||
modelPool = new ModelPool(Formats.UNLIT_MODEL, 64);
|
if (Backend.getInstance().compat.onAMDWindows()) {
|
||||||
|
allocator = ImmediateAllocator.INSTANCE;
|
||||||
|
} else {
|
||||||
|
allocator = new ModelPool(Formats.UNLIT_MODEL, 64);
|
||||||
|
}
|
||||||
this.models = CacheBuilder.newBuilder()
|
this.models = CacheBuilder.newBuilder()
|
||||||
.removalListener(notification -> {
|
.removalListener(notification -> {
|
||||||
GPUInstancer<?> instancer = (GPUInstancer<?>) notification.getValue();
|
GPUInstancer<?> instancer = (GPUInstancer<?>) notification.getValue();
|
||||||
|
@ -46,7 +53,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
@Override
|
@Override
|
||||||
public Instancer<D> model(Object key, Supplier<Model> modelSupplier) {
|
public Instancer<D> model(Object key, Supplier<Model> modelSupplier) {
|
||||||
try {
|
try {
|
||||||
return models.get(key, () -> new GPUInstancer<>(type, modelSupplier.get(), modelPool));
|
return models.get(key, () -> new GPUInstancer<>(type, modelSupplier.get(), allocator));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
throw new RuntimeException("error creating instancer", e);
|
throw new RuntimeException("error creating instancer", e);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +68,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
models.invalidateAll();
|
models.invalidateAll();
|
||||||
modelPool.delete();
|
if (allocator instanceof ModelPool pool) pool.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Collection;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
|
@ -28,8 +29,10 @@ public class InstancedMaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
// initialize all uninitialized instancers...
|
// initialize all uninitialized instancers...
|
||||||
instancers.forEach(GPUInstancer::init);
|
instancers.forEach(GPUInstancer::init);
|
||||||
// ...and then flush the model arena in case anything was marked for upload
|
if (material.allocator instanceof ModelPool pool) {
|
||||||
material.modelPool.flush();
|
// ...and then flush the model arena in case anything was marked for upload
|
||||||
|
pool.flush();
|
||||||
|
}
|
||||||
|
|
||||||
P program = this.program.get();
|
P program = this.program.get();
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@ public class IndexedModel extends BufferedModel {
|
||||||
public void drawInstances(int instanceCount) {
|
public void drawInstances(int instanceCount) {
|
||||||
if (!valid()) return;
|
if (!valid()) return;
|
||||||
|
|
||||||
|
ebo.bind();
|
||||||
|
|
||||||
GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount);
|
GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,9 +120,12 @@ public class ModelPool implements ModelAllocator {
|
||||||
|
|
||||||
VecBufferWriter consumer = new VecBufferWriter(buffer);
|
VecBufferWriter consumer = new VecBufferWriter(buffer);
|
||||||
|
|
||||||
|
int vertices = 0;
|
||||||
for (PooledModel model : models) {
|
for (PooledModel model : models) {
|
||||||
|
model.first = vertices;
|
||||||
model.model.buffer(consumer);
|
model.model.buffer(consumer);
|
||||||
if (model.callback != null) model.callback.onAlloc(model);
|
if (model.callback != null) model.callback.onAlloc(model);
|
||||||
|
vertices += model.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -125,80 +125,76 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
|
||||||
|
|
||||||
private ModelPart getBaseModel() {
|
private ModelPart getBaseModel() {
|
||||||
|
|
||||||
switch (chestType) {
|
return switch (chestType) {
|
||||||
case LEFT:
|
case LEFT -> ModelPart.builder("chest_base_left", 64, 64)
|
||||||
return ModelPart.builder("chest_base_left", 64, 64)
|
.sprite(renderMaterial.sprite())
|
||||||
.sprite(renderMaterial.sprite())
|
.cuboid()
|
||||||
.cuboid()
|
.textureOffset(0, 19)
|
||||||
.textureOffset(0, 19)
|
.start(0, 0, 1)
|
||||||
.start(0, 0, 1)
|
.size(15, 10, 14)
|
||||||
.size(15, 10, 14)
|
.endCuboid()
|
||||||
.endCuboid()
|
.build();
|
||||||
.build();
|
case RIGHT -> ModelPart.builder("chest_base_right", 64, 64)
|
||||||
case RIGHT:
|
.sprite(renderMaterial.sprite())
|
||||||
return ModelPart.builder("chest_base_right", 64, 64)
|
.cuboid()
|
||||||
.sprite(renderMaterial.sprite())
|
.textureOffset(0, 19)
|
||||||
.cuboid()
|
.start(1, 0, 1)
|
||||||
.textureOffset(0, 19)
|
.size(15, 10, 14)
|
||||||
.start(1, 0, 1)
|
.endCuboid()
|
||||||
.size(15, 10, 14)
|
.build();
|
||||||
.endCuboid()
|
default -> ModelPart.builder("chest_base", 64, 64)
|
||||||
.build();
|
.sprite(renderMaterial.sprite())
|
||||||
}
|
.cuboid()
|
||||||
|
.textureOffset(0, 19)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.end(15, 10, 15)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
};
|
||||||
|
|
||||||
return ModelPart.builder("chest_base", 64, 64)
|
|
||||||
.sprite(renderMaterial.sprite())
|
|
||||||
.cuboid()
|
|
||||||
.textureOffset(0, 19)
|
|
||||||
.start(1, 0, 1)
|
|
||||||
.end(15, 10, 15)
|
|
||||||
.endCuboid()
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelPart getLidModel() {
|
private ModelPart getLidModel() {
|
||||||
|
|
||||||
switch (chestType) {
|
return switch (chestType) {
|
||||||
case LEFT:
|
case LEFT -> ModelPart.builder("chest_lid_left", 64, 64)
|
||||||
return ModelPart.builder("chest_lid_left", 64, 64)
|
.sprite(renderMaterial.sprite())
|
||||||
.sprite(renderMaterial.sprite())
|
.cuboid()
|
||||||
.cuboid()
|
.textureOffset(0, 0)
|
||||||
.textureOffset(0, 0)
|
.start(0, 0, 1)
|
||||||
.start(0, 0, 1)
|
.size(15, 5, 14)
|
||||||
.size(15, 5, 14)
|
.endCuboid()
|
||||||
.endCuboid()
|
.cuboid()
|
||||||
.cuboid()
|
.start(0, -2, 15)
|
||||||
.start(0, -2, 15)
|
.size(1, 4, 1)
|
||||||
.size(1, 4, 1)
|
.endCuboid()
|
||||||
.endCuboid()
|
.build();
|
||||||
.build();
|
case RIGHT -> ModelPart.builder("chest_lid_right", 64, 64)
|
||||||
case RIGHT:
|
.sprite(renderMaterial.sprite())
|
||||||
return ModelPart.builder("chest_lid_right", 64, 64)
|
.cuboid()
|
||||||
.sprite(renderMaterial.sprite())
|
.textureOffset(0, 0)
|
||||||
.cuboid()
|
.start(1, 0, 1)
|
||||||
.textureOffset(0, 0)
|
.size(15, 5, 14)
|
||||||
.start(1, 0, 1)
|
.endCuboid()
|
||||||
.size(15, 5, 14)
|
.cuboid()
|
||||||
.endCuboid()
|
.start(15, -2, 15)
|
||||||
.cuboid()
|
.size(1, 4, 1)
|
||||||
.start(15, -2, 15)
|
.endCuboid()
|
||||||
.size(1, 4, 1)
|
.build();
|
||||||
.endCuboid()
|
default -> ModelPart.builder("chest_lid", 64, 64)
|
||||||
.build();
|
.sprite(renderMaterial.sprite())
|
||||||
}
|
.cuboid()
|
||||||
|
.textureOffset(0, 0)
|
||||||
|
.start(1, 0, 1)
|
||||||
|
.size(14, 5, 14)
|
||||||
|
.endCuboid()
|
||||||
|
.cuboid()
|
||||||
|
.start(7, -2, 15)
|
||||||
|
.size(2, 4, 1)
|
||||||
|
.endCuboid()
|
||||||
|
.build();
|
||||||
|
};
|
||||||
|
|
||||||
return ModelPart.builder("chest_lid", 64, 64)
|
|
||||||
.sprite(renderMaterial.sprite())
|
|
||||||
.cuboid()
|
|
||||||
.textureOffset(0, 0)
|
|
||||||
.start(1, 0, 1)
|
|
||||||
.size(14, 5, 14)
|
|
||||||
.endCuboid()
|
|
||||||
.cuboid()
|
|
||||||
.start(7, -2, 15)
|
|
||||||
.size(2, 4, 1)
|
|
||||||
.endCuboid()
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isChristmas() {
|
public static boolean isChristmas() {
|
||||||
|
|
Loading…
Reference in a new issue