diff options
-rw-r--r-- | dxil_converter.cpp | 49 | ||||
-rw-r--r-- | opcodes/converter_impl.hpp | 2 |
2 files changed, 51 insertions, 0 deletions
diff --git a/dxil_converter.cpp b/dxil_converter.cpp index 1e18170..1f03eed 100644 --- a/dxil_converter.cpp +++ b/dxil_converter.cpp @@ -5214,6 +5214,50 @@ bool Converter::Impl::emit_execution_modes_ray_tracing(spv::ExecutionModel model return true; } +bool Converter::Impl::emit_execution_modes_mesh() +{ + auto &builder = spirv_module.get_builder(); + auto *func = spirv_module.get_entry_function(); + + builder.addExtension("SPV_EXT_mesh_shader"); + builder.addCapability(spv::CapabilityMeshShadingEXT); + + auto *ms_state_node = get_shader_property_tag(entry_point_meta, DXIL::ShaderPropertyTag::MSState); + + if (ms_state_node) { + auto *arguments = llvm::cast<llvm::MDNode>(*ms_state_node); + unsigned max_vertex_count = get_constant_metadata(arguments, 1); + unsigned max_primitive_count = get_constant_metadata(arguments, 2); + auto topology = static_cast<DXIL::MeshOutputTopology>(get_constant_metadata(arguments, 3)); + + builder.addExecutionMode(func, spv::ExecutionModeOutputVertices, max_vertex_count); + builder.addExecutionMode(func, spv::ExecutionModeOutputPrimitivesEXT, max_primitive_count); + + switch (topology) + { + case DXIL::MeshOutputTopology::Undefined: + break; + + case DXIL::MeshOutputTopology::Line: + builder.addExecutionMode(func, spv::ExecutionModeOutputLinesEXT); + break; + + case DXIL::MeshOutputTopology::Triangle: + builder.addExecutionMode(func, spv::ExecutionModeOutputTrianglesEXT); + break; + + default: + LOGE("Unexpected mesh output topology (%u).\n", unsigned(topology)); + return false; + } + + execution_mode_meta.stage_output_num_vertex = max_vertex_count; + execution_mode_meta.stage_output_num_primitive = max_primitive_count; + return true; + } else + return false; +} + bool Converter::Impl::emit_execution_modes_fp_denorm() { // Check for SM 6.2 denorm handling. Only applies to FP32. @@ -5300,6 +5344,11 @@ bool Converter::Impl::emit_execution_modes() return false; break; + case spv::ExecutionModelMeshEXT: + if (!emit_execution_modes_mesh()) + return false; + break; + default: break; } diff --git a/opcodes/converter_impl.hpp b/opcodes/converter_impl.hpp index 30e4ddc..79b8124 100644 --- a/opcodes/converter_impl.hpp +++ b/opcodes/converter_impl.hpp @@ -180,6 +180,7 @@ struct Converter::Impl bool emit_execution_modes_domain(); bool emit_execution_modes_pixel(); bool emit_execution_modes_ray_tracing(spv::ExecutionModel model); + bool emit_execution_modes_mesh(); bool emit_execution_modes_fp_denorm(); bool analyze_instructions(); @@ -250,6 +251,7 @@ struct Converter::Impl { unsigned stage_input_num_vertex = 0; unsigned stage_output_num_vertex = 0; + unsigned stage_output_num_primitive = 0; unsigned gs_stream_active_mask = 0; llvm::Function *patch_constant_function = nullptr; unsigned workgroup_threads[3] = {}; |