GPU Shader Position-First Execution to Avoid Culled Varying Work
Find Innovative SolutionsGenerate Solutions
Solution Overview
Problem
Vertex shading in GPUs is inefficient due to wasted computational power and bandwidth from processing primitives that are ultimately culled, as existing solutions require splitting vertex shaders into position and varying shaders, which introduces inefficiencies and hardware complexity.
Innovation Solution
A method where vertex shaders emit positions first, wait for cull results, and then fetch and process varyings only for unculled primitives, reducing redundant processing and memory access without splitting shaders into separate components.
Engineering Contradictions & Design Principles
Engineering Contradiction Analysis
1Reliability
If vertex shading is performed before primitive culling, then position data can be calculated for all instances, but computational power and bandwidth are wasted on culled primitives
Solution Approach 1:
The vertex shader is divided into two separate parts: a position shader that calculates only position data, and a varying shader that calculates varying data. This segmentation allows the position shader to execute for all instances while the varying shader executes only for unculled instances, eliminating wasted computation on culled primitives.
Solution Approach 2:
The position shader executes first as a preliminary step to generate position data for all instances. After culling determines which primitives are visible, the varying shader then executes only for the surviving unculled instances. This preliminary execution of position calculation enables efficient subsequent filtering and selective processing.
2Productivity
If vertex shaders are split into position and varying shaders, then computational efficiency improves, but hardware complexity and scheduling overhead increase
Solution Approach 1:
A single unified vertex shader program contains both position calculation logic and varying calculation logic. The shader compiler automatically generates two separate shader binaries from this unified source, but the hardware executes them as an integrated unit. This universal approach maintains functionality while enabling efficient selective execution.
Solution Approach 2:
The shader compiler creates a copy of the vertex shader program, separating it into two distinct shader binaries: one for position calculation and one for varying calculation. These copies are then selectively executed based on cull results, allowing efficiency gains without requiring complex hardware modifications.
3Speed
If all input attributes are fetched at the beginning, then the first part of the shader can execute, but memory bandwidth is wasted fetching attributes for culled instances
Solution Approach 1:
Only the minimal set of input attributes required for position calculation are fetched and made available to the position shader. The full set of input attributes including varyings is fetched later, after cull results are known, and only for unculled instances. This staged preliminary action prevents wasted memory bandwidth while ensuring required data is available when needed.
Solution Approach 2:
Input attribute fetching is segmented into two phases: first, essential attributes for position calculation are fetched; second, additional attributes for varying calculation are fetched only for unculled instances after culling completes. This segmentation of data access matches the segmentation of shader execution, eliminating redundant memory operations.
Data Source
Figure 1A~1B
Figure 2
Figure 3A
AI summary
A method of operating a GPU is described. Input attributes used in executing a first part of a geometry task are fetched by a shader core. The first part of the task executes a first part of a shader to calculate position data for each instance of the task. The first part of the task is executed to output the position data for each instance of the task. The task is then descheduled until cull results are received for each instance. In response to receiving cull results indicating at least one remaining instance in the task, input attributes used in executing a second part of a task are fetched. The second part of the task executes a second part of a shader to calculate varyings for each remaining instance. The second part of the task is executed and the varyings for each remaining instance are output.