blob: 8bd2a845444e0ee12dc3f62efbea0355b85d0596 [file] [log] [blame] [edit]
// Copyright 2019 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.
#ifndef DAWNNATIVE_VULKAN_UTILSVULKAN_H_
#define DAWNNATIVE_VULKAN_UTILSVULKAN_H_
#include "common/vulkan_platform.h"
#include "dawn_native/Commands.h"
#include "dawn_native/dawn_platform.h"
namespace dawn_native {
struct ProgrammableStage;
} // namespace dawn_native
namespace dawn_native { namespace vulkan {
class Device;
// A Helper type used to build a pNext chain of extension structs.
// Usage is:
// 1) Create instance, passing the address of the first struct in the
// chain. This will parse the existing |pNext| chain in it to find
// its tail.
//
// 2) Call Add(&vk_struct) every time a new struct needs to be appended
// to the chain.
//
// 3) Alternatively, call Add(&vk_struct, VK_STRUCTURE_TYPE_XXX) to
// initialize the struct with a given VkStructureType value while
// appending it to the chain.
//
// Examples:
// VkPhysicalFeatures2 features2 = {
// .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
// .pNext = nullptr,
// };
//
// PNextChainBuilder featuresChain(&features2);
//
// featuresChain.Add(&featuresExtensions.subgroupSizeControl,
// VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT);
//
struct PNextChainBuilder {
// Constructor takes the address of a Vulkan structure instance, and
// walks its pNext chain to record the current location of its tail.
//
// NOTE: Some VK_STRUCT_TYPEs define their pNext field as a const void*
// which is why the VkBaseOutStructure* casts below are necessary.
template <typename VK_STRUCT_TYPE>
explicit PNextChainBuilder(VK_STRUCT_TYPE* head)
: mCurrent(reinterpret_cast<VkBaseOutStructure*>(head)) {
// Find the end of the current chain.
while (mCurrent->pNext != nullptr) {
mCurrent = mCurrent->pNext;
}
}
// Add one item to the chain. |vk_struct| must be a Vulkan structure
// that is already initialized.
template <typename VK_STRUCT_TYPE>
void Add(VK_STRUCT_TYPE* vkStruct) {
// Sanity checks to ensure proper type safety.
static_assert(
offsetof(VK_STRUCT_TYPE, sType) == offsetof(VkBaseOutStructure, sType) &&
offsetof(VK_STRUCT_TYPE, pNext) == offsetof(VkBaseOutStructure, pNext),
"Argument type is not a proper Vulkan structure type");
vkStruct->pNext = nullptr;
mCurrent->pNext = reinterpret_cast<VkBaseOutStructure*>(vkStruct);
mCurrent = mCurrent->pNext;
}
// A variant of Add() above that also initializes the |sType| field in |vk_struct|.
template <typename VK_STRUCT_TYPE>
void Add(VK_STRUCT_TYPE* vkStruct, VkStructureType sType) {
vkStruct->sType = sType;
Add(vkStruct);
}
private:
VkBaseOutStructure* mCurrent;
};
VkCompareOp ToVulkanCompareOp(wgpu::CompareFunction op);
VkImageAspectFlags VulkanAspectMask(const Aspect& aspects);
Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy, const Extent3D& copySize);
VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy,
const TextureCopy& textureCopy,
const Extent3D& copySize);
VkBufferImageCopy ComputeBufferImageCopyRegion(const TextureDataLayout& dataLayout,
const TextureCopy& textureCopy,
const Extent3D& copySize);
void SetDebugName(Device* device,
VkObjectType objectType,
uint64_t objectHandle,
const char* prefix,
std::string label = "");
// Helpers for creating VkSpecializationInfo
// The WebGPU overridable constants only support these scalar types
union SpecializationDataEntry {
bool b;
float f32;
int32_t i32;
uint32_t u32;
};
// Returns nullptr or &specializationInfo
// specializationInfo, specializationDataEntries, specializationMapEntries needs to
// be alive at least until VkSpecializationInfo is passed into Vulkan Create*Pipelines
VkSpecializationInfo* GetVkSpecializationInfo(
const ProgrammableStage& programmableStage,
VkSpecializationInfo* specializationInfo,
std::vector<SpecializationDataEntry>* specializationDataEntries,
std::vector<VkSpecializationMapEntry>* specializationMapEntries);
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_UTILSVULKAN_H_