Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions include/dxc/dxcapi.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,16 @@ struct HLSL_INTRINSIC_ARGUMENT {
// matching input constraints.
};

// HLSL_INTRINSIC flags
static const UINT INTRIN_FLAG_READ_ONLY = 1U << 0;
static const UINT INTRIN_FLAG_READ_NONE = 1U << 1;
static const UINT INTRIN_FLAG_IS_WAVE = 1U << 2;

struct HLSL_INTRINSIC {
UINT Op; // Intrinsic Op ID
BOOL bReadOnly; // Only read memory
BOOL bReadNone; // Not read memory
BOOL bIsWave; // Is a wave-sensitive op
UINT Flags; // INTRIN_FLAG_* flags
UINT MinShaderModel; // Encoded minimum shader model, 0 = no minimum
// (Major << 4) + (Minor & 0xf)
INT iOverloadParamIndex; // Parameter decide the overload type, -1 means ret
// type
UINT uNumArgs; // Count of arguments in pArgs.
Expand Down
15 changes: 12 additions & 3 deletions tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1810,12 +1810,21 @@ static void AddHLSLIntrinsicAttr(FunctionDecl *FD, ASTContext &context,
}
FD->addAttr(
HLSLIntrinsicAttr::CreateImplicit(context, tableName, lowering, opcode));
if (pIntrinsic->bReadNone)
if (pIntrinsic->Flags & INTRIN_FLAG_READ_NONE)
FD->addAttr(ConstAttr::CreateImplicit(context));
if (pIntrinsic->bReadOnly)
if (pIntrinsic->Flags & INTRIN_FLAG_READ_ONLY)
FD->addAttr(PureAttr::CreateImplicit(context));
if (pIntrinsic->bIsWave)
if (pIntrinsic->Flags & INTRIN_FLAG_IS_WAVE)
FD->addAttr(HLSLWaveSensitiveAttr::CreateImplicit(context));
// TBD: Add availability attribute if MinShaderModel is set.
// if (pIntrinsic->MinShaderModel) {
// unsigned Major = pIntrinsic->MinShaderModel >> 4;
// unsigned Minor = pIntrinsic->MinShaderModel & 0xF;
// FD->addAttr(AvailabilityAttr::CreateImplicit(
// context, &context.Idents.get(""), clang::VersionTuple(Major, Minor),
// clang::VersionTuple(), clang::VersionTuple(), false,
// "HLSL Intrinsic availability limited by shader model."));
//}
}

static FunctionDecl *
Expand Down
77 changes: 43 additions & 34 deletions tools/clang/unittests/HLSL/ExtensionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,79 +204,86 @@ Intrinsic Intrinsics[] = {
{L"test_fn",
DEFAULT_NAME,
"r",
{1, false, true, false, -1, countof(TestFnArgs), TestFnArgs}},
{1, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnArgs), TestFnArgs}},
{L"test_proc",
DEFAULT_NAME,
"r",
{2, false, false, false, -1, countof(TestProcArgs), TestProcArgs}},
{2, 0, 0, -1, countof(TestProcArgs), TestProcArgs}},
{L"test_poly",
"test_poly.$o",
"r",
{3, false, true, false, -1, countof(TestFnCustomArgs), TestFnCustomArgs}},
{3, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnCustomArgs),
TestFnCustomArgs}},
{L"test_int",
"test_int",
"r",
{4, false, true, false, -1, countof(TestFnIntArgs), TestFnIntArgs}},
{4, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnIntArgs), TestFnIntArgs}},
{L"test_nolower",
"test_nolower.$o",
"n",
{5, false, true, false, -1, countof(TestFnNoLowerArgs),
{5, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnNoLowerArgs),
TestFnNoLowerArgs}},
{L"test_pack_0",
"test_pack_0.$o",
"p",
{6, false, false, false, -1, countof(TestFnPack0), TestFnPack0}},
{6, 0, 0, -1, countof(TestFnPack0), TestFnPack0}},
{L"test_pack_1",
"test_pack_1.$o",
"p",
{7, false, true, false, -1, countof(TestFnPack1), TestFnPack1}},
{7, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnPack1), TestFnPack1}},
{L"test_pack_2",
"test_pack_2.$o",
"p",
{8, false, true, false, -1, countof(TestFnPack2), TestFnPack2}},
{8, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnPack2), TestFnPack2}},
{L"test_pack_3",
"test_pack_3.$o",
"p",
{9, false, true, false, -1, countof(TestFnPack3), TestFnPack3}},
{9, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestFnPack3), TestFnPack3}},
{L"test_pack_4",
"test_pack_4.$o",
"p",
{10, false, false, false, -1, countof(TestFnPack4), TestFnPack4}},
{10, 0, 0, -1, countof(TestFnPack4), TestFnPack4}},
{L"test_rand",
"test_rand",
"r",
{11, false, false, false, -1, countof(TestRand), TestRand}},
{11, 0, 0, -1, countof(TestRand), TestRand}},
{L"test_isinf",
"test_isinf",
"d",
{13, true, true, false, -1, countof(TestIsInf), TestIsInf}},
{13, INTRIN_FLAG_READ_ONLY | INTRIN_FLAG_READ_NONE, 0, -1,
countof(TestIsInf), TestIsInf}},
{L"test_ibfe",
"test_ibfe",
"d",
{14, true, true, false, -1, countof(TestIBFE), TestIBFE}},
{14, INTRIN_FLAG_READ_ONLY | INTRIN_FLAG_READ_NONE, 0, -1,
countof(TestIBFE), TestIBFE}},
// Make this intrinsic have the same opcode as an hlsl intrinsic with an
// unsigned counterpart for testing purposes.
{L"test_unsigned",
"test_unsigned",
"n",
{static_cast<unsigned>(hlsl::IntrinsicOp::IOP_min), false, true, false, -1,
countof(TestUnsigned), TestUnsigned}},
{static_cast<unsigned>(hlsl::IntrinsicOp::IOP_min), INTRIN_FLAG_READ_NONE,
0, -1, countof(TestUnsigned), TestUnsigned}},
{L"wave_proc",
DEFAULT_NAME,
"r",
{16, false, true, true, -1, countof(WaveProcArgs), WaveProcArgs}},
{16, INTRIN_FLAG_READ_NONE | INTRIN_FLAG_IS_WAVE, 0, -1,
countof(WaveProcArgs), WaveProcArgs}},
{L"test_o_1",
"test_o_1.$o:1",
"r",
{18, false, true, true, -1, countof(TestOverloadArgs), TestOverloadArgs}},
{18, INTRIN_FLAG_READ_NONE | INTRIN_FLAG_IS_WAVE, 0, -1,
countof(TestOverloadArgs), TestOverloadArgs}},
{L"test_o_2",
"test_o_2.$o:2",
"r",
{19, false, true, true, -1, countof(TestOverloadArgs), TestOverloadArgs}},
{19, INTRIN_FLAG_READ_NONE | INTRIN_FLAG_IS_WAVE, 0, -1,
countof(TestOverloadArgs), TestOverloadArgs}},
{L"test_o_3",
"test_o_3.$o:3",
"r",
{20, false, true, true, -1, countof(TestOverloadArgs), TestOverloadArgs}},
{20, INTRIN_FLAG_READ_NONE | INTRIN_FLAG_IS_WAVE, 0, -1,
countof(TestOverloadArgs), TestOverloadArgs}},
// custom lowering with both optional arguments and vector exploding.
// Arg 0 = Opcode
// Arg 1 = Pass as is
Expand All @@ -286,24 +293,26 @@ Intrinsic Intrinsics[] = {
{L"CustomLoadOp",
"CustomLoadOp",
"c:{\"default\" : \"0,1,2:?i1,3.0:?i32,3.1:?i32\"}",
{21, true, false, false, -1, countof(TestCustomLoadOp), TestCustomLoadOp}},
{21, INTRIN_FLAG_READ_ONLY, 0, -1, countof(TestCustomLoadOp),
TestCustomLoadOp}},
{L"CustomLoadOp",
"CustomLoadOp",
"c:{\"default\" : \"0,1,2:?i1,3.0:?i32,3.1:?i32\"}",
{21, true, false, false, -1, countof(TestCustomLoadOpBool),
{21, INTRIN_FLAG_READ_ONLY, 0, -1, countof(TestCustomLoadOpBool),
TestCustomLoadOpBool}},
{L"CustomLoadOp",
"CustomLoadOp",
"c:{\"default\" : \"0,1,2:?i1,3.0:?i32,3.1:?i32\"}",
{21, true, false, false, -1, countof(TestCustomLoadOpSubscript),
{21, INTRIN_FLAG_READ_ONLY, 0, -1, countof(TestCustomLoadOpSubscript),
TestCustomLoadOpSubscript}},
};

Intrinsic BufferIntrinsics[] = {
{L"MyBufferOp",
"MyBufferOp",
"m",
{12, false, true, false, -1, countof(TestMyBufferOp), TestMyBufferOp}},
{12, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestMyBufferOp),
TestMyBufferOp}},
};

// Test adding a method to an object that normally has no methods (SamplerState
Expand All @@ -312,7 +321,8 @@ Intrinsic SamplerIntrinsics[] = {
{L"MySamplerOp",
"MySamplerOp",
"m",
{15, false, true, false, -1, countof(TestMySamplerOp), TestMySamplerOp}},
{15, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestMySamplerOp),
TestMySamplerOp}},
};

// Define a lowering string to target a common dxil extension operation defined
Expand Down Expand Up @@ -345,20 +355,20 @@ Intrinsic Texture1DIntrinsics[] = {
{L"MyTextureOp",
"MyTextureOp",
MyTextureOp_LoweringInfo,
{17, false, true, false, -1, countof(TestMyTexture1DOp_0),
{17, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestMyTexture1DOp_0),
TestMyTexture1DOp_0}},
{L"MyTextureOp",
"MyTextureOp",
MyTextureOp_LoweringInfo,
{17, false, true, false, -1, countof(TestMyTexture1DOp_1),
{17, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestMyTexture1DOp_1),
TestMyTexture1DOp_1}},
};

Intrinsic Texture2DIntrinsics[] = {
{L"MyTextureOp",
"MyTextureOp",
MyTextureOp_LoweringInfo,
{17, false, true, false, -1, countof(TestMyTexture2DOp),
{17, INTRIN_FLAG_READ_NONE, 0, -1, countof(TestMyTexture2DOp),
TestMyTexture2DOp}},
};

Expand Down Expand Up @@ -1497,8 +1507,8 @@ TEST_F(ExtensionTest, EvalAttributeCollision) {
Intrinsic Intrinsic = {L"collide_proc",
"collide_proc",
"r",
{static_cast<unsigned>(op), true, false, false, -1,
countof(Args), Args}};
{static_cast<unsigned>(op), INTRIN_FLAG_READ_ONLY, 0,
-1, countof(Args), Args}};
Compiler c(m_dllSupport);
c.RegisterIntrinsicTable(new TestIntrinsicTable(&Intrinsic, 1));
c.Compile(R"(
Expand Down Expand Up @@ -1532,10 +1542,8 @@ TEST_F(ExtensionTest, NoUnwind) {
IA_C},
{"value", AR_QUAL_IN, 1, LITEMPLATE_ANY, 1, LICOMPTYPE_NUMERIC, 1, IA_C}};

Intrinsic Intrinsic = {L"test_proc",
"test_proc",
"r",
{1, false, false, false, -1, countof(Args), Args}};
Intrinsic Intrinsic = {
L"test_proc", "test_proc", "r", {1, 0, 0, -1, countof(Args), Args}};
Compiler c(m_dllSupport);
c.RegisterIntrinsicTable(new TestIntrinsicTable(&Intrinsic, 1));
c.Compile(R"(
Expand Down Expand Up @@ -1572,7 +1580,8 @@ TEST_F(ExtensionTest, DCE) {
Intrinsic Intrinsic = {L"test_proc",
"test_proc",
"r",
{1, true, true, false, -1, countof(Args), Args}};
{1, INTRIN_FLAG_READ_ONLY | INTRIN_FLAG_READ_NONE, 0,
-1, countof(Args), Args}};
Compiler c(m_dllSupport);
c.RegisterIntrinsicTable(new TestIntrinsicTable(&Intrinsic, 1));
c.Compile(R"(
Expand Down
29 changes: 29 additions & 0 deletions utils/hct/hctdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -8208,6 +8208,7 @@ def __init__(
unsigned_op,
overload_idx,
hidden,
min_shader_model,
):
self.name = name # Function name
self.idx = idx # Unique number within namespace
Expand Down Expand Up @@ -8235,6 +8236,12 @@ def __init__(
overload_idx # Parameter determines the overload type, -1 means ret type
)
self.hidden = hidden # Internal high-level op, not exposed to HLSL
# Encoded minimum shader model for this intrinsic
self.min_shader_model = 0
if min_shader_model:
self.min_shader_model = (min_shader_model[0] << 4) | (
min_shader_model[1] & 0x0F
)
self.key = (
("%3d" % ns_idx)
+ "!"
Expand Down Expand Up @@ -8612,6 +8619,7 @@ def process_attr(attr):
-1
) # Parameter determines the overload type, -1 means ret type.
hidden = False
min_shader_model = (0, 0)
for a in attrs:
if a == "":
continue
Expand Down Expand Up @@ -8644,6 +8652,24 @@ def process_attr(attr):
if d == "overload":
overload_param_index = int(v)
continue
if d == "min_sm":
# min_sm is a string like "6.0" or "6.5"
# Convert to a tuple of integers (major, minor)
try:
major_minor = v.split(".")
if len(major_minor) != 2:
raise ValueError
major, minor = major_minor
major = int(major)
minor = int(minor)
# minor of 15 has special meaning, and larger values
# cannot be encoded in the version DWORD.
if major < 0 or minor < 0 or minor > 14:
raise ValueError
min_shader_model = (major, minor)
except ValueError:
assert False, "invalid min_sm: %s" % (v)
continue
assert False, "invalid attr %s" % (a)

return (
Expand All @@ -8654,6 +8680,7 @@ def process_attr(attr):
unsigned_op,
overload_param_index,
hidden,
min_shader_model,
)

current_namespace = None
Expand Down Expand Up @@ -8701,6 +8728,7 @@ def process_attr(attr):
unsigned_op,
overload_param_index,
hidden,
min_shader_model,
) = process_attr(attr)
# Add an entry for this intrinsic.
if bracket_cleanup_re.search(opts):
Expand Down Expand Up @@ -8739,6 +8767,7 @@ def process_attr(attr):
unsigned_op,
overload_param_index,
hidden,
min_shader_model,
)
)
num_entries += 1
Expand Down
18 changes: 14 additions & 4 deletions utils/hct/hctdb_instrhelp.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,13 +989,23 @@ def get_hlsl_intrinsics():
result += "#ifdef ENABLE_SPIRV_CODEGEN\n\n"
# SPIRV Change Ends
arg_idx = 0
ns_table += " {(UINT)%s::%s_%s, %s, %s, %s, %d, %d, g_%s_Args%s},\n" % (
flags = []
if i.readonly:
flags.append("INTRIN_FLAG_READ_ONLY")
if i.readnone:
flags.append("INTRIN_FLAG_READ_NONE")
if i.wave:
flags.append("INTRIN_FLAG_IS_WAVE")
if flags:
flags = " | ".join(flags)
else:
flags = "0"
ns_table += " {(UINT)%s::%s_%s, %s, 0x%x, %d, %d, g_%s_Args%s},\n" % (
opcode_namespace,
id_prefix,
i.name,
str(i.readonly).lower(),
str(i.readnone).lower(),
str(i.wave).lower(),
flags,
i.min_shader_model,
i.overload_param_index,
len(i.params),
last_ns,
Expand Down