Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/dxil-spirv.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-11-08 17:04:42 +0300
committerGitHub <noreply@github.com>2022-11-08 17:04:42 +0300
commit95d9121381669740510c2b5f7605a8c2a18ffaf8 (patch)
treeec471f772a2737ce2125ddacbb0db97839f08fd5
parente6410fb48a2a43750512ab91586beda001fc721f (diff)
parent2bdd09a3afc1071d90a27d9fda9f8b7be19ab1fc (diff)
Merge pull request #133 from HansKristian-Work/per-primitive-mesh-capsHEADmaster
Fix some validation errors with Mesh Shaders
-rw-r--r--dxil_converter.cpp14
-rw-r--r--dxil_converter.hpp1
-rw-r--r--dxil_spirv_c.cpp5
-rw-r--r--opcodes/dxil/dxil_mesh.cpp5
-rw-r--r--spirv_module.cpp33
-rw-r--r--spirv_module.hpp2
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: