@@ -132,6 +132,11 @@ Reflector::Reflector(Options options,
132132 return ;
133133 }
134134
135+ shader_bundle_data_ = GenerateShaderBundleData ();
136+ if (!shader_bundle_data_) {
137+ return ;
138+ }
139+
135140 is_valid_ = true ;
136141}
137142
@@ -166,6 +171,10 @@ std::shared_ptr<RuntimeStageData> Reflector::GetRuntimeStageData() const {
166171 return runtime_stage_data_;
167172}
168173
174+ std::shared_ptr<ShaderBundleData> Reflector::GetShaderBundleData () const {
175+ return shader_bundle_data_;
176+ }
177+
169178std::optional<nlohmann::json> Reflector::GenerateTemplateArguments () const {
170179 nlohmann::json root;
171180
@@ -380,6 +389,69 @@ std::shared_ptr<RuntimeStageData> Reflector::GenerateRuntimeStageData() const {
380389 return data;
381390}
382391
392+ std::shared_ptr<ShaderBundleData> Reflector::GenerateShaderBundleData () const {
393+ const auto & entrypoints = compiler_->get_entry_points_and_stages ();
394+ if (entrypoints.size () != 1u ) {
395+ VALIDATION_LOG << " Single entrypoint not found." ;
396+ return nullptr ;
397+ }
398+ auto data = std::make_shared<ShaderBundleData>(
399+ options_.entry_point_name , //
400+ entrypoints.front ().execution_model , //
401+ options_.target_platform //
402+ );
403+ data->SetShaderData (shader_data_);
404+
405+ // Sort the IR so that the uniforms are in declaration order.
406+ std::vector<spirv_cross::ID> uniforms =
407+ SortUniforms (ir_.get (), compiler_.GetCompiler ());
408+
409+ for (auto & sorted_id : uniforms) {
410+ auto var = ir_->ids [sorted_id].get <spirv_cross::SPIRVariable>();
411+ const auto spir_type = compiler_->get_type (var.basetype );
412+ UniformDescription uniform_description;
413+ uniform_description.name = compiler_->get_name (var.self );
414+ uniform_description.location = compiler_->get_decoration (
415+ var.self , spv::Decoration::DecorationLocation);
416+ uniform_description.type = spir_type.basetype ;
417+ uniform_description.rows = spir_type.vecsize ;
418+ uniform_description.columns = spir_type.columns ;
419+ uniform_description.bit_width = spir_type.width ;
420+ uniform_description.array_elements = GetArrayElements (spir_type);
421+ data->AddUniformDescription (std::move (uniform_description));
422+ }
423+
424+ // We only need to worry about storing vertex attributes.
425+ if (entrypoints.front ().execution_model == spv::ExecutionModelVertex) {
426+ const auto inputs = compiler_->get_shader_resources ().stage_inputs ;
427+ auto input_offsets = ComputeOffsets (inputs);
428+ for (const auto & input : inputs) {
429+ auto location = compiler_->get_decoration (
430+ input.id , spv::Decoration::DecorationLocation);
431+ std::optional<size_t > offset = input_offsets[location];
432+
433+ const auto type = compiler_->get_type (input.type_id );
434+
435+ InputDescription input_description;
436+ input_description.name = input.name ;
437+ input_description.location = compiler_->get_decoration (
438+ input.id , spv::Decoration::DecorationLocation);
439+ input_description.set = compiler_->get_decoration (
440+ input.id , spv::Decoration::DecorationDescriptorSet);
441+ input_description.binding = compiler_->get_decoration (
442+ input.id , spv::Decoration::DecorationBinding);
443+ input_description.type = type.basetype ;
444+ input_description.bit_width = type.width ;
445+ input_description.vec_size = type.vecsize ;
446+ input_description.columns = type.columns ;
447+ input_description.offset = offset.value_or (0u );
448+ data->AddInputDescription (std::move (input_description));
449+ }
450+ }
451+
452+ return data;
453+ }
454+
383455std::optional<uint32_t > Reflector::GetArrayElements (
384456 const spirv_cross::SPIRType& type) const {
385457 if (type.array .empty ()) {
0 commit comments