Make GPU rendering toggleable to prevent crashes due to bad initialisation

pull/94/head v1.26.4
James Ball 2022-06-28 20:26:32 +01:00 zatwierdzone przez James H Ball
rodzic 6271507113
commit a7e8c2d9d5
11 zmienionych plików z 72 dodań i 27 usunięć

Wyświetl plik

@ -1,3 +1,7 @@
- 1.26.4
- Make GPU rendering toggleable to prevent crashes due to bad initialisation
- 1.26.3 - 1.26.3
- Fix potential bug with updating frequency spinner and slider from not-GUI thread - Fix potential bug with updating frequency spinner and slider from not-GUI thread

Wyświetl plik

@ -6,7 +6,7 @@
<groupId>sh.ball</groupId> <groupId>sh.ball</groupId>
<artifactId>osci-render</artifactId> <artifactId>osci-render</artifactId>
<version>1.26.3</version> <version>1.26.4</version>
<name>osci-render</name> <name>osci-render</name>

Wyświetl plik

@ -24,6 +24,8 @@ public class Camera {
private double focalLength; private double focalLength;
private Vector3 pos; private Vector3 pos;
private boolean hideEdges = false;
private boolean usingGpu = false;
public Camera(double focalLength, Vector3 pos) { public Camera(double focalLength, Vector3 pos) {
this.focalLength = focalLength; this.focalLength = focalLength;
@ -105,4 +107,20 @@ public class Camera {
public double getFocalLength() { public double getFocalLength() {
return focalLength; return focalLength;
} }
public void hideEdges(boolean hideEdges) {
this.hideEdges = hideEdges;
}
public boolean edgesHidden() {
return hideEdges;
}
public void usingGpu(boolean usingGpu) {
this.usingGpu = usingGpu;
}
public boolean isUsingGpu() {
return usingGpu;
}
} }

Wyświetl plik

@ -36,7 +36,9 @@ public class CameraDrawKernel extends Kernel {
private float focalLength; private float focalLength;
private int hideEdges = 0; private int hideEdges = 0;
private int usingObjectSet = 0; private int usingObjectSet = 0;
private boolean initialisedGpu = false;
private boolean failedGpu = false; private boolean failedGpu = false;
private int maxGroupSize = 256;
public CameraDrawKernel() {} public CameraDrawKernel() {}
@ -131,9 +133,13 @@ public class CameraDrawKernel extends Kernel {
this.cameraPosZ = (float) cameraPos.z; this.cameraPosZ = (float) cameraPos.z;
this.focalLength = (float) camera.getFocalLength(); this.focalLength = (float) camera.getFocalLength();
this.hideEdges = object.edgesHidden() ? 1 : 0; this.hideEdges = camera.edgesHidden() ? 1 : 0;
return executeGpu(); if (!camera.isUsingGpu() || failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) {
return executeCpu();
} else {
return executeGpu();
}
} }
private List<Shape> postProcessVertices() { private List<Shape> postProcessVertices() {
@ -164,16 +170,14 @@ public class CameraDrawKernel extends Kernel {
} }
private List<Shape> executeGpu() { private List<Shape> executeGpu() {
if (failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) {
return executeCpu();
}
try { try {
int maxGroupSize = 256; if (!initialisedGpu) {
try { try {
maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice()); maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice());
} catch (QueryFailedException e) { initialisedGpu = true;
logger.log(Level.WARNING, e.getMessage(), e); } catch (QueryFailedException e) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} }
execute(Range.create(roundUp(vertices.length / 3, maxGroupSize), maxGroupSize)); execute(Range.create(roundUp(vertices.length / 3, maxGroupSize), maxGroupSize));

Wyświetl plik

@ -26,7 +26,6 @@ public class WorldObject {
private List<List<Vector3>> vertexPath; private List<List<Vector3>> vertexPath;
private Vector3 position; private Vector3 position;
private Vector3 rotation; private Vector3 rotation;
private boolean hideEdges = false;
public WorldObject(Vector3[] vertices, int[] edgeIndices, int[][] faceIndices) { public WorldObject(Vector3[] vertices, int[] edgeIndices, int[][] faceIndices) {
vertexPath = new ArrayList<>(); vertexPath = new ArrayList<>();
@ -319,12 +318,4 @@ public class WorldObject {
return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position, return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position,
rotation); rotation);
} }
public void hideEdges(boolean hideEdges) {
this.hideEdges = hideEdges;
}
public boolean edgesHidden() {
return hideEdges;
}
} }

Wyświetl plik

@ -148,6 +148,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
@FXML @FXML
private CheckMenuItem hideHiddenMeshesCheckMenuItem; private CheckMenuItem hideHiddenMeshesCheckMenuItem;
@FXML @FXML
private CheckMenuItem renderUsingGpuCheckMenuItem;
@FXML
private Spinner<Integer> midiChannelSpinner; private Spinner<Integer> midiChannelSpinner;
@FXML @FXML
private Spinner<Double> attackSpinner; private Spinner<Double> attackSpinner;
@ -408,6 +410,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden)); hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden));
renderUsingGpuCheckMenuItem.selectedProperty().addListener((e, old, usingGpu) -> objController.renderUsingGpu(usingGpu));
NumberFormat format = NumberFormat.getIntegerInstance(); NumberFormat format = NumberFormat.getIntegerInstance();
UnaryOperator<TextFormatter.Change> filter = c -> { UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.isContentChange()) { if (c.isContentChange()) {
@ -691,6 +695,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
} }
// FIXME: Is this safe since we are accessing GUI object in non-GUI thread? // FIXME: Is this safe since we are accessing GUI object in non-GUI thread?
objController.hideHiddenMeshes(hideHiddenMeshesCheckMenuItem.isSelected()); objController.hideHiddenMeshes(hideHiddenMeshesCheckMenuItem.isSelected());
objController.renderUsingGpu(renderUsingGpuCheckMenuItem.isSelected());
executor.submit(producer); executor.submit(producer);
} else if (samples != null) { } else if (samples != null) {
samples.enable(); samples.enable();
@ -1141,6 +1146,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected()))); hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected())));
root.appendChild(hiddenEdges); root.appendChild(hiddenEdges);
Element usingGpu = document.createElement("usingGpu");
usingGpu.appendChild(document.createTextNode(String.valueOf(renderUsingGpuCheckMenuItem.isSelected())));
root.appendChild(usingGpu);
Element translationIncrement = document.createElement("translationIncrement"); Element translationIncrement = document.createElement("translationIncrement");
translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString())); translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString()));
root.appendChild(translationIncrement); root.appendChild(translationIncrement);
@ -1263,6 +1272,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent())); hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent()));
} }
Element usingGpu = (Element) root.getElementsByTagName("usingGpu").item(0);
if (usingGpu != null) {
renderUsingGpuCheckMenuItem.setSelected(Boolean.parseBoolean(usingGpu.getTextContent()));
}
Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0); Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0);
if (translationIncrement != null) { if (translationIncrement != null) {
translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent())); translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent()));

Wyświetl plik

@ -182,4 +182,8 @@ public class ObjController implements Initializable, SubController {
@Override @Override
public void load(Element root) {} public void load(Element root) {}
public void renderUsingGpu(boolean usingGpu) {
producer.setFrameSettings(ObjSettingsFactory.renderUsingGpu(usingGpu));
}
} }

Wyświetl plik

@ -11,8 +11,9 @@ public class ObjFrameSettings {
public Double rotateSpeed; public Double rotateSpeed;
public boolean resetRotation = false; public boolean resetRotation = false;
public Boolean hideEdges = null; public Boolean hideEdges = null;
public Boolean usingGpu = null;
protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges) { protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges, Boolean usingGpu) {
this.focalLength = focalLength; this.focalLength = focalLength;
this.cameraPos = cameraPos; this.cameraPos = cameraPos;
this.baseRotation = baseRotation; this.baseRotation = baseRotation;
@ -20,6 +21,7 @@ public class ObjFrameSettings {
this.rotateSpeed = rotateSpeed; this.rotateSpeed = rotateSpeed;
this.resetRotation = resetRotation; this.resetRotation = resetRotation;
this.hideEdges = hideEdges; this.hideEdges = hideEdges;
this.usingGpu = usingGpu;
} }
protected ObjFrameSettings(double focalLength) { protected ObjFrameSettings(double focalLength) {

Wyświetl plik

@ -68,7 +68,10 @@ public class ObjFrameSource implements FrameSource<List<Shape>> {
object.resetRotation(); object.resetRotation();
} }
if (obj.hideEdges != null) { if (obj.hideEdges != null) {
object.hideEdges(obj.hideEdges); camera.hideEdges(obj.hideEdges);
}
if (obj.usingGpu != null) {
camera.usingGpu(obj.usingGpu);
} }
} }
} }
@ -76,6 +79,6 @@ public class ObjFrameSource implements FrameSource<List<Shape>> {
// TODO: Refactor! // TODO: Refactor!
@Override @Override
public Object getFrameSettings() { public Object getFrameSettings() {
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, object.edgesHidden()); return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, camera.edgesHidden(), camera.isUsingGpu());
} }
} }

Wyświetl plik

@ -17,7 +17,7 @@ public class ObjSettingsFactory {
} }
public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) { public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) {
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null); return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null, null);
} }
public static ObjFrameSettings rotateSpeed(double rotateSpeed) { public static ObjFrameSettings rotateSpeed(double rotateSpeed) {
@ -29,6 +29,10 @@ public class ObjSettingsFactory {
} }
public static ObjFrameSettings hideEdges(Boolean hideEdges) { public static ObjFrameSettings hideEdges(Boolean hideEdges) {
return new ObjFrameSettings(null, null, null, null, null, false, hideEdges); return new ObjFrameSettings(null, null, null, null, null, false, hideEdges, null);
}
public static ObjFrameSettings renderUsingGpu(Boolean usingGpu) {
return new ObjFrameSettings(null, null, null, null, null, false, null, usingGpu);
} }
} }

Wyświetl plik

@ -21,7 +21,7 @@
<menus> <menus>
<Menu mnemonicParsing="false" text="File"> <Menu mnemonicParsing="false" text="File">
<items> <items>
<MenuItem disable="true" mnemonicParsing="false" text="osci-render v1.26.3" /> <MenuItem disable="true" mnemonicParsing="false" text="osci-render v1.26.4" />
<MenuItem fx:id="openProjectMenuItem" mnemonicParsing="false" text="Open Project"> <MenuItem fx:id="openProjectMenuItem" mnemonicParsing="false" text="Open Project">
<accelerator> <accelerator>
<KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" /> <KeyCodeCombination alt="UP" code="O" control="UP" meta="UP" shift="UP" shortcut="DOWN" />
@ -152,6 +152,7 @@
<CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" /> <CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" />
<CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" /> <CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" />
<CheckMenuItem fx:id="hideHiddenMeshesCheckMenuItem" mnemonicParsing="false" text="Hide Hidden Meshes" /> <CheckMenuItem fx:id="hideHiddenMeshesCheckMenuItem" mnemonicParsing="false" text="Hide Hidden Meshes" />
<CheckMenuItem fx:id="renderUsingGpuCheckMenuItem" mnemonicParsing="false" text="Render Using GPU" />
</items> </items>
</Menu> </Menu>
<Menu mnemonicParsing="false" text="Controls"> <Menu mnemonicParsing="false" text="Controls">