sema: check input patch size mismatch earlier. (#6363)
The check was done in the DXIL backend, and not in the SPIR-V backend. This causes the issue to be ignored on the SPIR-V side. Moved the check earlier to SEMA so a single check works for both backends. I had to split the existing HLSL check as it doesn't support having 2 run lines (AFAIK). Fixes #3739 --------- Signed-off-by: Nathan Gauër <brioche@google.com>
This commit is contained in:
Родитель
ec5b8aaba3
Коммит
cbbf459969
|
@ -7834,6 +7834,8 @@ def err_hlsl_missing_patch_constant_function : Error<
|
|||
"patch constant function '%0' must be defined">;
|
||||
def err_hlsl_patch_reachability_not_allowed : Error<
|
||||
"%select{patch constant|entry}0 function '%1' should not be reachable from %select{patch constant|entry}2 function '%3'">;
|
||||
def err_hlsl_patch_input_size_mismatch : Error<
|
||||
"Patch constant function's input patch input should have %0 elements, but has %1.">;
|
||||
def warn_hlsl_structurize_exits_lifetime_markers_conflict : Warning <
|
||||
"structurize-returns skipped function '%0' due to incompatibility with lifetime markers. Use -disable-lifetime-markers to enable structurize-exits on this function.">,
|
||||
InGroup< HLSLStructurizeExitsLifetimeMarkersConflict >;
|
||||
|
|
|
@ -1496,18 +1496,6 @@ void SetPatchConstantFunctionWithAttr(
|
|||
if (patchConstantFunctionPropsMap.count(patchConstFunc)) {
|
||||
const DxilFunctionProps &patchProps =
|
||||
*patchConstantFunctionPropsMap[patchConstFunc];
|
||||
if (patchProps.ShaderProps.HS.inputControlPoints != 0 &&
|
||||
patchProps.ShaderProps.HS.inputControlPoints !=
|
||||
HSProps->ShaderProps.HS.inputControlPoints) {
|
||||
clang::DiagnosticsEngine &Diags = CGM.getDiags();
|
||||
unsigned DiagID =
|
||||
Diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
|
||||
"Patch constant function's input patch input "
|
||||
"should have %0 elements, but has %1.");
|
||||
Diags.Report(Entry->second.SL, DiagID)
|
||||
<< HSProps->ShaderProps.HS.inputControlPoints
|
||||
<< patchProps.ShaderProps.HS.inputControlPoints;
|
||||
}
|
||||
if (patchProps.ShaderProps.HS.outputControlPoints != 0 &&
|
||||
patchProps.ShaderProps.HS.outputControlPoints !=
|
||||
HSProps->ShaderProps.HS.outputControlPoints) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "clang/Sema/SemaHLSL.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include <optional>
|
||||
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
@ -332,6 +333,17 @@ private:
|
|||
std::set<CXXMemberCallExpr *> &DiagnosedCalls;
|
||||
};
|
||||
|
||||
std::optional<uint32_t>
|
||||
getFunctionInputPatchCount(const FunctionDecl *function) {
|
||||
for (const auto *param : function->params()) {
|
||||
if (!hlsl::IsHLSLInputPatchType(param->getType()))
|
||||
continue;
|
||||
return hlsl::GetHLSLInputPatchCount(param->getType());
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void hlsl::DiagnoseTranslationUnit(clang::Sema *self) {
|
||||
|
@ -462,6 +474,15 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) {
|
|||
<< 0 << pPatchFnDecl->getName() << 1 << FDecl->getName();
|
||||
}
|
||||
}
|
||||
|
||||
auto hullPatchCount = getFunctionInputPatchCount(pPatchFnDecl);
|
||||
auto functionPatchCount = getFunctionInputPatchCount(FDecl);
|
||||
if (hullPatchCount.has_value() && functionPatchCount.has_value() &&
|
||||
hullPatchCount.value() != functionPatchCount.value()) {
|
||||
self->Diag(pPatchFnDecl->getSourceRange().getBegin(),
|
||||
diag::err_hlsl_patch_input_size_mismatch)
|
||||
<< functionPatchCount.value() << hullPatchCount.value();
|
||||
}
|
||||
}
|
||||
|
||||
DXIL::ShaderKind EntrySK = shaderModel->GetKind();
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %dxc -T hs_6_0 -E main %s -spirv -verify
|
||||
|
||||
|
||||
struct ControlPoint { float4 position : POSITION; };
|
||||
|
||||
struct HullPatchOut {
|
||||
float edge [3] : SV_TessFactor;
|
||||
float inside : SV_InsideTessFactor;
|
||||
};
|
||||
|
||||
HullPatchOut HullConst (InputPatch<ControlPoint,2> v) { /* expected-error{{Patch constant function's input patch input should have 3 elements, but has 2.}} */
|
||||
return (HullPatchOut)0;
|
||||
}
|
||||
|
||||
[domain("tri")]
|
||||
[partitioning("fractional_odd")]
|
||||
[outputtopology("triangle_cw")]
|
||||
[patchconstantfunc("HullConst")]
|
||||
[outputcontrolpoints(0)]
|
||||
ControlPoint main(InputPatch<ControlPoint,3> v, uint id : SV_OutputControlPointID) {
|
||||
return v[id];
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// RUN: %dxc -E main -T hs_6_0 %s | FileCheck %s
|
||||
|
||||
// CHECK-DAG: Patch Constant function HSPerPatchFunc should not have inout param
|
||||
// CHECK-DAG: Patch constant function's output patch input should have 3 elements, but has 5.
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// SimpleTessellation.hlsl
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
struct PSSceneIn
|
||||
{
|
||||
float4 pos : SV_Position;
|
||||
float2 tex : TEXCOORD0;
|
||||
float3 norm : NORMAL;
|
||||
|
||||
uint RTIndex : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Simple forwarding Tessellation shaders
|
||||
|
||||
struct HSPerVertexData
|
||||
{
|
||||
// This is just the original vertex verbatim. In many real life cases this would be a
|
||||
// control point instead
|
||||
PSSceneIn v;
|
||||
};
|
||||
|
||||
struct HSPerPatchData
|
||||
{
|
||||
// We at least have to specify tess factors per patch
|
||||
// As we're tesselating triangles, there will be 4 tess factors
|
||||
// In real life case this might contain face normal, for example
|
||||
float edges[ 3 ] : SV_TessFactor;
|
||||
float inside : SV_InsideTessFactor;
|
||||
};
|
||||
|
||||
float4 HSPerPatchFunc()
|
||||
{
|
||||
return 1.8;
|
||||
}
|
||||
|
||||
HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 12 > points, OutputPatch<HSPerVertexData, 5> outp, inout float x)
|
||||
{
|
||||
HSPerPatchData d;
|
||||
|
||||
d.edges[ 0 ] = 1;
|
||||
d.edges[ 1 ] = 1;
|
||||
d.edges[ 2 ] = 1;
|
||||
d.inside = 1;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
// hull per-control point shader
|
||||
[domain("tri")]
|
||||
[partitioning("fractional_odd")]
|
||||
[outputtopology("triangle_cw")]
|
||||
[patchconstantfunc("HSPerPatchFunc")]
|
||||
[outputcontrolpoints(3)]
|
||||
HSPerVertexData main(const uint id : SV_OutputControlPointID,
|
||||
const InputPatch< PSSceneIn, 12 > points )
|
||||
{
|
||||
HSPerVertexData v;
|
||||
|
||||
// Just forward the vertex
|
||||
v.v = points[ id ];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
// RUN: %dxc -E main -T hs_6_0 %s | FileCheck %s
|
||||
|
||||
// CHECK-DAG: Patch Constant function HSPerPatchFunc should not have inout param
|
||||
// CHECK-DAG: Patch constant function's input patch input should have 3 elements, but has 12.
|
||||
// CHECK-DAG: Patch constant function's output patch input should have 3 elements, but has 5.
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// SimpleTessellation.hlsl
|
||||
|
@ -46,7 +44,7 @@ float4 HSPerPatchFunc()
|
|||
return 1.8;
|
||||
}
|
||||
|
||||
HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 12 > points, OutputPatch<HSPerVertexData, 5> outp, inout float x)
|
||||
HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 12 > points, OutputPatch<HSPerVertexData, 3> outp)
|
||||
{
|
||||
HSPerPatchData d;
|
||||
|
||||
|
@ -64,8 +62,8 @@ HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 12 > points, OutputP
|
|||
[outputtopology("triangle_cw")]
|
||||
[patchconstantfunc("HSPerPatchFunc")]
|
||||
[outputcontrolpoints(3)]
|
||||
HSPerVertexData main( const uint id : SV_OutputControlPointID,
|
||||
const InputPatch< PSSceneIn, 3 > points )
|
||||
HSPerVertexData main(const uint id : SV_OutputControlPointID,
|
||||
const InputPatch< PSSceneIn, 3 > points )
|
||||
{
|
||||
HSPerVertexData v;
|
||||
|
||||
|
@ -74,5 +72,3 @@ HSPerVertexData main( const uint id : SV_OutputControlPointID,
|
|||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче