SBgl 0.1.0
A graphics framework in C99
Loading...
Searching...
No Matches
sbgl_batcher.c
Go to the documentation of this file.
1#include "sbgl_batcher.h"
2
4 const sbgl_DrawPacket* packets,
5 uint32_t packetCount,
6 sbgl_IndirectCommand* outCommands,
7 uint32_t maxCommands
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}
uint32_t sbgl_bake_commands(const sbgl_DrawPacket *packets, uint32_t packetCount, sbgl_IndirectCommand *outCommands, uint32_t maxCommands)
Definition sbgl_batcher.c:3
The baking pipeline for compressing draw packets into indirect commands.
#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