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.MemoryUtil;
|
||||
|
||||
import net.minecraft.Util;
|
||||
|
||||
/**
|
||||
* An instance of this class stores information about what OpenGL features are available.
|
||||
* <br>
|
||||
|
@ -19,13 +21,27 @@ public class GlCompat {
|
|||
|
||||
public final InstancedArrays instancedArrays;
|
||||
public final BufferStorage bufferStorage;
|
||||
public final boolean amd;
|
||||
|
||||
public GlCompat(GLCapabilities caps) {
|
||||
instancedArrays = getLatest(InstancedArrays.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;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
model = modelAllocator.alloc(modelData, arenaModel -> {
|
||||
vao.bind();
|
||||
|
||||
model.setupState();
|
||||
arenaModel.setupState();
|
||||
});
|
||||
|
||||
vao.bind();
|
||||
|
|
|
@ -5,10 +5,13 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.RenderWork;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
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.api.struct.StructType;
|
||||
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> {
|
||||
|
||||
final ModelPool modelPool;
|
||||
final ModelAllocator allocator;
|
||||
protected final Cache<Object, GPUInstancer<D>> models;
|
||||
protected final StructType<D> type;
|
||||
|
||||
public InstancedMaterial(StructType<D> 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()
|
||||
.removalListener(notification -> {
|
||||
GPUInstancer<?> instancer = (GPUInstancer<?>) notification.getValue();
|
||||
|
@ -46,7 +53,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
@Override
|
||||
public Instancer<D> model(Object key, Supplier<Model> modelSupplier) {
|
||||
try {
|
||||
return models.get(key, () -> new GPUInstancer<>(type, modelSupplier.get(), modelPool));
|
||||
return models.get(key, () -> new GPUInstancer<>(type, modelSupplier.get(), allocator));
|
||||
} catch (ExecutionException e) {
|
||||
throw new RuntimeException("error creating instancer", e);
|
||||
}
|
||||
|
@ -61,7 +68,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
|
||||
public void delete() {
|
||||
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.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
|
@ -28,8 +29,10 @@ public class InstancedMaterialRenderer<P extends WorldProgram> {
|
|||
|
||||
// initialize all uninitialized instancers...
|
||||
instancers.forEach(GPUInstancer::init);
|
||||
// ...and then flush the model arena in case anything was marked for upload
|
||||
material.modelPool.flush();
|
||||
if (material.allocator instanceof ModelPool pool) {
|
||||
// ...and then flush the model arena in case anything was marked for upload
|
||||
pool.flush();
|
||||
}
|
||||
|
||||
P program = this.program.get();
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ public class IndexedModel extends BufferedModel {
|
|||
public void drawInstances(int instanceCount) {
|
||||
if (!valid()) return;
|
||||
|
||||
ebo.bind();
|
||||
|
||||
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);
|
||||
|
||||
int vertices = 0;
|
||||
for (PooledModel model : models) {
|
||||
model.first = vertices;
|
||||
model.model.buffer(consumer);
|
||||
if (model.callback != null) model.callback.onAlloc(model);
|
||||
vertices += model.getVertexCount();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -125,80 +125,76 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends TileE
|
|||
|
||||
private ModelPart getBaseModel() {
|
||||
|
||||
switch (chestType) {
|
||||
case LEFT:
|
||||
return ModelPart.builder("chest_base_left", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 19)
|
||||
.start(0, 0, 1)
|
||||
.size(15, 10, 14)
|
||||
.endCuboid()
|
||||
.build();
|
||||
case RIGHT:
|
||||
return ModelPart.builder("chest_base_right", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 19)
|
||||
.start(1, 0, 1)
|
||||
.size(15, 10, 14)
|
||||
.endCuboid()
|
||||
.build();
|
||||
}
|
||||
return switch (chestType) {
|
||||
case LEFT -> ModelPart.builder("chest_base_left", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 19)
|
||||
.start(0, 0, 1)
|
||||
.size(15, 10, 14)
|
||||
.endCuboid()
|
||||
.build();
|
||||
case RIGHT -> ModelPart.builder("chest_base_right", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 19)
|
||||
.start(1, 0, 1)
|
||||
.size(15, 10, 14)
|
||||
.endCuboid()
|
||||
.build();
|
||||
default -> ModelPart.builder("chest_base", 64, 64)
|
||||
.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() {
|
||||
|
||||
switch (chestType) {
|
||||
case LEFT:
|
||||
return ModelPart.builder("chest_lid_left", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 0)
|
||||
.start(0, 0, 1)
|
||||
.size(15, 5, 14)
|
||||
.endCuboid()
|
||||
.cuboid()
|
||||
.start(0, -2, 15)
|
||||
.size(1, 4, 1)
|
||||
.endCuboid()
|
||||
.build();
|
||||
case RIGHT:
|
||||
return ModelPart.builder("chest_lid_right", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 0)
|
||||
.start(1, 0, 1)
|
||||
.size(15, 5, 14)
|
||||
.endCuboid()
|
||||
.cuboid()
|
||||
.start(15, -2, 15)
|
||||
.size(1, 4, 1)
|
||||
.endCuboid()
|
||||
.build();
|
||||
}
|
||||
return switch (chestType) {
|
||||
case LEFT -> ModelPart.builder("chest_lid_left", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 0)
|
||||
.start(0, 0, 1)
|
||||
.size(15, 5, 14)
|
||||
.endCuboid()
|
||||
.cuboid()
|
||||
.start(0, -2, 15)
|
||||
.size(1, 4, 1)
|
||||
.endCuboid()
|
||||
.build();
|
||||
case RIGHT -> ModelPart.builder("chest_lid_right", 64, 64)
|
||||
.sprite(renderMaterial.sprite())
|
||||
.cuboid()
|
||||
.textureOffset(0, 0)
|
||||
.start(1, 0, 1)
|
||||
.size(15, 5, 14)
|
||||
.endCuboid()
|
||||
.cuboid()
|
||||
.start(15, -2, 15)
|
||||
.size(1, 4, 1)
|
||||
.endCuboid()
|
||||
.build();
|
||||
default -> 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();
|
||||
};
|
||||
|
||||
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() {
|
||||
|
|
Loading…
Reference in a new issue