- Implemented ComputeSchedulerTest to validate device management, task scheduling, and resource cleanup for the compute scheduler. - Created mock_window class for testing Vulkan surface creation, supporting both headless and windowed modes. - Added shader_loader utility for loading SPIR-V shaders from files and providing minimal embedded shaders for testing. - Introduced test_helpers for creating and destroying shader modules, validating device features, and finding memory types. - Established VulkanTestBase and VulkanGPUTest classes to streamline Vulkan test setup and teardown processes.
161 lines
7.0 KiB
C++
161 lines
7.0 KiB
C++
#include "shader_loader.h"
|
|
#include <fstream>
|
|
#include <sstream>
|
|
|
|
namespace mirage::render::vulkan::test {
|
|
|
|
auto shader_loader::load_spirv_from_file(const std::filesystem::path& shader_path)
|
|
-> std::expected<std::vector<uint32_t>, 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<uint32_t> spirv_code(file_size / 4);
|
|
file.seekg(0);
|
|
file.read(reinterpret_cast<char*>(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<uint32_t>& {
|
|
// 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<uint32_t> 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<uint32_t>& {
|
|
// Minimal fragment shader SPIR-V that outputs a solid color vec4(1.0, 0.0, 0.0, 1.0)
|
|
static const std::vector<uint32_t> 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<uint32_t>& {
|
|
// Minimal compute shader SPIR-V with local_size(1, 1, 1)
|
|
static const std::vector<uint32_t> 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
|