Skip to content

Commit

Permalink
Allow select() to work with samplers (#5508)
Browse files Browse the repository at this point in the history
Add any_sampler builtin parameter type. This will match any sampler type
as the select() built-in added with HLSL 2021 requires.

Adds a new built-in overload that takes the any_sampler type and ensures
that the last two arguments and return type match. Many of the changes
were required because we never had to ensure object parameter types
matched nor transmit that type to the return type before. Most of the
changes to MatchArguments in SemaHLSL are addressing new issues this
revealed. Non-basic types can pass the conversion check if they outright
match.

Adds testing to select() and the ternary operator that it supplements
for these usages

Fixes #4673
  • Loading branch information
pow2clk authored Aug 9, 2023
1 parent 871fba1 commit a6497c3
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 78 deletions.
48 changes: 29 additions & 19 deletions include/dxc/dxcapi.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,32 @@ enum LEGAL_INTRINSIC_TEMPLATES {
static const BYTE INTRIN_COMPTYPE_FROM_TYPE_ELT0 = 0xff;

enum LEGAL_INTRINSIC_COMPTYPES {
LICOMPTYPE_VOID = 0, // void, used for function returns
LICOMPTYPE_BOOL = 1, // bool
LICOMPTYPE_INT = 2, // i32, int-literal
LICOMPTYPE_UINT = 3, // u32, int-literal
LICOMPTYPE_ANY_INT = 4, // i32, u32, i64, u64, int-literal
LICOMPTYPE_ANY_INT32 = 5, // i32, u32, int-literal
LICOMPTYPE_UINT_ONLY = 6, // u32, u64, int-literal; no casts allowed
LICOMPTYPE_FLOAT = 7, // f32, partial-precision-f32, float-literal
LICOMPTYPE_ANY_FLOAT = 8, // f32, partial-precision-f32, f64, float-literal, min10-float, min16-float, half
LICOMPTYPE_FLOAT_LIKE = 9, // f32, partial-precision-f32, float-literal, min10-float, min16-float, half
LICOMPTYPE_FLOAT_DOUBLE = 10, // f32, partial-precision-f32, f64, float-literal
LICOMPTYPE_DOUBLE = 11, // f64, float-literal
LICOMPTYPE_DOUBLE_ONLY = 12, // f64; no casts allowed
LICOMPTYPE_NUMERIC = 13, // float-literal, f32, partial-precision-f32, f64, min10-float, min16-float, int-literal, i32, u32, min12-int, min16-int, min16-uint, i64, u64
LICOMPTYPE_NUMERIC32 = 14, // float-literal, f32, partial-precision-f32, int-literal, i32, u32
LICOMPTYPE_NUMERIC32_ONLY = 15, // float-literal, f32, partial-precision-f32, int-literal, i32, u32; no casts allowed
LICOMPTYPE_ANY = 16, // float-literal, f32, partial-precision-f32, f64, min10-float, min16-float, int-literal, i32, u32, min12-int, min16-int, min16-uint, bool, i64, u64
LICOMPTYPE_VOID = 0, // void, used for function returns
LICOMPTYPE_BOOL = 1, // bool
LICOMPTYPE_INT = 2, // i32, int-literal
LICOMPTYPE_UINT = 3, // u32, int-literal
LICOMPTYPE_ANY_INT = 4, // i32, u32, i64, u64, int-literal
LICOMPTYPE_ANY_INT32 = 5, // i32, u32, int-literal
LICOMPTYPE_UINT_ONLY = 6, // u32, u64, int-literal; no casts allowed
LICOMPTYPE_FLOAT = 7, // f32, partial-precision-f32, float-literal
LICOMPTYPE_ANY_FLOAT = 8, // f32, partial-precision-f32, f64, float-literal,
// min10-float, min16-float, half
LICOMPTYPE_FLOAT_LIKE = 9, // f32, partial-precision-f32, float-literal,
// min10-float, min16-float, half
LICOMPTYPE_FLOAT_DOUBLE =
10, // f32, partial-precision-f32, f64, float-literal
LICOMPTYPE_DOUBLE = 11, // f64, float-literal
LICOMPTYPE_DOUBLE_ONLY = 12, // f64; no casts allowed
LICOMPTYPE_NUMERIC = 13, // float-literal, f32, partial-precision-f32, f64,
// min10-float, min16-float, int-literal, i32, u32,
// min12-int, min16-int, min16-uint, i64, u64
LICOMPTYPE_NUMERIC32 =
14, // float-literal, f32, partial-precision-f32, int-literal, i32, u32
LICOMPTYPE_NUMERIC32_ONLY = 15, // float-literal, f32, partial-precision-f32,
// int-literal, i32, u32; no casts allowed
LICOMPTYPE_ANY = 16, // float-literal, f32, partial-precision-f32, f64,
// min10-float, min16-float, int-literal, i32, u32,
// min12-int, min16-int, min16-uint, bool, i64, u64
LICOMPTYPE_SAMPLER1D = 17,
LICOMPTYPE_SAMPLER2D = 18,
LICOMPTYPE_SAMPLER3D = 19,
Expand All @@ -78,7 +87,7 @@ enum LEGAL_INTRINSIC_COMPTYPES {
LICOMPTYPE_SAMPLER = 22,
LICOMPTYPE_STRING = 23,
LICOMPTYPE_WAVE = 24,
LICOMPTYPE_UINT64 = 25, // u64, int-literal
LICOMPTYPE_UINT64 = 25, // u64, int-literal
LICOMPTYPE_FLOAT16 = 26,
LICOMPTYPE_INT16 = 27,
LICOMPTYPE_UINT16 = 28,
Expand All @@ -99,7 +108,8 @@ enum LEGAL_INTRINSIC_COMPTYPES {
LICOMPTYPE_UINT8_4PACKED = 41,
LICOMPTYPE_ANY_INT16_OR_32 = 42,
LICOMPTYPE_SINT16_OR_32_ONLY = 43,
LICOMPTYPE_COUNT = 44
LICOMPTYPE_ANY_SAMPLER = 44,
LICOMPTYPE_COUNT = 45
};

static const BYTE IA_SPECIAL_BASE = 0xf0;
Expand Down
132 changes: 74 additions & 58 deletions tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ static const ArTypeObjectKind g_AnyTT[] =
static const ArTypeObjectKind g_ObjectTT[] =
{
AR_TOBJ_OBJECT,
AR_TOBJ_STRING,
AR_TOBJ_UNKNOWN
};

Expand Down Expand Up @@ -1099,6 +1100,13 @@ static const ArBasicKind g_AnyCT[] =
AR_BASIC_UNKNOWN
};

static const ArBasicKind g_AnySamplerCT[] =
{
AR_OBJECT_SAMPLER,
AR_OBJECT_SAMPLERCOMPARISON,
AR_BASIC_UNKNOWN
};

static const ArBasicKind g_Sampler1DCT[] =
{
AR_OBJECT_SAMPLER1D,
Expand Down Expand Up @@ -1294,52 +1302,52 @@ static const ArBasicKind g_SInt16Or32OnlyCT[] =
};

// Basic kinds, indexed by a LEGAL_INTRINSIC_COMPTYPES value.
const ArBasicKind* g_LegalIntrinsicCompTypes[] =
{
g_NullCT, // LICOMPTYPE_VOID
g_BoolCT, // LICOMPTYPE_BOOL
g_IntCT, // LICOMPTYPE_INT
g_UIntCT, // LICOMPTYPE_UINT
g_AnyIntCT, // LICOMPTYPE_ANY_INT
g_AnyInt32CT, // LICOMPTYPE_ANY_INT32
g_UIntOnlyCT, // LICOMPTYPE_UINT_ONLY
g_FloatCT, // LICOMPTYPE_FLOAT
g_AnyFloatCT, // LICOMPTYPE_ANY_FLOAT
g_FloatLikeCT, // LICOMPTYPE_FLOAT_LIKE
g_FloatDoubleCT, // LICOMPTYPE_FLOAT_DOUBLE
g_DoubleCT, // LICOMPTYPE_DOUBLE
g_DoubleOnlyCT, // LICOMPTYPE_DOUBLE_ONLY
g_NumericCT, // LICOMPTYPE_NUMERIC
g_Numeric32CT, // LICOMPTYPE_NUMERIC32
g_Numeric32OnlyCT, // LICOMPTYPE_NUMERIC32_ONLY
g_AnyCT, // LICOMPTYPE_ANY
g_Sampler1DCT, // LICOMPTYPE_SAMPLER1D
g_Sampler2DCT, // LICOMPTYPE_SAMPLER2D
g_Sampler3DCT, // LICOMPTYPE_SAMPLER3D
g_SamplerCUBECT, // LICOMPTYPE_SAMPLERCUBE
g_SamplerCmpCT, // LICOMPTYPE_SAMPLERCMP
g_SamplerCT, // LICOMPTYPE_SAMPLER
g_StringCT, // LICOMPTYPE_STRING
g_WaveCT, // LICOMPTYPE_WAVE
g_UInt64CT, // LICOMPTYPE_UINT64
g_Float16CT, // LICOMPTYPE_FLOAT16
g_Int16CT, // LICOMPTYPE_INT16
g_UInt16CT, // LICOMPTYPE_UINT16
g_Numeric16OnlyCT, // LICOMPTYPE_NUMERIC16_ONLY
g_RayDescCT, // LICOMPTYPE_RAYDESC
g_AccelerationStructCT, // LICOMPTYPE_ACCELERATION_STRUCT,
g_UDTCT, // LICOMPTYPE_USER_DEFINED_TYPE
g_Texture2DCT, // LICOMPTYPE_TEXTURE2D
g_Texture2DArrayCT, // LICOMPTYPE_TEXTURE2DARRAY
g_ResourceCT, // LICOMPTYPE_RESOURCE
g_Int32OnlyCT, // LICOMPTYPE_INT32_ONLY
g_Int64OnlyCT, // LICOMPTYPE_INT64_ONLY
g_AnyInt64CT, // LICOMPTYPE_ANY_INT64
g_Float32OnlyCT, // LICOMPTYPE_FLOAT32_ONLY
g_Int8_4PackedCT, // LICOMPTYPE_INT8_4PACKED
g_UInt8_4PackedCT, // LICOMPTYPE_UINT8_4PACKED
g_AnyInt16Or32CT, // LICOMPTYPE_ANY_INT16_OR_32
g_SInt16Or32OnlyCT, // LICOMPTYPE_SINT16_OR_32_ONLY
const ArBasicKind *g_LegalIntrinsicCompTypes[] = {
g_NullCT, // LICOMPTYPE_VOID
g_BoolCT, // LICOMPTYPE_BOOL
g_IntCT, // LICOMPTYPE_INT
g_UIntCT, // LICOMPTYPE_UINT
g_AnyIntCT, // LICOMPTYPE_ANY_INT
g_AnyInt32CT, // LICOMPTYPE_ANY_INT32
g_UIntOnlyCT, // LICOMPTYPE_UINT_ONLY
g_FloatCT, // LICOMPTYPE_FLOAT
g_AnyFloatCT, // LICOMPTYPE_ANY_FLOAT
g_FloatLikeCT, // LICOMPTYPE_FLOAT_LIKE
g_FloatDoubleCT, // LICOMPTYPE_FLOAT_DOUBLE
g_DoubleCT, // LICOMPTYPE_DOUBLE
g_DoubleOnlyCT, // LICOMPTYPE_DOUBLE_ONLY
g_NumericCT, // LICOMPTYPE_NUMERIC
g_Numeric32CT, // LICOMPTYPE_NUMERIC32
g_Numeric32OnlyCT, // LICOMPTYPE_NUMERIC32_ONLY
g_AnyCT, // LICOMPTYPE_ANY
g_Sampler1DCT, // LICOMPTYPE_SAMPLER1D
g_Sampler2DCT, // LICOMPTYPE_SAMPLER2D
g_Sampler3DCT, // LICOMPTYPE_SAMPLER3D
g_SamplerCUBECT, // LICOMPTYPE_SAMPLERCUBE
g_SamplerCmpCT, // LICOMPTYPE_SAMPLERCMP
g_SamplerCT, // LICOMPTYPE_SAMPLER
g_StringCT, // LICOMPTYPE_STRING
g_WaveCT, // LICOMPTYPE_WAVE
g_UInt64CT, // LICOMPTYPE_UINT64
g_Float16CT, // LICOMPTYPE_FLOAT16
g_Int16CT, // LICOMPTYPE_INT16
g_UInt16CT, // LICOMPTYPE_UINT16
g_Numeric16OnlyCT, // LICOMPTYPE_NUMERIC16_ONLY
g_RayDescCT, // LICOMPTYPE_RAYDESC
g_AccelerationStructCT, // LICOMPTYPE_ACCELERATION_STRUCT,
g_UDTCT, // LICOMPTYPE_USER_DEFINED_TYPE
g_Texture2DCT, // LICOMPTYPE_TEXTURE2D
g_Texture2DArrayCT, // LICOMPTYPE_TEXTURE2DARRAY
g_ResourceCT, // LICOMPTYPE_RESOURCE
g_Int32OnlyCT, // LICOMPTYPE_INT32_ONLY
g_Int64OnlyCT, // LICOMPTYPE_INT64_ONLY
g_AnyInt64CT, // LICOMPTYPE_ANY_INT64
g_Float32OnlyCT, // LICOMPTYPE_FLOAT32_ONLY
g_Int8_4PackedCT, // LICOMPTYPE_INT8_4PACKED
g_UInt8_4PackedCT, // LICOMPTYPE_UINT8_4PACKED
g_AnyInt16Or32CT, // LICOMPTYPE_ANY_INT16_OR_32
g_SInt16Or32OnlyCT, // LICOMPTYPE_SINT16_OR_32_ONLY
g_AnySamplerCT, // LICOMPTYPE_ANY_SAMPLER
};
static_assert(ARRAYSIZE(g_LegalIntrinsicCompTypes) == LICOMPTYPE_COUNT,
"Intrinsic comp type table must be updated when new enumerants are added.");
Expand Down Expand Up @@ -2103,16 +2111,23 @@ static bool CombineBasicTypes(ArBasicKind LeftKind,
ArBasicKind RightKind,
_Out_ ArBasicKind* pOutKind)
{
if ((LeftKind < 0 || LeftKind >= AR_BASIC_COUNT) ||
(RightKind < 0 || RightKind >= AR_BASIC_COUNT)) {
// Make sure the kinds are both valid
if ((LeftKind < 0 || LeftKind >= AR_BASIC_MAXIMUM_COUNT) ||
(RightKind < 0 || RightKind >= AR_BASIC_MAXIMUM_COUNT)) {
return false;
}

// If kinds match perfectly, succeed without requiring they be basic
if (LeftKind == RightKind) {
*pOutKind = LeftKind;
return true;
}

// More complicated combination requires that the kinds be basic
if (LeftKind >= AR_BASIC_COUNT || RightKind >= AR_BASIC_COUNT) {
return false;
}

UINT uLeftProps = GetBasicKindProps(LeftKind);
UINT uRightProps = GetBasicKindProps(RightKind);
UINT uBits = GET_BPROP_BITS(uLeftProps) > GET_BPROP_BITS(uRightProps) ?
Expand Down Expand Up @@ -6203,11 +6218,7 @@ bool HLSLExternalSource::MatchArguments(
if (AR_TOBJ_UNKNOWN != Template[i]) {
if ((AR_TOBJ_SCALAR == Template[i]) && (AR_TOBJ_VECTOR == *pTT || AR_TOBJ_MATRIX == *pTT)) {
Template[i] = *pTT;
}
else if(AR_TOBJ_STRING == Template[i] && *pTT == AR_TOBJ_OBJECT) {
Template[i] = *pTT;
}
else {
} else {
while (AR_TOBJ_UNKNOWN != *pTT) {
if (Template[i] == *pTT)
break;
Expand Down Expand Up @@ -6370,12 +6381,11 @@ bool HLSLExternalSource::MatchArguments(
badArgIdx = std::min(badArgIdx, i);
}
pNewType = objectElement;
}
else if (pArgument->uLegalComponentTypes == LICOMPTYPE_TEXTURE2D
|| pArgument->uLegalComponentTypes == LICOMPTYPE_TEXTURE2DARRAY) {
} else if (i != 0 && Template[pArgument->uTemplateId] == AR_TOBJ_OBJECT) {
// For object parameters, just use the argument type
// Return type is assigned below
pNewType = Args[i - 1]->getType().getNonReferenceType();
}
else {
} else {
ArBasicKind pEltType;

// ComponentType, if the Id is special then it gets the
Expand Down Expand Up @@ -6449,6 +6459,12 @@ bool HLSLExternalSource::MatchArguments(
"have as many arguments and types as the intrinsic template");
}

// For object return types that need to match arguments, we need to slot in
// the full type here Can't do it sooner because when return is encountered
// above, the other arg types haven't been set
if (Template[pIntrinsic->pArgs[0].uTemplateId] == AR_TOBJ_OBJECT)
argTypes[0] = argTypes[pIntrinsic->pArgs[0].uComponentTypeId];

return badArgIdx == MaxIntrinsicArgs;
#undef CAB
}
Expand Down
Loading

0 comments on commit a6497c3

Please sign in to comment.