Skip to content

Commit

Permalink
Add support for SW primitive statistics counting
Browse files Browse the repository at this point in the history
For pre-GFX11, the primitive statistics counting is performed by HW via
the same mechanism of transform feedback. For GFX11+, since transform
feedback is done by SW emulation, the primitive statistics counting will
follow the same handling.

We add a new handler collectPrimitiveStats to deal with it. It is a
reduced version of SW transform feedback, only updating HW counters of
requested vertex streams. We don't merge it with SW transform feedback
because this will make the logic blurry. Indeed, some duplicated codes
are the trade-off.

For non-GS case, only the counter of stream 0 will be updated and
generated primitive count is passed by GE (we don't modify it). For GS
case, counters of all active vertex streams will be updated and we must
calculate generated primitive count first before doing such update. The
calculation is to count valid primitive mask bits in this NGG subgroup
and add them together.

The implementation of this PR is the foundation of
VK_EXT_primitives_generated_query.
  • Loading branch information
amdrexu committed Sep 18, 2023
1 parent 3d7228a commit a80c85b
Show file tree
Hide file tree
Showing 4 changed files with 357 additions and 62 deletions.
12 changes: 8 additions & 4 deletions lgc/builder/MiscBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ using namespace llvm;
Instruction *BuilderImpl::CreateEmitVertex(unsigned streamId) {
assert(m_shaderStage == ShaderStageGeometry);

// Mark this vertex stream as active if transform feedback is enabled or this is the rasterization stream.
if (m_pipelineState->enableXfb() || m_pipelineState->getRasterizerState().rasterStream == streamId)
// Mark this vertex stream as active if transform feedback is enabled, or primitive statistics counting is enabled,
// or this is the rasterization stream.
if (m_pipelineState->enableXfb() || m_pipelineState->enablePrimStats() ||
m_pipelineState->getRasterizerState().rasterStream == streamId)
m_pipelineState->setVertexStreamActive(streamId);

// Get GsWaveId
Expand All @@ -68,8 +70,10 @@ Instruction *BuilderImpl::CreateEmitVertex(unsigned streamId) {
Instruction *BuilderImpl::CreateEndPrimitive(unsigned streamId) {
assert(m_shaderStage == ShaderStageGeometry);

// Mark this vertex stream as active if transform feedback is enabled or this is the rasterization stream.
if (m_pipelineState->enableXfb() || m_pipelineState->getRasterizerState().rasterStream == streamId)
// Mark this vertex stream as active if transform feedback is enabled, or primitive statistics counting is enabled,
// or this is the rasterization stream.
if (m_pipelineState->enableXfb() || m_pipelineState->enablePrimStats() ||
m_pipelineState->getRasterizerState().rasterStream == streamId)
m_pipelineState->setVertexStreamActive(streamId);

// Get GsWaveId
Expand Down
2 changes: 1 addition & 1 deletion lgc/include/lgc/state/PipelineState.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ class PipelineState final : public Pipeline {
// Check if transform feedback is active
bool enableXfb() const { return m_xfbStateMetadata.enableXfb; }

// Check if we need count primitives if XFB is disabled
// Check if we need primitive statistics counting
bool enablePrimStats() const { return m_xfbStateMetadata.enablePrimStats; }

// Get transform feedback strides
Expand Down
Loading

0 comments on commit a80c85b

Please sign in to comment.