summaryrefslogtreecommitdiff
path: root/serialize.c
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2018-04-06 10:23:56 +0200
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>2018-04-06 10:23:56 +0200
commitacee7b888285c635f17b36cd13f8a6b6065b88e2 (patch)
tree88104e0ffc430b031acbe9fcf7b28ddf4b828488 /serialize.c
initial commit; import existing files
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Diffstat (limited to 'serialize.c')
-rw-r--r--serialize.c959
1 files changed, 959 insertions, 0 deletions
diff --git a/serialize.c b/serialize.c
new file mode 100644
index 0000000..14a296f
--- /dev/null
+++ b/serialize.c
@@ -0,0 +1,959 @@
+/*
+ * Copyright © 2018 Valve Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "serialize.h"
+
+/**
+ * Sampler.
+ */
+static void
+serialize_sampler(const VkSamplerCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->magFilter);
+ blob_write_uint32(metadata, pInfo->minFilter);
+ blob_write_uint32(metadata, pInfo->mipmapMode);
+ blob_write_uint32(metadata, pInfo->addressModeU);
+ blob_write_uint32(metadata, pInfo->addressModeV);
+ blob_write_uint32(metadata, pInfo->addressModeW);
+ blob_write_uint32(metadata, pInfo->mipLodBias);
+ blob_write_uint32(metadata, pInfo->anisotropyEnable);
+ blob_write_uint32(metadata, pInfo->maxAnisotropy);
+ blob_write_uint32(metadata, pInfo->compareEnable);
+ blob_write_uint32(metadata, pInfo->compareOp);
+ blob_write_uint32(metadata, pInfo->minLod);
+ blob_write_uint32(metadata, pInfo->maxLod);
+ blob_write_uint32(metadata, pInfo->borderColor);
+ blob_write_uint32(metadata, pInfo->unnormalizedCoordinates);
+}
+
+static void
+deserialize_sampler(VkSamplerCreateInfo *pInfo,
+ struct blob_reader *metadata)
+{
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+
+ pInfo->magFilter = blob_read_uint32(metadata);
+ pInfo->minFilter = blob_read_uint32(metadata);
+ pInfo->mipmapMode = blob_read_uint32(metadata);
+ pInfo->addressModeU = blob_read_uint32(metadata);
+ pInfo->addressModeV = blob_read_uint32(metadata);
+ pInfo->addressModeW = blob_read_uint32(metadata);
+ pInfo->mipLodBias = blob_read_uint32(metadata);
+ pInfo->anisotropyEnable = blob_read_uint32(metadata);
+ pInfo->maxAnisotropy = blob_read_uint32(metadata);
+ pInfo->compareEnable = blob_read_uint32(metadata);
+ pInfo->compareOp = blob_read_uint32(metadata);
+ pInfo->minLod = blob_read_uint32(metadata);
+ pInfo->maxLod = blob_read_uint32(metadata);
+ pInfo->borderColor = blob_read_uint32(metadata);
+ pInfo->unnormalizedCoordinates = blob_read_uint32(metadata);
+}
+
+/**
+ * Render pass.
+ */
+static void
+serialize_render_pass(struct pipeline_info *pipeline,
+ struct blob *metadata)
+{
+ const VkRenderPassCreateInfo *pInfo = &pipeline->renderPassInfo;
+
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->attachmentCount);
+ if (pInfo->attachmentCount) {
+ blob_write_bytes(metadata, pInfo->pAttachments,
+ sizeof(*pInfo->pAttachments) *
+ pInfo->attachmentCount);
+ }
+
+ blob_write_uint32(metadata, pInfo->subpassCount);
+ for (uint32_t i = 0; i < pInfo->subpassCount; i++) {
+ const VkSubpassDescription *subpass = &pInfo->pSubpasses[i];
+ bool has_depth_stencil = subpass->pDepthStencilAttachment ? true : false;
+
+ blob_write_uint32(metadata, subpass->flags);
+ blob_write_uint32(metadata, subpass->pipelineBindPoint);
+
+ blob_write_uint32(metadata, subpass->inputAttachmentCount);
+ if (subpass->inputAttachmentCount) {
+ blob_write_bytes(metadata, subpass->pInputAttachments,
+ sizeof(*subpass->pInputAttachments) *
+ subpass->inputAttachmentCount);
+ }
+
+ blob_write_uint32(metadata, subpass->colorAttachmentCount);
+ if (subpass->colorAttachmentCount) {
+ bool has_resolve = subpass->pResolveAttachments ? true : false;
+
+ blob_write_bytes(metadata, subpass->pColorAttachments,
+ sizeof(*subpass->pColorAttachments) *
+ subpass->colorAttachmentCount);
+
+ blob_write_uint32(metadata, has_resolve);
+ if (has_resolve) {
+ blob_write_bytes(metadata, subpass->pResolveAttachments,
+ sizeof(*subpass->pResolveAttachments) *
+ subpass->colorAttachmentCount);
+ }
+ }
+
+ blob_write_uint32(metadata, has_depth_stencil);
+ if (has_depth_stencil) {
+ blob_write_bytes(metadata, subpass->pDepthStencilAttachment,
+ sizeof(*subpass->pDepthStencilAttachment));
+ }
+
+ blob_write_uint32(metadata, subpass->preserveAttachmentCount);
+ if (subpass->preserveAttachmentCount) {
+ blob_write_bytes(metadata, subpass->pPreserveAttachments,
+ sizeof(*subpass->pPreserveAttachments) *
+ subpass->preserveAttachmentCount);
+ }
+ }
+
+ blob_write_uint32(metadata, pInfo->dependencyCount);
+ if (pInfo->dependencyCount) {
+ blob_write_bytes(metadata, pInfo->pDependencies,
+ sizeof(*pInfo->pDependencies) *
+ pInfo->dependencyCount);
+ }
+}
+
+static bool
+deserialize_render_pass(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkRenderPassCreateInfo *pInfo = &pipeline->renderPassInfo;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
+
+ pInfo->attachmentCount = blob_read_uint32(metadata);
+ if (pInfo->attachmentCount) {
+ pInfo->pAttachments =
+ blob_read_bytes(metadata, sizeof(*pInfo->pAttachments) *
+ pInfo->attachmentCount);
+ }
+
+ pInfo->subpassCount = blob_read_uint32(metadata);
+ if (pInfo->subpassCount) {
+ VkSubpassDescription *pSubpasses =
+ calloc(pInfo->subpassCount, sizeof(*pSubpasses)); /* TODO: remove me */
+
+ for (uint32_t i = 0; i < pInfo->subpassCount; i++) {
+ VkSubpassDescription *subpass = &pSubpasses[i];
+
+ subpass->flags = blob_read_uint32(metadata);
+ subpass->pipelineBindPoint = blob_read_uint32(metadata);
+
+ subpass->inputAttachmentCount = blob_read_uint32(metadata);
+ if (subpass->inputAttachmentCount) {
+ subpass->pInputAttachments =
+ blob_read_bytes(metadata, sizeof(*subpass->pInputAttachments) *
+ subpass->inputAttachmentCount);
+ }
+
+ subpass->colorAttachmentCount = blob_read_uint32(metadata);
+ if (subpass->colorAttachmentCount) {
+ subpass->pColorAttachments =
+ blob_read_bytes(metadata, sizeof(*subpass->pColorAttachments) *
+ subpass->colorAttachmentCount);
+
+ if (blob_read_uint32(metadata)) {
+ subpass->pResolveAttachments =
+ blob_read_bytes(metadata, sizeof(*subpass->pResolveAttachments) *
+ subpass->colorAttachmentCount);
+ }
+ }
+
+ if (blob_read_uint32(metadata)) {
+ subpass->pDepthStencilAttachment =
+ blob_read_bytes(metadata, sizeof(*subpass->pDepthStencilAttachment));
+ }
+
+ subpass->preserveAttachmentCount = blob_read_uint32(metadata);
+ if (subpass->preserveAttachmentCount) {
+ subpass->pPreserveAttachments =
+ blob_read_bytes(metadata, sizeof(*subpass->pPreserveAttachments) *
+ subpass->preserveAttachmentCount);
+ }
+ }
+
+ pInfo->pSubpasses = pSubpasses;
+ }
+
+ pInfo->dependencyCount = blob_read_uint32(metadata);
+ if (pInfo->dependencyCount) {
+ pInfo->pDependencies =
+ blob_read_bytes(metadata, sizeof(*pInfo->pDependencies) *
+ pInfo->dependencyCount);
+ }
+
+ return true;
+}
+
+/**
+ * Shader module.
+ */
+static void
+serialize_shader_module(const VkShaderModuleCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->codeSize);
+ blob_write_bytes(metadata, pInfo->pCode, pInfo->codeSize);
+}
+
+static bool
+deserialize_shader_module(VkShaderModuleCreateInfo *pInfo,
+ struct blob_reader *metadata)
+{
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
+
+ pInfo->codeSize = blob_read_uint32(metadata);
+ pInfo->pCode = blob_read_bytes(metadata, pInfo->codeSize);
+
+ return true;
+}
+
+/**
+ * Descriptor set layout.
+ */
+static void
+serialize_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->bindingCount);
+ for (uint32_t i = 0; i < pInfo->bindingCount; i++) {
+ const VkDescriptorSetLayoutBinding *binding =
+ &pInfo->pBindings[i];
+
+ blob_write_uint32(metadata, binding->binding);
+ blob_write_uint32(metadata, binding->descriptorType);
+ blob_write_uint32(metadata, binding->descriptorCount);
+ blob_write_uint32(metadata, binding->stageFlags);
+
+ /* TODO: pImmutableSamplers */
+ }
+}
+
+static bool
+deserialize_descriptor_set_layout(VkDescriptorSetLayoutCreateInfo *pInfo,
+ struct blob_reader *metadata)
+{
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
+
+ pInfo->bindingCount = blob_read_uint32(metadata);
+ if (pInfo->bindingCount) {
+ VkDescriptorSetLayoutBinding *pBindings =
+ calloc(pInfo->bindingCount, sizeof(*pBindings)); /* TODO: remove me */
+
+ if (!pBindings)
+ return false;
+
+ for (uint32_t i = 0; i < pInfo->bindingCount; i++) {
+ VkDescriptorSetLayoutBinding *binding = &pBindings[i];
+
+ binding->binding = blob_read_uint32(metadata);
+ binding->descriptorType = blob_read_uint32(metadata);
+ binding->descriptorCount = blob_read_uint32(metadata);
+ binding->stageFlags = blob_read_uint32(metadata);
+ binding->pImmutableSamplers = NULL;
+ /* TODO: pImmutableSamplers */
+ }
+
+ pInfo->pBindings = pBindings;
+ }
+
+ return true;
+}
+
+/**
+ * Pipeline layout.
+ */
+static void
+serialize_pipeline_layout(struct pipeline_info *pipeline,
+ struct blob *metadata)
+{
+ VkPipelineLayoutCreateInfo *pInfo = &pipeline->pipelineLayoutInfo;
+
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->setLayoutCount);
+ for (uint32_t i = 0; i < pInfo->setLayoutCount; i++) {
+ serialize_descriptor_set_layout(&pipeline->pSetLayoutsInfo[i],
+ metadata);
+ }
+
+ blob_write_uint32(metadata, pInfo->pushConstantRangeCount);
+ if (pInfo->pushConstantRangeCount) {
+ blob_write_bytes(metadata, pInfo->pPushConstantRanges,
+ sizeof(*pInfo->pPushConstantRanges) *
+ pInfo->pushConstantRangeCount);
+ }
+}
+
+static bool
+deserialize_pipeline_layout(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineLayoutCreateInfo *pInfo = &pipeline->pipelineLayoutInfo;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
+
+ pInfo->setLayoutCount = blob_read_uint32(metadata);
+ if (pInfo->setLayoutCount) {
+ pipeline->pSetLayoutsInfo =
+ calloc(pInfo->setLayoutCount, sizeof(*pipeline->pSetLayoutsInfo));
+
+ if (!pipeline->pSetLayoutsInfo)
+ return false;
+
+ for (uint32_t i = 0; i < pInfo->setLayoutCount; i++) {
+ if (!deserialize_descriptor_set_layout(&pipeline->pSetLayoutsInfo[i],
+ metadata))
+ return false;
+ }
+ }
+
+ pInfo->pushConstantRangeCount = blob_read_uint32(metadata);
+ if (pInfo->pushConstantRangeCount) {
+ pInfo->pPushConstantRanges =
+ blob_read_bytes(metadata, sizeof(*pInfo->pPushConstantRanges) *
+ pInfo->pushConstantRangeCount);
+ }
+
+ return true;
+}
+
+/**
+ * Graphics pipeline.
+ */
+/* Shader stage. */
+void
+serialize_shader_stage_state(const VkPipelineShaderStageCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->stage);
+ blob_write_string(metadata, pInfo->pName);
+}
+
+static bool
+deserialize_shader_stage_state(VkPipelineShaderStageCreateInfo *pInfo,
+ struct blob_reader *metadata)
+{
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
+
+ pInfo->stage = blob_read_uint32(metadata);
+ pInfo->pName = blob_read_string(metadata);
+
+ return true;
+}
+
+static void
+serialize_shader_stage_states(struct pipeline_info *pipeline,
+ struct blob *metadata)
+{
+ for (uint32_t i = 0; i < pipeline->stageCount; i++) {
+ serialize_shader_stage_state(&pipeline->pShaderStagesInfo[i],
+ metadata);
+
+ serialize_shader_module(&pipeline->pShaderModulesInfo[i], metadata);
+ }
+}
+
+static bool
+deserialize_shader_stage_states(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ bool valid = true;
+
+ pipeline->pShaderStagesInfo =
+ calloc(pipeline->stageCount, sizeof(*pipeline->pShaderStagesInfo));
+ if (!pipeline->pShaderStagesInfo)
+ return false;
+
+ pipeline->pShaderModulesInfo =
+ calloc(pipeline->stageCount, sizeof (*pipeline->pShaderModulesInfo));
+ if (!pipeline->pShaderModulesInfo)
+ return false;
+
+ for (uint32_t i = 0; i < pipeline->stageCount; i++) {
+ valid &= deserialize_shader_stage_state(&pipeline->pShaderStagesInfo[i],
+ metadata);
+
+ valid &= deserialize_shader_module(&pipeline->pShaderModulesInfo[i],
+ metadata);
+ }
+
+ return valid;
+}
+
+/* Vertex input state. */
+static void
+serialize_vertex_input_state(const VkPipelineVertexInputStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->vertexBindingDescriptionCount);
+ if (pInfo->vertexBindingDescriptionCount) {
+ blob_write_bytes(metadata, pInfo->pVertexBindingDescriptions,
+ sizeof(*pInfo->pVertexBindingDescriptions) *
+ pInfo->vertexBindingDescriptionCount);
+ }
+
+ blob_write_uint32(metadata, pInfo->vertexAttributeDescriptionCount);
+ if (pInfo->vertexAttributeDescriptionCount) {
+ blob_write_bytes(metadata, pInfo->pVertexAttributeDescriptions,
+ sizeof(*pInfo->pVertexAttributeDescriptions) *
+ pInfo->vertexAttributeDescriptionCount);
+ }
+}
+
+static bool
+deserialize_vertex_input_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineVertexInputStateCreateInfo *pInfo = &pipeline->vertexInputState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
+
+ pInfo->vertexBindingDescriptionCount = blob_read_uint32(metadata);
+ if (pInfo->vertexBindingDescriptionCount) {
+ pInfo->pVertexBindingDescriptions =
+ blob_read_bytes(metadata, sizeof(*pInfo->pVertexBindingDescriptions) *
+ pInfo->vertexBindingDescriptionCount);
+ }
+
+ pInfo->vertexAttributeDescriptionCount = blob_read_uint32(metadata);
+ if (pInfo->vertexAttributeDescriptionCount) {
+ pInfo->pVertexAttributeDescriptions =
+ blob_read_bytes(metadata, sizeof(*pInfo->pVertexAttributeDescriptions) *
+ pInfo->vertexAttributeDescriptionCount);
+ }
+
+ return true;
+}
+
+/* Input assembly state. */
+static void
+serialize_input_assembly_state(const VkPipelineInputAssemblyStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->topology);
+ blob_write_uint32(metadata, pInfo->primitiveRestartEnable);
+}
+
+static bool
+deserialize_input_assembly_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineInputAssemblyStateCreateInfo *pInfo = &pipeline->inputAssemblyState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);
+
+ pInfo->topology = blob_read_uint32(metadata);
+ pInfo->primitiveRestartEnable = blob_read_uint32(metadata);
+
+ return true;
+}
+
+/* Tessellation state. */
+static void
+serialize_tessellation_state(const VkPipelineTessellationStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ bool has_state =
+ pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
+
+ blob_write_uint32(metadata, has_state);
+ if (!has_state)
+ return;
+
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->patchControlPoints);
+}
+
+static bool
+deserialize_tessellation_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineTessellationStateCreateInfo *pInfo = &pipeline->tessellationState;
+ bool has_state;
+
+ has_state = blob_read_uint32(metadata);
+ if (!has_state)
+ return true;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO);
+
+ pInfo->patchControlPoints = blob_read_uint32(metadata);
+
+ return true;
+}
+
+/* Viewport state. */
+static void
+serialize_viewport_state(const VkPipelineViewportStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ bool has_viewports = pInfo->pViewports ? true : false;
+ bool has_scissors = pInfo->pScissors ? true : false;
+
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->viewportCount);
+ blob_write_uint32(metadata, has_viewports);
+ if (has_viewports) {
+ blob_write_bytes(metadata, pInfo->pViewports,
+ sizeof(*pInfo->pViewports) *
+ pInfo->viewportCount);
+ }
+
+ blob_write_uint32(metadata, pInfo->scissorCount);
+ blob_write_uint32(metadata, has_scissors);
+ if (has_scissors) {
+ blob_write_bytes(metadata, pInfo->pScissors,
+ sizeof(*pInfo->pScissors) *
+ pInfo->scissorCount);
+ }
+}
+
+static bool
+deserialize_viewport_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineViewportStateCreateInfo *pInfo = &pipeline->viewportState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO);
+
+ pInfo->viewportCount = blob_read_uint32(metadata);
+ if (blob_read_uint32(metadata)) {
+ pInfo->pViewports =
+ blob_read_bytes(metadata, sizeof(*pInfo->pViewports) *
+ pInfo->viewportCount);
+ }
+
+ pInfo->scissorCount = blob_read_uint32(metadata);
+ if (blob_read_uint32(metadata)) {
+ pInfo->pScissors =
+ blob_read_bytes(metadata, sizeof(*pInfo->pScissors) *
+ pInfo->scissorCount);
+ }
+
+ return true;
+}
+
+/* Rasterization state. */
+static void
+serialize_rasterization_state(const VkPipelineRasterizationStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->depthClampEnable);
+ blob_write_uint32(metadata, pInfo->rasterizerDiscardEnable);
+ blob_write_uint32(metadata, pInfo->polygonMode);
+ blob_write_uint32(metadata, pInfo->cullMode);
+ blob_write_uint32(metadata, pInfo->frontFace);
+ blob_write_uint32(metadata, pInfo->depthBiasEnable);
+ blob_write_uint32(metadata, pInfo->depthBiasConstantFactor);
+ blob_write_uint32(metadata, pInfo->depthBiasClamp);
+ blob_write_uint32(metadata, pInfo->depthBiasSlopeFactor);
+ blob_write_uint32(metadata, pInfo->lineWidth);
+}
+
+static bool
+deserialize_rasterization_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineRasterizationStateCreateInfo *pInfo = &pipeline->rasterizationState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO);
+
+ pInfo->depthClampEnable = blob_read_uint32(metadata);
+ pInfo->rasterizerDiscardEnable = blob_read_uint32(metadata);
+ pInfo->polygonMode = blob_read_uint32(metadata);
+ pInfo->cullMode = blob_read_uint32(metadata);
+ pInfo->frontFace = blob_read_uint32(metadata);
+ pInfo->depthBiasEnable = blob_read_uint32(metadata);
+ pInfo->depthBiasConstantFactor = blob_read_uint32(metadata);
+ pInfo->depthBiasClamp = blob_read_uint32(metadata);
+ pInfo->depthBiasSlopeFactor = blob_read_uint32(metadata);
+ pInfo->lineWidth = blob_read_uint32(metadata);
+
+ return true;
+}
+
+/* Multisample state. */
+static void
+serialize_multisample_state(const VkPipelineMultisampleStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ bool has_sample_mask = pInfo->pSampleMask ? true : false;
+
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->rasterizationSamples);
+ blob_write_uint32(metadata, pInfo->sampleShadingEnable);
+ blob_write_uint32(metadata, pInfo->minSampleShading);
+
+ blob_write_uint32(metadata, has_sample_mask);
+ if (has_sample_mask) {
+ unsigned count = MAX2(pInfo->rasterizationSamples / 32, 1);
+
+ blob_write_bytes(metadata, pInfo->pSampleMask,
+ sizeof(*pInfo->pSampleMask) * count);
+ }
+
+ blob_write_uint32(metadata, pInfo->alphaToCoverageEnable);
+ blob_write_uint32(metadata, pInfo->alphaToOneEnable);
+}
+
+static bool
+deserialize_multisample_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineMultisampleStateCreateInfo *pInfo = &pipeline->multisampleState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO);
+
+ pInfo->rasterizationSamples = blob_read_uint32(metadata);
+ pInfo->sampleShadingEnable = blob_read_uint32(metadata);
+ pInfo->minSampleShading = blob_read_uint32(metadata);
+
+ if (blob_read_uint32(metadata)) {
+ unsigned count = MAX2(pInfo->rasterizationSamples / 32, 1);
+
+ pInfo->pSampleMask =
+ blob_read_bytes(metadata, sizeof(*pInfo->pSampleMask) * count);
+ }
+
+ pInfo->alphaToCoverageEnable = blob_read_uint32(metadata);
+ pInfo->alphaToOneEnable = blob_read_uint32(metadata);
+
+ return true;
+}
+
+/* Depth stencil state. */
+static void
+serialize_depth_stencil_state(const VkPipelineDepthStencilStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->depthTestEnable);
+ blob_write_uint32(metadata, pInfo->depthWriteEnable);
+ blob_write_uint32(metadata, pInfo->depthCompareOp);
+ blob_write_uint32(metadata, pInfo->depthBoundsTestEnable);
+ blob_write_uint32(metadata, pInfo->stencilTestEnable);
+
+ blob_write_bytes(metadata, &pInfo->front, sizeof(pInfo->front));
+ blob_write_bytes(metadata, &pInfo->back, sizeof(pInfo->back));
+
+ blob_write_uint32(metadata, pInfo->minDepthBounds);
+ blob_write_uint32(metadata, pInfo->maxDepthBounds);
+}
+
+static bool
+deserialize_depth_stencil_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineDepthStencilStateCreateInfo *pInfo = &pipeline->depthStencilState;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
+
+ pInfo->depthTestEnable = blob_read_uint32(metadata);
+ pInfo->depthWriteEnable = blob_read_uint32(metadata);
+ pInfo->depthCompareOp = blob_read_uint32(metadata);
+ pInfo->depthBoundsTestEnable = blob_read_uint32(metadata);
+ pInfo->stencilTestEnable = blob_read_uint32(metadata);
+
+ blob_copy_bytes(metadata, &pInfo->front, sizeof(pInfo->front));
+ blob_copy_bytes(metadata, &pInfo->back, sizeof(pInfo->back));
+
+ pInfo->minDepthBounds = blob_read_uint32(metadata);
+ pInfo->maxDepthBounds = blob_read_uint32(metadata);
+
+ return true;
+}
+
+/* Color blend state. */
+static void
+serialize_color_blend_state(const VkPipelineColorBlendStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ bool has_state =
+ pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+
+ blob_write_uint32(metadata, has_state);
+ if (!has_state)
+ return;
+
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->logicOpEnable);
+ blob_write_uint32(metadata, pInfo->logicOp);
+
+ blob_write_uint32(metadata, pInfo->attachmentCount);
+ if (pInfo->attachmentCount) {
+ blob_write_bytes(metadata, pInfo->pAttachments,
+ sizeof(*pInfo->pAttachments) *
+ pInfo->attachmentCount);
+ }
+
+ blob_write_bytes(metadata, pInfo->blendConstants,
+ sizeof(pInfo->blendConstants));
+}
+
+static bool
+deserialize_color_blend_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineColorBlendStateCreateInfo *pInfo = &pipeline->colorBlendState;
+ bool has_state;
+
+ has_state = blob_read_uint32(metadata);
+ if (!has_state)
+ return true;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO);
+
+ pInfo->logicOpEnable = blob_read_uint32(metadata);
+ pInfo->logicOp = blob_read_uint32(metadata);
+
+ pInfo->attachmentCount = blob_read_uint32(metadata);
+ if (pInfo->attachmentCount) {
+ pInfo->pAttachments =
+ blob_read_bytes(metadata, sizeof(*pInfo->pAttachments) *
+ pInfo->attachmentCount);
+ }
+
+ blob_copy_bytes(metadata, pInfo->blendConstants,
+ sizeof(pInfo->blendConstants));
+
+ return true;
+}
+
+/* Dynamic state. */
+static void
+serialize_dynamic_state(const VkPipelineDynamicStateCreateInfo *pInfo,
+ struct blob *metadata)
+{
+ bool has_state =
+ pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+
+ blob_write_uint32(metadata, has_state);
+ if (!has_state)
+ return;
+
+ blob_write_uint32(metadata, pInfo->sType);
+
+ blob_write_uint32(metadata, pInfo->dynamicStateCount);
+ blob_write_bytes(metadata, pInfo->pDynamicStates,
+ sizeof(*pInfo->pDynamicStates) *
+ pInfo->dynamicStateCount);
+}
+
+static bool
+deserialize_dynamic_state(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkPipelineDynamicStateCreateInfo *pInfo = &pipeline->dynamicState;
+ bool has_state;
+
+ has_state = blob_read_uint32(metadata);
+ if (!has_state)
+ return true;
+
+ pInfo->sType = blob_read_uint32(metadata);
+ assert(pInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO);
+
+ pInfo->dynamicStateCount = blob_read_uint32(metadata);
+ pInfo->pDynamicStates =
+ blob_read_bytes(metadata, sizeof(*pInfo->pDynamicStates) *
+ pInfo->dynamicStateCount);
+
+ return true;
+}
+
+static void
+serialize_graphics_pipeline(struct pipeline_info *pipeline,
+ struct blob *metadata)
+{
+
+ pipeline->bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ blob_write_uint32(metadata, pipeline->stageCount);
+
+ /* Shader stages and modules. */
+ serialize_shader_stage_states(pipeline, metadata);
+
+ /* Graphics states. */
+ serialize_vertex_input_state(&pipeline->vertexInputState, metadata);
+ serialize_input_assembly_state(&pipeline->inputAssemblyState, metadata);
+ serialize_tessellation_state(&pipeline->tessellationState, metadata);
+ serialize_viewport_state(&pipeline->viewportState, metadata);
+ serialize_rasterization_state(&pipeline->rasterizationState, metadata);
+ serialize_multisample_state(&pipeline->multisampleState, metadata);
+ serialize_depth_stencil_state(&pipeline->depthStencilState, metadata);
+ serialize_color_blend_state(&pipeline->colorBlendState, metadata);
+ serialize_dynamic_state(&pipeline->dynamicState, metadata);
+
+ /* Pipeline layout and render pass. */
+ serialize_pipeline_layout(pipeline, metadata);
+ serialize_render_pass(pipeline, metadata);
+}
+
+static bool
+deserialize_graphics_pipeline(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ bool valid = true;
+
+ pipeline->bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ pipeline->stageCount = blob_read_uint32(metadata);
+
+ /* Shader stages and modules. */
+ valid &= deserialize_shader_stage_states(pipeline, metadata);
+
+ /* Graphics states. */
+ valid &= deserialize_vertex_input_state(pipeline, metadata);
+ valid &= deserialize_input_assembly_state(pipeline, metadata);
+ valid &= deserialize_tessellation_state(pipeline, metadata);
+ valid &= deserialize_viewport_state(pipeline, metadata);
+ valid &= deserialize_rasterization_state(pipeline, metadata);
+ valid &= deserialize_multisample_state(pipeline, metadata);
+ valid &= deserialize_depth_stencil_state(pipeline, metadata);
+ valid &= deserialize_color_blend_state(pipeline, metadata);
+ valid &= deserialize_dynamic_state(pipeline, metadata);
+
+ /* Pipeline layout and render pass. */
+ valid &= deserialize_pipeline_layout(pipeline, metadata);
+ valid &= deserialize_render_pass(pipeline, metadata);
+
+ return valid;
+}
+
+static void
+serialize_compute_pipeline(struct pipeline_info *pipeline,
+ struct blob *metadata)
+{
+ serialize_shader_stage_states(pipeline, metadata);
+ serialize_pipeline_layout(pipeline, metadata);
+}
+
+static bool
+deserialize_compute_pipeline(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ bool valid = true;
+
+ pipeline->bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
+ pipeline->stageCount = 1;
+
+ valid &= deserialize_shader_stage_states(pipeline, metadata);
+ valid &= deserialize_pipeline_layout(pipeline, metadata);
+
+ return valid;
+}
+
+void
+serialize_pipeline(struct pipeline_info *pipeline, struct blob *metadata)
+{
+ VkStructureType sType =
+ pipeline->bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ?
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO :
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
+
+ blob_write_uint32(metadata, sType);
+
+ switch (pipeline->bindPoint) {
+ case VK_PIPELINE_BIND_POINT_GRAPHICS:
+ serialize_graphics_pipeline(pipeline, metadata);
+ break;
+ case VK_PIPELINE_BIND_POINT_COMPUTE:
+ serialize_compute_pipeline(pipeline, metadata);
+ break;
+ default:
+ assert(!"invalid pipeline tyoe");
+ break;
+ }
+}
+
+bool
+deserialize_pipeline(struct pipeline_info *pipeline,
+ struct blob_reader *metadata)
+{
+ VkStructureType sType;
+
+ sType = blob_read_uint32(metadata);
+
+ switch (sType) {
+ case VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
+ return deserialize_graphics_pipeline(pipeline, metadata);
+ case VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
+ return deserialize_compute_pipeline(pipeline, metadata);
+ default:
+ return false;
+ }
+}