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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/dxc/dxcapi.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ enum LEGAL_INTRINSIC_COMPTYPES {

#ifdef ENABLE_SPIRV_CODEGEN
LICOMPTYPE_VK_BUFFER_POINTER = 54,
LICOMPTYPE_COUNT = 55
LICOMPTYPE_VK_SAMPLED_TEXTURE2D = 55,
LICOMPTYPE_COUNT = 56
#else
LICOMPTYPE_COUNT = 54
#endif
Expand Down
6 changes: 6 additions & 0 deletions tools/clang/include/clang/AST/HlslTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,12 @@ clang::CXXRecordDecl *
DeclareVkBufferPointerType(clang::ASTContext &context,
clang::DeclContext *declContext);

clang::CXXRecordDecl *DeclareVkSampledTextureType(
clang::ASTContext &context, clang::DeclContext *declContext,
llvm::StringRef hlslTypeName, clang::QualType defaultParamType,
clang::QualType coordinateType, clang::QualType locationType,
clang::QualType offsetType);

clang::CXXRecordDecl *DeclareInlineSpirvType(clang::ASTContext &context,
clang::DeclContext *declContext,
llvm::StringRef typeName,
Expand Down
3 changes: 3 additions & 0 deletions tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7610,6 +7610,9 @@ def err_hlsl_unsupported_typedbuffer_template_parameter : Error<
"elements of typed buffers and textures must be scalars or vectors">;
def err_hlsl_unsupported_typedbuffer_template_parameter_size : Error<
"elements of typed buffers and textures must fit in four 32-bit quantities">;
def err_hlsl_unsupported_vk_sampledtexture_template_parameter
: Error<"%0 cannot be used as a type parameter where it must be of type "
"float, int, uint or their vector equivalents">;
def err_hlsl_unsupported_payload_access_qualifier : Error<
"payload access qualifiers are only allowed for member variables of a payload structure">;
def err_hlsl_unsupported_payload_access_qualifier_struct : Error<
Expand Down
3 changes: 3 additions & 0 deletions tools/clang/include/clang/SPIRV/AstTypeProbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ bool isTexture(QualType);
/// Texture2DMSArray type.
bool isTextureMS(QualType);

/// \brief Returns true if the given type is an HLSL SampledTexture type.
bool isSampledTexture(QualType);

/// \brief Returns true if the given type is an HLSL RWTexture type.
bool isRWTexture(QualType);

Expand Down
8 changes: 8 additions & 0 deletions tools/clang/include/clang/SPIRV/SpirvBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ class SpirvBuilder {
/// If compareVal is given a non-zero value, *Dref* variants of OpImageSample*
/// will be generated.
///
/// If the of `image` is a sampled image, then that image will be sampled.
/// In this case, `sampler` must be `nullptr`. If `image` is not a sampled
/// image, a sampled image will be created by combining `image` and `sampler`.
///
/// If lod or grad is given a non-zero value, *ExplicitLod variants of
/// OpImageSample* will be generated; otherwise, *ImplicitLod variant will
/// be generated.
Expand Down Expand Up @@ -334,6 +338,10 @@ class SpirvBuilder {

/// \brief Creates SPIR-V instructions for gathering the given image.
///
/// If the of `image` is a sampled image, then that image will be gathered.
/// In this case, `sampler` must be `nullptr`. If `image` is not a sampled
/// image, a sampled image will be created by combining `image` and `sampler`.
///
/// If compareVal is given a non-null value, OpImageDrefGather or
/// OpImageSparseDrefGather will be generated; otherwise, OpImageGather or
/// OpImageSparseGather will be generated.
Expand Down
282 changes: 282 additions & 0 deletions tools/clang/lib/AST/ASTContextHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,288 @@ CXXRecordDecl *hlsl::DeclareNodeOrRecordType(
}

#ifdef ENABLE_SPIRV_CODEGEN
static void AddSampleFunction(ASTContext &context, CXXRecordDecl *recordDecl,
QualType returnType, QualType coordinateType,
QualType offsetType) {
QualType floatType = context.FloatTy;
QualType uintType = context.UnsignedIntTy;
// Sample(location)
CXXMethodDecl *sampleDecl = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, ArrayRef<QualType>(coordinateType),
ArrayRef<StringRef>(StringRef("location")),
context.DeclarationNames.getIdentifier(&context.Idents.get("Sample")),
/*isConst*/ true);
sampleDecl->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Sample)));
sampleDecl->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Sample(location, offset)
QualType params2[] = {coordinateType, offsetType};
StringRef names2[] = {"location", "offset"};
CXXMethodDecl *sampleDecl2 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, params2, names2,
context.DeclarationNames.getIdentifier(&context.Idents.get("Sample")),
/*isConst*/ true);
sampleDecl2->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Sample)));
sampleDecl2->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Sample(location, offset, clamp)
QualType params3[] = {coordinateType, offsetType, floatType};
StringRef names3[] = {"location", "offset", "clamp"};
CXXMethodDecl *sampleDecl3 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, params3, names3,
context.DeclarationNames.getIdentifier(&context.Idents.get("Sample")),
/*isConst*/ true);
sampleDecl3->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Sample)));
sampleDecl3->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Sample(location, offset, clamp, status)
QualType params4[] = {coordinateType, offsetType, floatType,
context.getLValueReferenceType(uintType)};
StringRef names4[] = {"location", "offset", "clamp", "status"};
CXXMethodDecl *sampleDecl4 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, params4, names4,
context.DeclarationNames.getIdentifier(&context.Idents.get("Sample")),
/*isConst*/ true);
sampleDecl4->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Sample)));
sampleDecl4->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));
}

static void AddCalculateLevelOfDetailFunction(ASTContext &context,
CXXRecordDecl *recordDecl,
QualType coordinateType,
bool unclamped) {
QualType floatType = context.FloatTy;

const char *functionName =
unclamped ? "CalculateLevelOfDetailUnclamped" : "CalculateLevelOfDetail";
const auto intrinsicOp =
unclamped ? hlsl::IntrinsicOp::MOP_CalculateLevelOfDetailUnclamped
: hlsl::IntrinsicOp::MOP_CalculateLevelOfDetail;

// // CalculateLevelOfDetail(location),
// CalculateLevelOfDetailUnclamped(location)
CXXMethodDecl *lodDecl = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, floatType, ArrayRef<QualType>(coordinateType),
ArrayRef<StringRef>(StringRef("location")),
context.DeclarationNames.getIdentifier(&context.Idents.get(functionName)),
/*isConst*/ true);
lodDecl->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(intrinsicOp)));
lodDecl->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));
}

static void AddGatherFunction(ASTContext &context, CXXRecordDecl *recordDecl,
QualType returnType, QualType coordinateType,
QualType offsetType) {
// Gather(location)
CXXMethodDecl *gatherDecl = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, ArrayRef<QualType>(coordinateType),
ArrayRef<StringRef>(StringRef("location")),
context.DeclarationNames.getIdentifier(&context.Idents.get("Gather")),
/*isConst*/ true);
gatherDecl->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Gather)));
gatherDecl->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Gather(location, offset)
QualType gatherParams2[] = {coordinateType, offsetType};
StringRef gatherNames2[] = {"location", "offset"};
CXXMethodDecl *gatherDecl2 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, gatherParams2, gatherNames2,
context.DeclarationNames.getIdentifier(&context.Idents.get("Gather")),
/*isConst*/ true);
gatherDecl2->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Gather)));
gatherDecl2->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Gather(location, offset, status)
QualType gatherParams3[] = {
coordinateType, offsetType,
context.getLValueReferenceType(context.UnsignedIntTy)};
StringRef gatherNames3[] = {"location", "offset", "status"};
CXXMethodDecl *gatherDecl3 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, gatherParams3, gatherNames3,
context.DeclarationNames.getIdentifier(&context.Idents.get("Gather")),
/*isConst*/ true);
gatherDecl3->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Gather)));
gatherDecl3->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));
}

static void AddGetDimensionsFunction(ASTContext &context,
CXXRecordDecl *recordDecl,
QualType coordinateType) {
QualType uintType = context.UnsignedIntTy;
QualType intType = context.IntTy;
QualType floatType = context.FloatTy;

// GetDimensions(width, height)
QualType getDimensionsParams2[] = {context.getLValueReferenceType(uintType),
context.getLValueReferenceType(uintType)};
StringRef getDimensionsNames2[] = {"width", "height"};
CXXMethodDecl *getDimensionsDecl2 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams2,
getDimensionsNames2,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl2->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));
// GetDimensions(width, height) float version
QualType getDimensionsParams2Float[] = {
context.getLValueReferenceType(floatType),
context.getLValueReferenceType(floatType)};
StringRef getDimensionsNames2Float[] = {"width", "height"};
CXXMethodDecl *getDimensionsDecl2Float =
CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams2Float,
getDimensionsNames2Float,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl2Float->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));
// GetDimensions(width, height) int version
QualType getDimensionsParams2Int[] = {
context.getLValueReferenceType(intType),
context.getLValueReferenceType(intType)};
StringRef getDimensionsNames2Int[] = {"width", "height"};
CXXMethodDecl *getDimensionsDecl2Int =
CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams2Int,
getDimensionsNames2Int,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl2Int->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));

// GetDimensions(mipLevel, width, height, numLevels)
QualType getDimensionsParams4[] = {uintType,
context.getLValueReferenceType(uintType),
context.getLValueReferenceType(uintType),
context.getLValueReferenceType(uintType)};
StringRef getDimensionsNames4[] = {"mipLevel", "width", "height",
"numLevels"};
CXXMethodDecl *getDimensionsDecl4 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams4,
getDimensionsNames4,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl4->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));
// GetDimensions(mipLevel, width, height, numLevels) float version
QualType getDimensionsParams4Float[] = {
uintType, context.getLValueReferenceType(floatType),
context.getLValueReferenceType(floatType),
context.getLValueReferenceType(floatType)};
StringRef getDimensionsNames4Float[] = {"mipLevel", "width", "height",
"numLevels"};
CXXMethodDecl *getDimensionsDecl4Float =
CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams4Float,
getDimensionsNames4Float,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl4Float->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));
// GetDimensions(mipLevel, width, height, numLevels) int version
QualType getDimensionsParams4Int[] = {
uintType, context.getLValueReferenceType(intType),
context.getLValueReferenceType(intType),
context.getLValueReferenceType(intType)};
StringRef getDimensionsNames4Int[] = {"mipLevel", "width", "height",
"numLevels"};
CXXMethodDecl *getDimensionsDecl4Int =
CreateObjectFunctionDeclarationWithParams(
context, recordDecl, context.VoidTy, getDimensionsParams4Int,
getDimensionsNames4Int,
context.DeclarationNames.getIdentifier(
&context.Idents.get("GetDimensions")),
/*isConst*/ true);
getDimensionsDecl4Int->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "",
static_cast<int>(hlsl::IntrinsicOp::MOP_GetDimensions)));
}

static void AddLoadFunction(ASTContext &context, CXXRecordDecl *recordDecl,
QualType returnType, QualType locationType,
QualType offsetType) {
QualType uintType = context.UnsignedIntTy;

// Load(location)
CXXMethodDecl *loadDecl = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, ArrayRef<QualType>(locationType),
ArrayRef<StringRef>(StringRef("location")),
context.DeclarationNames.getIdentifier(&context.Idents.get("Load")),
/*isConst*/ true);
loadDecl->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Load)));
loadDecl->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Load(location, offset)
QualType loadParams2[] = {locationType, offsetType};
StringRef loadNames2[] = {"location", "offset"};
CXXMethodDecl *loadDecl2 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, loadParams2, loadNames2,
context.DeclarationNames.getIdentifier(&context.Idents.get("Load")),
/*isConst*/ true);
loadDecl2->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Load)));
loadDecl2->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));

// Load(location, offset, status)
QualType loadParams3[] = {locationType, offsetType,
context.getLValueReferenceType(uintType)};
StringRef loadNames3[] = {"location", "offset", "status"};
CXXMethodDecl *loadDecl3 = CreateObjectFunctionDeclarationWithParams(
context, recordDecl, returnType, loadParams3, loadNames3,
context.DeclarationNames.getIdentifier(&context.Idents.get("Load")),
/*isConst*/ true);
loadDecl3->addAttr(HLSLIntrinsicAttr::CreateImplicit(
context, "op", "", static_cast<int>(hlsl::IntrinsicOp::MOP_Load)));
loadDecl3->addAttr(HLSLCXXOverloadAttr::CreateImplicit(context));
}

CXXRecordDecl *hlsl::DeclareVkSampledTextureType(
ASTContext &context, DeclContext *declContext, llvm::StringRef hlslTypeName,
QualType defaultParamType, QualType coordinateType, QualType locationType,
QualType offsetType) {
BuiltinTypeDeclBuilder Builder(declContext, hlslTypeName,
TagDecl::TagKind::TTK_Struct);

TemplateTypeParmDecl *TyParamDecl =
Builder.addTypeTemplateParam("SampledTextureType", defaultParamType);

Builder.startDefinition();

QualType paramType = QualType(TyParamDecl->getTypeForDecl(), 0);
CXXRecordDecl *recordDecl = Builder.getRecordDecl();

AddSampleFunction(context, recordDecl, paramType, coordinateType, offsetType);
AddCalculateLevelOfDetailFunction(context, recordDecl, coordinateType,
/*unclamped=*/false);
AddCalculateLevelOfDetailFunction(context, recordDecl, coordinateType,
/*unclamped=*/true);
AddGatherFunction(context, recordDecl, paramType, coordinateType, offsetType);
AddGetDimensionsFunction(context, recordDecl, coordinateType);
AddLoadFunction(context, recordDecl, paramType, locationType, offsetType);

Builder.completeDefinition();
return recordDecl;
}

CXXRecordDecl *hlsl::DeclareVkBufferPointerType(ASTContext &context,
DeclContext *declContext) {
BuiltinTypeDeclBuilder Builder(declContext, "BufferPointer",
Expand Down
11 changes: 11 additions & 0 deletions tools/clang/lib/SPIRV/AstTypeProbe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,17 @@ bool isTexture(QualType type) {
return false;
}

bool isSampledTexture(QualType type) {
if (const auto *rt = type->getAs<RecordType>()) {
const auto name = rt->getDecl()->getName();
// TODO(https://github.com/microsoft/DirectXShaderCompiler/issues/7979): Add
// other sampled texture types as needed.
if (name == "SampledTexture2D")
return true;
}
return false;
}

bool isTextureMS(QualType type) {
if (const auto *rt = type->getAs<RecordType>()) {
const auto name = rt->getDecl()->getName();
Expand Down
Loading