diff options
| author | lucy96chen <47800040+lucy96chen@users.noreply.github.com> | 2022-05-26 10:54:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-26 10:54:35 -0700 |
| commit | 43e1b7cdc70b2fcac8a3e8ee72f5bc91726f4ec5 (patch) | |
| tree | 1e4701b4ab324a199b81e1f6c671f6660f1050c5 /tools/gfx/vulkan/vk-helper-functions.h | |
| parent | 5ff4f42c636a67724523e4fe60697cfac64908cd (diff) | |
Split render-vk.h/.cpp into a set of smaller files (#2244)
* Some preliminary work on splitting render-vk
* render-vk split, tests currently crash on null reference
* fixed circular include
Diffstat (limited to 'tools/gfx/vulkan/vk-helper-functions.h')
| -rw-r--r-- | tools/gfx/vulkan/vk-helper-functions.h | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/tools/gfx/vulkan/vk-helper-functions.h b/tools/gfx/vulkan/vk-helper-functions.h new file mode 100644 index 000000000..86233027c --- /dev/null +++ b/tools/gfx/vulkan/vk-helper-functions.h @@ -0,0 +1,182 @@ +// vk-helper-functions.h +#pragma once + +#include "vk-base.h" +#include "core/slang-blob.h" +#include "vk-util.h" + +// Vulkan has a different coordinate system to ogl +// http://anki3d.org/vulkan-coordinate-system/ +#ifndef ENABLE_VALIDATION_LAYER +# if _DEBUG +# define ENABLE_VALIDATION_LAYER 1 +# else +# define ENABLE_VALIDATION_LAYER 0 +# endif +#endif + +#ifdef _MSC_VER +# include <stddef.h> +# pragma warning(disable : 4996) +# if (_MSC_VER < 1900) +# define snprintf sprintf_s +# endif +#endif + +#if SLANG_WINDOWS_FAMILY +# include <dxgi1_2.h> +#endif + +namespace gfx +{ + +using namespace Slang; + +namespace vk +{ + +// In order to bind shader parameters to the correct locations, we need to +// be able to describe those locations. Most shader parameters in Vulkan +// simply consume a single `binding`, but we also need to deal with +// parameters that represent push-constant ranges. +// +// In more complex cases we might be binding an entire "sub-object" like +// a parameter block, an entry point, etc. For the general case, we need +// to be able to represent a composite offset that includes offsets for +// each of the cases that Vulkan supports. + +/// A "simple" binding offset that records `binding`, `set`, etc. offsets +struct SimpleBindingOffset +{ + /// An offset in GLSL/SPIR-V `binding`s + uint32_t binding = 0; + + /// The descriptor `set` that the `binding` field should be understood as an index into + uint32_t bindingSet = 0; + + /// The offset in push-constant ranges (not bytes) + uint32_t pushConstantRange = 0; + + /// Create a default (zero) offset + SimpleBindingOffset() {} + + /// Create an offset based on offset information in the given Slang `varLayout` + SimpleBindingOffset(slang::VariableLayoutReflection* varLayout) + { + if (varLayout) + { + bindingSet = (uint32_t)varLayout->getBindingSpace( + SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT); + binding = + (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT); + pushConstantRange = + (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_PUSH_CONSTANT_BUFFER); + } + } + + /// Add any values in the given `offset` + void operator+=(SimpleBindingOffset const& offset) + { + binding += offset.binding; + bindingSet += offset.bindingSet; + pushConstantRange += offset.pushConstantRange; + } +}; + +// While a "simple" binding offset representation will work in many cases, +// once we need to deal with layout for programs with interface-type parameters +// that have been statically specialized, we also need to track the offset +// for where to bind any "pending" data that arises from the process of static +// specialization. +// +// In order to conveniently track both the "primary" and "pending" offset information, +// we will define a more complete `BindingOffset` type that combines simple +// binding offsets for the primary and pending parts. + +/// A representation of the offset at which to bind a shader parameter or sub-object +struct BindingOffset : SimpleBindingOffset +{ + // Offsets for "primary" data are stored directly in the `BindingOffset` + // via the inheritance from `SimpleBindingOffset`. + + /// Offset for any "pending" data + SimpleBindingOffset pending; + + /// Create a default (zero) offset + BindingOffset() {} + + /// Create an offset from a simple offset + explicit BindingOffset(SimpleBindingOffset const& offset) + : SimpleBindingOffset(offset) + {} + + /// Create an offset based on offset information in the given Slang `varLayout` + BindingOffset(slang::VariableLayoutReflection* varLayout) + : SimpleBindingOffset(varLayout) + , pending(varLayout->getPendingDataLayout()) + {} + + /// Add any values in the given `offset` + void operator+=(SimpleBindingOffset const& offset) { SimpleBindingOffset::operator+=(offset); } + + /// Add any values in the given `offset` + void operator+=(BindingOffset const& offset) + { + SimpleBindingOffset::operator+=(offset); + pending += offset.pending; + } +}; + +/// Context information required when binding shader objects to the pipeline +struct RootBindingContext +{ + /// The pipeline layout being used for binding + VkPipelineLayout pipelineLayout; + + /// An allocator to use for descriptor sets during binding + DescriptorSetAllocator* descriptorSetAllocator; + + /// The device being used + DeviceImpl* device; + + /// The descriptor sets that are being allocated and bound + VkDescriptorSet* descriptorSets; + + /// Information about all the push-constant ranges that should be bound + ConstArrayView<VkPushConstantRange> pushConstantRanges; + + uint32_t descriptorSetCounter = 0; +}; + +Size calcRowSize(Format format, int width); +GfxCount calcNumRows(Format format, int height); + +VkAttachmentLoadOp translateLoadOp(IRenderPassLayout::TargetLoadOp loadOp); +VkAttachmentStoreOp translateStoreOp(IRenderPassLayout::TargetStoreOp storeOp); +VkPipelineCreateFlags translateRayTracingPipelineFlags(RayTracingPipelineFlags::Enum flags); + +uint32_t getMipLevelSize(uint32_t mipLevel, uint32_t size); +VkImageLayout translateImageLayout(ResourceState state); + +VkAccessFlagBits calcAccessFlags(ResourceState state); +VkPipelineStageFlagBits calcPipelineStageFlags(ResourceState state, bool src); +VkAccessFlags translateAccelerationStructureAccessFlag(AccessFlag access); + +VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state); +VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceStateSet states); +VkImageUsageFlagBits _calcImageUsageFlags(ResourceState state); +VkImageViewType _calcImageViewType(ITextureResource::Type type, const ITextureResource::Desc& desc); +VkImageUsageFlagBits _calcImageUsageFlags(ResourceStateSet states); +VkImageUsageFlags _calcImageUsageFlags( + ResourceStateSet states, MemoryType memoryType, const void* initData); + +VkAccessFlags calcAccessFlagsFromImageLayout(VkImageLayout layout); +VkPipelineStageFlags calcPipelineStageFlagsFromImageLayout(VkImageLayout layout); + +VkImageAspectFlags getAspectMaskFromFormat(VkFormat format); + +} // namespace vk + +Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer); + +} // namespace gfx |
