I saw SV_PrimitiveID semantic in documentation which says it creates an ID for each primitive which are unique in every draw call.
I have seen this semantic in Geometry shader and I'm confused with the term primitive. I have vertex buffer with vertices of a cube and a sphere, does SV_PrimitiveID index cube vertices 0 and sphere 1 or for every triangle in vertex buffer it gives a number(imagining GS inputs triangle list). I also don't know if the first situation was true how does it distinguish between cube and sphere when they are both in one vertex buffer.
What the SV_PrimitiveID
means is determined by the D3D11_PRIMITIVE_TOPOLOGY
(set by ID3D11DeviceContext::IASetPrimitiveTopology
). Every draw call every primitive is assigned a number in order that the primitives are drawn.
For example:
// buffers that will be copied to the gpu
struct Vertex { float X, Y, Z; } VertexData[6] =
{
{ 0, 0, 0 },
{ 1, 0, 0 },
{ 1, 1, 0 },
{ 1, 1, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 },
};
struct Triangle { int A, B, C; } IndexData[2] =
{
{ 0, 1, 2 },// SV_PrimitiveID == 0
{ 2, 4, 0 },// SV_PrimitiveID == 1
};
struct Instance { float X, Y, Z; } InstanceData[2] =
{
{ 0, 0, 0 },// SV_InstanceID == 0
{ 0, 0, 1 },// SV_InstanceID == 1
};
...
pDeviceConstext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
pDeviceConstext->Draw(6, 0);// would result in two triangles numbered (value of SV_PrimitiveID) 0 and 1
pDeviceConstext->DrawIndexed(2 * 3, 0, 0);// same thing
pDeviceConstext->DrawInstanced(6, 2, 0, 0);// now 4 triangles, 2 for the 0th instance and 2 for the 1st; SV_PrimitiveID restarts from zero for every instance!
...
I don't know for sure the interaction between geometry shaders and SV_PrimitiveID, but DirectX is well-documented. Here are some links:
https://learn.microsoft.com/en-us/windows/win32/direct3d11/geometry-shader-stage https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-geometry-shader
Personally I find useful to visually display any information that I might find confusing. For example setting something like this as the pixel shader:
float4 main(uint pid : SV_PrimitiveId) : SV_Target
{
static const uint N = 16;
float3 color = float3(((pid / uint3(1, N, N * N)) % N) / (float)N);
return float4(color, 1);
}