MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ reflect_spirv()

bool MayaFlux::Core::VKShaderModule::reflect_spirv ( const std::vector< uint32_t > &  spirv_code)
private

Perform reflection on SPIR-V bytecode.

Parameters
spirv_codeSPIR-V bytecode
Returns
true if reflection succeeded

Uses SPIRV-Reflect library to extract bindings, push constants, workgroup sizes, etc. Falls back to basic parsing if library unavailable.

Definition at line 343 of file VKShaderModule.cpp.

344{
345#ifdef MAYAFLUX_USE_SPIRV_REFLECT
346 SpvReflectShaderModule module;
347 SpvReflectResult result = spvReflectCreateShaderModule(
348 spirv_code.size() * sizeof(uint32_t),
349 spirv_code.data(),
350 &module);
351
352 if (result != SPV_REFLECT_RESULT_SUCCESS) {
354 "SPIRV-Reflect failed: {}", static_cast<int>(result));
355 return false;
356 }
357
358 uint32_t binding_count = 0;
359 result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
360 if (result == SPV_REFLECT_RESULT_SUCCESS && binding_count > 0) {
361 std::vector<SpvReflectDescriptorBinding*> bindings(binding_count);
362 spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.data());
363
364 for (const auto* binding : bindings) {
365 ShaderReflection::DescriptorBinding desc;
366 desc.set = binding->set;
367 desc.binding = binding->binding;
368 desc.type = static_cast<vk::DescriptorType>(binding->descriptor_type);
369 desc.stage = m_stage;
370 desc.count = binding->count;
371 desc.name = binding->name ? binding->name : "";
372
373 m_reflection.bindings.push_back(desc);
374 }
375
377 "Reflected {} descriptor bindings", binding_count);
378 }
379
380 uint32_t push_constant_count = 0;
381 result = spvReflectEnumeratePushConstantBlocks(&module, &push_constant_count, nullptr);
382 if (result == SPV_REFLECT_RESULT_SUCCESS && push_constant_count > 0) {
383 std::vector<SpvReflectBlockVariable*> push_constants(push_constant_count);
384 spvReflectEnumeratePushConstantBlocks(&module, &push_constant_count, push_constants.data());
385
386 for (const auto* block : push_constants) {
387 ShaderReflection::PushConstantRange range;
388 range.stage = m_stage;
389 range.offset = block->offset;
390 range.size = block->size;
391
392 m_reflection.push_constants.push_back(range);
393 }
394
396 "Reflected {} push constant blocks", push_constant_count);
397 }
398
399 if (m_stage == vk::ShaderStageFlagBits::eCompute) {
400 m_reflection.workgroup_size = std::array<uint32_t, 3> {
401 module.entry_points[0].local_size.x,
402 module.entry_points[0].local_size.y,
403 module.entry_points[0].local_size.z
404 };
405
407 "Compute shader workgroup size: [{}, {}, {}]",
411 }
412
413 spvReflectDestroyShaderModule(&module);
414 return true;
415
416#else
418 "SPIRV-Reflect not available - shader reflection disabled");
419
420 if (m_stage == vk::ShaderStageFlagBits::eCompute) {
421 // SPIR-V OpExecutionMode LocalSize pattern
422 // This is a simplified parser - production code should use SPIRV-Reflect
423 for (size_t i = 0; i < spirv_code.size() - 4; ++i) {
424 if ((spirv_code[i] & 0xFFFF) == 17) {
425 uint32_t mode = spirv_code[i + 2];
426 if (mode == 17) {
427 m_reflection.workgroup_size = std::array<uint32_t, 3> {
428 spirv_code[i + 3],
429 spirv_code[i + 4],
430 spirv_code[i + 5]
431 };
432
434 "Extracted compute workgroup size: [{}, {}, {}]",
438 break;
439 }
440 }
441 }
442 }
443
444 return false; // Reflection incomplete without SPIRV-Reflect
445#endif
446}
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
vk::ShaderStageFlagBits m_stage
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
std::vector< DescriptorBinding > bindings
std::vector< PushConstantRange > push_constants
std::optional< std::array< uint32_t, 3 > > workgroup_size
local_size_x/y/z

References MayaFlux::Core::ShaderReflection::DescriptorBinding::binding, MayaFlux::Core::ShaderReflection::bindings, MayaFlux::Journal::Core, MayaFlux::Core::ShaderReflection::DescriptorBinding::count, MayaFlux::Journal::GraphicsBackend, m_reflection, m_stage, MF_DEBUG, MF_WARN, MayaFlux::Core::ShaderReflection::DescriptorBinding::name, MayaFlux::Core::ShaderReflection::PushConstantRange::offset, MayaFlux::Core::ShaderReflection::push_constants, MayaFlux::Core::ShaderReflection::DescriptorBinding::set, MayaFlux::Core::ShaderReflection::PushConstantRange::size, MayaFlux::Core::ShaderReflection::DescriptorBinding::stage, MayaFlux::Core::ShaderReflection::PushConstantRange::stage, MayaFlux::Core::ShaderReflection::DescriptorBinding::type, and MayaFlux::Core::ShaderReflection::workgroup_size.

Referenced by create_from_spirv().

+ Here is the caller graph for this function: