1b8e80941Smrg/****************************************************************************
2b8e80941Smrg * Copyright (C) 2016 Intel Corporation.   All Rights Reserved.
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg ***************************************************************************/
23b8e80941Smrg
24b8e80941Smrg#include "memory/InitMemory.h"
25b8e80941Smrg#include "util/u_cpu_detect.h"
26b8e80941Smrg#include "util/u_dl.h"
27b8e80941Smrg#include "swr_public.h"
28b8e80941Smrg#include "swr_screen.h"
29b8e80941Smrg
30b8e80941Smrg#include <stdio.h>
31b8e80941Smrg
32b8e80941Smrg// Helper function to resolve the backend filename based on architecture
33b8e80941Smrgstatic bool
34b8e80941Smrgswr_initialize_screen_interface(struct swr_screen *screen, const char arch[])
35b8e80941Smrg{
36b8e80941Smrg#ifdef HAVE_SWR_BUILTIN
37b8e80941Smrg   screen->pLibrary = NULL;
38b8e80941Smrg   screen->pfnSwrGetInterface = SwrGetInterface;
39b8e80941Smrg   InitTilesTable();
40b8e80941Smrg   fprintf(stderr, "(using: builtin).\n");
41b8e80941Smrg#else
42b8e80941Smrg   char filename[256] = { 0 };
43b8e80941Smrg   sprintf(filename, "%sswr%s%s", UTIL_DL_PREFIX, arch, UTIL_DL_EXT);
44b8e80941Smrg
45b8e80941Smrg   screen->pLibrary = util_dl_open(filename);
46b8e80941Smrg   if (!screen->pLibrary) {
47b8e80941Smrg      fprintf(stderr, "(skipping: %s).\n", util_dl_error());
48b8e80941Smrg      return false;
49b8e80941Smrg   }
50b8e80941Smrg
51b8e80941Smrg   util_dl_proc pApiProc = util_dl_get_proc_address(screen->pLibrary,
52b8e80941Smrg      "SwrGetInterface");
53b8e80941Smrg   util_dl_proc pInitFunc = util_dl_get_proc_address(screen->pLibrary,
54b8e80941Smrg      "InitTilesTable");
55b8e80941Smrg   if (!pApiProc || !pInitFunc) {
56b8e80941Smrg      fprintf(stderr, "(skipping: %s).\n", util_dl_error());
57b8e80941Smrg      util_dl_close(screen->pLibrary);
58b8e80941Smrg      screen->pLibrary = NULL;
59b8e80941Smrg      return false;
60b8e80941Smrg   }
61b8e80941Smrg
62b8e80941Smrg   screen->pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;
63b8e80941Smrg   pInitFunc();
64b8e80941Smrg
65b8e80941Smrg   fprintf(stderr, "(using: %s).\n", filename);
66b8e80941Smrg#endif
67b8e80941Smrg   return true;
68b8e80941Smrg}
69b8e80941Smrg
70b8e80941Smrg
71b8e80941Smrgstruct pipe_screen *
72b8e80941Smrgswr_create_screen(struct sw_winsys *winsys)
73b8e80941Smrg{
74b8e80941Smrg   struct pipe_screen *p_screen = swr_create_screen_internal(winsys);
75b8e80941Smrg   if (!p_screen) {
76b8e80941Smrg      return NULL;
77b8e80941Smrg   }
78b8e80941Smrg
79b8e80941Smrg   struct swr_screen *screen = swr_screen(p_screen);
80b8e80941Smrg   screen->is_knl = false;
81b8e80941Smrg
82b8e80941Smrg   util_cpu_detect();
83b8e80941Smrg
84b8e80941Smrg   if (util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512er) {
85b8e80941Smrg      fprintf(stderr, "SWR detected KNL instruction support ");
86b8e80941Smrg#ifndef HAVE_SWR_KNL
87b8e80941Smrg      fprintf(stderr, "(skipping: not built).\n");
88b8e80941Smrg#else
89b8e80941Smrg      if (swr_initialize_screen_interface(screen, "KNL")) {
90b8e80941Smrg         screen->is_knl = true;
91b8e80941Smrg         return p_screen;
92b8e80941Smrg      }
93b8e80941Smrg#endif
94b8e80941Smrg   }
95b8e80941Smrg
96b8e80941Smrg   if (util_cpu_caps.has_avx512f && util_cpu_caps.has_avx512bw) {
97b8e80941Smrg      fprintf(stderr, "SWR detected SKX instruction support ");
98b8e80941Smrg#ifndef HAVE_SWR_SKX
99b8e80941Smrg      fprintf(stderr, "(skipping not built).\n");
100b8e80941Smrg#else
101b8e80941Smrg      if (swr_initialize_screen_interface(screen, "SKX"))
102b8e80941Smrg         return p_screen;
103b8e80941Smrg#endif
104b8e80941Smrg   }
105b8e80941Smrg
106b8e80941Smrg   if (util_cpu_caps.has_avx2) {
107b8e80941Smrg      fprintf(stderr, "SWR detected AVX2 instruction support ");
108b8e80941Smrg#ifndef HAVE_SWR_AVX2
109b8e80941Smrg      fprintf(stderr, "(skipping not built).\n");
110b8e80941Smrg#else
111b8e80941Smrg      if (swr_initialize_screen_interface(screen, "AVX2"))
112b8e80941Smrg         return p_screen;
113b8e80941Smrg#endif
114b8e80941Smrg   }
115b8e80941Smrg
116b8e80941Smrg   if (util_cpu_caps.has_avx) {
117b8e80941Smrg      fprintf(stderr, "SWR detected AVX instruction support ");
118b8e80941Smrg#ifndef HAVE_SWR_AVX
119b8e80941Smrg      fprintf(stderr, "(skipping not built).\n");
120b8e80941Smrg#else
121b8e80941Smrg      if (swr_initialize_screen_interface(screen, "AVX"))
122b8e80941Smrg         return p_screen;
123b8e80941Smrg#endif
124b8e80941Smrg   }
125b8e80941Smrg
126b8e80941Smrg   fprintf(stderr, "SWR could not initialize a supported CPU architecture.\n");
127b8e80941Smrg   swr_destroy_screen_internal(&screen);
128b8e80941Smrg
129b8e80941Smrg   return NULL;
130b8e80941Smrg}
131b8e80941Smrg
132b8e80941Smrg
133b8e80941Smrg#ifdef _WIN32
134b8e80941Smrg// swap function called from libl_gdi.c
135b8e80941Smrg
136b8e80941Smrgvoid
137b8e80941Smrgswr_gdi_swap(struct pipe_screen *screen,
138b8e80941Smrg             struct pipe_resource *res,
139b8e80941Smrg             void *hDC)
140b8e80941Smrg{
141b8e80941Smrg   screen->flush_frontbuffer(screen,
142b8e80941Smrg                             res,
143b8e80941Smrg                             0, 0,
144b8e80941Smrg                             hDC,
145b8e80941Smrg                             NULL);
146b8e80941Smrg}
147b8e80941Smrg
148b8e80941Smrg#endif /* _WIN32 */
149