Skip to content

Commit 1d3dea9

Browse files
committed
Pipeline cache
1 parent c5feac3 commit 1d3dea9

4 files changed

Lines changed: 56 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
bin
22
build
33
.vscode
4+
*.bin
45

56
# CMake
67
CMakeLists.txt.user

src/main.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ VkCommandBuffer commandBuffers[FRAMES_IN_FLIGHT];
3535
VkFence fences[FRAMES_IN_FLIGHT];
3636
VkSemaphore acquireSemaphores[FRAMES_IN_FLIGHT];
3737
VkSemaphore releaseSemaphores[FRAMES_IN_FLIGHT];
38+
VkPipelineCache pipelineCache;
3839

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

240+
pipelineCache = createPipelineCache(context, "../shaders/pipeline_cache.bin");
241+
239242
recreateRenderPass();
240243

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

401404

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

422425

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

468-
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);
469-
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);
471+
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);
472+
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);
470473

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

929+
destroyPipelineCache(context, pipelineCache, "../shaders/pipeline_cache.bin");
930+
926931
for (uint32_t i = 0; i < sceneFramebuffers.size(); ++i) {
927932
VK(vkDestroyFramebuffer(context->device, sceneFramebuffers[i], 0));
928933
VK(vkDestroyFramebuffer(context->device, gaussFramebuffers[i], 0));

src/vulkan_base/vulkan_base.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ void uploadDataToImage(VulkanContext* context, VulkanImage* image, void* data, s
7474
void destroyImage(VulkanContext* context, VulkanImage* image);
7575

7676
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height,
77-
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);
77+
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);
7878
VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderFilename,
79-
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo);
79+
uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts, VkPushConstantRange* pushConstant, VkSpecializationInfo* specializationInfo, VkPipelineCache pipelineCache = 0);
8080
void destroyPipeline(VulkanContext* context, VulkanPipeline* pipeline);
81+
VkPipelineCache createPipelineCache(VulkanContext* context, const char* filename);
82+
void destroyPipelineCache(VulkanContext* context, VkPipelineCache cache, const char* filename);

src/vulkan_base/vulkan_pipeline.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ VkShaderModule createShaderModule(VulkanContext* context, const char* shaderFile
2828
}
2929

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

@@ -118,7 +118,7 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
118118
createInfo.layout = pipelineLayout;
119119
createInfo.renderPass = renderPass;
120120
createInfo.subpass = subpassIndex;
121-
VKA(vkCreateGraphicsPipelines(context->device, 0, 1, &createInfo, 0, &pipeline));
121+
VKA(vkCreateGraphicsPipelines(context->device, pipelineCache, 1, &createInfo, 0, &pipeline));
122122
}
123123

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

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

162162
// Module can be destroyed after pipeline creation
@@ -171,4 +171,42 @@ VulkanPipeline createComputePipeline(VulkanContext* context, const char* shaderF
171171
void destroyPipeline(VulkanContext* context, VulkanPipeline* pipeline) {
172172
VK(vkDestroyPipeline(context->device, pipeline->pipeline, 0));
173173
VK(vkDestroyPipelineLayout(context->device, pipeline->pipelineLayout, 0));
174+
}
175+
176+
VkPipelineCache createPipelineCache(VulkanContext* context, const char* filename) {
177+
VkPipelineCache result = {0};
178+
179+
FILE* file = fopen(filename, "rb");
180+
long fileSize = 0;
181+
uint8_t* buffer = 0;
182+
if(file) {
183+
fseek(file, 0, SEEK_END);
184+
fileSize = ftell(file);
185+
fseek(file, 0, SEEK_SET);
186+
buffer = new uint8_t[fileSize];
187+
fread(buffer, 1, fileSize, file);
188+
}
189+
190+
VkPipelineCacheCreateInfo createInfo = {VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
191+
if(buffer) {
192+
createInfo.initialDataSize = fileSize;
193+
createInfo.pInitialData = buffer;
194+
}
195+
vkCreatePipelineCache(context->device, &createInfo, 0, &result);
196+
197+
if(buffer) {
198+
delete[] buffer;
199+
}
200+
return result;
201+
}
202+
203+
void destroyPipelineCache(VulkanContext* context, VkPipelineCache cache, const char* filename) {
204+
size_t cacheSize = 0;
205+
vkGetPipelineCacheData(context->device, cache, &cacheSize, 0);
206+
uint8_t* cacheData = new uint8_t[cacheSize];
207+
vkGetPipelineCacheData(context->device, cache, &cacheSize, cacheData);
208+
FILE* file = fopen(filename, "wb");
209+
fwrite(cacheData, sizeof(uint8_t), cacheSize, file);
210+
delete[] cacheData;
211+
vkDestroyPipelineCache(context->device, cache, 0);
174212
}

0 commit comments

Comments
 (0)