blob: d5ae27ff837c6a10f939451a7d89de26c64837b4 [file] [log] [blame]
// Copyright 2019 The Shaderc Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "shaderc/shaderc.h"
#include "spvc/spvc.h"
typedef shaderc_spvc_status (*InitCmd)(const shaderc_spvc_context_t,
const uint32_t*, size_t,
shaderc_spvc_compile_options_t);
shaderc_compilation_result_t assemble_shader(const char* shader) {
shaderc_compiler_t shaderc;
shaderc = shaderc_compiler_initialize();
shaderc_compile_options_t opt = shaderc_compile_options_initialize();
shaderc_compilation_result_t res =
shaderc_assemble_into_spv(shaderc, shader, strlen(shader), opt);
shaderc_compile_options_release(opt);
shaderc_compiler_release(shaderc);
return res;
}
int test_exec(shaderc_spvc_context_t context,
shaderc_spvc_compile_options_t options,
shaderc_compilation_result_t assembled_shader, InitCmd init_cmd,
const char* target_lang) {
shaderc_spvc_compilation_result_t result = shaderc_spvc_result_create();
assert(result);
shaderc_spvc_status status = init_cmd(
context, (const uint32_t*)shaderc_result_get_bytes(assembled_shader),
shaderc_result_get_length(assembled_shader) / sizeof(uint32_t), options);
int ret_val;
if (status == shaderc_spvc_status_success) {
shaderc_spvc_status compile_status =
shaderc_spvc_compile_shader(context, result);
if (compile_status == shaderc_spvc_status_success) {
const char* result_str;
shaderc_spvc_result_get_string_output(result, &result_str);
printf("success! %lu characters of %s\n",
(unsigned long)(strlen(result_str)),
target_lang);
ret_val = 1;
} else {
printf("failed to produce %s\n", target_lang);
ret_val = 0;
}
} else {
printf("failed to initialize %s\n", target_lang);
ret_val = 0;
}
shaderc_spvc_result_destroy(result);
return ret_val;
}
int run_glsl(shaderc_spvc_context_t context,
shaderc_spvc_compile_options_t options,
shaderc_compilation_result_t assembled_shader) {
return test_exec(context, options, assembled_shader,
shaderc_spvc_initialize_for_glsl, "glsl");
}
int run_hlsl(shaderc_spvc_context_t context,
shaderc_spvc_compile_options_t options,
shaderc_compilation_result_t assembled_shader) {
return test_exec(context, options, assembled_shader,
shaderc_spvc_initialize_for_hlsl, "hlsl");
}
int run_msl(shaderc_spvc_context_t context,
shaderc_spvc_compile_options_t options,
shaderc_compilation_result_t assembled_shader) {
return test_exec(context, options, assembled_shader,
shaderc_spvc_initialize_for_msl, "msl");
}
int run_smoke_test(const char* shader, int transform_from_webgpu) {
shaderc_compilation_result_t assembled_shader = assemble_shader(shader);
if (assembled_shader == NULL) {
printf("failed to assemble input!\n");
return -1;
}
int ret_code = 0;
shaderc_spvc_context_t context = shaderc_spvc_context_create();
shaderc_spvc_compile_options_t options;
if (transform_from_webgpu) {
options = shaderc_spvc_compile_options_create(
shaderc_spvc_spv_env_webgpu_0, shaderc_spvc_spv_env_vulkan_1_1);
} else {
options = shaderc_spvc_compile_options_create(
shaderc_spvc_spv_env_vulkan_1_0, shaderc_spvc_spv_env_vulkan_1_0);
}
if (!run_glsl(context, options, assembled_shader)) ret_code = -1;
if (!run_hlsl(context, options, assembled_shader)) ret_code = -1;
if (!run_msl(context, options, assembled_shader)) ret_code = -1;
shaderc_spvc_compile_options_destroy(options);
shaderc_spvc_context_destroy(context);
shaderc_result_release(assembled_shader);
return ret_code;
}