Skip to content

Commit

Permalink
Pipeline cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Pilzschaf committed Apr 3, 2023
1 parent c5feac3 commit 1d3dea9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
bin
build
.vscode
*.bin

# CMake
CMakeLists.txt.user
Expand Down
13 changes: 9 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ VkCommandBuffer commandBuffers[FRAMES_IN_FLIGHT];
VkFence fences[FRAMES_IN_FLIGHT];
VkSemaphore acquireSemaphores[FRAMES_IN_FLIGHT];
VkSemaphore releaseSemaphores[FRAMES_IN_FLIGHT];
VkPipelineCache pipelineCache;

VulkanBuffer spriteVertexBuffer;
VulkanBuffer spriteIndexBuffer;
Expand Down Expand Up @@ -236,6 +237,8 @@ void initApplication(SDL_Window* window) {
SDL_Vulkan_CreateSurface(window, context->instance, &surface);
swapchain = createSwapchain(context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT);

pipelineCache = createPipelineCache(context, "../shaders/pipeline_cache.bin");

recreateRenderPass();

//model = createModel(context, "../data/models/monkey.glb");
Expand Down Expand Up @@ -396,7 +399,7 @@ void initApplication(SDL_Window* window) {
vertexInputBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
vertexInputBinding.stride = sizeof(float) * 7;
spritePipeline = createPipeline(context, "../shaders/texture_vert.spv", "../shaders/texture_frag.spv", renderPass, swapchain.width, swapchain.height,
vertexAttributeDescriptions, ARRAY_COUNT(vertexAttributeDescriptions), &vertexInputBinding, 1, &spriteDescriptorLayout, 0, 0, VK_SAMPLE_COUNT_4_BIT);
vertexAttributeDescriptions, ARRAY_COUNT(vertexAttributeDescriptions), &vertexInputBinding, 1, &spriteDescriptorLayout, 0, 0, VK_SAMPLE_COUNT_4_BIT, 0, pipelineCache);


VkVertexInputAttributeDescription modelAttributeDescriptions[3] = {};
Expand All @@ -417,7 +420,7 @@ void initApplication(SDL_Window* window) {
modelInputBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
modelInputBinding.stride = sizeof(float) * 8;
modelPipeline = createPipeline(context, "../shaders/model_vert.spv", "../shaders/model_frag.spv", renderPass, swapchain.width, swapchain.height,
modelAttributeDescriptions, ARRAY_COUNT(modelAttributeDescriptions), &modelInputBinding, 1, &modelDescriptorSetLayout, 0, 0, VK_SAMPLE_COUNT_4_BIT);
modelAttributeDescriptions, ARRAY_COUNT(modelAttributeDescriptions), &modelInputBinding, 1, &modelDescriptorSetLayout, 0, 0, VK_SAMPLE_COUNT_4_BIT, 0, pipelineCache);


// Preparations for Guassian Blur pass
Expand Down Expand Up @@ -465,8 +468,8 @@ void initApplication(SDL_Window* window) {
specializationInfo.dataSize = sizeof(vertical);
specializationInfo.pData = &vertical;

gaussPipelineVertical = createPipeline(context, "../shaders/gaussian_vert.spv", "../shaders/gaussian_frag.spv", gaussRenderPass, swapchain.width, swapchain.height, 0, 0, 0, 1, &gaussDescriptorSetLayout, &pushConstants, 0, VK_SAMPLE_COUNT_1_BIT, &specializationInfo);
gaussPipelineHorizontal = createPipeline(context, "../shaders/gaussian_vert.spv", "../shaders/gaussian_frag.spv", gaussRenderPassFinal, swapchain.width, swapchain.height, 0, 0, 0, 1, &gaussDescriptorSetLayout, &pushConstants, 0, VK_SAMPLE_COUNT_1_BIT);
gaussPipelineVertical = createPipeline(context, "../shaders/gaussian_vert.spv", "../shaders/gaussian_frag.spv", gaussRenderPass, swapchain.width, swapchain.height, 0, 0, 0, 1, &gaussDescriptorSetLayout, &pushConstants, 0, VK_SAMPLE_COUNT_1_BIT, &specializationInfo, pipelineCache);
gaussPipelineHorizontal = createPipeline(context, "../shaders/gaussian_vert.spv", "../shaders/gaussian_frag.spv", gaussRenderPassFinal, swapchain.width, swapchain.height, 0, 0, 0, 1, &gaussDescriptorSetLayout, &pushConstants, 0, VK_SAMPLE_COUNT_1_BIT, 0, pipelineCache);

for(uint32_t i = 0; i < ARRAY_COUNT(fences); ++i) {
VkFenceCreateInfo createInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
Expand Down Expand Up @@ -923,6 +926,8 @@ void shutdownApplication() {
vkDestroySampler(context->device, sampler, 0);
vkDestroySampler(context->device, linearSampler, 0);

destroyPipelineCache(context, pipelineCache, "../shaders/pipeline_cache.bin");

for (uint32_t i = 0; i < sceneFramebuffers.size(); ++i) {
VK(vkDestroyFramebuffer(context->device, sceneFramebuffers[i], 0));
VK(vkDestroyFramebuffer(context->device, gaussFramebuffers[i], 0));
Expand Down
6 changes: 4 additions & 2 deletions src/vulkan_base/vulkan_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ void uploadDataToImage(VulkanContext* context, VulkanImage* image, void* data, s
void destroyImage(VulkanContext* context, VulkanImage* image);

VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height,
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, uint32_t subpassIndex = 0, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, VkSpecializationInfo* specializationInfo = 0);
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, uint32_t subpassIndex = 0, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, VkSpecializationInfo* specializationInfo = 0, VkPipelineCache pipelineCache = 0);
VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderFilename,
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo);
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo, VkPipelineCache pipelineCache = 0);
void destroyPipeline(VulkanContext* context, VulkanPipeline* pipeline);
VkPipelineCache createPipelineCache(VulkanContext* context, const char* filename);
void destroyPipelineCache(VulkanContext* context, VkPipelineCache cache, const char* filename);
46 changes: 42 additions & 4 deletions src/vulkan_base/vulkan_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ VkShaderModule createShaderModule(VulkanContext* context, const char* shaderFile
}

VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height,
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, uint32_t subpassIndex, VkSampleCountFlagBits sampleCount, VkSpecializationInfo* specializationInfo) {
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, uint32_t subpassIndex, VkSampleCountFlagBits sampleCount, VkSpecializationInfo* specializationInfo, VkPipelineCache pipelineCache) {
VkShaderModule vertexShaderModule = createShaderModule(context, vertexShaderFilename);
VkShaderModule fragmentShaderModule = createShaderModule(context, fragmentShaderFilename);

Expand Down Expand Up @@ -118,7 +118,7 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
createInfo.layout = pipelineLayout;
createInfo.renderPass = renderPass;
createInfo.subpass = subpassIndex;
VKA(vkCreateGraphicsPipelines(context->device, 0, 1, &createInfo, 0, &pipeline));
VKA(vkCreateGraphicsPipelines(context->device, pipelineCache, 1, &createInfo, 0, &pipeline));
}

// Module can be destroyed after pipeline creation
Expand All @@ -132,7 +132,7 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
}

VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderFilename,
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo) {
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo, VkPipelineCache pipelineCache) {
VkShaderModule shaderModule = createShaderModule(context, shaderFilename);
VkPipelineShaderStageCreateInfo shaderStage;
shaderStage = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
Expand All @@ -156,7 +156,7 @@ VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderF
VkComputePipelineCreateInfo createInfo = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
createInfo.stage = shaderStage;
createInfo.layout = pipelineLayout;
VKA(vkCreateComputePipelines(context->device, 0, 1, &createInfo, 0, &pipeline));
VKA(vkCreateComputePipelines(context->device, pipelineCache, 1, &createInfo, 0, &pipeline));
}

// Module can be destroyed after pipeline creation
Expand All @@ -171,4 +171,42 @@ VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderF
void destroyPipeline(VulkanContext* context, VulkanPipeline* pipeline) {
VK(vkDestroyPipeline(context->device, pipeline->pipeline, 0));
VK(vkDestroyPipelineLayout(context->device, pipeline->pipelineLayout, 0));
}

VkPipelineCache createPipelineCache(VulkanContext* context, const char* filename) {
VkPipelineCache result = {0};

FILE* file = fopen(filename, "rb");
long fileSize = 0;
uint8_t* buffer = 0;
if(file) {
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = new uint8_t[fileSize];
fread(buffer, 1, fileSize, file);
}

VkPipelineCacheCreateInfo createInfo = {VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
if(buffer) {
createInfo.initialDataSize = fileSize;
createInfo.pInitialData = buffer;
}
vkCreatePipelineCache(context->device, &createInfo, 0, &result);

if(buffer) {
delete[] buffer;
}
return result;
}

void destroyPipelineCache(VulkanContext* context, VkPipelineCache cache, const char* filename) {
size_t cacheSize = 0;
vkGetPipelineCacheData(context->device, cache, &cacheSize, 0);
uint8_t* cacheData = new uint8_t[cacheSize];
vkGetPipelineCacheData(context->device, cache, &cacheSize, cacheData);
FILE* file = fopen(filename, "wb");
fwrite(cacheData, sizeof(uint8_t), cacheSize, file);
delete[] cacheData;
vkDestroyPipelineCache(context->device, cache, 0);
}

0 comments on commit 1d3dea9

Please sign in to comment.