Add strided memory pushing and improved spritebatching

This commit is contained in:
2026-05-08 20:53:05 -05:00
parent 73e73d8772
commit 1ff990ff44
14 changed files with 355 additions and 126 deletions
+82
View File
@@ -423,6 +423,87 @@ static void test_memoryResize(void **state) {
assert_int_equal(memoryGetAllocatedCount(), 0);
}
static void test_memoryCopyInterleaved(void **state) {
(void)state;
// Basic: copy 4 uint32_t values from contiguous source into every-other dest
// slot (stride = 2*sizeof(uint32_t)).
uint32_t src[4] = { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
uint32_t dest[8];
memoryZero(dest, sizeof(dest));
memoryCopyInterleaved(
dest, sizeof(uint32_t) * 2,
src, sizeof(uint32_t),
sizeof(uint32_t), 4
);
assert_int_equal(dest[0], 0x11111111);
assert_int_equal(dest[2], 0x22222222);
assert_int_equal(dest[4], 0x33333333);
assert_int_equal(dest[6], 0x44444444);
// Skipped slots should be untouched.
assert_int_equal(dest[1], 0);
assert_int_equal(dest[3], 0);
assert_int_equal(dest[5], 0);
assert_int_equal(dest[7], 0);
// Strided source: pick every second element into a contiguous destination.
uint32_t src2[8] = { 0xA, 0xFF, 0xB, 0xFF, 0xC, 0xFF, 0xD, 0xFF };
uint32_t dest2[4];
memoryZero(dest2, sizeof(dest2));
memoryCopyInterleaved(
dest2, sizeof(uint32_t),
src2, sizeof(uint32_t) * 2,
sizeof(uint32_t), 4
);
assert_int_equal(dest2[0], 0xA);
assert_int_equal(dest2[1], 0xB);
assert_int_equal(dest2[2], 0xC);
assert_int_equal(dest2[3], 0xD);
// Multi-byte element: copy structs field-by-field pattern.
typedef struct { uint32_t x; uint32_t y; } pair_t;
uint32_t yVals[3] = { 10, 20, 30 };
pair_t pairs[3];
memoryZero(pairs, sizeof(pairs));
memoryCopyInterleaved(
&pairs[0].y, sizeof(pair_t),
yVals, sizeof(uint32_t),
sizeof(uint32_t), 3
);
assert_int_equal(pairs[0].y, 10);
assert_int_equal(pairs[1].y, 20);
assert_int_equal(pairs[2].y, 30);
assert_int_equal(pairs[0].x, 0);
assert_int_equal(pairs[1].x, 0);
assert_int_equal(pairs[2].x, 0);
// Count of 0 is a no-op.
uint32_t untouched[2] = { 0xDEAD, 0xBEEF };
memoryCopyInterleaved(untouched, 4, src, 4, 4, 0);
assert_int_equal(untouched[0], 0xDEAD);
// NULL dest
expect_assert_failure(memoryCopyInterleaved(NULL, 8, src, 4, 4, 2));
// NULL src
expect_assert_failure(memoryCopyInterleaved(dest, 8, NULL, 4, 4, 2));
// elementSize 0
expect_assert_failure(memoryCopyInterleaved(dest, 8, src, 4, 0, 2));
// destStride smaller than elementSize
expect_assert_failure(memoryCopyInterleaved(dest, 2, src, 4, 4, 2));
// srcStride smaller than elementSize
expect_assert_failure(memoryCopyInterleaved(dest, 8, src, 2, 4, 2));
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_memoryAllocate),
@@ -435,6 +516,7 @@ int main(int argc, char **argv) {
cmocka_unit_test(test_memoryCompare),
cmocka_unit_test(test_memoryReallocate),
cmocka_unit_test(test_memoryResize),
cmocka_unit_test(test_memoryCopyInterleaved),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}