Skip to content

Commit 7feddb7

Browse files
committed
Adding dxil tests
1 parent 2b5c513 commit 7feddb7

File tree

9 files changed

+260
-9
lines changed

9 files changed

+260
-9
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===--- BuiltinsSPIRV.td - SPIRV Builtin function database ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsBase.td"
10+
11+
def SPIRVDistance : Builtin {
12+
let Spellings = ["__builtin_spirv_distance"];
13+
let Attributes = [NoThrow, Const];
14+
let Prototype = "void(...)";
15+
}
16+
17+
def SPIRVLength : Builtin {
18+
let Spellings = ["__builtin_spirv_length"];
19+
let Attributes = [NoThrow, Const];
20+
let Prototype = "void(...)";
21+
}
22+
23+
def SPIRVReflect : Builtin {
24+
let Spellings = ["__builtin_spirv_reflect"];
25+
let Attributes = [NoThrow, Const];
26+
let Prototype = "void(...)";
27+
}
28+
29+
def SPIRVRefract : Builtin {
30+
let Spellings = ["__builtin_spirv_refract"];
31+
let Attributes = [NoThrow, Const];
32+
let Prototype = "void(...)";
33+
}
34+
35+
def SPIRVSmoothStep : Builtin {
36+
let Spellings = ["__builtin_spirv_smoothstep"];
37+
let Attributes = [NoThrow, Const, CustomTypeChecking];
38+
let Prototype = "void(...)";
39+
}

clang/lib/CodeGen/TargetBuiltins/SPIR.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
5858
/*ReturnType=*/I->getType(), Intrinsic::spv_reflect,
5959
ArrayRef<Value *>{I, N}, nullptr, "spv.reflect");
6060
}
61+
case SPIRV::BI__builtin_spirv_refract: {
62+
Value *I = EmitScalarExpr(E->getArg(0));
63+
Value *N = EmitScalarExpr(E->getArg(1));
64+
Value *eta = EmitScalarExpr(E->getArg(2));
65+
assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
66+
E->getArg(1)->getType()->hasFloatingRepresentation() &&
67+
E->getArg(2)->getType()->hasFloatingRepresentation() &&
68+
"refract operands must have a float representation");
69+
assert(E->getArg(0)->getType()->isVectorType() &&
70+
E->getArg(1)->getType()->isVectorType() &&
71+
"refract I and N operands must be a vector");
72+
return Builder.CreateIntrinsic(
73+
/*ReturnType=*/I->getType(), Intrinsic::spv_refract,
74+
ArrayRef<Value *>{I, N, eta}, nullptr, "spv.refract");
75+
}
6176
case SPIRV::BI__builtin_spirv_smoothstep: {
6277
Value *Min = EmitScalarExpr(E->getArg(0));
6378
Value *Max = EmitScalarExpr(E->getArg(1));

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,42 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) {
7171
#endif
7272
}
7373

74+
template <typename T> constexpr T refract_impl(T I, T N, T eta) {
75+
T k = 1 - eta * eta * (1 - (N * I * N *I));
76+
if(k < 0)
77+
return 0;
78+
else
79+
return (eta * I - (eta * N * I + sqrt(k)) * N);
80+
}
81+
82+
template <typename T, int L>
83+
constexpr vector<T, L> refract_vec_impl(vector<T, L> I, vector<T, L> N, T eta) {
84+
#if (__has_builtin(__builtin_spirv_refract))
85+
return __builtin_spirv_refract(I, N, eta);
86+
#else
87+
vector<T, L> k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
88+
if(k < 0)
89+
return 0;
90+
else
91+
return (eta * I - (eta * dot(N, I) + sqrt(k)) * N);
92+
#endif
93+
}
94+
95+
/*
96+
template <typename T, typename U> constexpr T refract_impl(T I, T N, U eta) {
97+
return I - 2 * N * I * N;
98+
}
99+
100+
template <typename T, int L>
101+
constexpr vector<T, L> refract_vec_impl(vector<T, L> I, vector<T, L> N) {
102+
#if (__has_builtin(__builtin_spirv_refract))
103+
return __builtin_spirv_refract(I, N);
104+
#else
105+
return I - 2 * N * dot(I, N);
106+
#endif
107+
}
108+
*/
109+
74110
template <typename T> constexpr T fmod_impl(T X, T Y) {
75111
#if !defined(__DIRECTX__)
76112
return __builtin_elementwise_fmod(X, Y);

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,83 @@ reflect(__detail::HLSL_FIXED_VECTOR<float, L> I,
475475
return __detail::reflect_vec_impl(I, N);
476476
}
477477

478+
//===----------------------------------------------------------------------===//
479+
// refract builtin
480+
//===----------------------------------------------------------------------===//
481+
482+
/// \fn T refract(T I, T N, T eta)
483+
/// \brief Returns a refraction using an entering ray, \a I, a surface
484+
/// normal, \a N and refraction index \a eta
485+
/// \param I The entering ray.
486+
/// \param N The surface normal.
487+
/// \param eta The refraction index.
488+
///
489+
/// The return value is a floating-point vector that represents the refraction
490+
/// using the refraction index, \a eta, for the direction of the entering ray, \a I,
491+
/// off a surface with the normal \a N.
492+
///
493+
/// This function calculates the refraction vector using the following formulas:
494+
/// k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
495+
/// if k < 0.0 the result is 0.0
496+
/// otherwise, the result is eta * I - (eta * dot(N, I) + sqrt(k)) * N
497+
///
498+
/// I and N must already be normalized in order to achieve the desired result.
499+
///
500+
/// I and N must be a scalar or vector whose component type is
501+
/// floating-point.
502+
///
503+
/// eta must be a 16-bit or 32-bit floating-point scalar.
504+
///
505+
/// Result type, the type of I, and the type of N must all be the same type.
506+
507+
template <typename T>
508+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
509+
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
510+
__detail::is_same<half, T>::value,
511+
T> refract(T I, T N, T eta) {
512+
return __detail::refract_impl(I, N, eta);
513+
}
514+
515+
/*
516+
template <typename T, typename U>
517+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
518+
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
519+
__detail::is_same<half, T>::value,
520+
T> refract(T I, T N, U eta) {
521+
return __detail::refract_impl(I, N, eta);
522+
}
523+
524+
template <typename T, typename U>
525+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
526+
const inline __detail::enable_if_t<__detail::is_arithmetic<U>::Value &&
527+
__detail::is_same<half, T>::value,
528+
T> refract(T I, T N, U eta) {
529+
return __detail::refract_impl(I, N, eta);
530+
}
531+
*/
532+
533+
template <typename T>
534+
const inline __detail::enable_if_t<
535+
__detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
536+
refract(T I, T N, T eta) {
537+
return __detail::refract_impl(I, N, eta);
538+
}
539+
540+
template <int L>
541+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
542+
const inline __detail::HLSL_FIXED_VECTOR<half, L> refract(
543+
__detail::HLSL_FIXED_VECTOR<half, L> I,
544+
__detail::HLSL_FIXED_VECTOR<half, L> N, half eta) {
545+
return __detail::refract_vec_impl(I, N, eta);
546+
}
547+
548+
template <int L>
549+
const inline __detail::HLSL_FIXED_VECTOR<float, L>
550+
refract(__detail::HLSL_FIXED_VECTOR<float, L> I,
551+
__detail::HLSL_FIXED_VECTOR<float, L> N, float eta) {
552+
return __detail::refract_vec_impl(I, N, eta);
553+
}
554+
478555
//===----------------------------------------------------------------------===//
479556
// smoothstep builtin
480557
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaSPIRV.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,50 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI,
203203
TheCall->setType(RetTy);
204204
break;
205205
}
206+
case SPIRV::BI__builtin_spirv_refract: {
207+
if (SemaRef.checkArgCount(TheCall, 3))
208+
return true;
209+
210+
ExprResult A = TheCall->getArg(0);
211+
QualType ArgTyA = A.get()->getType();
212+
auto *VTyA = ArgTyA->getAs<VectorType>();
213+
if (VTyA == nullptr) {
214+
SemaRef.Diag(A.get()->getBeginLoc(),
215+
diag::err_typecheck_convert_incompatible)
216+
<< ArgTyA
217+
<< SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
218+
<< 0 << 0;
219+
return true;
220+
}
221+
222+
ExprResult B = TheCall->getArg(1);
223+
QualType ArgTyB = B.get()->getType();
224+
auto *VTyB = ArgTyB->getAs<VectorType>();
225+
if (VTyB == nullptr) {
226+
SemaRef.Diag(B.get()->getBeginLoc(),
227+
diag::err_typecheck_convert_incompatible)
228+
<< ArgTyB
229+
<< SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
230+
<< 0 << 0;
231+
return true;
232+
}
233+
234+
ExprResult C = TheCall->getArg(2);
235+
QualType ArgTyC = C.get()->getType();
236+
if (!ArgTyC->hasFloatingRepresentation()) {
237+
SemaRef.Diag(C.get()->getBeginLoc(),
238+
diag::err_builtin_invalid_arg_type)
239+
<< 3 << /* scalar or vector */ 5 << /* no int */ 0 << /* fp */ 1
240+
<< ArgTyC;
241+
return true;
242+
}
243+
244+
QualType RetTy = ArgTyA;
245+
TheCall->setType(RetTy);
246+
assert(RetTy == ArgTyA);
247+
//assert(ArgTyB == ArgTyA);
248+
break;
249+
}
206250
case SPIRV::BI__builtin_spirv_reflect: {
207251
if (SemaRef.checkArgCount(TheCall, 2))
208252
return true;
@@ -223,7 +267,7 @@ bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI,
223267
QualType ArgTyB = B.get()->getType();
224268
auto *VTyB = ArgTyB->getAs<VectorType>();
225269
if (VTyB == nullptr) {
226-
SemaRef.Diag(A.get()->getBeginLoc(),
270+
SemaRef.Diag(B.get()->getBeginLoc(),
227271
diag::err_typecheck_convert_incompatible)
228272
<< ArgTyB
229273
<< SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1

clang/test/CodeGenHLSL/builtins/reflect.hlsl

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,32 @@
66
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
77
// RUN: -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK
88

9-
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh(
10-
// CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
9+
// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_refract_halfDhDhDh(
10+
// CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef nofpclass(nan inf) [[N:%.*]], half noundef nofpclass(nan inf) [[eta:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
1111
// CHECK-NEXT: [[ENTRY:.*:]]
12-
// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[I]], 0xH4000
13-
// CHECK-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[N]], [[N]]
14-
// CHECK-NEXT: [[MUL2_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[TMP0]], [[MUL_I]]
15-
// CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[I]], [[MUL2_I]]
16-
// CHECK-NEXT: ret half [[SUB_I]]
12+
// CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[eta]], [[eta]]
13+
// CHECK-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[N:%.*]], %I
14+
// CHECK_NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[TMP0:%.*]], [[TMP0:%.*]]
15+
// CHECK_NEXT: [[SUB1_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 0xH3C00, [[TMP1:%.*]]
16+
// CHECK_NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half %mul.i, [[SUB1_I:%.*]]
17+
// CHECK_NEXT: [[SUB5_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half 0xH3C00, [[MUL4_I:%.*]]
18+
// CHECK_NEXT: [[CMP_I:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt half [[SUB5_I:%.*]], 0xH0000
19+
// CHECK_NEXT: br i1 [[CMP_I:%.*]], label %_ZN4hlsl8__detail12refract_implIDhEET_S2_S2_S2_.exit, label %if.else.i
20+
// CHECK_NEXT:
21+
// CHECK_NEXT: if.else.i: ; preds = %entry
22+
// CHECK_NEXT: [[MUL6_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[eta]], %I
23+
// CHECK_NEXT: [[MUL7_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[N:%.*]], %I
24+
// CHECK_NEXT: [[MUL8_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[MUL7_I:%.*]], [[eta]]
25+
// CHECK_NEXT: %2 = tail call reassoc nnan ninf nsz arcp afn half @llvm.sqrt.f16(half [[SUB5_I:%.*]])
26+
// CHECK_NEXT: [[ADD_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn half %2, [[MUL8_I:%.*]]
27+
// CHECK_NEXT: [[MUL9_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[ADD_I:%.*]], [[N:%.*]]
28+
// CHECK_NEXT: [[SUB10_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[MUL6_I:%.*]], [[MUL9_I:%.*]]
29+
// CHECK_NEXT: br label %_ZN4hlsl8__detail12refract_implIDhEET_S2_S2_S2_.exit
30+
// CHECK_NEXT:
31+
// CHECK_NEXT: _ZN4hlsl8__detail12refract_implIDhEET_S2_S2_S2_.exit: ; preds = %entry, %if.else.i
32+
// CHECK_NEXT: [[RETVAL_0_I:%.*]] = phi nsz half [ [[SUB10_I:%.*]], %if.else.i ], [ 0xH0000, %entry ]
33+
// CHECK_NEXT: ret half [[RETVAL_0_I:%.*]]
34+
1735
//
1836
// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh(
1937
// SPVCHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ let TargetPrefix = "spv" in {
7575
[IntrNoMem] >;
7676
def int_spv_length : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
7777
def int_spv_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
78+
def int_spv_refract : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
7879
def int_spv_reflect : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
7980
def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
8081
def int_spv_saturate : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;

llvm/lib/IR/IRBuilder.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,8 +865,27 @@ CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
865865

866866
SmallVector<Type *> ArgTys;
867867
ArgTys.reserve(Args.size());
868-
for (auto &I : Args)
868+
int i =0;
869+
Type * Ity;
870+
Type * Nty;
871+
Type * etaty;
872+
873+
for (auto &I : Args) {
874+
if(i ==0)
875+
Ity = I->getType();
876+
if(i ==1)
877+
Nty = I->getType();
878+
if(i ==2)
879+
etaty = I->getType();
869880
ArgTys.push_back(I->getType());
881+
i++;
882+
}
883+
//assert(Ity == RetTy);
884+
//assert(Nty == RetTy);
885+
assert(Nty == Ity);
886+
887+
888+
870889
FunctionType *FTy = FunctionType::get(RetTy, ArgTys, false);
871890
SmallVector<Type *> OverloadTys;
872891
Intrinsic::MatchIntrinsicTypesResult Res =

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
30943094
return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
30953095
case Intrinsic::spv_normalize:
30963096
return selectExtInst(ResVReg, ResType, I, CL::normalize, GL::Normalize);
3097+
case Intrinsic::spv_refract:
3098+
return selectExtInst(ResVReg, ResType, I, GL::Refract);
30973099
case Intrinsic::spv_reflect:
30983100
return selectExtInst(ResVReg, ResType, I, GL::Reflect);
30993101
case Intrinsic::spv_rsqrt:

0 commit comments

Comments
 (0)