CPU vs GPU: How They Work Together for Graphics Rendering

The Collaborative Relationship Between CPUs and GPUs
The Central Processing Unit (CPU) and Graphics Processing Unit (GPU) within your computer are constantly working in tandem. This collaboration is essential for providing a smooth and visually appealing user experience.
These two components interact continuously while your computer is in use, ensuring responsiveness and clarity in the interface you see.
How CPUs and GPUs Work Together
Modern computing relies heavily on the coordinated efforts of both the CPU and GPU. Each processor excels at different types of tasks, and their combined strengths deliver optimal performance.
The CPU is generally responsible for handling the bulk of the processing, including operating system functions and application logic. Conversely, the GPU specializes in rendering images, videos, and other visual content.
When you perform tasks like gaming, video editing, or even simply browsing the web, the CPU and GPU share the workload. The CPU prepares the data, and the GPU then processes it to create the visuals displayed on your screen.
Origin of the Information
This explanation originates from a question and answer session hosted on SuperUser.
SuperUser is a part of Stack Exchange, a network of community-driven question and answer websites.
The original photograph accompanying this discussion was taken by sskennel.
Understanding the Rendering Pipeline
A SuperUser user, Sathya, initiated a discussion regarding the intricate process behind rendering graphics. The query centered around a simple C++ program, Triangle.exe, utilizing OpenGL to display a rotating triangle.
The core of the question lies in understanding the interaction between the CPU and GPU, from the moment the executable is launched in Windows XP to the visual output on the monitor. The example, while basic, serves as a foundation for comprehending more complex graphics operations.
Key Components Involved
Several hardware and software elements collaborate to achieve this visual result. These include, but aren't limited to, the following:
Hardware
- HDD: The hard disk drive stores the program's executable file.
- System Memory (RAM): This provides temporary storage for the program's code and data.
- CPU: The central processing unit initially handles the execution of the .exe file.
- Video Memory: Dedicated memory used by the GPU for storing textures and framebuffers.
- GPU: The graphics processing unit ultimately renders the triangle and outputs it to the display.
- LCD Display: The monitor that visually presents the rendered image.
Software
- Operating System: Windows XP manages the overall system resources and execution.
- DirectX/OpenGL API: These application programming interfaces provide a standardized way for the program to communicate with the GPU.
- Nvidia Driver: This software enables communication between the operating system and the specific Nvidia GPU.
The request was for an explanation suitable for an intermediate IT professional, avoiding excessive detail while maintaining accuracy. It was noted that even some experienced IT personnel might struggle to articulate this process correctly.
The initial step involves loading the Triangle.exe program from the HDD into RAM. The CPU then begins executing the program's instructions. These instructions include calls to the OpenGL API.
The OpenGL API acts as an intermediary, translating the program's requests into commands the GPU can understand. The Nvidia Driver facilitates this communication, ensuring compatibility between the operating system, OpenGL, and the specific Nvidia graphics card.
The GPU receives these commands and performs the necessary calculations to render the triangle. This includes vertex processing, rasterization, and fragment shading. The rendered image is then stored in Video Memory.
Finally, the GPU sends the image data to the LCD Display, which presents the rotating triangle to the user. This entire sequence happens rapidly, creating the illusion of smooth animation.
Understanding CPU and GPU Interaction in Rendering Graphics
Although numerous individuals within the community responded to the initial query, Oliver Salzburg provided an exceptionally thorough answer, complemented by insightful graphics.
Image courtesy of JasonC, available as wallpaper here.
He explains:
My focus will be on the programming aspects and how the various components communicate with each other. This may clarify certain areas of the process.
The Rendering Process
What steps are involved in displaying even a single image, such as the one you initially presented?
There are multiple methods for drawing a triangle on the screen. For simplicity, let's assume vertex buffers are not utilized. (A vertex buffer is a designated memory region for storing coordinate data.) Let's presume the program directly informs the graphics processing pipeline about each vertex – a vertex being a coordinate in space – sequentially.
However, before any drawing can occur, initial setup procedures are necessary. The reason for this will become apparent later:
// Clear The Screen And The Depth BufferglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Reset The Current Modelview MatrixglMatrixMode(GL_MODELVIEW);glLoadIdentity();// Drawing Using TrianglesglBegin(GL_TRIANGLES);// RedglColor3f(1.0f,0.0f,0.0f);// Top Of Triangle (Front)glVertex3f( 0.0f, 1.0f, 0.0f);// GreenglColor3f(0.0f,1.0f,0.0f);// Left Of Triangle (Front)glVertex3f(-1.0f,-1.0f, 1.0f);// BlueglColor3f(0.0f,0.0f,1.0f);// Right Of Triangle (Front)glVertex3f( 1.0f,-1.0f, 1.0f);// Done DrawingglEnd();
What Does This Code Achieve?
When developing a program that utilizes the graphics card, you typically select an interface to the driver. Common interfaces include:
- OpenGL
- Direct3D
- CUDA
For this illustration, we will focus on OpenGL. Your chosen interface provides the necessary tools for your program to communicate with the graphics card (or, more precisely, with the driver, which then relays instructions to the card).
This interface offers a set of tools in the form of an Application Programming Interface (API) that you can invoke from your code.
The example above demonstrates the use of this API. Let's examine it more closely.
Initial Setup
Prior to actual drawing, a setup phase is required. This involves defining the viewport (the area to be rendered), the perspective (the virtual camera), and anti-aliasing settings (to smooth edges)...
However, we won't delve into those details. Instead, we'll focus on the tasks that must be performed every frame, such as:
Clearing the Screen
The graphics pipeline does not automatically clear the screen each frame. You must explicitly instruct it to do so. The reason is as follows:

Without clearing the screen, subsequent frames would simply be drawn on top of the previous ones. Therefore, we call glClear with the GL_COLOR_BUFFER_BIT flag. The other flag (GL_DEPTH_BUFFER_BIT) instructs OpenGL to clear the depth buffer, which is used to determine the relative depth of pixels.
Transformation

Image source
Transformation involves taking the input coordinates (the triangle's vertices) and applying the ModelView matrix. This matrix defines the rotation, scaling, and translation (movement) of the model (the vertices).
Next, the Projection matrix is applied, positioning the coordinates relative to the camera.
Finally, the Viewport matrix transforms the coordinates to match the size of the monitor. The vertices are now prepared for rendering!
We will revisit transformation later.
Drawing
To draw a triangle, we instruct OpenGL to begin a new triangle list by calling glBegin with the GL_TRIANGLES constant.
Other drawing primitives, such as triangle strips or triangle fans, exist. These are primarily optimizations, reducing communication between the CPU and GPU for the same number of triangles.
We then provide a series of three vertices that define each triangle. Each triangle requires three coordinates (as we are working in 3D space). I also specify a color for each vertex using glColor3f before calling glVertex3f.
OpenGL automatically calculates the shading between the three vertices (the triangle's corners), interpolating the color across the polygon's surface.
Interaction
When you click within the window, the application simply captures the window message signaling the click. You can then execute any desired action within your program.
However, interacting with a 3D scene is considerably more complex.
First, you must determine the precise pixel clicked by the user. Then, considering the perspective, you can calculate the direction of a ray originating from the mouse click and extending into the scene. If this ray intersects any object in the scene, you know the user has clicked that object.
How do you initiate rotation?
Transformation Methods
I identify two primary types of transformations:
- Matrix-based transformation
- Bone-based transformation
The key difference is that bones affect individual vertices, while matrices apply the same transformation to all drawn vertices.
Example
Previously, we loaded the identity matrix before drawing our triangle. The identity matrix applies no transformation. Therefore, the triangle's appearance is solely determined by the perspective. It will not rotate.
To rotate it, you could perform the calculations yourself (on the CPU) and call glVertex3f with adjusted coordinates. Alternatively, you can let the GPU handle the work by calling glRotatef before drawing:
// Rotate The Triangle On The Y axis glRotatef(amount,0.0f,1.0f,0.0f);
amount represents a fixed value. To animate the rotation, you must track and increment amount each frame.
What About the Matrix Discussion Earlier?
In this simple example, matrices are not a concern. Calling glRotatef handles all the matrix calculations for you.
glRotateproduces a rotation ofangledegrees around the vector x y z . The current matrix (seeglMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix, as ifglMultMatrix were called with the following matrix as its argument:x 2 1 - c + c x y 1 - c - z s x z 1 - c + y s 0 y x 1 - c + z s y 2 1 - c + c y z 1 - c - x s 0 x z 1 - c - y s y z 1 - c + x s z 2 1 - c + c 0 0 0 0 1
Thank you for that detailed explanation!
Conclusion
It's evident that a significant amount of communication occurs with OpenGL. However, OpenGL provides limited feedback to us.
The primary information OpenGL provides is when an operation is complete. Each operation takes a certain amount of time, ranging from incredibly fast to potentially slow.
Sending a single vertex to the GPU is exceptionally fast. However, sending thousands of vertices every frame might not be an issue, depending on the hardware.
Clearing the screen can take a millisecond or longer, depending on the viewport size. This involves drawing every pixel in the desired color, potentially millions of pixels.
Beyond that, we can primarily query OpenGL for the capabilities of the graphics adapter (maximum resolution, anti-aliasing levels, color depth, etc.).
We can also populate a texture with pixels, each holding a specific color value. This texture becomes a large "file" filled with data. We can load this into the graphics card, create a shader, instruct the shader to use the texture as input, and perform complex calculations.
The resulting calculations (represented as new colors) can then be rendered into a new texture.
This is how you can leverage the GPU for tasks beyond traditional rendering. CUDA likely operates similarly in this regard, although I haven't had the opportunity to work with it.
We have only scratched the surface of this complex subject. 3D graphics programming is a challenging field.

Image Source
Do you have anything to add to this explanation? Share your thoughts in the comments. For more insights from other tech-savvy Stack Exchange users, visit the full discussion thread here.