Cleaned up primitives code.

This commit is contained in:
Armin Novak 2019-11-07 15:19:49 +01:00 committed by akallabeth
parent 5f0943f0fe
commit 0a3721587a
6 changed files with 363 additions and 301 deletions

View File

@ -1,41 +0,0 @@
# - Try to find the OpenCL library
# Once done this will define
#
# OPENCL_ROOT - A list of search hints
#
# OPENCL_FOUND - system has OpenCL
# OPENCL_INCLUDE_DIR - the OpenCL include directory
# OPENCL_LIBRARIES - opencl library
if (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARY)
set(OPENCL_FIND_QUIETLY TRUE)
endif()
find_path(OPENCL_INCLUDE_DIR NAMES OpenCL/opencl.h CL/cl.h
PATH_SUFFIXES include
HINTS ${OPENCL_ROOT})
find_library(OPENCL_LIBRARY
NAMES OpenCL
PATH_SUFFIXES lib
HINTS ${OPENCL_ROOT})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCL DEFAULT_MSG OPENCL_LIBRARY OPENCL_INCLUDE_DIR)
if (OPENCL_INCLUDE_DIR AND OPENCL_LIBRARY)
set(OPENCL_FOUND TRUE)
set(OPENCL_LIBRARIES ${OPENCL_LIBRARY})
endif()
if (OPENCL_FOUND)
if (NOT OPENCL_FIND_QUIETLY)
message(STATUS "Found OpenCL: ${OPENCL_LIBRARIES}")
endif()
else()
if (OPENCL_FIND_REQUIRED)
message(FATAL_ERROR "OpenCL was not found")
endif()
endif()
mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)

View File

@ -193,9 +193,10 @@ typedef struct
typedef enum
{
PRIMITIVES_PURE_SOFT, /** use generic software implementation */
PRIMITIVES_ONLY_CPU, /** use generic software or cpu optimized routines */
PRIMITIVES_AUTODETECT /** detect the best routines */
PRIMITIVES_PURE_SOFT, /** use generic software implementation */
PRIMITIVES_ONLY_CPU, /** use generic software or cpu optimized routines */
PRIMITIVES_ONLY_GPU, /** use opencl optimized routines */
PRIMITIVES_AUTODETECT /** detect the best routines */
} primitive_hints;
#ifdef __cplusplus

View File

@ -296,8 +296,8 @@ if (WITH_OPENCL)
freerdp_definition_add(-DOPENCL_SOURCE_PATH="${CMAKE_INSTALL_PREFIX}/${FREERDP_PLUGIN_PATH}")
set(PRIMITIVES_OPENCL_SRCS primitives/prim_YUV_opencl.c)
freerdp_include_directory_add(${OPENCL_INCLUDE_DIRS})
freerdp_library_add(${OPENCL_LIBRARIES})
freerdp_include_directory_add(${OpenCL_INCLUDE_DIRS})
freerdp_library_add(OpenCL::OpenCL)
install(FILES primitives/primitives.cl DESTINATION ${FREERDP_PLUGIN_PATH})
endif()

View File

@ -26,13 +26,31 @@
#include <freerdp/primitives.h>
#include "prim_internal.h"
#if defined(WITH_OPENCL)
#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
#include <CL/cl.h>
#endif
#endif
#define TAG FREERDP_TAG("primitives")
typedef struct
{
BOOL support;
cl_platform_id platformId;
cl_device_id deviceId;
cl_context context;
cl_command_queue commandQueue;
cl_program program;
} primitives_opencl_context;
static primitives_opencl_context* primitives_get_opencl_context(void);
static pstatus_t opencl_YUV420ToRGB(const char *kernelName, const BYTE* pSrc[3], const UINT32 srcStep[3],
BYTE* pDst, UINT32 dstStep, const prim_size_t* roi)
static pstatus_t opencl_YUV420ToRGB(const char* kernelName, const BYTE* pSrc[3],
const UINT32 srcStep[3], BYTE* pDst, UINT32 dstStep,
const prim_size_t* roi)
{
cl_int ret;
int i;
@ -146,6 +164,203 @@ error_objs:
return -1;
}
static primitives_opencl_context openclContext;
primitives_opencl_context* primitives_get_opencl_context(void)
{
return &openclContext;
}
pstatus_t primitives_uninit_opencl(void)
{
if (!openclContext.support)
return PRIMITIVES_SUCCESS;
clReleaseProgram(openclContext.program);
clReleaseCommandQueue(openclContext.commandQueue);
clReleaseContext(openclContext.context);
clReleaseDevice(openclContext.deviceId);
openclContext.support = FALSE;
return PRIMITIVES_SUCCESS;
}
BOOL primitives_init_opencl_context(primitives_opencl_context* cl)
{
cl_platform_id* platform_ids = NULL;
cl_uint ndevices, nplatforms, i;
cl_kernel kernel;
cl_int ret;
char sourcePath[1000];
BOOL gotGPU = FALSE;
FILE* f;
size_t programLen;
char* programSource;
ret = clGetPlatformIDs(0, NULL, &nplatforms);
if (ret != CL_SUCCESS || nplatforms < 1)
return FALSE;
platform_ids = calloc(nplatforms, sizeof(*platform_ids));
if (!platform_ids)
return FALSE;
ret = clGetPlatformIDs(nplatforms, platform_ids, &nplatforms);
if (ret != CL_SUCCESS)
{
free(platform_ids);
return FALSE;
}
for (i = 0; (i < nplatforms) && !gotGPU; i++)
{
cl_device_id device_id;
cl_context context;
char platformName[1000];
char deviceName[1000];
ret = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, sizeof(platformName),
platformName, NULL);
if (ret != CL_SUCCESS)
continue;
ret = clGetDeviceIDs(platform_ids[i], CL_DEVICE_TYPE_GPU, 1, &device_id, &ndevices);
if (ret != CL_SUCCESS)
continue;
ret = clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(deviceName), deviceName, NULL);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable get device name for platform %s", platformName);
clReleaseDevice(device_id);
continue;
}
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create context for platform %s, device %s",
platformName, deviceName);
clReleaseDevice(device_id);
continue;
}
cl->commandQueue = clCreateCommandQueue(context, device_id, 0, &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create command queue");
clReleaseContext(context);
clReleaseDevice(device_id);
continue;
}
WLog_INFO(TAG, "openCL: using platform=%s device=%s", platformName, deviceName);
cl->platformId = platform_ids[i];
cl->deviceId = device_id;
cl->context = context;
gotGPU = TRUE;
}
free(platform_ids);
if (!gotGPU)
{
WLog_ERR(TAG, "openCL: no GPU found");
return FALSE;
}
snprintf(sourcePath, sizeof(sourcePath), "%s/primitives.cl", OPENCL_SOURCE_PATH);
f = fopen(sourcePath, "r");
if (!f)
{
WLog_ERR(TAG, "openCL: unable to open source file %s", sourcePath);
goto error_source_file;
}
fseek(f, 0, SEEK_END);
programLen = ftell(f);
fseek(f, 0, SEEK_SET);
programSource = malloc(programLen);
if (!programSource)
{
WLog_ERR(TAG, "openCL: unable to allocate memory(%d bytes) for source file %s", programLen,
sourcePath);
fclose(f);
goto error_source_file;
}
if (fread(programSource, programLen, 1, f) <= 0)
{
WLog_ERR(TAG, "openCL: unable to read openCL program in %s", sourcePath);
free(programSource);
fclose(f);
goto error_source_file;
}
fclose(f);
cl->program =
clCreateProgramWithSource(cl->context, 1, (const char**)&programSource, &programLen, &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create command queue");
goto out_program_create;
}
free(programSource);
ret = clBuildProgram(cl->program, 1, &cl->deviceId, NULL, NULL, NULL);
if (ret != CL_SUCCESS)
{
size_t length;
char buffer[2048];
ret = clGetProgramBuildInfo(cl->program, cl->deviceId, CL_PROGRAM_BUILD_LOG, sizeof(buffer),
buffer, &length);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG,
"openCL: building program failed but unable to retrieve buildLog, error=%d",
ret);
}
else
{
WLog_ERR(TAG, "openCL: unable to build program, errorLog=%s", buffer);
}
goto out_program_build;
}
kernel = clCreateKernel(cl->program, "yuv420_to_bgra_1b", &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create yuv420_to_bgra_1b kernel");
goto out_program_build;
}
clReleaseKernel(kernel);
cl->support = TRUE;
return TRUE;
out_program_build:
clReleaseProgram(cl->program);
error_source_file:
out_program_create:
clReleaseCommandQueue(cl->commandQueue);
clReleaseContext(cl->context);
clReleaseDevice(cl->deviceId);
return FALSE;
}
BOOL primitives_init_opencl(primitives_t* prims)
{
if (!primitives_init_opencl_context(&openclContext))
return FALSE;
primitives_init_YUV_opencl(prims);
prims->flags |= PRIM_FLAGS_HAVE_EXTGPU;
prims->uninit = primitives_uninit_opencl;
return TRUE;
}
static pstatus_t opencl_YUV420ToRGB_8u_P3AC4R(const BYTE* pSrc[3], const UINT32 srcStep[3],
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, const prim_size_t* roi)
@ -154,18 +369,23 @@ static pstatus_t opencl_YUV420ToRGB_8u_P3AC4R(const BYTE* pSrc[3], const UINT32
switch(DstFormat)
{
case PIXEL_FORMAT_BGRA32:
case PIXEL_FORMAT_BGRX32:
kernel_name = "yuv420_to_bgra_1b";
break;
case PIXEL_FORMAT_XRGB32:
case PIXEL_FORMAT_ARGB32:
kernel_name = "yuv420_to_argb_1b";
break;
default: {
primitives_opencl_context *cl = primitives_get_opencl_context();
return cl->YUV420ToRGB_backup(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
}
case PIXEL_FORMAT_BGRA32:
case PIXEL_FORMAT_BGRX32:
kernel_name = "yuv420_to_bgra_1b";
break;
case PIXEL_FORMAT_XRGB32:
case PIXEL_FORMAT_ARGB32:
kernel_name = "yuv420_to_argb_1b";
break;
default:
{
primitives_t* p = primitives_get_by_type(PRIMITIVES_ONLY_CPU);
if (!p)
p = primitives_get_by_type(PRIMITIVES_PURE_SOFT);
if (!p)
return -1;
return p->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
}
}
return opencl_YUV420ToRGB(kernel_name, pSrc, srcStep, pDst, dstStep, roi);

View File

@ -209,6 +209,7 @@ FREERDP_LOCAL void primitives_init_YUV_opt(primitives_t* prims);
#endif
#if defined(WITH_OPENCL)
<<<<<<< HEAD
#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
@ -230,8 +231,14 @@ typedef struct
FREERDP_LOCAL BOOL primitives_init_opencl(primitives_t* prims);
FREERDP_LOCAL pstatus_t primitives_uninit_opencl(void);
FREERDP_LOCAL primitives_opencl_context *primitives_get_opencl_context(void);
=======
FREERDP_LOCAL BOOL primitives_init_opencl(primitives_t* prims);
FREERDP_LOCAL pstatus_t primitives_uninit_opencl(void);
>>>>>>> 79139d536... Cleaned up primitives code.
FREERDP_LOCAL void primitives_init_YUV_opencl(primitives_t* prims);
#endif
FREERDP_LOCAL primitives_t* primitives_get_by_type(DWORD type);
#endif /* FREERDP_LIB_PRIM_INTERNAL_H */

View File

@ -34,6 +34,7 @@
/* hints to know which kind of primitives to use */
static primitive_hints primitivesHints = PRIMITIVES_AUTODETECT;
static BOOL primitives_init_optimized(primitives_t* prims);
void primitives_set_hints(primitive_hints hints)
{
@ -50,6 +51,17 @@ primitive_hints primitives_get_hints(void)
static primitives_t pPrimitivesGeneric = { 0 };
static INIT_ONCE generic_primitives_InitOnce = INIT_ONCE_STATIC_INIT;
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
static primitives_t pPrimitivesCpu = { 0 };
#endif
#if defined(WITH_OPENCL)
static primitives_t pPrimitivesGpu = { 0 };
#endif
#if defined(HAVE_OPTIMIZED_PRIMITIVES)
static INIT_ONCE auto_primitives_InitOnce = INIT_ONCE_STATIC_INIT;
#endif
static primitives_t pPrimitives = { 0 };
static INIT_ONCE primitives_InitOnce = INIT_ONCE_STATIC_INIT;
@ -190,12 +202,16 @@ static BOOL primitives_autodetect_best(primitives_t *prims)
{
BOOL ret = FALSE;
UINT64 benchDuration = 150; // 100 ms
UINT32 genericCount = 0, optimizedCount = 0, openclCount = 0;
UINT32 genericCount = 0;
UINT32 bestCount;
primitives_t *genericPrims = primitives_get_generic();
primitives_t optimizedPrims;
primitives_t* genericPrims = primitives_get_generic();
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
primitives_t* optimizedPrims = primitives_get_by_type(PRIMITIVES_ONLY_CPU);
UINT32 optimizedCount = 0;
#endif
#if defined(WITH_OPENCL)
primitives_t openclPrims;
primitives_t* openclPrims = primitives_get_by_type(PRIMITIVES_ONLY_GPU);
UINT32 openclCount = 0;
#endif
const char *primName = "generic";
@ -209,29 +225,19 @@ static BOOL primitives_autodetect_best(primitives_t *prims)
goto out;
}
if (!primitives_init_optimized(&optimizedPrims))
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
if (!primitives_YUV_benchmark_run(yuvBench, optimizedPrims, benchDuration, &optimizedCount))
{
WLog_ERR(TAG, "error initializing CPU optimized primitives");
WLog_ERR(TAG, "error running optimized YUV bench");
goto out;
}
if(optimizedPrims.flags & PRIM_FLAGS_HAVE_EXTCPU) /* run the test only if we really have optimizations */
{
if (!primitives_YUV_benchmark_run(yuvBench, &optimizedPrims, benchDuration, &optimizedCount))
{
WLog_ERR(TAG, "error running optimized YUV bench");
goto out;
}
}
#endif
#if defined(WITH_OPENCL)
if (primitives_init_opencl(&openclPrims))
if (!primitives_YUV_benchmark_run(yuvBench, openclPrims, benchDuration, &openclCount))
{
if (!primitives_YUV_benchmark_run(yuvBench, &openclPrims, benchDuration, &openclCount))
{
WLog_ERR(TAG, "error running opencl YUV bench");
goto out;
}
WLog_ERR(TAG, "error running opencl YUV bench");
goto out;
}
#endif
@ -239,23 +245,43 @@ static BOOL primitives_autodetect_best(primitives_t *prims)
bestCount = genericCount;
*prims = *genericPrims;
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
if (bestCount < optimizedCount)
{
bestCount = optimizedCount;
*prims = optimizedPrims;
*prims = *optimizedPrims;
primName = "optimized";
}
#endif
#if defined(WITH_OPENCL)
if (bestCount < openclCount)
{
bestCount = openclCount;
*prims = openclPrims;
*prims = *openclPrims;
primName = "openCL";
}
#endif
WLog_DBG(TAG, "benchmark result: generic=%d optimized=%d openCL=%d", genericCount, optimizedCount, openclCount);
WLog_DBG(TAG,
"benchmark result: generic=%" PRIu32
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
" optimized=%" PRIu32
#endif
#if defined(WITH_OPENCL)
" openCL=%" PRIu32
#endif
,
genericCount
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
,
optimizedCount
#endif
#if defined(WITH_OPENCL)
,
openclCount
#endif
);
WLog_INFO(TAG, "primitives autodetect, using %s", primName);
ret = TRUE;
out:
@ -264,6 +290,24 @@ out:
}
static BOOL CALLBACK primitives_init_cb(PINIT_ONCE once, PVOID param, PVOID* context)
{
WINPR_UNUSED(once);
WINPR_UNUSED(param);
WINPR_UNUSED(context);
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
if (!primitives_init_optimized(&pPrimitivesCpu))
return FALSE;
#endif
#if defined(WITH_OPENCL)
if (!primitives_init_opencl(&pPrimitivesGpu))
return FALSE;
#endif
return TRUE;
}
static BOOL CALLBACK primitives_auto_init_cb(PINIT_ONCE once, PVOID param, PVOID* context)
{
WINPR_UNUSED(once);
WINPR_UNUSED(param);
@ -272,220 +316,28 @@ static BOOL CALLBACK primitives_init_cb(PINIT_ONCE once, PVOID param, PVOID* con
return primitives_init(&pPrimitives, primitivesHints);
}
#if defined(WITH_OPENCL)
static primitives_opencl_context openclContext;
primitives_opencl_context *primitives_get_opencl_context(void)
{
return &openclContext;
}
pstatus_t primitives_uninit_opencl(void)
{
if (!openclContext.support)
return PRIMITIVES_SUCCESS;
clReleaseProgram(openclContext.program);
clReleaseCommandQueue(openclContext.commandQueue);
clReleaseContext(openclContext.context);
clReleaseDevice(openclContext.deviceId);
openclContext.support = FALSE;
return PRIMITIVES_SUCCESS;
}
BOOL primitives_init_opencl_context(primitives_opencl_context *cl)
{
cl_platform_id *platform_ids = NULL;
cl_uint ndevices, nplatforms, i;
cl_kernel kernel;
cl_int ret;
char sourcePath[1000];
primitives_t optimized;
BOOL gotGPU = FALSE;
FILE *f;
size_t programLen;
char *programSource;
if (!primitives_init_optimized(&optimized))
return FALSE;
cl->YUV420ToRGB_backup = optimized.YUV420ToRGB_8u_P3AC4R;
ret = clGetPlatformIDs(0, NULL, &nplatforms);
if (ret != CL_SUCCESS || nplatforms < 1)
return FALSE;
platform_ids = calloc(nplatforms, sizeof(*platform_ids));
if (!platform_ids)
return FALSE;
ret = clGetPlatformIDs(nplatforms, platform_ids, &nplatforms);
if (ret != CL_SUCCESS)
{
free(platform_ids);
return FALSE;
}
for (i = 0; (i < nplatforms) && !gotGPU; i++)
{
cl_device_id device_id;
cl_context context;
char platformName[1000];
char deviceName[1000];
ret = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, sizeof(platformName), platformName, NULL);
if (ret != CL_SUCCESS)
continue;
ret = clGetDeviceIDs(platform_ids[i], CL_DEVICE_TYPE_GPU, 1, &device_id, &ndevices);
if (ret != CL_SUCCESS)
continue;
ret = clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(deviceName), deviceName, NULL);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable get device name for platform %s", platformName);
clReleaseDevice(device_id);
continue;
}
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create context for platform %s, device %s", platformName, deviceName);
clReleaseDevice(device_id);
continue;
}
cl->commandQueue = clCreateCommandQueue(context, device_id, 0, &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create command queue");
clReleaseContext(context);
clReleaseDevice(device_id);
continue;
}
WLog_INFO(TAG, "openCL: using platform=%s device=%s", platformName, deviceName);
cl->platformId = platform_ids[i];
cl->deviceId = device_id;
cl->context = context;
gotGPU = TRUE;
}
free(platform_ids);
if (!gotGPU)
{
WLog_ERR(TAG, "openCL: no GPU found");
return FALSE;
}
snprintf(sourcePath, sizeof(sourcePath), "%s/primitives.cl", OPENCL_SOURCE_PATH);
f = fopen(sourcePath, "r");
if (!f)
{
WLog_ERR(TAG, "openCL: unable to open source file %s", sourcePath);
goto error_source_file;
}
fseek(f, 0, SEEK_END);
programLen = ftell(f);
fseek(f, 0, SEEK_SET);
programSource = malloc(programLen);
if (!programSource) {
WLog_ERR(TAG, "openCL: unable to allocate memory(%d bytes) for source file %s",
programLen, sourcePath);
fclose(f);
goto error_source_file;
}
if (fread(programSource, programLen, 1, f) <= 0)
{
WLog_ERR(TAG, "openCL: unable to read openCL program in %s", sourcePath);
free(programSource);
fclose(f);
goto error_source_file;
}
fclose(f);
cl->program = clCreateProgramWithSource(cl->context, 1, (const char **)&programSource,
&programLen, &ret);
if (ret != CL_SUCCESS) {
WLog_ERR(TAG, "openCL: unable to create command queue");
goto out_program_create;
}
free(programSource);
ret = clBuildProgram(cl->program, 1, &cl->deviceId, NULL, NULL, NULL);
if (ret != CL_SUCCESS)
{
size_t length;
char buffer[2048];
ret = clGetProgramBuildInfo(cl->program, cl->deviceId, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &length);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: building program failed but unable to retrieve buildLog, error=%d", ret);
}
else
{
WLog_ERR(TAG, "openCL: unable to build program, errorLog=%s", buffer);
}
goto out_program_build;
}
kernel = clCreateKernel(cl->program, "yuv420_to_bgra_1b", &ret);
if (ret != CL_SUCCESS)
{
WLog_ERR(TAG, "openCL: unable to create yuv420_to_bgra_1b kernel");
goto out_program_build;
}
clReleaseKernel(kernel);
cl->support = TRUE;
return TRUE;
out_program_build:
clReleaseProgram(cl->program);
error_source_file:
out_program_create:
clReleaseCommandQueue(cl->commandQueue);
clReleaseContext(cl->context);
clReleaseDevice(cl->deviceId);
return FALSE;
}
BOOL primitives_init_opencl(primitives_t* prims)
{
if (!primitives_init_opencl_context(&openclContext))
return FALSE;
primitives_init_optimized(prims);
primitives_init_YUV_opencl(prims);
prims->flags |= PRIM_FLAGS_HAVE_EXTGPU;
prims->uninit = primitives_uninit_opencl;
return TRUE;
}
#endif
BOOL primitives_init(primitives_t *p, primitive_hints hints)
BOOL primitives_init(primitives_t* p, primitive_hints hints)
{
switch(hints)
{
case PRIMITIVES_PURE_SOFT:
return primitives_init_generic(p);
case PRIMITIVES_ONLY_CPU:
return primitives_init_optimized(p);
case PRIMITIVES_AUTODETECT:
return primitives_autodetect_best(p);
default:
WLog_ERR(TAG, "unknown hint %d", hints);
return FALSE;
case PRIMITIVES_AUTODETECT:
return primitives_autodetect_best(p);
case PRIMITIVES_PURE_SOFT:
*p = pPrimitivesGeneric;
return TRUE;
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
case PRIMITIVES_ONLY_CPU:
*p = pPrimitivesCpu;
return TRUE;
#endif
#if defined(WITH_OPENCL)
case PRIMITIVES_ONLY_GPU:
*p = pPrimitivesGpu;
return TRUE;
#endif
default:
WLog_ERR(TAG, "unknown hint %d", hints);
return FALSE;
}
}
@ -495,15 +347,17 @@ void primitives_uninit() {
}
/* ------------------------------------------------------------------------- */
primitives_t* primitives_get(void)
static void setup(void)
{
InitOnceExecuteOnce(&generic_primitives_InitOnce, primitives_init_generic_cb, NULL, NULL);
#if defined(HAVE_OPTIMIZED_PRIMITIVES)
InitOnceExecuteOnce(&primitives_InitOnce, primitives_init_cb, NULL, NULL);
InitOnceExecuteOnce(&auto_primitives_InitOnce, primitives_auto_init_cb, NULL, NULL);
}
primitives_t* primitives_get(void)
{
setup();
return &pPrimitives;
#else
return &pPrimitivesGeneric;
#endif
}
primitives_t* primitives_get_generic(void)
@ -512,7 +366,28 @@ primitives_t* primitives_get_generic(void)
return &pPrimitivesGeneric;
}
DWORD primitives_flags(primitives_t *p)
primitives_t* primitives_get_by_type(DWORD type)
{
InitOnceExecuteOnce(&generic_primitives_InitOnce, primitives_init_generic_cb, NULL, NULL);
switch (type)
{
#if defined(WITH_OPENCL)
case PRIMITIVES_ONLY_GPU:
InitOnceExecuteOnce(&primitives_InitOnce, primitives_init_cb, NULL, NULL);
return &pPrimitivesGpu;
#endif
#if defined(HAVE_CPU_OPTIMIZED_PRIMITIVES)
case PRIMITIVES_ONLY_CPU:
InitOnceExecuteOnce(&primitives_InitOnce, primitives_init_cb, NULL, NULL);
return &pPrimitivesCpu;
#endif
case PRIMITIVES_PURE_SOFT:
default:
return &pPrimitivesGeneric;
}
}
DWORD primitives_flags(primitives_t* p)
{
return p->flags;
}