#include "shader_loader.h" #include #include namespace mirage::render::vulkan::test { auto shader_loader::load_spirv_from_file(const std::filesystem::path& shader_path) -> std::expected, std::string> { std::filesystem::path full_path = shader_path; // If path is relative, prepend TEST_SHADER_DIR if (shader_path.is_relative()) { #ifdef TEST_SHADER_DIR full_path = std::filesystem::path(TEST_SHADER_DIR) / shader_path; #else full_path = get_shader_dir() / shader_path; #endif } // Open file in binary mode std::ifstream file(full_path, std::ios::binary | std::ios::ate); if (!file.is_open()) { return std::unexpected("Failed to open shader file: " + full_path.string()); } // Get file size auto file_size = file.tellg(); if (file_size % 4 != 0) { return std::unexpected("Invalid SPIR-V file size (not multiple of 4): " + full_path.string()); } // Read file contents std::vector spirv_code(file_size / 4); file.seekg(0); file.read(reinterpret_cast(spirv_code.data()), file_size); if (!file) { return std::unexpected("Failed to read shader file: " + full_path.string()); } return spirv_code; } auto shader_loader::get_shader_dir() -> std::filesystem::path { #ifdef TEST_SHADER_DIR return std::filesystem::path(TEST_SHADER_DIR); #else // Fallback: assume tests/shaders relative to executable return std::filesystem::current_path() / "tests" / "shaders"; #endif } auto shader_loader::get_minimal_vertex_shader() -> const std::vector& { // Minimal vertex shader SPIR-V that outputs gl_Position = vec4(0.0, 0.0, 0.0, 1.0) // This is a placeholder - will be replaced with actual compiled SPIR-V static const std::vector spirv = { 0x07230203, 0x00010000, 0x000d0007, 0x00000021, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000d, 0x00000011, 0x00030003, 0x00000002, 0x000001c2, 0x00090004, 0x415f4c47, 0x735f4252, 0x72617065, 0x5f657461, 0x64616873, 0x6f5f7265, 0x63656a62, 0x00007374, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x0000000b, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x0000000b, 0x00000000, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00070006, 0x0000000b, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, 0x00070006, 0x0000000b, 0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00070006, 0x0000000b, 0x00000003, 0x435f6c67, 0x446c6c75, 0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00050048, 0x0000000b, 0x00000000, 0x0000000b, 0x00000000, 0x00050048, 0x0000000b, 0x00000001, 0x0000000b, 0x00000001, 0x00050048, 0x0000000b, 0x00000002, 0x0000000b, 0x00000003, 0x00050048, 0x0000000b, 0x00000003, 0x0000000b, 0x00000004, 0x00030047, 0x0000000b, 0x00000002, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040015, 0x00000008, 0x00000020, 0x00000000, 0x0004002b, 0x00000008, 0x00000009, 0x00000001, 0x0004001c, 0x0000000a, 0x00000006, 0x00000009, 0x0006001e, 0x0000000b, 0x00000007, 0x00000006, 0x0000000a, 0x0000000a, 0x00040020, 0x0000000c, 0x00000003, 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, 0x00040015, 0x0000000e, 0x00000020, 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x0004002b, 0x00000006, 0x00000013, 0x00000000, 0x0004002b, 0x00000006, 0x00000014, 0x3f800000, 0x0007002c, 0x00000007, 0x00000015, 0x00000013, 0x00000013, 0x00000013, 0x00000014, 0x00040020, 0x00000016, 0x00000003, 0x00000007, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00050041, 0x00000016, 0x00000017, 0x0000000d, 0x0000000f, 0x0003003e, 0x00000017, 0x00000015, 0x000100fd, 0x00010038 }; return spirv; } auto shader_loader::get_minimal_fragment_shader() -> const std::vector& { // Minimal fragment shader SPIR-V that outputs a solid color vec4(1.0, 0.0, 0.0, 1.0) static const std::vector spirv = { 0x07230203, 0x00010000, 0x000d0007, 0x0000000d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x00000009, 0x00000000, 0x00030010, 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001c2, 0x00090004, 0x415f4c47, 0x735f4252, 0x72617065, 0x5f657461, 0x64616873, 0x6f5f7265, 0x63656a62, 0x00007374, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00050005, 0x00000009, 0x4374756f, 0x726f6c6f, 0x00000000, 0x00040047, 0x00000009, 0x0000001e, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040020, 0x00000008, 0x00000003, 0x00000007, 0x0004003b, 0x00000008, 0x00000009, 0x00000003, 0x0004002b, 0x00000006, 0x0000000a, 0x3f800000, 0x0004002b, 0x00000006, 0x0000000b, 0x00000000, 0x0007002c, 0x00000007, 0x0000000c, 0x0000000a, 0x0000000b, 0x0000000b, 0x0000000a, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0003003e, 0x00000009, 0x0000000c, 0x000100fd, 0x00010038 }; return spirv; } auto shader_loader::get_minimal_compute_shader() -> const std::vector& { // Minimal compute shader SPIR-V with local_size(1, 1, 1) static const std::vector spirv = { 0x07230203, 0x00010000, 0x000d0007, 0x00000006, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2, 0x00090004, 0x415f4c47, 0x735f4252, 0x72617065, 0x5f657461, 0x64616873, 0x6f5f7265, 0x63656a62, 0x00007374, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x000100fd, 0x00010038 }; return spirv; } } // namespace mirage::render::vulkan::test