Skip to content

Commit

Permalink
[DX] Add support for program signatures (#67346)
Browse files Browse the repository at this point in the history
For DirectX, program signatures are encoded into three different binary
sections depending on if the signature is for inputs, outputs, or
patches. All three signature types use the same data structure encoding
so they can share a lot of logic.

This patch adds support for reading and writing program signature data
as both yaml and binary data.

Fixes #57743 and #57744
  • Loading branch information
llvm-beanz committed Oct 5, 2023
1 parent 7e28234 commit 9f87522
Show file tree
Hide file tree
Showing 13 changed files with 859 additions and 65 deletions.
68 changes: 68 additions & 0 deletions llvm/include/llvm/BinaryFormat/DXContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,74 @@ struct ResourceBindInfo : public v0::ResourceBindInfo {
} // namespace v2
} // namespace PSV

#define COMPONENT_PRECISION(Val, Enum) Enum = Val,
enum class SigMinPrecision : uint32_t {
#include "DXContainerConstants.def"
};

ArrayRef<EnumEntry<SigMinPrecision>> getSigMinPrecisions();

#define D3D_SYSTEM_VALUE(Val, Enum) Enum = Val,
enum class D3DSystemValue : uint32_t {
#include "DXContainerConstants.def"
};

ArrayRef<EnumEntry<D3DSystemValue>> getD3DSystemValues();

#define COMPONENT_TYPE(Val, Enum) Enum = Val,
enum class SigComponentType : uint32_t {
#include "DXContainerConstants.def"
};

ArrayRef<EnumEntry<SigComponentType>> getSigComponentTypes();

struct ProgramSignatureHeader {
uint32_t ParamCount;
uint32_t FirstParamOffset;

void swapBytes() {
sys::swapByteOrder(ParamCount);
sys::swapByteOrder(ParamCount);
}
};

struct ProgramSignatureElement {
uint32_t Stream; // Stream index (parameters must appear in non-decreasing
// stream order)
uint32_t NameOffset; // Offset from the start of the ProgramSignatureHeader to
// the start of the null terminated string for the name.
uint32_t Index; // Semantic Index
D3DSystemValue SystemValue; // Semantic type. Similar to PSV::SemanticKind.
SigComponentType CompType; // Type of bits.
uint32_t Register; // Register Index (row index)
uint8_t Mask; // Mask (column allocation)

// The ExclusiveMask has a different meaning for input and output signatures.
// For an output signature, masked components of the output register are never
// written to.
// For an input signature, masked components of the input register are always
// read.
uint8_t ExclusiveMask;

uint16_t Unused;
SigMinPrecision MinPrecision; // Minimum precision of input/output data

void swapBytes() {
sys::swapByteOrder(Stream);
sys::swapByteOrder(NameOffset);
sys::swapByteOrder(Index);
sys::swapByteOrder(SystemValue);
sys::swapByteOrder(CompType);
sys::swapByteOrder(Register);
sys::swapByteOrder(Mask);
sys::swapByteOrder(ExclusiveMask);
sys::swapByteOrder(MinPrecision);
}
};

static_assert(sizeof(ProgramSignatureElement) == 32,
"ProgramSignatureElement is misaligned");

} // namespace dxbc
} // namespace llvm

Expand Down
51 changes: 51 additions & 0 deletions llvm/include/llvm/BinaryFormat/DXContainerConstants.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ CONTAINER_PART(DXIL)
CONTAINER_PART(SFI0)
CONTAINER_PART(HASH)
CONTAINER_PART(PSV0)
CONTAINER_PART(ISG1)
CONTAINER_PART(OSG1)
CONTAINER_PART(PSG1)

#undef CONTAINER_PART
#endif
Expand Down Expand Up @@ -101,6 +104,20 @@ COMPONENT_TYPE(9, Float64)
#undef COMPONENT_TYPE
#endif

#ifdef COMPONENT_PRECISION

COMPONENT_PRECISION(0, Default)
COMPONENT_PRECISION(1, Float16)
COMPONENT_PRECISION(2, Float2_8)
COMPONENT_PRECISION(3, Reserved)
COMPONENT_PRECISION(4, SInt16)
COMPONENT_PRECISION(5, UInt16)
COMPONENT_PRECISION(0xf0, Any16)
COMPONENT_PRECISION(0xf1, Any10)

#undef COMPONENT_PRECISION
#endif

#ifdef INTERPOLATION_MODE

INTERPOLATION_MODE(0, Undefined)
Expand All @@ -115,3 +132,37 @@ INTERPOLATION_MODE(8, Invalid)

#undef INTERPOLATION_MODE
#endif

#ifdef D3D_SYSTEM_VALUE

D3D_SYSTEM_VALUE(0, Undefined)
D3D_SYSTEM_VALUE(1, Position)
D3D_SYSTEM_VALUE(2, ClipDistance)
D3D_SYSTEM_VALUE(3, CullDistance)
D3D_SYSTEM_VALUE(4, RenderTargetArrayIndex)
D3D_SYSTEM_VALUE(5, ViewPortArrayIndex)
D3D_SYSTEM_VALUE(6, VertexID)
D3D_SYSTEM_VALUE(7, PrimitiveID)
D3D_SYSTEM_VALUE(8, InstanceID)
D3D_SYSTEM_VALUE(9, IsFrontFace)
D3D_SYSTEM_VALUE(10, SampleIndex)
D3D_SYSTEM_VALUE(11, FinalQuadEdgeTessfactor)
D3D_SYSTEM_VALUE(12, FinalQuadInsideTessfactor)
D3D_SYSTEM_VALUE(13, FinalTriEdgeTessfactor)
D3D_SYSTEM_VALUE(14, FinalTriInsideTessfactor)
D3D_SYSTEM_VALUE(15, FinalLineDetailTessfactor)
D3D_SYSTEM_VALUE(16, FinalLineDensityTessfactor)
D3D_SYSTEM_VALUE(23, Barycentrics)
D3D_SYSTEM_VALUE(24, ShadingRate)
D3D_SYSTEM_VALUE(25, CullPrimitive)
D3D_SYSTEM_VALUE(64, Target)
D3D_SYSTEM_VALUE(65, Depth)
D3D_SYSTEM_VALUE(66, Coverage)
D3D_SYSTEM_VALUE(67, DepthGE)
D3D_SYSTEM_VALUE(68, DepthLE)
D3D_SYSTEM_VALUE(69, StencilRef)
D3D_SYSTEM_VALUE(70, InnerCoverage)

#undef D3D_SYSTEM_VALUE

#endif
28 changes: 28 additions & 0 deletions llvm/include/llvm/MC/DXContainerPSVInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,34 @@ struct PSVRuntimeInfo {
}
};

class Signature {
struct Parameter {
uint32_t Stream;
StringRef Name;
uint32_t Index;
dxbc::D3DSystemValue SystemValue;
dxbc::SigComponentType CompType;
uint32_t Register;
uint8_t Mask;
uint8_t ExclusiveMask;
dxbc::SigMinPrecision MinPrecision;
};

SmallVector<Parameter> Params;

public:
void addParam(uint32_t Stream, StringRef Name, uint32_t Index,
dxbc::D3DSystemValue SystemValue,
dxbc::SigComponentType CompType, uint32_t Register,
uint8_t Mask, uint8_t ExclusiveMask,
dxbc::SigMinPrecision MinPrecision) {
Params.push_back(Parameter{Stream, Name, Index, SystemValue, CompType,
Register, Mask, ExclusiveMask, MinPrecision});
}

void write(raw_ostream &OS);
};

} // namespace mcdxbc
} // namespace llvm

Expand Down
Loading

0 comments on commit 9f87522

Please sign in to comment.