summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChuck Atkins <[email protected]>2018-01-18 14:57:58 -0500
committerGeorge Kyriazis <[email protected]>2018-01-19 13:16:00 -0600
commita4be2bcee2f344b864ed133ddde3dac7a266cab8 (patch)
tree8306d375dabc4b1e55511734b20da19eba6fb823 /src
parent2ed8b6f82704081a8992b3c30995ac8873b0c711 (diff)
swr: allow a single swr architecture to be builtin
Part 2 of 2 (part 1 is autoconf changes, part 2 is C++ changes) When only a single SWR architecture is being used, this allows that architecture to be builtin rather than as a separate libswrARCH.so that gets loaded via dlopen. Since there are now several different code paths for each detected CPU architecture, the log output is also adjusted to convey where the backend is getting loaded from. This allows SWR to be used for static mesa builds which are still important for large HPC environments where shared libraries can impose unacceptable application startup times as hundreds of thousands of copies of the libs are loaded from a shared parallel filesystem. Based on an initial implementation by Tim Rowley. v2: Refactor repetitive preprocessor checks to reduce code duplication v3: Formatting changes per Bruce C. Also delay screen creation until end to avoid leaks when failure conditions are hit. Signed-off-by: Chuck Atkins <[email protected]> Reviewed-by: Bruce Cherniak <[email protected]> CC: Tim Rowley <[email protected]> Reviewed-by: Bruce Cherniak <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/swr/swr_loader.cpp84
1 files changed, 49 insertions, 35 deletions
diff --git a/src/gallium/drivers/swr/swr_loader.cpp b/src/gallium/drivers/swr/swr_loader.cpp
index 9d6f918e349..7f28bdb5366 100644
--- a/src/gallium/drivers/swr/swr_loader.cpp
+++ b/src/gallium/drivers/swr/swr_loader.cpp
@@ -28,81 +28,95 @@
#include <stdio.h>
+// Helper function to resolve the backend filename based on architecture
+inline void get_swr_arch_filename(const char arch[], char filename[])
+{
+#ifdef HAVE_SWR_BUILTIN
+ strcpy(filename , "builtin");
+#else
+ sprintf(filename, "%sswr%s%s", UTIL_DL_PREFIX, arch, UTIL_DL_EXT);
+#endif
+}
+
struct pipe_screen *
swr_create_screen(struct sw_winsys *winsys)
{
char filename[256] = { 0 };
- fprintf(stderr, "SWR detected ");
-
- util_dl_library *pLibrary = nullptr;
+ bool found = false;
+ bool is_knl = false;
+ PFNSwrGetInterface pfnSwrGetInterface = nullptr;
util_cpu_detect();
- bool is_knl = false;
-
- if (!strlen(filename) &&
- util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512er) {
-#if HAVE_SWR_KNL
- fprintf(stderr, "KNL ");
- sprintf(filename, "%s%s%s", UTIL_DL_PREFIX, "swrKNL", UTIL_DL_EXT);
- is_knl = true;
+ if (!found && util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512er) {
+ fprintf(stderr, "SWR detected KNL instruction support ");
+#ifndef HAVE_SWR_KNL
+ fprintf(stderr, "(skipping not built).\n");
#else
- fprintf(stderr, "KNL (not built) ");
+ get_swr_arch_filename("KNL", filename);
+ found = true;
+ is_knl = true;
#endif
}
- if (!strlen(filename) &&
- util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512bw) {
-#if HAVE_SWR_SKX
- fprintf(stderr, "SKX ");
- sprintf(filename, "%s%s%s", UTIL_DL_PREFIX, "swrSKX", UTIL_DL_EXT);
+ if (!found && util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512bw) {
+ fprintf(stderr, "SWR detected SKX instruction support ");
+#ifndef HAVE_SWR_SKX
+ fprintf(stderr, "(skipping not built).\n");
#else
- fprintf(stderr, "SKX (not built) ");
+ get_swr_arch_filename("SKX", filename);
+ found = true;
#endif
}
- if (!strlen(filename) && util_cpu_caps.has_avx2) {
-#if HAVE_SWR_AVX2
- fprintf(stderr, "AVX2 ");
- sprintf(filename, "%s%s%s", UTIL_DL_PREFIX, "swrAVX2", UTIL_DL_EXT);
+ if (!found && util_cpu_caps.has_avx2) {
+ fprintf(stderr, "SWR detected AVX2 instruction support ");
+#ifndef HAVE_SWR_AVX2
+ fprintf(stderr, "(skipping not built).\n");
#else
- fprintf(stderr, "AVX2 (not built) ");
+ get_swr_arch_filename("AVX2", filename);
+ found = true;
#endif
}
- if (!strlen(filename) && util_cpu_caps.has_avx) {
-#if HAVE_SWR_AVX
- fprintf(stderr, "AVX ");
- sprintf(filename, "%s%s%s", UTIL_DL_PREFIX, "swrAVX", UTIL_DL_EXT);
+ if (!found && util_cpu_caps.has_avx) {
+ fprintf(stderr, "SWR detected AVX instruction support ");
+#ifndef HAVE_SWR_AVX
+ fprintf(stderr, "(skipping not built).\n");
#else
- fprintf(stderr, "AVX (not built) ");
+ get_swr_arch_filename("AVX", filename);
+ found = true;
#endif
}
- if (!strlen(filename)) {
- fprintf(stderr, "- no appropriate swr architecture library. Aborting!\n");
+ if (!found) {
+ fprintf(stderr, "SWR could not detect a supported CPU architecture.\n");
exit(-1);
- } else {
- fprintf(stderr, "\n");
}
- pLibrary = util_dl_open(filename);
+ fprintf(stderr, "(using %s).\n", filename);
+#ifdef HAVE_SWR_BUILTIN
+ pfnSwrGetInterface = SwrGetInterface;
+#else
+ util_dl_library *pLibrary = util_dl_open(filename);
if (!pLibrary) {
fprintf(stderr, "SWR library load failure: %s\n", util_dl_error());
exit(-1);
}
util_dl_proc pApiProc = util_dl_get_proc_address(pLibrary, "SwrGetInterface");
-
if (!pApiProc) {
fprintf(stderr, "SWR library search failure: %s\n", util_dl_error());
exit(-1);
}
+ pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;
+#endif
+
struct pipe_screen *screen = swr_create_screen_internal(winsys);
- swr_screen(screen)->pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;
swr_screen(screen)->is_knl = is_knl;
+ swr_screen(screen)->pfnSwrGetInterface = pfnSwrGetInterface;
return screen;
}