16 std::shared_ptr<const fml::Mapping>
sources)
23 const shaderc::CompileOptions& spirv_options)
const {
24 if (!sources_ || sources_->GetMapping() ==
nullptr) {
29 shaderc::Compiler spv_compiler;
30 if (!spv_compiler.IsValid()) {
33 <<
" to SPIRV compiler.";
39 if (shader_kind == shaderc_shader_kind::shaderc_glsl_infer_from_source) {
44 auto result = std::make_shared<shaderc::SpvCompilationResult>(
45 spv_compiler.CompileGlslToSpv(
46 reinterpret_cast<const char*
>(sources_->GetMapping()),
53 if (
result->GetCompilationStatus() !=
54 shaderc_compilation_status::shaderc_compilation_status_success) {
56 <<
" to SPIRV failed; "
58 result->GetCompilationStatus())
59 <<
". " <<
result->GetNumErrors() <<
" error(s) and "
60 <<
result->GetNumWarnings() <<
" warning(s).";
64 if (
result->GetNumErrors() > 0 ||
result->GetNumWarnings() > 0 ||
65 !
result->GetErrorMessage().empty()) {
76 const auto data_length = (
result->cend() -
result->cbegin()) *
77 sizeof(
decltype(
result)::element_type::element_type);
79 return std::make_unique<fml::NonOwnedMapping>(
80 reinterpret_cast<const uint8_t*
>(
result->cbegin()),
86std::string SPIRVCompiler::GetSourcePrefix()
const {
93 using Limit = std::pair<shaderc_limit, int>;
94 static constexpr std::array<Limit, 83> limits = {
95 Limit{shaderc_limit::shaderc_limit_max_lights, 8},
96 Limit{shaderc_limit::shaderc_limit_max_clip_planes, 6},
97 Limit{shaderc_limit::shaderc_limit_max_texture_units, 2},
98 Limit{shaderc_limit::shaderc_limit_max_texture_coords, 8},
99 Limit{shaderc_limit::shaderc_limit_max_vertex_attribs, 16},
100 Limit{shaderc_limit::shaderc_limit_max_vertex_uniform_components, 4096},
101 Limit{shaderc_limit::shaderc_limit_max_varying_floats, 60},
102 Limit{shaderc_limit::shaderc_limit_max_vertex_texture_image_units, 16},
103 Limit{shaderc_limit::shaderc_limit_max_combined_texture_image_units, 80},
104 Limit{shaderc_limit::shaderc_limit_max_texture_image_units, 16},
105 Limit{shaderc_limit::shaderc_limit_max_fragment_uniform_components, 1024},
106 Limit{shaderc_limit::shaderc_limit_max_draw_buffers, 8},
107 Limit{shaderc_limit::shaderc_limit_max_vertex_uniform_vectors, 256},
108 Limit{shaderc_limit::shaderc_limit_max_varying_vectors, 15},
109 Limit{shaderc_limit::shaderc_limit_max_fragment_uniform_vectors, 256},
110 Limit{shaderc_limit::shaderc_limit_max_vertex_output_vectors, 16},
111 Limit{shaderc_limit::shaderc_limit_max_fragment_input_vectors, 15},
112 Limit{shaderc_limit::shaderc_limit_min_program_texel_offset, -8},
113 Limit{shaderc_limit::shaderc_limit_max_program_texel_offset, 7},
114 Limit{shaderc_limit::shaderc_limit_max_clip_distances, 8},
115 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_count_x, 65535},
116 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_count_y, 65535},
117 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_count_z, 65535},
118 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_size_x, 1024},
119 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_size_y, 1024},
120 Limit{shaderc_limit::shaderc_limit_max_compute_work_group_size_z, 64},
121 Limit{shaderc_limit::shaderc_limit_max_compute_uniform_components, 512},
122 Limit{shaderc_limit::shaderc_limit_max_compute_texture_image_units, 16},
123 Limit{shaderc_limit::shaderc_limit_max_compute_image_uniforms, 8},
124 Limit{shaderc_limit::shaderc_limit_max_compute_atomic_counters, 8},
125 Limit{shaderc_limit::shaderc_limit_max_compute_atomic_counter_buffers, 1},
126 Limit{shaderc_limit::shaderc_limit_max_varying_components, 60},
127 Limit{shaderc_limit::shaderc_limit_max_vertex_output_components, 64},
128 Limit{shaderc_limit::shaderc_limit_max_geometry_input_components, 64},
129 Limit{shaderc_limit::shaderc_limit_max_geometry_output_components, 128},
130 Limit{shaderc_limit::shaderc_limit_max_fragment_input_components, 128},
131 Limit{shaderc_limit::shaderc_limit_max_image_units, 8},
132 Limit{shaderc_limit::
133 shaderc_limit_max_combined_image_units_and_fragment_outputs,
135 Limit{shaderc_limit::shaderc_limit_max_combined_shader_output_resources,
137 Limit{shaderc_limit::shaderc_limit_max_image_samples, 0},
138 Limit{shaderc_limit::shaderc_limit_max_vertex_image_uniforms, 0},
139 Limit{shaderc_limit::shaderc_limit_max_tess_control_image_uniforms, 0},
140 Limit{shaderc_limit::shaderc_limit_max_tess_evaluation_image_uniforms, 0},
141 Limit{shaderc_limit::shaderc_limit_max_geometry_image_uniforms, 0},
142 Limit{shaderc_limit::shaderc_limit_max_fragment_image_uniforms, 8},
143 Limit{shaderc_limit::shaderc_limit_max_combined_image_uniforms, 8},
144 Limit{shaderc_limit::shaderc_limit_max_geometry_texture_image_units, 16},
145 Limit{shaderc_limit::shaderc_limit_max_geometry_output_vertices, 256},
146 Limit{shaderc_limit::shaderc_limit_max_geometry_total_output_components,
148 Limit{shaderc_limit::shaderc_limit_max_geometry_uniform_components, 512},
149 Limit{shaderc_limit::shaderc_limit_max_geometry_varying_components, 60},
150 Limit{shaderc_limit::shaderc_limit_max_tess_control_input_components,
152 Limit{shaderc_limit::shaderc_limit_max_tess_control_output_components,
154 Limit{shaderc_limit::shaderc_limit_max_tess_control_texture_image_units,
156 Limit{shaderc_limit::shaderc_limit_max_tess_control_uniform_components,
159 shaderc_limit::shaderc_limit_max_tess_control_total_output_components,
161 Limit{shaderc_limit::shaderc_limit_max_tess_evaluation_input_components,
163 Limit{shaderc_limit::shaderc_limit_max_tess_evaluation_output_components,
166 shaderc_limit::shaderc_limit_max_tess_evaluation_texture_image_units,
168 Limit{shaderc_limit::shaderc_limit_max_tess_evaluation_uniform_components,
170 Limit{shaderc_limit::shaderc_limit_max_tess_patch_components, 120},
171 Limit{shaderc_limit::shaderc_limit_max_patch_vertices, 32},
172 Limit{shaderc_limit::shaderc_limit_max_tess_gen_level, 64},
173 Limit{shaderc_limit::shaderc_limit_max_viewports, 16},
174 Limit{shaderc_limit::shaderc_limit_max_vertex_atomic_counters, 0},
175 Limit{shaderc_limit::shaderc_limit_max_tess_control_atomic_counters, 0},
176 Limit{shaderc_limit::shaderc_limit_max_tess_evaluation_atomic_counters,
178 Limit{shaderc_limit::shaderc_limit_max_geometry_atomic_counters, 0},
179 Limit{shaderc_limit::shaderc_limit_max_fragment_atomic_counters, 8},
180 Limit{shaderc_limit::shaderc_limit_max_combined_atomic_counters, 8},
181 Limit{shaderc_limit::shaderc_limit_max_atomic_counter_bindings, 1},
182 Limit{shaderc_limit::shaderc_limit_max_vertex_atomic_counter_buffers, 0},
184 shaderc_limit::shaderc_limit_max_tess_control_atomic_counter_buffers,
186 Limit{shaderc_limit::
187 shaderc_limit_max_tess_evaluation_atomic_counter_buffers,
189 Limit{shaderc_limit::shaderc_limit_max_geometry_atomic_counter_buffers,
191 Limit{shaderc_limit::shaderc_limit_max_fragment_atomic_counter_buffers,
193 Limit{shaderc_limit::shaderc_limit_max_combined_atomic_counter_buffers,
195 Limit{shaderc_limit::shaderc_limit_max_atomic_counter_buffer_size, 32},
196 Limit{shaderc_limit::shaderc_limit_max_transform_feedback_buffers, 4},
197 Limit{shaderc_limit::
198 shaderc_limit_max_transform_feedback_interleaved_components,
200 Limit{shaderc_limit::shaderc_limit_max_cull_distances, 8},
201 Limit{shaderc_limit::shaderc_limit_max_combined_clip_and_cull_distances,
203 Limit{shaderc_limit::shaderc_limit_max_samples, 4},
205 for (
auto& [limit,
value] : limits) {
206 compiler_opts.SetLimit(limit,
value);
211 constexpr uint32_t kBindingBaseOffset = 64;
212 static const shaderc_uniform_kind kUniformKinds[] = {
213 shaderc_uniform_kind::shaderc_uniform_kind_sampler,
214 shaderc_uniform_kind::shaderc_uniform_kind_texture,
215 shaderc_uniform_kind::shaderc_uniform_kind_image,
216 shaderc_uniform_kind::shaderc_uniform_kind_buffer,
217 shaderc_uniform_kind::shaderc_uniform_kind_storage_buffer,
220 for (
size_t i = 0u;
i <
sizeof(kUniformKinds) /
sizeof(shaderc_uniform_kind);
222 options.SetBindingBaseForStage(
223 shaderc_shader_kind::shaderc_fragment_shader,
237 static std::unique_ptr<UniqueIncluder>
Make(
238 std::shared_ptr<Includer> includer) {
239 return std::unique_ptr<UniqueIncluder>(
247 shaderc_include_result*
GetInclude(
const char* requested_source,
248 shaderc_include_type
type,
249 const char* requesting_source,
250 size_t include_depth)
override {
251 return includer_->GetInclude(requested_source,
260 return includer_->ReleaseInclude(
data);
264 std::shared_ptr<Includer> includer_;
267 : includer_(
std::move(includer)) {
271 UniqueIncluder(
const UniqueIncluder&) =
delete;
273 UniqueIncluder& operator=(
const UniqueIncluder&) =
delete;
277 shaderc::CompileOptions
options;
282 options.SetAutoBindUniforms(
true);
283 options.SetAutoMapLocations(
true);
288 options.SetGenerateDebugInfo();
306 options.AddMacroDefinition(macro);
std::shared_ptr< fml::Mapping > CompileToSPV(std::stringstream &error_stream, const shaderc::CompileOptions &spirv_options) const
SPIRVCompiler(const SourceOptions &options, std::shared_ptr< const fml::Mapping > sources)
Wraps a shared includer so unique includers may be created to satisfy the shaderc API....
void ReleaseInclude(shaderc_include_result *data) override
shaderc_include_result * GetInclude(const char *requested_source, shaderc_include_type type, const char *requesting_source, size_t include_depth) override
~UniqueIncluder()=default
static std::unique_ptr< UniqueIncluder > Make(std::shared_ptr< Includer > includer)
#define FML_CHECK(condition)
#define COMPILER_ERROR_NO_PREFIX(stream)
#define COMPILER_ERROR(stream)
std::string SourceLanguageToString(SourceLanguage source_language)
static void SetBindingBaseOffset(shaderc::CompileOptions &options)
shaderc_shader_kind ToShaderCShaderKind(SourceType type)
static void SetDefaultLimitations(shaderc::CompileOptions &compiler_opts)
std::string ShaderCErrorToString(shaderc_compilation_status status)
std::optional< shaderc_source_language > source_langauge
std::vector< std::string > macro_definitions
bool relaxed_vulkan_rules
shaderc_optimization_level optimization_level
std::optional< SPIRVCompilerSourceProfile > source_profile
std::shared_ptr< Includer > includer
shaderc::CompileOptions BuildShadercOptions() const
std::optional< SPIRVCompilerTargetEnv > target
SourceLanguage source_language
std::string entry_point_name
std::shared_ptr< const fml::Mapping > data