#include "Std140Buffer.h" #include #include #include namespace { int gFailures = 0; void Expect(bool condition, const char* message) { if (condition) return; std::cerr << "FAIL: " << message << "\n"; ++gFailures; } float ReadFloat(const std::vector& buffer, std::size_t offset) { float value = 0.0f; std::memcpy(&value, buffer.data() + offset, sizeof(float)); return value; } int ReadInt(const std::vector& buffer, std::size_t offset) { int value = 0; std::memcpy(&value, buffer.data() + offset, sizeof(int)); return value; } void TestScalarPacking() { std::vector buffer; AppendStd140Float(buffer, 1.25f); AppendStd140Int(buffer, 7); Expect(buffer.size() == 8, "scalar values pack tightly on 4-byte alignment"); Expect(ReadFloat(buffer, 0) == 1.25f, "float value is written at offset 0"); Expect(ReadInt(buffer, 4) == 7, "int value is written at offset 4"); } void TestVectorAlignment() { std::vector buffer; AppendStd140Float(buffer, 1.0f); AppendStd140Vec2(buffer, 2.0f, 3.0f); AppendStd140Vec4(buffer, 4.0f, 5.0f, 6.0f, 7.0f); Expect(buffer.size() == 32, "vec2 aligns to 8 bytes and vec4 aligns to 16 bytes"); Expect(ReadFloat(buffer, 8) == 2.0f, "vec2 x value is aligned"); Expect(ReadFloat(buffer, 12) == 3.0f, "vec2 y value follows x"); Expect(ReadFloat(buffer, 16) == 4.0f, "vec4 x value is aligned"); Expect(ReadFloat(buffer, 28) == 7.0f, "vec4 w value is written"); } void TestGlobalParamStylePacking() { std::vector buffer; AppendStd140Float(buffer, 10.0f); // time AppendStd140Vec2(buffer, 1920.0f, 1080.0f); // input resolution AppendStd140Vec2(buffer, 1280.0f, 720.0f); // output resolution AppendStd140Float(buffer, 45296.0f); // UTC time of day AppendStd140Float(buffer, 36000.0f); // UTC offset AppendStd140Float(buffer, 0.75f); // startup random AppendStd140Float(buffer, 42.0f); // frame count AppendStd140Float(buffer, 0.5f); // mix AppendStd140Float(buffer, 1.0f); // bypass AppendStd140Int(buffer, 3); // source history length AppendStd140Int(buffer, 2); // temporal history length AppendStd140Float(buffer, 0.25f); // float parameter AppendStd140Vec2(buffer, 4.0f, 5.0f); // vec2 parameter AppendStd140Vec4(buffer, 0.1f, 0.2f, 0.3f, 1.0f); // color parameter AppendStd140Int(buffer, 1); // boolean parameter AppendStd140Int(buffer, 2); // enum parameter buffer.resize(AlignStd140(buffer.size(), 16), 0); Expect(buffer.size() == 112, "global parameter style block is padded to a 16-byte boundary"); Expect(ReadFloat(buffer, 0) == 10.0f, "time is at the start of the block"); Expect(ReadFloat(buffer, 8) == 1920.0f, "first vec2 aligns after scalar padding"); Expect(ReadFloat(buffer, 16) == 1280.0f, "second vec2 follows first vec2"); Expect(ReadFloat(buffer, 24) == 45296.0f, "UTC time follows output resolution"); Expect(ReadFloat(buffer, 28) == 36000.0f, "UTC offset follows UTC time"); Expect(ReadFloat(buffer, 32) == 0.75f, "startup random follows UTC offset"); Expect(ReadInt(buffer, 48) == 3, "history length scalar remains tightly packed"); Expect(ReadFloat(buffer, 64) == 4.0f, "vec2 shader parameter aligns to 8 bytes"); Expect(ReadFloat(buffer, 80) == 0.1f, "color parameter aligns to 16 bytes"); Expect(ReadInt(buffer, 96) == 1, "boolean parameter follows vec4"); Expect(ReadInt(buffer, 100) == 2, "enum parameter follows boolean"); } } int main() { TestScalarPacking(); TestVectorAlignment(); TestGlobalParamStylePacking(); if (gFailures != 0) { std::cerr << gFailures << " Std140Buffer test failure(s).\n"; return 1; } std::cout << "Std140Buffer tests passed.\n"; return 0; }