<div dir="ltr">For context, without this, the library handle from dlopen never get's closed, even under successful operation, and the swr_screen created never get's freed on error.  Also error conditions resulted in exit() rather than NULL return. <br><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div>- Chuck<br></div></div></div></div></div></div></div>
<br><div class="gmail_quote">On Mon, Jan 22, 2018 at 10:12 AM, Chuck Atkins <span dir="ltr"><<a href="mailto:chuck.atkins@kitware.com" target="_blank">chuck.atkins@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Signed-off-by: Chuck Atkins <<a href="mailto:chuck.atkins@kitware.com">chuck.atkins@kitware.com</a>><br>
---<br>
 src/gallium/drivers/swr/swr_<wbr>loader.cpp | 100 +++++++++++++++++-------------<wbr>---<br>
 src/gallium/drivers/swr/swr_<wbr>public.h   |   6 +-<br>
 src/gallium/drivers/swr/swr_<wbr>screen.cpp |  26 +++++++--<br>
 src/gallium/drivers/swr/swr_<wbr>screen.h   |   3 +<br>
 4 files changed, 79 insertions(+), 56 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/swr/swr_<wbr>loader.cpp b/src/gallium/drivers/swr/swr_<wbr>loader.cpp<br>
</span>index 7f28bdb536..01b9804646 100644<br>
<span class="">--- a/src/gallium/drivers/swr/swr_<wbr>loader.cpp<br>
+++ b/src/gallium/drivers/swr/swr_<wbr>loader.cpp<br>
@@ -29,96 +29,98 @@<br>
 #include <stdio.h><br>
<br>
 // Helper function to resolve the backend filename based on architecture<br>
-inline void get_swr_arch_filename(const char arch[], char filename[])<br>
+static bool<br>
+swr_initialize_screen_<wbr>interface(struct swr_screen *screen, const char arch[])<br>
 {<br>
 #ifdef HAVE_SWR_BUILTIN<br>
-   strcpy(filename , "builtin");<br>
+   screen->pLibrary = NULL;<br>
+   screen->pfnSwrGetInterface = SwrGetInterface;<br>
+   fprintf(stderr, "(using: builtin).\n");<br>
 #else<br>
+   char filename[256] = { 0 };<br>
    sprintf(filename, "%sswr%s%s", UTIL_DL_PREFIX, arch, UTIL_DL_EXT);<br>
+<br>
+   screen->pLibrary = util_dl_open(filename);<br>
+   if (!screen->pLibrary) {<br>
</span>+      fprintf(stderr, "(skipping: %s).\n", util_dl_error());<br>
<span class="">+      return false;<br>
+   }<br>
+<br>
+   util_dl_proc pApiProc = util_dl_get_proc_address(<wbr>screen->pLibrary,<br>
+      "SwrGetInterface");<br>
+   if (!pApiProc) {<br>
</span>+      fprintf(stderr, "(skipping: %s).\n", util_dl_error());<br>
<div class="HOEnZb"><div class="h5">+      util_dl_close(screen-><wbr>pLibrary);<br>
+      screen->pLibrary = NULL;<br>
+      return false;<br>
+   }<br>
+<br>
+   screen->pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;<br>
+   fprintf(stderr, "(using: %s).\n", filename);<br>
 #endif<br>
+   return true;<br>
 }<br>
<br>
+<br>
 struct pipe_screen *<br>
 swr_create_screen(struct sw_winsys *winsys)<br>
 {<br>
-   char filename[256] = { 0 };<br>
-   bool found = false;<br>
-   bool is_knl = false;<br>
-   PFNSwrGetInterface pfnSwrGetInterface = nullptr;<br>
+   struct pipe_screen *p_screen = swr_create_screen_internal(<wbr>winsys);<br>
+   if (!p_screen) {<br>
+      return NULL;<br>
+   }<br>
+<br>
+   struct swr_screen *screen = swr_screen(p_screen);<br>
+   screen->is_knl = false;<br>
<br>
    util_cpu_detect();<br>
<br>
-   if (!found && util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512er) {<br>
+   if (util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512er) {<br>
       fprintf(stderr, "SWR detected KNL instruction support ");<br>
 #ifndef HAVE_SWR_KNL<br>
-      fprintf(stderr, "(skipping not built).\n");<br>
+      fprintf(stderr, "(skipping: not built).\n");<br>
 #else<br>
-      get_swr_arch_filename("KNL", filename);<br>
-      found = true;<br>
-      is_knl = true;<br>
+      if (swr_initialize_screen_<wbr>interface(screen, "KNL")) {<br>
+         screen->is_knl = true;<br>
+         return p_screen;<br>
+      }<br>
 #endif<br>
    }<br>
<br>
-   if (!found && util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512bw) {<br>
+   if (util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512bw) {<br>
       fprintf(stderr, "SWR detected SKX instruction support ");<br>
 #ifndef HAVE_SWR_SKX<br>
       fprintf(stderr, "(skipping not built).\n");<br>
 #else<br>
-      get_swr_arch_filename("SKX", filename);<br>
-      found = true;<br>
+      if (swr_initialize_screen_<wbr>interface(screen, "SKX"))<br>
+         return p_screen;<br>
 #endif<br>
    }<br>
<br>
-   if (!found && util_cpu_caps.has_avx2) {<br>
+   if (util_cpu_caps.has_avx2) {<br>
       fprintf(stderr, "SWR detected AVX2 instruction support ");<br>
 #ifndef HAVE_SWR_AVX2<br>
       fprintf(stderr, "(skipping not built).\n");<br>
 #else<br>
-      get_swr_arch_filename("AVX2", filename);<br>
-      found = true;<br>
+      if (swr_initialize_screen_<wbr>interface(screen, "AVX2"))<br>
+         return p_screen;<br>
 #endif<br>
    }<br>
<br>
-   if (!found && util_cpu_caps.has_avx) {<br>
+   if (util_cpu_caps.has_avx) {<br>
       fprintf(stderr, "SWR detected AVX instruction support ");<br>
 #ifndef HAVE_SWR_AVX<br>
       fprintf(stderr, "(skipping not built).\n");<br>
 #else<br>
-      get_swr_arch_filename("AVX", filename);<br>
-      found = true;<br>
+      if (swr_initialize_screen_<wbr>interface(screen, "AVX"))<br>
+         return p_screen;<br>
 #endif<br>
    }<br>
<br>
-   if (!found) {<br>
-      fprintf(stderr, "SWR could not detect a supported CPU architecture.\n");<br>
-      exit(-1);<br>
-   }<br>
-<br>
-   fprintf(stderr, "(using %s).\n", filename);<br>
-<br>
-#ifdef HAVE_SWR_BUILTIN<br>
-   pfnSwrGetInterface = SwrGetInterface;<br>
-#else<br>
-   util_dl_library *pLibrary = util_dl_open(filename);<br>
-   if (!pLibrary) {<br>
-      fprintf(stderr, "SWR library load failure: %s\n", util_dl_error());<br>
-      exit(-1);<br>
-   }<br>
-<br>
-   util_dl_proc pApiProc = util_dl_get_proc_address(<wbr>pLibrary, "SwrGetInterface");<br>
-   if (!pApiProc) {<br>
-      fprintf(stderr, "SWR library search failure: %s\n", util_dl_error());<br>
-      exit(-1);<br>
-   }<br>
-<br>
-   pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;<br>
-#endif<br>
-<br>
-   struct pipe_screen *screen = swr_create_screen_internal(<wbr>winsys);<br>
-   swr_screen(screen)->is_knl = is_knl;<br>
-   swr_screen(screen)-><wbr>pfnSwrGetInterface = pfnSwrGetInterface;<br>
+   fprintf(stderr, "SWR could not initialize a supported CPU architecture.\n");<br>
+   swr_destroy_screen_internal(&<wbr>screen);<br>
<br>
-   return screen;<br>
+   return NULL;<br>
 }<br>
<br>
<br>
diff --git a/src/gallium/drivers/swr/swr_<wbr>public.h b/src/gallium/drivers/swr/swr_<wbr>public.h<br>
index 4b150705cd..4351b3aae0 100644<br>
--- a/src/gallium/drivers/swr/swr_<wbr>public.h<br>
+++ b/src/gallium/drivers/swr/swr_<wbr>public.h<br>
@@ -25,8 +25,9 @@<br>
 #define SWR_PUBLIC_H<br>
<br>
 struct pipe_screen;<br>
-struct sw_winsys;<br>
 struct sw_displaytarget;<br>
+struct sw_winsys;<br>
+struct swr_screen;<br>
<br>
 #ifdef __cplusplus<br>
 extern "C" {<br>
@@ -38,6 +39,9 @@ struct pipe_screen *swr_create_screen(struct sw_winsys *winsys);<br>
 // arch-specific dll entry point<br>
 PUBLIC struct pipe_screen *swr_create_screen_internal(<wbr>struct sw_winsys *winsys);<br>
<br>
+// cleanup for failed screen creation<br>
+PUBLIC void swr_destroy_screen_internal(<wbr>struct swr_screen **screen);<br>
+<br>
 #ifdef _WIN32<br>
 void swr_gdi_swap(struct pipe_screen *screen,<br>
                   struct pipe_resource *res,<br>
diff --git a/src/gallium/drivers/swr/swr_<wbr>screen.cpp b/src/gallium/drivers/swr/swr_<wbr>screen.cpp<br>
index b67ac25ac8..cbb2b844a9 100644<br>
--- a/src/gallium/drivers/swr/swr_<wbr>screen.cpp<br>
+++ b/src/gallium/drivers/swr/swr_<wbr>screen.cpp<br>
@@ -1052,6 +1052,24 @@ swr_flush_frontbuffer(struct pipe_screen *p_screen,<br>
 }<br>
<br>
<br>
+PUBLIC void<br>
+swr_destroy_screen_internal(<wbr>struct swr_screen **screen)<br>
+{<br>
+   struct pipe_screen *p_screen = &(*screen)->base;<br>
+<br>
+   swr_fence_finish(p_screen, NULL, (*screen)->flush_fence, 0);<br>
+   swr_fence_reference(p_screen, &(*screen)->flush_fence, NULL);<br>
+<br>
+   JitDestroyContext((*screen)-><wbr>hJitMgr);<br>
+<br>
+   if ((*screen)->pLibrary)<br>
+      util_dl_close((*screen)-><wbr>pLibrary);<br>
+<br>
+   FREE(*screen);<br>
+   *screen = NULL;<br>
+}<br>
+<br>
+<br>
 static void<br>
 swr_destroy_screen(struct pipe_screen *p_screen)<br>
 {<br>
@@ -1060,15 +1078,10 @@ swr_destroy_screen(struct pipe_screen *p_screen)<br>
<br>
    fprintf(stderr, "SWR destroy screen!\n");<br>
<br>
-   swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);<br>
-   swr_fence_reference(p_screen, &screen->flush_fence, NULL);<br>
-<br>
-   JitDestroyContext(screen-><wbr>hJitMgr);<br>
-<br>
    if (winsys->destroy)<br>
       winsys->destroy(winsys);<br>
<br>
-   FREE(screen);<br>
+   swr_destroy_screen_internal(&<wbr>screen);<br>
 }<br>
<br>
<br>
@@ -1119,6 +1132,7 @@ struct pipe_screen *<br>
 swr_create_screen_internal(<wbr>struct sw_winsys *winsys)<br>
 {<br>
    struct swr_screen *screen = CALLOC_STRUCT(swr_screen);<br>
+   memset(screen, 0, sizeof(struct swr_screen));<br>
<br>
    if (!screen)<br>
       return NULL;<br>
diff --git a/src/gallium/drivers/swr/swr_<wbr>screen.h b/src/gallium/drivers/swr/swr_<wbr>screen.h<br>
index 89faab182c..b80d8c70ec 100644<br>
--- a/src/gallium/drivers/swr/swr_<wbr>screen.h<br>
+++ b/src/gallium/drivers/swr/swr_<wbr>screen.h<br>
@@ -28,6 +28,7 @@<br>
<br>
 #include "pipe/p_screen.h"<br>
 #include "pipe/p_defines.h"<br>
+#include "util/u_dl.h"<br>
 #include "util/u_format.h"<br>
 #include "api.h"<br>
<br>
@@ -50,6 +51,8 @@ struct swr_screen {<br>
<br>
    HANDLE hJitMgr;<br>
<br>
+   /* Dynamic backend implementations */<br>
+   util_dl_library *pLibrary;<br>
    PFNSwrGetInterface pfnSwrGetInterface;<br>
<br>
    /* Do we run on Xeon Phi? */<br>
--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>