1 // Testbench for MSL resource binding APIs.
2 // It does not validate output at the moment, but it's useful for ad-hoc testing.
3 
4 #include <spirv_cross_c.h>
5 #include <vector>
6 #include <stdio.h>
7 #include <stdlib.h>
8 
9 #define SPVC_CHECKED_CALL(x) do { \
10 	if ((x) != SPVC_SUCCESS) { \
11 		fprintf(stderr, "Failed at line %d.\n", __LINE__); \
12 		exit(1); \
13 	} \
14 } while(0)
15 
read_file(const char * path)16 static std::vector<SpvId> read_file(const char *path)
17 {
18 	long len;
19 	FILE *file = fopen(path, "rb");
20 
21 	if (!file)
22 		return {};
23 
24 	fseek(file, 0, SEEK_END);
25 	len = ftell(file);
26 	rewind(file);
27 
28 	std::vector<SpvId> buffer(len / sizeof(SpvId));
29 	if (fread(buffer.data(), 1, len, file) != (size_t)len)
30 	{
31 		fclose(file);
32 		return {};
33 	}
34 
35 	fclose(file);
36 	return buffer;
37 }
38 
main(int argc,char ** argv)39 int main(int argc, char **argv)
40 {
41 	if (argc != 2)
42 		return EXIT_FAILURE;
43 
44 	auto buffer = read_file(argv[1]);
45 	if (buffer.empty())
46 		return EXIT_FAILURE;
47 
48 	spvc_context ctx;
49 	spvc_parsed_ir parsed_ir;
50 	spvc_compiler compiler;
51 
52 	SPVC_CHECKED_CALL(spvc_context_create(&ctx));
53 	SPVC_CHECKED_CALL(spvc_context_parse_spirv(ctx, buffer.data(), buffer.size(), &parsed_ir));
54 	SPVC_CHECKED_CALL(spvc_context_create_compiler(ctx, SPVC_BACKEND_MSL, parsed_ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler));
55 	SPVC_CHECKED_CALL(spvc_compiler_msl_add_discrete_descriptor_set(compiler, 3));
56 
57 	spvc_compiler_options opts;
58 	SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler, &opts));
59 	SPVC_CHECKED_CALL(spvc_compiler_options_set_bool(opts, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, SPVC_TRUE));
60 	SPVC_CHECKED_CALL(spvc_compiler_options_set_uint(opts, SPVC_COMPILER_OPTION_MSL_VERSION, 20000));
61 	SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler, opts));
62 
63 	spvc_msl_resource_binding binding;
64 	spvc_msl_resource_binding_init(&binding);
65 	binding.binding = SPVC_MSL_ARGUMENT_BUFFER_BINDING;
66 	binding.stage = SpvExecutionModelFragment;
67 	binding.desc_set = 0;
68 	binding.msl_buffer = 2;
69 	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
70 
71 	binding.desc_set = 1;
72 	binding.msl_buffer = 3;
73 	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
74 
75 	const char *str;
76 	SPVC_CHECKED_CALL(spvc_compiler_compile(compiler, &str));
77 
78 	fprintf(stderr, "Output:\n%s\n", str);
79 
80 	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 0, SPVC_MSL_ARGUMENT_BUFFER_BINDING))
81 		return EXIT_FAILURE;
82 
83 	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 1, SPVC_MSL_ARGUMENT_BUFFER_BINDING))
84 		return EXIT_FAILURE;
85 }
86 
87