101e04c3fSmrg/****************************************************************************
201e04c3fSmrg * Copyright (C) 2016 Intel Corporation.   All Rights Reserved.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg ***************************************************************************/
2301e04c3fSmrg
2401e04c3fSmrg#include "memory/InitMemory.h"
2501e04c3fSmrg#include "util/u_cpu_detect.h"
2601e04c3fSmrg#include "util/u_dl.h"
2701e04c3fSmrg#include "swr_public.h"
2801e04c3fSmrg#include "swr_screen.h"
2901e04c3fSmrg
3001e04c3fSmrg#include <stdio.h>
3101e04c3fSmrg
3201e04c3fSmrg// Helper function to resolve the backend filename based on architecture
3301e04c3fSmrgstatic bool
3401e04c3fSmrgswr_initialize_screen_interface(struct swr_screen *screen, const char arch[])
3501e04c3fSmrg{
3601e04c3fSmrg#ifdef HAVE_SWR_BUILTIN
3701e04c3fSmrg   screen->pLibrary = NULL;
3801e04c3fSmrg   screen->pfnSwrGetInterface = SwrGetInterface;
397ec681f3Smrg   screen->pfnSwrGetTileInterface = SwrGetTileIterface;
4001e04c3fSmrg   InitTilesTable();
417ec681f3Smrg   swr_print_info("(using: builtin).\n");
4201e04c3fSmrg#else
4301e04c3fSmrg   char filename[256] = { 0 };
4401e04c3fSmrg   sprintf(filename, "%sswr%s%s", UTIL_DL_PREFIX, arch, UTIL_DL_EXT);
4501e04c3fSmrg
4601e04c3fSmrg   screen->pLibrary = util_dl_open(filename);
4701e04c3fSmrg   if (!screen->pLibrary) {
4801e04c3fSmrg      fprintf(stderr, "(skipping: %s).\n", util_dl_error());
4901e04c3fSmrg      return false;
5001e04c3fSmrg   }
5101e04c3fSmrg
5201e04c3fSmrg   util_dl_proc pApiProc = util_dl_get_proc_address(screen->pLibrary,
5301e04c3fSmrg      "SwrGetInterface");
547ec681f3Smrg   util_dl_proc pTileApiProc = util_dl_get_proc_address(screen->pLibrary,
557ec681f3Smrg      "SwrGetTileIterface");
5601e04c3fSmrg   util_dl_proc pInitFunc = util_dl_get_proc_address(screen->pLibrary,
5701e04c3fSmrg      "InitTilesTable");
587ec681f3Smrg   if (!pApiProc || !pInitFunc || !pTileApiProc) {
5901e04c3fSmrg      fprintf(stderr, "(skipping: %s).\n", util_dl_error());
6001e04c3fSmrg      util_dl_close(screen->pLibrary);
6101e04c3fSmrg      screen->pLibrary = NULL;
6201e04c3fSmrg      return false;
6301e04c3fSmrg   }
6401e04c3fSmrg
6501e04c3fSmrg   screen->pfnSwrGetInterface = (PFNSwrGetInterface)pApiProc;
667ec681f3Smrg   screen->pfnSwrGetTileInterface = (PFNSwrGetTileInterface)pTileApiProc;
677ec681f3Smrg
687ec681f3Smrg   SWR_ASSERT(screen->pfnSwrGetInterface != nullptr);
697ec681f3Smrg   SWR_ASSERT(screen->pfnSwrGetTileInterface != nullptr);
707ec681f3Smrg   SWR_ASSERT(pInitFunc != nullptr);
717ec681f3Smrg
7201e04c3fSmrg   pInitFunc();
7301e04c3fSmrg
747ec681f3Smrg   swr_print_info("(using: %s).\n", filename);
7501e04c3fSmrg#endif
767ec681f3Smrg
7701e04c3fSmrg   return true;
7801e04c3fSmrg}
7901e04c3fSmrg
8001e04c3fSmrg
8101e04c3fSmrgstruct pipe_screen *
8201e04c3fSmrgswr_create_screen(struct sw_winsys *winsys)
8301e04c3fSmrg{
8401e04c3fSmrg   struct pipe_screen *p_screen = swr_create_screen_internal(winsys);
8501e04c3fSmrg   if (!p_screen) {
8601e04c3fSmrg      return NULL;
8701e04c3fSmrg   }
8801e04c3fSmrg
8901e04c3fSmrg   struct swr_screen *screen = swr_screen(p_screen);
9001e04c3fSmrg   screen->is_knl = false;
9101e04c3fSmrg
9201e04c3fSmrg   util_cpu_detect();
9301e04c3fSmrg
947ec681f3Smrg   if (util_get_cpu_caps()->has_avx512f && util_get_cpu_caps()->has_avx512er) {
957ec681f3Smrg      swr_print_info("SWR detected KNL instruction support ");
9601e04c3fSmrg#ifndef HAVE_SWR_KNL
977ec681f3Smrg      swr_print_info("(skipping: not built).\n");
9801e04c3fSmrg#else
9901e04c3fSmrg      if (swr_initialize_screen_interface(screen, "KNL")) {
10001e04c3fSmrg         screen->is_knl = true;
10101e04c3fSmrg         return p_screen;
10201e04c3fSmrg      }
10301e04c3fSmrg#endif
10401e04c3fSmrg   }
10501e04c3fSmrg
1067ec681f3Smrg   if (util_get_cpu_caps()->has_avx512f && util_get_cpu_caps()->has_avx512bw) {
1077ec681f3Smrg      swr_print_info("SWR detected SKX instruction support ");
10801e04c3fSmrg#ifndef HAVE_SWR_SKX
1097ec681f3Smrg      swr_print_info("(skipping not built).\n");
11001e04c3fSmrg#else
11101e04c3fSmrg      if (swr_initialize_screen_interface(screen, "SKX"))
11201e04c3fSmrg         return p_screen;
11301e04c3fSmrg#endif
11401e04c3fSmrg   }
11501e04c3fSmrg
1167ec681f3Smrg   if (util_get_cpu_caps()->has_avx2) {
1177ec681f3Smrg      swr_print_info("SWR detected AVX2 instruction support ");
11801e04c3fSmrg#ifndef HAVE_SWR_AVX2
1197ec681f3Smrg      swr_print_info("(skipping not built).\n");
12001e04c3fSmrg#else
12101e04c3fSmrg      if (swr_initialize_screen_interface(screen, "AVX2"))
12201e04c3fSmrg         return p_screen;
12301e04c3fSmrg#endif
12401e04c3fSmrg   }
12501e04c3fSmrg
1267ec681f3Smrg   if (util_get_cpu_caps()->has_avx) {
1277ec681f3Smrg      swr_print_info("SWR detected AVX instruction support ");
12801e04c3fSmrg#ifndef HAVE_SWR_AVX
1297ec681f3Smrg      swr_print_info("(skipping not built).\n");
13001e04c3fSmrg#else
13101e04c3fSmrg      if (swr_initialize_screen_interface(screen, "AVX"))
13201e04c3fSmrg         return p_screen;
13301e04c3fSmrg#endif
13401e04c3fSmrg   }
13501e04c3fSmrg
13601e04c3fSmrg   fprintf(stderr, "SWR could not initialize a supported CPU architecture.\n");
13701e04c3fSmrg   swr_destroy_screen_internal(&screen);
13801e04c3fSmrg
13901e04c3fSmrg   return NULL;
14001e04c3fSmrg}
14101e04c3fSmrg
14201e04c3fSmrg
14301e04c3fSmrg#ifdef _WIN32
14401e04c3fSmrg// swap function called from libl_gdi.c
14501e04c3fSmrg
14601e04c3fSmrgvoid
14701e04c3fSmrgswr_gdi_swap(struct pipe_screen *screen,
1487ec681f3Smrg             struct pipe_context *ctx,
14901e04c3fSmrg             struct pipe_resource *res,
15001e04c3fSmrg             void *hDC)
15101e04c3fSmrg{
15201e04c3fSmrg   screen->flush_frontbuffer(screen,
1537ec681f3Smrg                             ctx,
15401e04c3fSmrg                             res,
15501e04c3fSmrg                             0, 0,
15601e04c3fSmrg                             hDC,
15701e04c3fSmrg                             NULL);
15801e04c3fSmrg}
15901e04c3fSmrg
16001e04c3fSmrg#endif /* _WIN32 */
161