Path: blob/main/examples/online-compile/main.cc
1560 views
// Copyright 2016 The Shaderc Authors. All rights reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314// The program demonstrates basic shader compilation using the Shaderc C++ API.15// For clarity, each method is deliberately self-contained.16//17// Techniques demonstrated:18// - Preprocessing GLSL source text19// - Compiling a shader to SPIR-V assembly text20// - Compliing a shader to a SPIR-V binary module21// - Performing optimization with compilation22// - Setting basic options: setting a preprocessor symbol.23// - Checking compilation status and extracting an error message.2425#include <cstring>26#include <iostream>27#include <string>28#include <vector>2930#include <shaderc/shaderc.hpp>3132// Returns GLSL shader source text after preprocessing.33std::string preprocess_shader(const std::string& source_name,34shaderc_shader_kind kind,35const std::string& source) {36shaderc::Compiler compiler;37shaderc::CompileOptions options;3839// Like -DMY_DEFINE=140options.AddMacroDefinition("MY_DEFINE", "1");4142shaderc::PreprocessedSourceCompilationResult result =43compiler.PreprocessGlsl(source, kind, source_name.c_str(), options);4445if (result.GetCompilationStatus() != shaderc_compilation_status_success) {46std::cerr << result.GetErrorMessage();47return "";48}4950return {result.cbegin(), result.cend()};51}5253// Compiles a shader to SPIR-V assembly. Returns the assembly text54// as a string.55std::string compile_file_to_assembly(const std::string& source_name,56shaderc_shader_kind kind,57const std::string& source,58bool optimize = false) {59shaderc::Compiler compiler;60shaderc::CompileOptions options;6162// Like -DMY_DEFINE=163options.AddMacroDefinition("MY_DEFINE", "1");64if (optimize) options.SetOptimizationLevel(shaderc_optimization_level_size);6566shaderc::AssemblyCompilationResult result = compiler.CompileGlslToSpvAssembly(67source, kind, source_name.c_str(), options);6869if (result.GetCompilationStatus() != shaderc_compilation_status_success) {70std::cerr << result.GetErrorMessage();71return "";72}7374return {result.cbegin(), result.cend()};75}7677// Compiles a shader to a SPIR-V binary. Returns the binary as78// a vector of 32-bit words.79std::vector<uint32_t> compile_file(const std::string& source_name,80shaderc_shader_kind kind,81const std::string& source,82bool optimize = false) {83shaderc::Compiler compiler;84shaderc::CompileOptions options;8586// Like -DMY_DEFINE=187options.AddMacroDefinition("MY_DEFINE", "1");88if (optimize) options.SetOptimizationLevel(shaderc_optimization_level_size);8990shaderc::SpvCompilationResult module =91compiler.CompileGlslToSpv(source, kind, source_name.c_str(), options);9293if (module.GetCompilationStatus() != shaderc_compilation_status_success) {94std::cerr << module.GetErrorMessage();95return std::vector<uint32_t>();96}9798return {module.cbegin(), module.cend()};99}100101int main() {102const char kShaderSource[] =103"#version 310 es\n"104"void main() { int x = MY_DEFINE; }\n";105106{ // Preprocessing107auto preprocessed = preprocess_shader(108"shader_src", shaderc_glsl_vertex_shader, kShaderSource);109std::cout << "Compiled a vertex shader resulting in preprocessed text:"110<< std::endl111<< preprocessed << std::endl;112}113114{ // Compiling115auto assembly = compile_file_to_assembly(116"shader_src", shaderc_glsl_vertex_shader, kShaderSource);117std::cout << "SPIR-V assembly:" << std::endl << assembly << std::endl;118119auto spirv =120compile_file("shader_src", shaderc_glsl_vertex_shader, kShaderSource);121std::cout << "Compiled to a binary module with " << spirv.size()122<< " words." << std::endl;123}124125{ // Compiling with optimizing126auto assembly =127compile_file_to_assembly("shader_src", shaderc_glsl_vertex_shader,128kShaderSource, /* optimize = */ true);129std::cout << "Optimized SPIR-V assembly:" << std::endl130<< assembly << std::endl;131132auto spirv = compile_file("shader_src", shaderc_glsl_vertex_shader,133kShaderSource, /* optimize = */ true);134std::cout << "Compiled to an optimized binary module with " << spirv.size()135<< " words." << std::endl;136}137138{ // Error case139const char kBadShaderSource[] =140"#version 310 es\nint main() { int main_should_be_void; }\n";141142std::cout << std::endl << "Compiling a bad shader:" << std::endl;143compile_file("bad_src", shaderc_glsl_vertex_shader, kBadShaderSource);144}145146{ // Compile using the C API.147std::cout << "\n\nCompiling with the C API" << std::endl;148149// The first example has a compilation problem. The second does not.150const char source[2][80] = {"void main() {}", "#version 450\nvoid main() {}"};151152shaderc_compiler_t compiler = shaderc_compiler_initialize();153for (int i = 0; i < 2; ++i) {154std::cout << " Source is:\n---\n" << source[i] << "\n---\n";155shaderc_compilation_result_t result = shaderc_compile_into_spv(156compiler, source[i], std::strlen(source[i]), shaderc_glsl_vertex_shader,157"main.vert", "main", nullptr);158auto status = shaderc_result_get_compilation_status(result);159std::cout << " Result code " << int(status) << std::endl;160if (status != shaderc_compilation_status_success) {161std::cout << "error: " << shaderc_result_get_error_message(result)162<< std::endl;163}164shaderc_result_release(result);165}166shaderc_compiler_release(compiler);167}168169return 0;170}171172173