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