/* * 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 #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) { if (pInfo->sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) { blob_write_uint32(metadata, VK_STRUCTURE_TYPE_MAX_ENUM); return; } bool has_viewports = pInfo->pViewports ? true : false; bool has_scissors = pInfo->pScissors ? true : false; 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); if (pInfo->sType == VK_STRUCTURE_TYPE_MAX_ENUM) { return true; } 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) { if (pInfo->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) { blob_write_uint32(metadata, VK_STRUCTURE_TYPE_MAX_ENUM); return; } bool has_sample_mask = pInfo->pSampleMask ? true : false; 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); if (pInfo->sType == VK_STRUCTURE_TYPE_MAX_ENUM) { return true; } 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) { if (pInfo->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) { blob_write_uint32(metadata, VK_STRUCTURE_TYPE_MAX_ENUM); return; } 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); if (pInfo->sType == VK_STRUCTURE_TYPE_MAX_ENUM) { return true; } 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; } }