Update type validation to support legal UDT case.

New Rules:
outer type may be: [ptr to][1 dim array of]( UDT struct | scalar )
inner type (UDT struct member) may be: [N dim array of]( UDT struct | scalar )
scalar type may be: ( float(16|32|64) | int(16|32|64) )

- Disallow pointers to pointers, and pointers in structs
- Disallow multi-dim arrays at top-level, but allow within struct
This commit is contained in:
Tex Riddell 2019-10-17 20:41:53 -07:00
Родитель a9fe6e19f5
Коммит 6357448a38
4 изменённых файлов: 21 добавлений и 5 удалений

Просмотреть файл

@ -3184,6 +3184,7 @@ TYPES.DEFINED Type must be defined based on DXIL pri
TYPES.I8 I8 can only used as immediate value for intrinsic
TYPES.INTWIDTH Int type must be of valid width
TYPES.NOMULTIDIM Only one dimension allowed for array type
TYPES.NOPTRTOPTR Pointers to pointers, or pointers in structures are not allowed
TYPES.NOVECTOR Vector types must not be present
UNI.NOWAVESENSITIVEGRADIENT Gradient operations are not affected by wave-sensitive data or control flow.
========================================= =======================================================================================================================================================================================================================================================================================================

Просмотреть файл

@ -271,6 +271,7 @@ enum class ValidationRule : unsigned {
TypesI8, // I8 can only used as immediate value for intrinsic
TypesIntWidth, // Int type must be of valid width
TypesNoMultiDim, // Only one dimension allowed for array type
TypesNoPtrToPtr, // Pointers to pointers, or pointers in structures are not allowed
TypesNoVector, // Vector types must not be present
// Uniform analysis

Просмотреть файл

@ -201,6 +201,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
case hlsl::ValidationRule::TypesDefined: return "Type '%0' is not defined on DXIL primitives";
case hlsl::ValidationRule::TypesIntWidth: return "Int type '%0' has an invalid width";
case hlsl::ValidationRule::TypesNoMultiDim: return "Only one dimension allowed for array type";
case hlsl::ValidationRule::TypesNoPtrToPtr: return "Pointers to pointers, or pointers in structures are not allowed";
case hlsl::ValidationRule::TypesI8: return "I8 can only used as immediate value for intrinsic";
case hlsl::ValidationRule::SmName: return "Unknown shader model '%0'";
case hlsl::ValidationRule::SmDxilVersion: return "Shader model requires Dxil Version %0,%1";
@ -2699,18 +2700,30 @@ static bool IsDxilBuiltinStructType(StructType *ST, hlsl::OP *hlslOP) {
}
}
static bool ValidateType(Type *Ty, ValidationContext &ValCtx) {
// outer type may be: [ptr to][1 dim array of]( UDT struct | scalar )
// inner type (UDT struct member) may be: [N dim array of]( UDT struct | scalar )
// scalar type may be: ( float(16|32|64) | int(16|32|64) )
static bool ValidateType(Type *Ty, ValidationContext &ValCtx, bool bInner = false) {
DXASSERT_NOMSG(Ty != nullptr);
if (Ty->isPointerTy()) {
return ValidateType(Ty->getPointerElementType(), ValCtx);
Type *EltTy = Ty->getPointerElementType();
if (bInner || EltTy->isPointerTy()) {
ValCtx.EmitTypeError(Ty, ValidationRule::TypesNoPtrToPtr);
return false;
}
Ty = EltTy;
}
if (Ty->isArrayTy()) {
Type *EltTy = Ty->getArrayElementType();
if (isa<ArrayType>(EltTy)) {
if (!bInner && isa<ArrayType>(EltTy)) {
// Outermost array should be converted to single-dim,
// but arrays inside struct are allowed to be multi-dim
ValCtx.EmitTypeError(Ty, ValidationRule::TypesNoMultiDim);
return false;
}
return ValidateType(EltTy, ValCtx);
while (EltTy->isArrayTy())
EltTy = EltTy->getArrayElementType();
Ty = EltTy;
}
if (Ty->isStructTy()) {
bool result = true;
@ -2728,7 +2741,7 @@ static bool ValidateType(Type *Ty, ValidationContext &ValCtx) {
result = false;
}
for (auto e : ST->elements()) {
if (!ValidateType(e, ValCtx)) {
if (!ValidateType(e, ValCtx, /*bInner*/true)) {
result = false;
}
}

Просмотреть файл

@ -2390,6 +2390,7 @@ class db_dxil(object):
self.add_valrule_msg("Types.Defined", "Type must be defined based on DXIL primitives", "Type '%0' is not defined on DXIL primitives")
self.add_valrule_msg("Types.IntWidth", "Int type must be of valid width", "Int type '%0' has an invalid width")
self.add_valrule("Types.NoMultiDim", "Only one dimension allowed for array type")
self.add_valrule("Types.NoPtrToPtr", "Pointers to pointers, or pointers in structures are not allowed")
self.add_valrule("Types.I8", "I8 can only used as immediate value for intrinsic")
self.add_valrule_msg("Sm.Name", "Target shader model name must be known", "Unknown shader model '%0'")