Fix: EEVEE renders with CPU instead of GPU in Linux clients (#229)
* Fix: EEVEE renders with CPU instead of GPU in Linux clients In Linux systems, setting the env LD_LIBRARY_PATH var to point the /lib folder included in the sheepit binary compressed .zip, mandates Blender to swap whatever openGL library is already in use by the OS. Modern GPU drivers install their own optimised version of the OpenGL library and replacing it creates incompatibilities that avoid EEVEE to run. To detect if Blender already uses the standard OS provided OpenGL library is via _ldd_ Linux command. The execution in a system with OpenGL libraries already in use delivers an output similar to this: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fefefb9c000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) While a system with no OS OpenGL libraries that requires the shipped default OpenGL lib to work returns this instead: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => not found libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) In the former case, the SheepIt client will set the LD_LIBRARY_PATH env var to point the /lib folder to allow Blender to execute properly.
This commit is contained in:
@@ -18,7 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.sheepit.client.os;
|
package com.sheepit.client.os;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -152,11 +154,13 @@ public class Linux extends OS {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
|
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
|
||||||
// the renderer have a lib directory so add to the LD_LIBRARY_PATH
|
|
||||||
// (even if we are not sure that it is the renderer who is launch
|
|
||||||
|
|
||||||
Map<String, String> new_env = new HashMap<String, String>();
|
Map<String, String> new_env = new HashMap<String, String>();
|
||||||
new_env.putAll(java.lang.System.getenv()); // clone the env
|
new_env.putAll(java.lang.System.getenv()); // clone the env
|
||||||
|
|
||||||
|
// if Blender is already loading an OpenGL library, don't need to load Blender's default one (it will
|
||||||
|
// create system incompatibilities). If no OpenGL library is found, then load the one included in the binary
|
||||||
|
// zip file
|
||||||
|
if (isOpenGLAreadyInstalled(command.get(0)) == false) {
|
||||||
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
|
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
|
||||||
|
|
||||||
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
|
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
|
||||||
@@ -166,6 +170,7 @@ public class Linux extends OS {
|
|||||||
else {
|
else {
|
||||||
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
|
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<String> actual_command = command;
|
List<String> actual_command = command;
|
||||||
if (this.hasNiceBinary == null) {
|
if (this.hasNiceBinary == null) {
|
||||||
@@ -228,4 +233,45 @@ public class Linux extends OS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isOpenGLAreadyInstalled(String pathToRendEXE) {
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.command("bash", "-c", "ldd '" + pathToRendEXE + "'"); // support for paths with an space
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
StringBuilder screenOutput = new StringBuilder();
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
// check the shared libraries that Blender is loading at run time. If it already loads an existing
|
||||||
|
// version of OpenGL (ie the one shipped with NVIDIA drivers) then return false to avoid the client
|
||||||
|
// replacing them (and glitching the EEVEE render). Otherwise return true and load the /lib folder
|
||||||
|
// to ensure that Blender works correctly
|
||||||
|
if (line.toLowerCase().contains("libgl.so")) {
|
||||||
|
return !line.toLowerCase().contains("not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case of error we can later check the screen output from ldd
|
||||||
|
screenOutput.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
int exitCode = process.waitFor();
|
||||||
|
if (exitCode != 0) {
|
||||||
|
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. Exit code %d", exitCode));
|
||||||
|
System.err.println(String.format("Screen output from ldd execution: %s", screenOutput.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. IOException %s", e.getMessage()));
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. InterruptedException %s", e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user