diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-11-08 17:04:42 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-08 17:04:42 +0300 |
commit | 95d9121381669740510c2b5f7605a8c2a18ffaf8 (patch) | |
tree | ec471f772a2737ce2125ddacbb0db97839f08fd5 | |
parent | e6410fb48a2a43750512ab91586beda001fc721f (diff) | |
parent | 2bdd09a3afc1071d90a27d9fda9f8b7be19ab1fc (diff) |
Fix some validation errors with Mesh Shaders
-rw-r--r-- | dxil_converter.cpp | 14 | ||||
-rw-r--r-- | dxil_converter.hpp | 1 | ||||
-rw-r--r-- | dxil_spirv_c.cpp | 5 | ||||
-rw-r--r-- | opcodes/dxil/dxil_mesh.cpp | 5 | ||||
-rw-r--r-- | spirv_module.cpp | 33 | ||||
-rw-r--r-- | spirv_module.hpp | 2 |
6 files changed, 53 insertions, 7 deletions
diff --git a/dxil_converter.cpp b/dxil_converter.cpp index 6d2827e..aec682e 100644 --- a/dxil_converter.cpp +++ b/dxil_converter.cpp @@ -3603,7 +3603,7 @@ bool Converter::Impl::emit_other_variables() { auto &builder = spirv_module.get_builder(); - if (execution_model == spv::ExecutionModelMeshEXT) + if (execution_model == spv::ExecutionModelMeshEXT && execution_mode_meta.stage_output_num_primitive) { unsigned index_dim = execution_mode_meta.primitive_index_dimension; @@ -4486,7 +4486,11 @@ bool Converter::Impl::emit_stage_input_variables() builder.addDecoration(variable_id, spv::DecorationComponent, vk_input.component); if (execution_model == spv::ExecutionModelFragment && (vk_input.flags & STAGE_IO_PER_PRIMITIVE)) + { builder.addDecoration(variable_id, spv::DecorationPerPrimitiveEXT); + builder.addExtension("SPV_EXT_mesh_shader"); + builder.addCapability(spv::CapabilityMeshShadingEXT); + } } } @@ -5833,6 +5837,14 @@ ConvertedFunction Converter::Impl::convert_entry_point() entry_point_meta = get_entry_point_meta(module, options.entry_point.empty() ? nullptr : options.entry_point.c_str()); execution_model = get_execution_model(module, entry_point_meta); + if (execution_model == spv::ExecutionModelFragment && + resource_mapping_iface && resource_mapping_iface->has_nontrivial_stage_input_remapping()) + { + // Force SPIR-V 1.4 for fragment shaders if we might end up requiring mesh shader capabilities. + // Non-trivial stage input remapping may require PerPrimitiveEXT decoration. + spirv_module.set_override_spirv_version(0x10400); + } + if (!entry_point_meta) { if (!options.entry_point.empty()) diff --git a/dxil_converter.hpp b/dxil_converter.hpp index 8986716..a4b973f 100644 --- a/dxil_converter.hpp +++ b/dxil_converter.hpp @@ -209,6 +209,7 @@ public: virtual bool remap_stage_output(const D3DStageIO &d3d_output, VulkanStageIO &vk_output) = 0; virtual unsigned get_root_constant_word_count() = 0; virtual unsigned get_root_descriptor_count() = 0; + virtual bool has_nontrivial_stage_input_remapping() = 0; }; enum class Option : uint32_t diff --git a/dxil_spirv_c.cpp b/dxil_spirv_c.cpp index a8247da..12fbac6 100644 --- a/dxil_spirv_c.cpp +++ b/dxil_spirv_c.cpp @@ -274,6 +274,11 @@ struct Remapper : ResourceRemappingInterface } } + bool has_nontrivial_stage_input_remapping() override + { + return stage_input_remapper != nullptr; + } + bool remap_stage_output(const D3DStageIO &d3d_output, VulkanStageIO &vk_output) override { dxil_spv_d3d_shader_stage_io c_output = { d3d_output.semantic, d3d_output.semantic_index }; diff --git a/opcodes/dxil/dxil_mesh.cpp b/opcodes/dxil/dxil_mesh.cpp index 5b784b1..a2e79f4 100644 --- a/opcodes/dxil/dxil_mesh.cpp +++ b/opcodes/dxil/dxil_mesh.cpp @@ -45,6 +45,11 @@ bool emit_emit_indices_instruction(Converter::Impl &impl, const llvm::CallInst * { auto &builder = impl.builder(); + // If we for some reason have max primitives 0 in the execution mode, + // just ignore any access to index buffer. + if (!impl.primitive_index_array_id) + return true; + unsigned index_dim = impl.execution_mode_meta.primitive_index_dimension; spv::Id index_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1, index_dim); spv::Id index_scalar_type_id = impl.get_type_id(DXIL::ComponentType::U32, 1, 1); diff --git a/spirv_module.cpp b/spirv_module.cpp index 06b9ddb..7af741c 100644 --- a/spirv_module.cpp +++ b/spirv_module.cpp @@ -126,6 +126,8 @@ struct SPIRVModule::Impl : BlockEmissionInterface Vector<CBVOp> physical_cbv_call_ids; DescriptorQAInfo descriptor_qa_info; + + uint32_t override_spirv_version = 0; }; spv::Id SPIRVModule::Impl::get_type_for_builtin(spv::BuiltIn builtin, bool &requires_flat) @@ -916,9 +918,16 @@ bool SPIRVModule::Impl::execution_model_is_ray_tracing() const bool SPIRVModule::Impl::spirv_requires_14() const { - return execution_model_is_ray_tracing() || - execution_model == spv::ExecutionModelMeshEXT || - execution_model == spv::ExecutionModelTaskEXT; + static const uint32_t Version_1_4 = 0x00010400; + if (override_spirv_version) + { + return override_spirv_version >= Version_1_4; + } + else + { + return execution_model_is_ray_tracing() || execution_model == spv::ExecutionModelMeshEXT || + execution_model == spv::ExecutionModelTaskEXT; + } } bool SPIRVModule::Impl::finalize_spirv(Vector<uint32_t> &spirv) @@ -929,9 +938,16 @@ bool SPIRVModule::Impl::finalize_spirv(Vector<uint32_t> &spirv) builder.dump(spirv); if (spirv.size() >= 2) { - static const uint32_t Version_1_3 = 0x00010300; - static const uint32_t Version_1_4 = 0x00010400; - spirv[1] = spirv_requires_14() ? Version_1_4 : Version_1_3; + if (override_spirv_version) + { + spirv[1] = override_spirv_version; + } + else + { + static const uint32_t Version_1_3 = 0x00010300; + static const uint32_t Version_1_4 = 0x00010400; + spirv[1] = spirv_requires_14() ? Version_1_4 : Version_1_3; + } } return !mark_error; } @@ -1396,6 +1412,11 @@ const DescriptorQAInfo &SPIRVModule::get_descriptor_qa_info() const return impl->descriptor_qa_info; } +void SPIRVModule::set_override_spirv_version(uint32_t version) +{ + impl->override_spirv_version = version; +} + bool SPIRVModule::opcode_is_control_dependent(spv::Op opcode) { // An opcode is considered control dependent if it is affected by other invocations in the subgroup. diff --git a/spirv_module.hpp b/spirv_module.hpp index b460fe4..241cce7 100644 --- a/spirv_module.hpp +++ b/spirv_module.hpp @@ -101,6 +101,8 @@ public: static bool opcode_is_control_dependent(spv::Op opcode); + void set_override_spirv_version(uint32_t version); + DXIL_SPV_OVERRIDE_NEW_DELETE private: |