Index: VulkanGame.vcxproj
===================================================================
--- VulkanGame.vcxproj	(revision 4d84c72295f25dbb441372ffced031fcde06d52a)
+++ VulkanGame.vcxproj	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -135,4 +135,5 @@
     <ClCompile Include="FileStackWalker.cpp" />
     <ClCompile Include="game-gui-sdl.cpp" />
+    <ClCompile Include="graphics-pipeline_vulkan.cpp" />
     <ClCompile Include="logger.cpp" />
     <ClCompile Include="main-vulkan.cpp" />
@@ -148,4 +149,6 @@
     <ClInclude Include="game-gui-sdl.hpp" />
     <ClInclude Include="game-gui.hpp" />
+    <ClInclude Include="graphics-pipeline.hpp" />
+    <ClInclude Include="graphics-pipeline_vulkan.hpp" />
     <ClInclude Include="logger.hpp" />
     <ClInclude Include="StackWalker.h" />
Index: graphics-pipeline.hpp
===================================================================
--- graphics-pipeline.hpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
+++ graphics-pipeline.hpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -0,0 +1,15 @@
+#ifndef _GRAPHICS_PIPELINE_H
+#define _GRAPHICS_PIPELINE_H
+
+#include <string>
+
+using namespace std;
+
+class GraphicsPipeline {
+public:
+   virtual ~GraphicsPipeline() {};
+
+   virtual void createPipeline(string vertShaderFile, string fragShaderFile) = 0;
+};
+
+#endif // _GRAPHICS_PIPELINE_H
Index: graphics-pipeline_vulkan.cpp
===================================================================
--- graphics-pipeline_vulkan.cpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
+++ graphics-pipeline_vulkan.cpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -0,0 +1,71 @@
+#include "graphics-pipeline_vulkan.hpp"
+
+#include <fstream>
+#include <stdexcept>
+
+GraphicsPipeline_Vulkan::GraphicsPipeline_Vulkan(VkDevice device) {
+   this->device = device;
+}
+
+GraphicsPipeline_Vulkan::~GraphicsPipeline_Vulkan() {
+}
+
+void GraphicsPipeline_Vulkan::createPipeline(string vertShaderFile, string fragShaderFile) {
+   vector<char> vertShaderCode = readFile(vertShaderFile);
+   vector<char> fragShaderCode = readFile(fragShaderFile);
+
+   VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
+   VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
+
+   VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
+   vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+   vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
+   vertShaderStageInfo.module = vertShaderModule;
+   vertShaderStageInfo.pName = "main";
+
+   VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
+   fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+   fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+   fragShaderStageInfo.module = fragShaderModule;
+   fragShaderStageInfo.pName = "main";
+
+   VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
+
+   VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
+   vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+   vkDestroyShaderModule(device, vertShaderModule, nullptr);
+   vkDestroyShaderModule(device, fragShaderModule, nullptr);
+}
+
+VkShaderModule GraphicsPipeline_Vulkan::createShaderModule(const vector<char>& code) {
+   VkShaderModuleCreateInfo createInfo = {};
+   createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+   createInfo.codeSize = code.size();
+   createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
+
+   VkShaderModule shaderModule;
+   if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
+      throw runtime_error("failed to create shader module!");
+   }
+
+   return shaderModule;
+}
+
+vector<char> GraphicsPipeline_Vulkan::readFile(const string& filename) {
+   ifstream file(filename, ios::ate | ios::binary);
+
+   if (!file.is_open()) {
+      throw runtime_error("failed to open file!");
+   }
+
+   size_t fileSize = (size_t)file.tellg();
+   vector<char> buffer(fileSize);
+
+   file.seekg(0);
+   file.read(buffer.data(), fileSize);
+
+   file.close();
+
+   return buffer;
+}
Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
+++ graphics-pipeline_vulkan.hpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -0,0 +1,24 @@
+#ifndef _GRAPHICS_PIPELINE_VULKAN_H
+#define _GRAPHICS_PIPELINE_VULKAN_H
+
+#include "graphics-pipeline.hpp"
+
+#include <vulkan/vulkan.h>
+
+#include <vector>
+
+class GraphicsPipeline_Vulkan : public GraphicsPipeline {
+   public:
+      GraphicsPipeline_Vulkan(VkDevice device);
+      ~GraphicsPipeline_Vulkan();
+
+      void createPipeline(string vertShaderFile, string fragShaderFile);
+   
+   private:
+      VkDevice device;
+
+      VkShaderModule createShaderModule(const vector<char>& code);
+      vector<char> readFile(const string& filename);
+};
+
+#endif // _GRAPHICS_PIPELINE_VULKAN_H
Index: pipeline-outline.txt
===================================================================
--- pipeline-outline.txt	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
+++ pipeline-outline.txt	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -0,0 +1,11 @@
+Have common functions for the opengl and vuilkan pipelines
+Try to keep state internal and just expose common functions
+
+For vulkan, concerns are bindingDescription and attributeDescriptions
+	-Since we just have one data array split up into point-sized chunks,
+	 we can just have a single bindngDescription
+	-attributeDescriptions will have to be defined per pipeline
+	 (something similar will happen in opengl for varying attributes)
+
+VkPipeline and VkPipelineLayout are used for creating the pipeline commands,
+so keep track of them
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 4d84c72295f25dbb441372ffced031fcde06d52a)
+++ vulkan-game.cpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -105,4 +105,12 @@
    createRenderPass();
    createCommandPool();
+
+   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device));
+   graphicsPipelines.back().createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
+
+   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device));
+   graphicsPipelines.back().createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
+
+   cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
 }
 
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 4d84c72295f25dbb441372ffced031fcde06d52a)
+++ vulkan-game.hpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -3,4 +3,5 @@
 
 #include "game-gui-sdl.hpp"
+#include "graphics-pipeline_vulkan.hpp"
 
 #ifdef NDEBUG
@@ -19,4 +20,6 @@
    private:
       GameGui* gui;
+
+      vector<GraphicsPipeline_Vulkan> graphicsPipelines;
 
       SDL_version sdlVersion;
Index: vulkan-ref.cpp
===================================================================
--- vulkan-ref.cpp	(revision 4d84c72295f25dbb441372ffced031fcde06d52a)
+++ vulkan-ref.cpp	(revision 7d2b0b939e693b4a2e2af92be31aacc7500f7ada)
@@ -863,6 +863,7 @@
 
       void createGraphicsPipeline(string vertShaderFile, string fragShaderFile, GraphicsPipelineInfo& info) {
-         auto vertShaderCode = readFile(vertShaderFile);
-         auto fragShaderCode = readFile(fragShaderFile);
+/*** START OF REFACTORED CODE ***/
+         vector<char> vertShaderCode = readFile(vertShaderFile);
+         vector<char> fragShaderCode = readFile(fragShaderFile);
 
          VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
@@ -885,4 +886,5 @@
          VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
          vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+/*** END OF REFACTORED CODE ***/
 
          vertexInputInfo.vertexBindingDescriptionCount = 1;
@@ -995,6 +997,8 @@
          }
 
+/*** START OF REFACTORED CODE ***/
          vkDestroyShaderModule(device, vertShaderModule, nullptr);
          vkDestroyShaderModule(device, fragShaderModule, nullptr);
+/*** END OF REFACTORED CODE ***/
       }
 
