Skip to content

Implement the PrimitiveIndex HLSL Function #99193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
12 tasks
Tracked by #99235
farzonl opened this issue Jul 16, 2024 · 0 comments
Open
12 tasks
Tracked by #99235

Implement the PrimitiveIndex HLSL Function #99193

farzonl opened this issue Jul 16, 2024 · 0 comments
Labels
backend:DirectX backend:SPIR-V bot:HLSL HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues.

Comments

@farzonl
Copy link
Member

farzonl commented Jul 16, 2024

  • Implement PrimitiveIndex clang builtin,
  • Link PrimitiveIndex clang builtin with hlsl_intrinsics.h
  • Add sema checks for PrimitiveIndex to CheckHLSLBuiltinFunctionCall in SemaChecking.cpp
  • Add codegen for PrimitiveIndex to EmitHLSLBuiltinExpr in CGBuiltin.cpp
  • Add codegen tests to clang/test/CodeGenHLSL/builtins/PrimitiveIndex.hlsl
  • Add sema tests to clang/test/SemaHLSL/BuiltIns/PrimitiveIndex-errors.hlsl
  • Create the int_dx_PrimitiveIndex intrinsic in IntrinsicsDirectX.td
  • Create the DXILOpMapping of int_dx_PrimitiveIndex to 161 in DXIL.td
  • Create the PrimitiveIndex.ll and PrimitiveIndex_errors.ll tests in llvm/test/CodeGen/DirectX/
  • Create the int_spv_PrimitiveIndex intrinsic in IntrinsicsSPIRV.td
  • In SPIRVInstructionSelector.cpp create the PrimitiveIndex lowering and map it to int_spv_PrimitiveIndex in SPIRVInstructionSelector::selectIntrinsic.
  • Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/hlsl-intrinsics/PrimitiveIndex.ll

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
161 PrimitiveIndex 6.3 ('library', 'intersection', 'anyhit', 'closesthit')

SPIR-V

PrimitiveId

Short Description

PrimitiveId - Primitive ID

Description

PrimitiveId
Decorating a variable with the PrimitiveId built-in decoration will
make that variable contain the index of the current primitive.

The index of the first primitive generated by a drawing command is zero,
and the index is incremented after every individual point, line, or
triangle primitive is processed.

For triangles drawn as points or line segments (see Polygon Mode ), the primitive index
is incremented only once, even if multiple points or lines are
eventually drawn.

Variables decorated with PrimitiveId are reset to zero between each
instance drawn.

Restarting a primitive topology using primitive restart has no effect on
the value of variables decorated with PrimitiveId .

In tessellation control and tessellation evaluation shaders, it will
contain the index of the patch within the current set of rendering
primitives that corresponds to the shader invocation.

In a geometry shader, it will contain the number of primitives presented
as input to the shader since the current set of rendering primitives was
started.

In a fragment shader, it will contain the primitive index written by the
mesh shader if a mesh shader is present, or the primitive index written
by the geometry shader if a geometry shader is present, or with the
value that would have been presented as input to the geometry shader had
it been present.

In an intersection, any-hit, or closest hit shader, it will contain the
index within the geometry of the triangle or bounding box being
processed.

Note

When the PrimitiveId decoration is applied to an output variable in the mesh shader or geometry shader, the resulting value is seen through the PrimitiveId decorated input variable in the fragment shader.

The fragment shader using PrimitiveId will need to declare either the MeshShadingNV , MeshShadingEXT , Geometry or Tessellation capability to satisfy the requirement SPIR-V has to use PrimitiveId .

Valid Usage


  • VUID-PrimitiveId-PrimitiveId-04330

    The PrimitiveId decoration must be used only within the
    MeshEXT , MeshNV , IntersectionKHR , AnyHitKHR ,
    ClosestHitKHR , TessellationControl ,
    TessellationEvaluation , Geometry , or Fragment
    Execution Model


  • VUID-PrimitiveId-Fragment-04331

    If pipeline contains both the Fragment and Geometry
    Execution Model and a variable decorated with PrimitiveId
    is read from Fragment shader, then the Geometry shader
    must write to the output variables decorated with PrimitiveId
    in all execution paths


  • VUID-PrimitiveId-Fragment-04332

    If pipeline contains both the Fragment and MeshEXT or
    MeshNV Execution Model and a variable decorated with
    PrimitiveId is read from Fragment shader, then the MeshEXT
    or MeshNV shader must write to the output variables decorated
    with PrimitiveId in all execution paths


  • VUID-PrimitiveId-Fragment-04333

    If Fragment Execution Model contains a variable decorated
    with PrimitiveId , then either the MeshShadingEXT ,
    MeshShadingNV , Geometry or Tessellation capability
    must also be declared


  • VUID-PrimitiveId-PrimitiveId-04334

    The variable decorated with PrimitiveId within the
    TessellationControl , TessellationEvaluation , Fragment ,
    IntersectionKHR , AnyHitKHR , or ClosestHitKHR
    Execution Model must be declared using the Input
    Storage Class


  • VUID-PrimitiveId-PrimitiveId-04335

    The variable decorated with PrimitiveId within the Geometry
    Execution Model must be declared using the Input or
    Output Storage Class


  • VUID-PrimitiveId-PrimitiveId-04336

    The variable decorated with PrimitiveId within the MeshEXT or
    MeshNV Execution Model must be declared using the
    Output Storage Class


  • VUID-PrimitiveId-PrimitiveId-04337

    The variable decorated with PrimitiveId must be declared as a
    scalar 32-bit integer value


  • VUID-PrimitiveId-PrimitiveId-07040

    The variable decorated with PrimitiveId within the MeshEXT
    Execution Model must also be decorated with the
    PerPrimitiveEXT decoration

Test Case(s)

Example 1

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

export uint fn() {
    return PrimitiveIndex();
}

SPIRV Example(s):

Example 2

//dxc PrimitiveIndex_spirv_test.hlsl -T ps_6_8 -E fn -enable-16bit-types -spirv -fspv-target-env=universal1.5 -fcgl -O0


uint fn( ) : SV_Target {

	return PrimitiveIndex();
}

HLSL:

Retrieves the autogenerated index of the primitive within the geometry inside the bottom-level acceleration structure instance.

Syntax

uint PrimitiveIndex();

Remarks

For D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES, this is the triangle index within the geometry object.

For D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS, this is the index into the AABB array defining the geometry object.

This function can be called from the following raytracing shader types:

See also

@farzonl farzonl added backend:DirectX backend:SPIR-V bot:HLSL HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues. labels Jul 16, 2024
@damyanp damyanp moved this to Ready in HLSL Support Oct 30, 2024
@damyanp damyanp moved this from Ready to Planning in HLSL Support Oct 30, 2024
@damyanp damyanp moved this from Planning to Designing in HLSL Support Nov 26, 2024
@damyanp damyanp removed the status in HLSL Support Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:DirectX backend:SPIR-V bot:HLSL HLSL HLSL Language Support metabug Issue to collect references to a group of similar or related issues.
Projects
Status: No status
Development

No branches or pull requests

1 participant