summaryrefslogtreecommitdiff
path: root/tools/gfx/vulkan/vk-helper-functions.h
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2022-05-26 10:54:35 -0700
committerGitHub <noreply@github.com>2022-05-26 10:54:35 -0700
commit43e1b7cdc70b2fcac8a3e8ee72f5bc91726f4ec5 (patch)
tree1e4701b4ab324a199b81e1f6c671f6660f1050c5 /tools/gfx/vulkan/vk-helper-functions.h
parent5ff4f42c636a67724523e4fe60697cfac64908cd (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.h182
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