--- /dev/null
+#include <stdexcept>
+#include "device.h"
+#include "module.h"
+#include "module_backend.h"
+#include "vulkan.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+VulkanSpirVModule::VulkanSpirVModule():
+ device(Device::get_current())
+{ }
+
+VulkanSpirVModule::VulkanSpirVModule(VulkanSpirVModule &&other):
+ device(other.device),
+ handle(other.handle)
+{
+ other.handle = 0;
+}
+
+VulkanSpirVModule::~VulkanSpirVModule()
+{
+ const VulkanFunctions &vk = device.get_functions();
+
+ if(handle)
+ vk.DestroyShaderModule(handle);
+}
+
+void VulkanSpirVModule::create()
+{
+ const vector<uint32_t> &code = static_cast<const SpirVModule *>(this)->code;
+ const VulkanFunctions &vk = device.get_functions();
+
+ VkShaderModuleCreateInfo module_info = { };
+ module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ module_info.codeSize = code.size()*4;
+ module_info.pCode = code.data();
+
+ vk.CreateShaderModule(module_info, handle);
+}
+
+
+unsigned get_vulkan_stage(unsigned stage)
+{
+ switch(stage)
+ {
+ case SpirVModule::VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
+ case SpirVModule::GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
+ case SpirVModule::FRAGMENT: return VK_SHADER_STAGE_FRAGMENT_BIT;
+ default: throw invalid_argument("get_vulkan_stage");
+ }
+}
+
+} // namespace GL
+} // namespace Msp