Skip to content

Implement the lit HLSL Function #99135

@farzonl

Description

@farzonl
  • Write implementation in hlsl_intrinsics.h header
  • Add codegen tests to clang/test/CodeGenHLSL/builtins/lit.hlsl
  • Add sema tests to clang/test/SemaHLSL/BuiltIns/lit-errors.hlsl

Example HLSL header code

https://godbolt.org/z/YYEGrbh1a

define <4 x float> @"\01?fn@@YA?AV?$vector@M$03@@MMM@Z"(float %p1, float %p2, float %p3) #0 {
  call void @llvm.dbg.value(metadata float %p3, i64 0, metadata !35, metadata !36), !dbg !37
  call void @llvm.dbg.value(metadata float %p2, i64 0, metadata !38, metadata !36), !dbg !39
  call void @llvm.dbg.value(metadata float %p1, i64 0, metadata !40, metadata !36), !dbg !41
  %1 = fcmp fast olt float %p1, 0.000000e+00, !dbg !42
  %2 = select i1 %1, float 0.000000e+00, float %p1, !dbg !42
  %3 = insertelement <4 x float> <float 1.000000e+00, float undef, float undef, float 1.000000e+00>, float %2, i64 1, !dbg !42
  %4 = fcmp fast olt float %p2, 0.000000e+00, !dbg !42
  %5 = or i1 %1, %4, !dbg !42
  %Log = call float @dx.op.unary.f32(i32 23, float %p2), !dbg !42
  %6 = fmul fast float %Log, %p3, !dbg !42
  %Exp = call float @dx.op.unary.f32(i32 21, float %6), !dbg !42
  %7 = select i1 %5, float 0.000000e+00, float %Exp, !dbg !42
  %8 = insertelement <4 x float> %3, float %7, i64 2, !dbg !42
  %9 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @dx.nothing.a, i32 0, i32 0), !dbg !43
  ret <4 x float> %8, !dbg !43
}

Rough Translation:

float4 lit(float P1, float P2, float P3) {
    float ClampedP1 = (P1 < 0.0f) ? 0.0f : P1;
    float4 Result = {1.0f, ClampedP1, 0.0f, 1.0f};
    int CombinedCond = (P1 < 0.0f) || (P2 < 0.0f);
    float P2Log = log(P2);
    float Exp = exp(P2Log * P3);

    Result[2] = CombinedCond ? 0.0f : Exp;
    return Result;
}

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
23 Log 6.0 ()

SPIR-V

FMax:

Description:

FMax

Result is y if x < y; otherwise result is x. Which operand is
the result is undefined if one of the operands is a NaN.

The operands must all be a scalar or vector whose component type is
floating-point.

Result Type and the type of all operands must be the same type.
Results are computed per component.

Number Operand 1 Operand 2 Operand 3 Operand 4

40

<id>
x

<id>
y

Test Case(s)

Example 1

//dxc lit_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export float4 fn(float p1, float p2, float p3) {
    return lit(p1, p2, p3);
}

HLSL:

Returns a lighting coefficient vector.

ret lit(n_dot_l, n_dot_h, m)

This function returns a lighting coefficient vector (ambient, diffuse, specular, 1) where:

  • ambient = 1
  • diffuse = n · l < 0 ? 0 : n · l
  • specular = n · l < 0 || n · h < 0 ? 0 : (n · h) ^ m

Where the vector n is the normal vector, l is the direction to light and h is the half vector.

Parameters

Item Description
n_dot_l
[in] The dot product of the normalized surface normal and the light vector.
n_dot_h
[in] The dot product of the half-angle vector and the surface normal.
m
[in] A specular exponent.

Return Value

The lighting coefficient vector.

Type Description

Name Template Type Component Type Size
n_dot_l scalar float 1
n_dot_h scalar float 1
m scalar float 1
ret vector float 4

Minimum Shader Model

This function is supported in the following shader models.

Shader Model Supported
Shader Model 2 (DirectX HLSL) and higher shader models yes
Shader Model 1 (DirectX HLSL) yes (vs_1_1 only)

See also

Intrinsic Functions (DirectX HLSL)

Metadata

Metadata

Assignees

Labels

HLSLHLSL Language Supportbot:HLSLmetaissueIssue to collect references to a group of similar or related issues.

Type

No type

Projects

Status

Closed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions