/// @param pa - The primitive assembly object.
/// @param pGsOut - output stream for GS
template <
- bool HasStreamOutT,
- bool HasRastT>
+ typename HasStreamOutT,
+ typename HasRastT>
static void GeometryShaderStage(
DRAW_CONTEXT *pDC,
uint32_t workerId,
// set up new binner and state for the GS output topology
PFN_PROCESS_PRIMS pfnClipFunc = nullptr;
- if (HasRastT)
+ if (HasRastT::value)
{
switch (pState->outputTopology)
{
else
{
// early exit if this stream is not enabled for streamout
- if (HasStreamOutT && !state.soState.streamEnable[stream])
+ if (HasStreamOutT::value && !state.soState.streamEnable[stream])
{
continue;
}
{
totalPrimsGenerated += gsPa.NumPrims();
- if (HasStreamOutT)
+ if (HasStreamOutT::value)
{
StreamOut(pDC, gsPa, workerId, pSoPrimData, stream);
}
- if (HasRastT && state.soState.streamToRasterizer == stream)
+ if (HasRastT::value && state.soState.streamToRasterizer == stream)
{
simdscalari vPrimId;
// pull primitiveID from the GS output if available
/// @param pa - The primitive assembly object.
/// @param pGsOut - output stream for GS
template <
- bool HasGeometryShaderT,
- bool HasStreamOutT,
- bool HasRastT>
+ typename HasGeometryShaderT,
+ typename HasStreamOutT,
+ typename HasRastT>
static void TessellationStages(
DRAW_CONTEXT *pDC,
uint32_t workerId,
SWR_ASSERT(tsCtx);
PFN_PROCESS_PRIMS pfnClipFunc = nullptr;
- if (HasRastT)
+ if (HasRastT::value)
{
switch (tsState.postDSTopology)
{
while (tessPa.HasWork())
{
- if (HasGeometryShaderT)
+ if (HasGeometryShaderT::value)
{
GeometryShaderStage<HasStreamOutT, HasRastT>(
pDC, workerId, tessPa, pGsOut, pCutBuffer, pCutStreamBuffer, pSoPrimData,
}
else
{
- if (HasStreamOutT)
+ if (HasStreamOutT::value)
{
StreamOut(pDC, tessPa, workerId, pSoPrimData, 0);
}
- if (HasRastT)
+ if (HasRastT::value)
{
simdvector prim[3]; // Only deal with triangles, lines, or points
RDTSC_START(FEPAAssemble);
/// @brief FE handler for SwrDraw.
/// @tparam IsIndexedT - Is indexed drawing enabled
/// @tparam HasTessellationT - Is tessellation enabled
-/// @tparam HasGeometryShaderT - Is the geometry shader stage enabled
+/// @tparam HasGeometryShaderT::value - Is the geometry shader stage enabled
/// @tparam HasStreamOutT - Is stream-out enabled
/// @tparam HasRastT - Is rasterization enabled
/// @param pContext - pointer to SWR context.
/// @param workerId - thread's worker id.
/// @param pUserData - Pointer to DRAW_WORK
template <
- bool IsIndexedT,
- bool HasTessellationT,
- bool HasGeometryShaderT,
- bool HasStreamOutT,
- bool HasRastT>
+ typename IsIndexedT,
+ typename HasTessellationT,
+ typename HasGeometryShaderT,
+ typename HasStreamOutT,
+ typename HasRastT>
void ProcessDraw(
SWR_CONTEXT *pContext,
DRAW_CONTEXT *pDC,
uint32_t endVertex = work.numVerts;
const int32_t* pLastRequestedIndex = nullptr;
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
switch (work.type)
{
vsContext.pVin = &vin;
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
fetchInfo.BaseVertex = work.baseVertex;
void* pGsOut = nullptr;
void* pCutBuffer = nullptr;
void* pStreamCutBuffer = nullptr;
- if (HasGeometryShaderT)
+ if (HasGeometryShaderT::value)
{
AllocateGsBuffers(pDC, state, &pGsOut, &pCutBuffer, &pStreamCutBuffer);
}
- if (HasTessellationT)
+ if (HasTessellationT::value)
{
SWR_ASSERT(state.tsState.tsEnable == true);
SWR_ASSERT(state.pfnHsFunc != nullptr);
// allocate space for streamout input prim data
uint32_t* pSoPrimData = nullptr;
- if (HasStreamOutT)
+ if (HasStreamOutT::value)
{
pSoPrimData = (uint32_t*)pDC->pArena->AllocAligned(4096, 16);
simdscalari vIndex;
uint32_t i = 0;
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
fetchInfo.pIndices = work.pIB;
}
// PaGetNextVsOutput currently has the side effect of updating some PA state machine state.
// So we need to keep this outside of (i < endVertex) check.
simdmask* pvCutIndices = nullptr;
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
pvCutIndices = &pa.GetNextVsIndices();
}
vsContext.mask = GenerateMask(endVertex - i);
// forward cut mask to the PA
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
*pvCutIndices = _simd_movemask_ps(_simd_castsi_ps(fetchInfo.CutMask));
}
{
UPDATE_STAT(IaPrimitives, pa.NumPrims());
- if (HasTessellationT)
+ if (HasTessellationT::value)
{
TessellationStages<HasGeometryShaderT, HasStreamOutT, HasRastT>(
pDC, workerId, pa, pGsOut, pCutBuffer, pStreamCutBuffer, pSoPrimData, pa.GetPrimID(work.startPrimID));
}
- else if (HasGeometryShaderT)
+ else if (HasGeometryShaderT::value)
{
GeometryShaderStage<HasStreamOutT, HasRastT>(
pDC, workerId, pa, pGsOut, pCutBuffer, pStreamCutBuffer, pSoPrimData, pa.GetPrimID(work.startPrimID));
else
{
// If streamout is enabled then stream vertices out to memory.
- if (HasStreamOutT)
+ if (HasStreamOutT::value)
{
StreamOut(pDC, pa, workerId, pSoPrimData, 0);
}
- if (HasRastT)
+ if (HasRastT::value)
{
SWR_ASSERT(pDC->pState->pfnProcessPrims);
pDC->pState->pfnProcessPrims(pDC, pa, workerId, prim,
} while (pa.NextPrim());
i += KNOB_SIMD_WIDTH;
- if (IsIndexedT)
+ if (IsIndexedT::value)
{
fetchInfo.pIndices = (int*)((uint8_t*)fetchInfo.pIndices + KNOB_SIMD_WIDTH * indexSize);
}
RDTSC_STOP(FEProcessDraw, numPrims * work.numInstances, pDC->drawId);
}
-// Explicit Instantiation of all combinations
-template void ProcessDraw<false, false, false, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, false, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, false, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, false, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, true, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, true, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, true, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, false, true, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, false, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, false, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, false, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, false, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, true, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, true, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, true, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<false, true, true, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, false, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, false, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, false, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, false, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, true, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, true, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, true, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, false, true, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, false, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, false, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, false, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, false, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, true, false, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, true, false, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, true, true, false>(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
-template void ProcessDraw<true, true, true, true, true >(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t workerId, void *pUserData);
+
+struct FEDrawChooser
+{
+ typedef PFN_FE_WORK_FUNC FuncType;
+
+ template <typename... ArgsB>
+ static FuncType GetFunc()
+ {
+ return ProcessDraw<ArgsB...>;
+ }
+};
+
+
+// Selector for correct templated Draw front-end function
+PFN_FE_WORK_FUNC GetProcessDrawFunc(
+ bool IsIndexed,
+ bool HasTessellation,
+ bool HasGeometryShader,
+ bool HasStreamOut,
+ bool HasRasterization)
+{
+ return TemplateArgUnroller<FEDrawChooser>::GetFunc(IsIndexed, HasTessellation, HasGeometryShader, HasStreamOut, HasRasterization);
+}
//////////////////////////////////////////////////////////////////////////