diff --git a/lib/HLSL/DxilPackSignatureElement.cpp b/lib/HLSL/DxilPackSignatureElement.cpp index 3f6b0ce300..0337c4c28f 100644 --- a/lib/HLSL/DxilPackSignatureElement.cpp +++ b/lib/HLSL/DxilPackSignatureElement.cpp @@ -73,8 +73,10 @@ unsigned PackDxilSignature(DxilSignature &sig, DXIL::PackingStrategy packing) { // incrementally assign each element that belongs in the signature to the // start of the next free row for (auto &SE : packElements) { - SE.SetLocation(rowsUsed, 0); - rowsUsed += SE.GetRows(); + if (SE.GetRows() <= (32 - rowsUsed)) { + SE.SetLocation(rowsUsed, 0); + rowsUsed += SE.GetRows(); + } } break; diff --git a/lib/HLSL/HLSignatureLower.cpp b/lib/HLSL/HLSignatureLower.cpp index bb5c25f6ee..3e03d7725e 100644 --- a/lib/HLSL/HLSignatureLower.cpp +++ b/lib/HLSL/HLSignatureLower.cpp @@ -37,8 +37,7 @@ namespace { // Return semantic index. unsigned UpdateSemanticAndInterpMode(StringRef &semName, DXIL::InterpolationMode &mode, - DXIL::SigPointKind kind, - LLVMContext &Context) { + DXIL::SigPointKind kind, Function *Entry) { llvm::StringRef baseSemName; // The 'FOO' in 'FOO1'. uint32_t semIndex; // The '1' in 'FOO1' @@ -61,7 +60,9 @@ unsigned UpdateSemanticAndInterpMode(StringRef &semName, case InterpolationMode::Kind::Constant: case InterpolationMode::Kind::Undefined: case InterpolationMode::Kind::Invalid: { - llvm_unreachable("invalid interpolation mode for SV_Position"); + dxilutil::EmitErrorOnFunction( + Entry->getContext(), Entry, + "invalid interpolation mode for SV_Position"); } break; case InterpolationMode::Kind::LinearNoperspective: case InterpolationMode::Kind::LinearNoperspectiveCentroid: @@ -80,7 +81,7 @@ DxilSignatureElement *FindArgInSignature(Argument &arg, DxilSignature &sig) { // Match output ID. unsigned semIndex = - UpdateSemanticAndInterpMode(semantic, interpMode, kind, arg.getContext()); + UpdateSemanticAndInterpMode(semantic, interpMode, kind, arg.getParent()); for (uint32_t i = 0; i < sig.GetElements().size(); i++) { DxilSignatureElement &SE = sig.GetElement(i); @@ -290,7 +291,7 @@ void HLSignatureLower::ProcessArgument(Function *func, return; } UpdateSemanticAndInterpMode(semanticStr, interpMode, sigPoint->GetKind(), - arg.getContext()); + func); // Get Semantic interpretation, skipping if not in signature const Semantic *pSemantic = Semantic::GetByName(semanticStr); @@ -519,15 +520,17 @@ void HLSignatureLower::AllocateDxilInputOutputs() { hlsl::PackDxilSignature(EntrySig.InputSignature, packing); if (!EntrySig.InputSignature.IsFullyAllocated()) { - llvm_unreachable( + dxilutil::EmitErrorOnFunction( + Entry->getContext(), Entry, "Failed to allocate all input signature elements in available space."); } if (props.shaderKind != DXIL::ShaderKind::Amplification) { hlsl::PackDxilSignature(EntrySig.OutputSignature, packing); if (!EntrySig.OutputSignature.IsFullyAllocated()) { - llvm_unreachable("Failed to allocate all output signature elements in " - "available space."); + dxilutil::EmitErrorOnFunction(Entry->getContext(), Entry, + "Failed to allocate all output signature " + "elements in available space."); } } @@ -536,8 +539,9 @@ void HLSignatureLower::AllocateDxilInputOutputs() { props.shaderKind == DXIL::ShaderKind::Mesh) { hlsl::PackDxilSignature(EntrySig.PatchConstOrPrimSignature, packing); if (!EntrySig.PatchConstOrPrimSignature.IsFullyAllocated()) { - llvm_unreachable("Failed to allocate all patch constant signature " - "elements in available space."); + dxilutil::EmitErrorOnFunction(Entry->getContext(), Entry, + "Failed to allocate all patch constant " + "signature elements in available space."); } } } diff --git a/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/ia_sig_too_large.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/ia_sig_too_large.hlsl new file mode 100644 index 0000000000..fdb10a19da --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/ia_sig_too_large.hlsl @@ -0,0 +1,14 @@ +// RUN: %dxc -E main -T vs_6_0 %s | FileCheck %s + +// Expect error when the Input Assembler (vertex input) signature is too large +// CHECK: error: Failed to allocate all input signature elements in available space. + +struct VSIN { + float4 pos : Position; + float array1[30] : ARRAY1; + float array2[2] : ARRAY2; +}; + +float4 main(VSIN In) : SV_Position { + return In.pos; +} diff --git a/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/invalid_interpolation_sv_position.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/invalid_interpolation_sv_position.hlsl new file mode 100644 index 0000000000..e9ab3558cd --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/invalid_interpolation_sv_position.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s + +// CHECK: error: invalid interpolation mode for SV_Position + +struct PSIN { + nointerpolation float4 pos : SV_Position; +}; + +float main(PSIN In) : SV_Target{ + return In.pos.x; +} diff --git a/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/output_sig_too_large.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/output_sig_too_large.hlsl new file mode 100644 index 0000000000..1541621180 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/output_sig_too_large.hlsl @@ -0,0 +1,15 @@ +// RUN: %dxc -E main -T vs_6_0 %s | FileCheck %s + +// Expect error when the output signature is too large +// CHECK: error: Failed to allocate all output signature elements in available space. + +struct VSOUT { + float4 pos : SV_Position; + float4 array1[30] : BIGARRAY; + float4 array2[2] : SMALLARRAY; +}; + +VSOUT main() { + VSOUT Out = (VSOUT)0; + return Out; +} diff --git a/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/pc_sig_too_large.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/pc_sig_too_large.hlsl new file mode 100644 index 0000000000..944fe7a380 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/diagnostics/errors/pc_sig_too_large.hlsl @@ -0,0 +1,39 @@ +// RUN: %dxc -E main -T hs_6_0 %s | FileCheck %s + +// Expect error when the patch constant signature is too large +// CHECK: error: Failed to allocate all patch constant signature elements in available space. + +#define NumOutPoints 2 + +struct HsCpIn { + float4 pos : SV_Position; +}; + +struct HsCpOut { + float4 pos : SV_Position; +}; + +struct HsPcfOut +{ + float tessOuter[4] : SV_TessFactor; + float tessInner[2] : SV_InsideTessFactor; + float4 array1[25] : BIGARRAY; + float4 array2[2] : SMALLARRAY; +}; + +HsPcfOut pcf(InputPatch patch, uint patchId : SV_PrimitiveID) { + HsPcfOut output = (HsPcfOut)0; + return output; +} + +[patchconstantfunc("pcf")] +[domain("quad")] +[partitioning("fractional_odd")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(NumOutPoints)] +HsCpOut main(InputPatch patch, + uint cpId : SV_OutputControlPointID, + uint patchId : SV_PrimitiveID) { + HsCpOut output = (HsCpOut)0; + return output; +}