SBgl 0.1.0
A graphics framework in C99
Loading...
Searching...
No Matches
sbgl_batcher.h File Reference

The baking pipeline for compressing draw packets into indirect commands. More...

Include dependency graph for sbgl_batcher.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

uint32_t sbgl_bake_commands (const sbgl_DrawPacket *packets, uint32_t packetCount, sbgl_IndirectCommand *outCommands, uint32_t maxCommands)
 

Detailed Description

The baking pipeline for compressing draw packets into indirect commands.

The batcher provides the logic for grouping multiple draw requests into consolidated indirect commands, maximizing GPU throughput.

Definition in file sbgl_batcher.h.

Function Documentation

◆ sbgl_bake_commands()

uint32_t sbgl_bake_commands ( const sbgl_DrawPacket * packets,
uint32_t packetCount,
sbgl_IndirectCommand * outCommands,
uint32_t maxCommands )

Bakes an array of sorted draw packets into optimized indirect commands.

The system groups contiguous draw packets that share the same mesh, material, and sort key into single multi-instance draw calls. This reduction minimizes the overhead of submitting thousands of individual commands to the graphics hardware.

Parameters
packetsA contiguous array of draw packets, assumed to be sorted.
packetCountTotal number of packets provided in the input array.
outCommandsDestination array for generated indirect commands.
maxCommandsMaximum number of commands the output array can hold.
Returns
The total number of indirect commands generated.

Definition at line 3 of file sbgl_batcher.c.

8 {
9 if (packetCount == 0 || maxCommands == 0) {
10 return 0;
11 }
12
13 // The system initializes the first command using the first packet in the stream.
14 // Geometry parameters are derived from the mesh identifier.
15 uint32_t commandCount = 1;
16
17 switch (SBGL_GET_MESH_ID(packets[0].header)) {
18 case 0: // Triangle
19 outCommands[0].indexCount = 3;
20 outCommands[0].firstIndex = 0;
21 outCommands[0].vertexOffset = 0;
22 break;
23 case 1: // Cube
24 outCommands[0].indexCount = 36;
25 outCommands[0].firstIndex = 3;
26 outCommands[0].vertexOffset = 3;
27 break;
28 case 2: // Pyramid
29 outCommands[0].indexCount = 18;
30 outCommands[0].firstIndex = 39;
31 outCommands[0].vertexOffset = 11;
32 break;
33 case 3: // Voxel Chunk (Procedural 32x32 grid of cubes)
34 outCommands[0].indexCount = 36864; // 32 * 32 * 36
35 outCommands[0].firstIndex = 0; // Generated in shader via gl_VertexIndex
36 outCommands[0].vertexOffset = 0;
37 break;
38 default:
39
40 outCommands[0].indexCount = 0;
41 outCommands[0].firstIndex = 0;
42 outCommands[0].vertexOffset = 0;
43 break;
44 }
45
46 outCommands[0].instanceCount = 1;
47 outCommands[0].firstInstance = 0;
48
49 // The logic iterates through remaining packets, comparing each to its predecessor.
50 // If the state matches, the instance count of the current command is incremented.
51 // Otherwise, a new command is started if space permits in the output buffer.
52 for (uint32_t i = 1; i < packetCount; ++i) {
53 const sbgl_DrawPacket* packet = &packets[i];
54 const sbgl_DrawPacket* previous = &packets[i - 1];
55
56 bool canBatch = (packet->header == previous->header) && (packet->key == previous->key);
57
58 if (canBatch) {
59 outCommands[commandCount - 1].instanceCount++;
60 } else {
61 if (commandCount >= maxCommands) {
62 break;
63 }
64
65 sbgl_IndirectCommand* command = &outCommands[commandCount];
66
67 switch (SBGL_GET_MESH_ID(packet->header)) {
68 case 0: // Triangle
69 command->indexCount = 3;
70 command->firstIndex = 0;
71 command->vertexOffset = 0;
72 break;
73 case 1: // Cube
74 command->indexCount = 36;
75 command->firstIndex = 3;
76 command->vertexOffset = 3;
77 break;
78 case 2: // Pyramid
79 command->indexCount = 18;
80 command->firstIndex = 39;
81 command->vertexOffset = 11;
82 break;
83 case 3: // Voxel Chunk
84 command->indexCount = 36864;
85 command->firstIndex = 0;
86 command->vertexOffset = 0;
87 break;
88 default:
89 command->indexCount = 0;
90 command->firstIndex = 0;
91 command->vertexOffset = 0;
92 break;
93 }
94
95 command->instanceCount = 1;
96
97 // The starting instance index is set to the current packet index,
98 // assuming instance data is packed contiguously in the order of sorted packets.
99 command->firstInstance = i;
100
101 commandCount++;
102 }
103 }
104
105 return commandCount;
106}
#define SBGL_GET_MESH_ID(h)
Definition sbgl_types.h:89
Encapsulates all data required to submit a single draw call. Optimized for cache density (16 bytes).
Definition sbgl_types.h:97
sbgl_SortKey key
Definition sbgl_types.h:98
uint32_t header
Definition sbgl_types.h:99
Standard Vulkan Indirect Draw command layout.
Definition sbgl_types.h:111