blob: d89649e746295b63f71d0e9ce89ffcfecf8e0e4e [file] [log] [blame]
// Copyright 2022 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstring>
#include "dawn/native/vulkan/CacheKeyVk.h"
#include "dawn/native/vulkan/RenderPassCache.h"
namespace dawn::native {
template <>
void CacheKeySerializer<VkDescriptorSetLayoutBinding>::Serialize(
CacheKey* key,
const VkDescriptorSetLayoutBinding& t) {
key->Record(t.binding, t.descriptorType, t.descriptorCount, t.stageFlags);
}
template <>
void CacheKeySerializer<VkDescriptorSetLayoutCreateInfo>::Serialize(
CacheKey* key,
const VkDescriptorSetLayoutCreateInfo& t) {
key->Record(t.flags).RecordIterable(t.pBindings, t.bindingCount);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPushConstantRange>::Serialize(CacheKey* key,
const VkPushConstantRange& t) {
key->Record(t.stageFlags, t.offset, t.size);
}
template <>
void CacheKeySerializer<VkPipelineLayoutCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineLayoutCreateInfo& t) {
// The set layouts are not serialized here because they are pointers to backend objects.
// They need to be cross-referenced with the frontend objects and serialized from there.
key->Record(t.flags).RecordIterable(t.pPushConstantRanges, t.pushConstantRangeCount);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>::Serialize(
CacheKey* key,
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT& t) {
key->Record(t.requiredSubgroupSize);
}
template <>
void CacheKeySerializer<VkSpecializationMapEntry>::Serialize(CacheKey* key,
const VkSpecializationMapEntry& t) {
key->Record(t.constantID, t.offset, t.size);
}
template <>
void CacheKeySerializer<VkSpecializationInfo>::Serialize(CacheKey* key,
const VkSpecializationInfo& t) {
key->RecordIterable(t.pMapEntries, t.mapEntryCount)
.RecordIterable(static_cast<const uint8_t*>(t.pData), t.dataSize);
}
template <>
void CacheKeySerializer<VkPipelineShaderStageCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineShaderStageCreateInfo& t) {
// The shader module is not serialized here because it is a pointer to a backend object.
key->Record(t.flags, t.stage)
.RecordIterable(t.pName, strlen(t.pName))
.Record(t.pSpecializationInfo);
vulkan::SerializePnext<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(key, &t);
}
template <>
void CacheKeySerializer<VkComputePipelineCreateInfo>::Serialize(
CacheKey* key,
const VkComputePipelineCreateInfo& t) {
// The pipeline layout is not serialized here because it is a pointer to a backend object.
// It needs to be cross-referenced with the frontend objects and serialized from there. The
// base pipeline information is also currently not recorded since we do not use them in our
// backend implementation. If we decide to use them later on, they also need to be
// cross-referenced from the frontend.
key->Record(t.flags, t.stage);
}
template <>
void CacheKeySerializer<VkVertexInputBindingDescription>::Serialize(
CacheKey* key,
const VkVertexInputBindingDescription& t) {
key->Record(t.binding, t.stride, t.inputRate);
}
template <>
void CacheKeySerializer<VkVertexInputAttributeDescription>::Serialize(
CacheKey* key,
const VkVertexInputAttributeDescription& t) {
key->Record(t.location, t.binding, t.format, t.offset);
}
template <>
void CacheKeySerializer<VkPipelineVertexInputStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineVertexInputStateCreateInfo& t) {
key->Record(t.flags)
.RecordIterable(t.pVertexBindingDescriptions, t.vertexBindingDescriptionCount)
.RecordIterable(t.pVertexAttributeDescriptions, t.vertexAttributeDescriptionCount);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineInputAssemblyStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineInputAssemblyStateCreateInfo& t) {
key->Record(t.flags, t.topology, t.primitiveRestartEnable);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineTessellationStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineTessellationStateCreateInfo& t) {
key->Record(t.flags, t.patchControlPoints);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkViewport>::Serialize(CacheKey* key, const VkViewport& t) {
key->Record(t.x, t.y, t.width, t.height, t.minDepth, t.maxDepth);
}
template <>
void CacheKeySerializer<VkOffset2D>::Serialize(CacheKey* key, const VkOffset2D& t) {
key->Record(t.x, t.y);
}
template <>
void CacheKeySerializer<VkExtent2D>::Serialize(CacheKey* key, const VkExtent2D& t) {
key->Record(t.width, t.height);
}
template <>
void CacheKeySerializer<VkRect2D>::Serialize(CacheKey* key, const VkRect2D& t) {
key->Record(t.offset, t.extent);
}
template <>
void CacheKeySerializer<VkPipelineViewportStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineViewportStateCreateInfo& t) {
key->Record(t.flags)
.RecordIterable(t.pViewports, t.viewportCount)
.RecordIterable(t.pScissors, t.scissorCount);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineRasterizationStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineRasterizationStateCreateInfo& t) {
key->Record(t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode, t.cullMode,
t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor, t.depthBiasClamp,
t.depthBiasSlopeFactor, t.lineWidth);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineMultisampleStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineMultisampleStateCreateInfo& t) {
key->Record(t.flags, t.rasterizationSamples, t.sampleShadingEnable, t.minSampleShading,
t.pSampleMask, t.alphaToCoverageEnable, t.alphaToOneEnable);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkStencilOpState>::Serialize(CacheKey* key, const VkStencilOpState& t) {
key->Record(t.failOp, t.passOp, t.depthFailOp, t.compareOp, t.compareMask, t.writeMask,
t.reference);
}
template <>
void CacheKeySerializer<VkPipelineDepthStencilStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineDepthStencilStateCreateInfo& t) {
key->Record(t.flags, t.depthTestEnable, t.depthWriteEnable, t.depthCompareOp,
t.depthBoundsTestEnable, t.stencilTestEnable, t.front, t.back, t.minDepthBounds,
t.maxDepthBounds);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineColorBlendAttachmentState>::Serialize(
CacheKey* key,
const VkPipelineColorBlendAttachmentState& t) {
key->Record(t.blendEnable, t.srcColorBlendFactor, t.dstColorBlendFactor, t.colorBlendOp,
t.srcAlphaBlendFactor, t.dstAlphaBlendFactor, t.alphaBlendOp, t.colorWriteMask);
}
template <>
void CacheKeySerializer<VkPipelineColorBlendStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineColorBlendStateCreateInfo& t) {
key->Record(t.flags, t.logicOpEnable, t.logicOp)
.RecordIterable(t.pAttachments, t.attachmentCount)
.Record(t.blendConstants);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<VkPipelineDynamicStateCreateInfo>::Serialize(
CacheKey* key,
const VkPipelineDynamicStateCreateInfo& t) {
key->Record(t.flags).RecordIterable(t.pDynamicStates, t.dynamicStateCount);
vulkan::SerializePnext<>(key, &t);
}
template <>
void CacheKeySerializer<vulkan::RenderPassCacheQuery>::Serialize(
CacheKey* key,
const vulkan::RenderPassCacheQuery& t) {
key->Record(t.colorMask.to_ulong(), t.resolveTargetMask.to_ulong(), t.sampleCount);
// Manually iterate the color attachment indices and their corresponding format/load/store
// ops because the data is sparse and may be uninitialized. Since we record the colorMask
// member above, recording sparse data should be fine here.
for (ColorAttachmentIndex i : IterateBitSet(t.colorMask)) {
key->Record(t.colorFormats[i], t.colorLoadOp[i], t.colorStoreOp[i]);
}
// Serialize the depth-stencil toggle bit, and the parameters if applicable.
key->Record(t.hasDepthStencil);
if (t.hasDepthStencil) {
key->Record(t.depthStencilFormat, t.depthLoadOp, t.depthStoreOp, t.stencilLoadOp,
t.stencilStoreOp, t.readOnlyDepthStencil);
}
}
template <>
void CacheKeySerializer<VkGraphicsPipelineCreateInfo>::Serialize(
CacheKey* key,
const VkGraphicsPipelineCreateInfo& t) {
// The pipeline layout and render pass are not serialized here because they are pointers to
// backend objects. They need to be cross-referenced with the frontend objects and
// serialized from there. The base pipeline information is also currently not recorded since
// we do not use them in our backend implementation. If we decide to use them later on, they
// also need to be cross-referenced from the frontend.
key->Record(t.flags)
.RecordIterable(t.pStages, t.stageCount)
.Record(t.pVertexInputState, t.pInputAssemblyState, t.pTessellationState, t.pViewportState,
t.pRasterizationState, t.pMultisampleState, t.pDepthStencilState,
t.pColorBlendState, t.pDynamicState, t.subpass);
vulkan::SerializePnext<>(key, &t);
}
} // namespace dawn::native