1 /*
2 * Copyright (c) 2022 The Khronos Group Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * OpenCL is a trademark of Apple Inc. used under license by Khronos.
17 */
18
19 #include "icd.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <CL/cl_layer.h>
23 #if defined(_WIN32)
24 #include <io.h>
25 #include <share.h>
26 #include <sys/stat.h>
27 #else
28 #include <unistd.h>
29 #endif
30 #include <fcntl.h>
31
32 int stdout_bak, stderr_bak;
33
34 // Temporarily deactivate stdout:
35 // https://stackoverflow.com/a/4832902
36
37 #if defined(_WIN32)
38 #define SECURE 1
39 #define OPEN _open
40 #define OPEN_FLAGS _O_WRONLY
41 #define CLOSE _close
42 #define DUP _dup
43 #define DUP2 _dup2
44 #define NULL_STREAM "nul"
45 #else
46 #define OPEN open
47 #define OPEN_FLAGS O_WRONLY
48 #define CLOSE close
49 #define DUP dup
50 #define DUP2 dup2
51 #define NULL_STREAM "/dev/null"
52 #endif
53
54 static inline int
silence_stream(FILE * file,int fd)55 silence_stream(FILE *file, int fd)
56 {
57 int new_fd, fd_bak;
58 fflush(file);
59 fd_bak = DUP(fd);
60 #if defined(_WIN32) && SECURE
61 _sopen_s(&new_fd, NULL_STREAM, OPEN_FLAGS, _SH_DENYNO, _S_IWRITE);
62 #else
63 new_fd = OPEN(NULL_STREAM, OPEN_FLAGS);
64 #endif
65 DUP2(new_fd, fd);
66 CLOSE(new_fd);
67 return fd_bak;
68 }
69
silence_layers(void)70 static void silence_layers(void)
71 {
72 stdout_bak = silence_stream(stdout, 1);
73 stderr_bak = silence_stream(stderr, 2);
74 }
75
76 static inline void
restore_stream(FILE * file,int fd,int fd_bak)77 restore_stream(FILE *file, int fd, int fd_bak)
78 {
79 fflush(file);
80 DUP2(fd_bak, fd);
81 CLOSE(fd_bak);
82 }
83
restore_outputs(void)84 static void restore_outputs(void)
85 {
86 restore_stream(stdout, 1, stdout_bak);
87 restore_stream(stderr, 2, stderr_bak);
88 }
89
printLayerInfo(const struct KHRLayer * layer)90 void printLayerInfo(const struct KHRLayer *layer)
91 {
92 cl_layer_api_version api_version = 0;
93 pfn_clGetLayerInfo p_clGetLayerInfo = (pfn_clGetLayerInfo)(size_t)layer->p_clGetLayerInfo;
94 cl_int result = CL_SUCCESS;
95 size_t sz;
96
97 printf("%s:\n", layer->libraryName);
98 result = p_clGetLayerInfo(CL_LAYER_API_VERSION, sizeof(api_version), &api_version, NULL);
99 if (CL_SUCCESS == result)
100 printf("\tCL_LAYER_API_VERSION: %d\n", (int)api_version);
101
102 result = p_clGetLayerInfo(CL_LAYER_NAME, 0, NULL, &sz);
103 if (CL_SUCCESS == result)
104 {
105 char *name = (char *)malloc(sz);
106 if (name)
107 {
108 result = p_clGetLayerInfo(CL_LAYER_NAME, sz, name, NULL);
109 if (CL_SUCCESS == result)
110 printf("\tCL_LAYER_NAME: %s\n", name);
111 free(name);
112 }
113 }
114 }
115
main(int argc,char * argv[])116 int main (int argc, char *argv[])
117 {
118 (void)argc;
119 (void)argv;
120 silence_layers();
121 atexit(restore_outputs);
122 khrIcdInitialize();
123 restore_outputs();
124 atexit(silence_layers);
125 const struct KHRLayer *layer = khrFirstLayer;
126 while (layer)
127 {
128 printLayerInfo(layer);
129 layer = layer->next;
130 }
131 return 0;
132 }
133