yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongEnable Windows full debug testsuite in CI (#7085)8f20632a0

master
6.1 KiB180 linesraw
1// vk-helper-functions.h
2#pragma once
3
4#include "core/slang-blob.h"
5#include "vk-base.h"
6#include "vk-util.h"
7
8// Vulkan has a different coordinate system to ogl
9// http://anki3d.org/vulkan-coordinate-system/
10
11#ifdef _MSC_VER
12#include <stddef.h>
13#pragma warning(disable : 4996)
14#if (_MSC_VER < 1900)
15#define snprintf sprintf_s
16#endif
17#endif
18
19#if SLANG_WINDOWS_FAMILY
20#include <dxgi1_2.h>
21#endif
22
23namespace gfx
24{
25
26using namespace Slang;
27
28namespace vk
29{
30
31// In order to bind shader parameters to the correct locations, we need to
32// be able to describe those locations. Most shader parameters in Vulkan
33// simply consume a single `binding`, but we also need to deal with
34// parameters that represent push-constant ranges.
35//
36// In more complex cases we might be binding an entire "sub-object" like
37// a parameter block, an entry point, etc. For the general case, we need
38// to be able to represent a composite offset that includes offsets for
39// each of the cases that Vulkan supports.
40
41/// A "simple" binding offset that records `binding`, `set`, etc. offsets
42struct SimpleBindingOffset
43{
44    /// An offset in GLSL/SPIR-V `binding`s
45    uint32_t binding = 0;
46
47    /// The descriptor `set` that the `binding` field should be understood as an index into
48    uint32_t bindingSet = 0;
49
50    /// The offset in push-constant ranges (not bytes)
51    uint32_t pushConstantRange = 0;
52
53    /// Create a default (zero) offset
54    SimpleBindingOffset() {}
55
56    /// Create an offset based on offset information in the given Slang `varLayout`
57    SimpleBindingOffset(slang::VariableLayoutReflection* varLayout)
58    {
59        if (varLayout)
60        {
61            bindingSet = (uint32_t)varLayout->getBindingSpace(
62                SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT);
63            binding =
64                (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT);
65            pushConstantRange =
66                (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_PUSH_CONSTANT_BUFFER);
67        }
68    }
69
70    /// Add any values in the given `offset`
71    void operator+=(SimpleBindingOffset const& offset)
72    {
73        binding += offset.binding;
74        bindingSet += offset.bindingSet;
75        pushConstantRange += offset.pushConstantRange;
76    }
77};
78
79// While a "simple" binding offset representation will work in many cases,
80// once we need to deal with layout for programs with interface-type parameters
81// that have been statically specialized, we also need to track the offset
82// for where to bind any "pending" data that arises from the process of static
83// specialization.
84//
85// In order to conveniently track both the "primary" and "pending" offset information,
86// we will define a more complete `BindingOffset` type that combines simple
87// binding offsets for the primary and pending parts.
88
89/// A representation of the offset at which to bind a shader parameter or sub-object
90struct BindingOffset : SimpleBindingOffset
91{
92    // Offsets for "primary" data are stored directly in the `BindingOffset`
93    // via the inheritance from `SimpleBindingOffset`.
94
95    /// Offset for any "pending" data
96    SimpleBindingOffset pending;
97
98    /// Create a default (zero) offset
99    BindingOffset() {}
100
101    /// Create an offset from a simple offset
102    explicit BindingOffset(SimpleBindingOffset const& offset)
103        : SimpleBindingOffset(offset)
104    {
105    }
106
107    /// Create an offset based on offset information in the given Slang `varLayout`
108    BindingOffset(slang::VariableLayoutReflection* varLayout)
109        : SimpleBindingOffset(varLayout), pending(varLayout->getPendingDataLayout())
110    {
111    }
112
113    /// Add any values in the given `offset`
114    void operator+=(SimpleBindingOffset const& offset) { SimpleBindingOffset::operator+=(offset); }
115
116    /// Add any values in the given `offset`
117    void operator+=(BindingOffset const& offset)
118    {
119        SimpleBindingOffset::operator+=(offset);
120        pending += offset.pending;
121    }
122};
123
124/// Context information required when binding shader objects to the pipeline
125struct RootBindingContext
126{
127    /// The pipeline layout being used for binding
128    VkPipelineLayout pipelineLayout;
129
130    /// An allocator to use for descriptor sets during binding
131    DescriptorSetAllocator* descriptorSetAllocator;
132
133    /// The device being used
134    DeviceImpl* device;
135
136    /// The descriptor sets that are being allocated and bound
137    List<VkDescriptorSet>* descriptorSets;
138
139    /// Information about all the push-constant ranges that should be bound
140    ConstArrayView<VkPushConstantRange> pushConstantRanges;
141};
142
143Size calcRowSize(Format format, int width);
144GfxCount calcNumRows(Format format, int height);
145
146VkAttachmentLoadOp translateLoadOp(IRenderPassLayout::TargetLoadOp loadOp);
147VkAttachmentStoreOp translateStoreOp(IRenderPassLayout::TargetStoreOp storeOp);
148VkPipelineCreateFlags translateRayTracingPipelineFlags(RayTracingPipelineFlags::Enum flags);
149
150uint32_t getMipLevelSize(uint32_t mipLevel, uint32_t size);
151VkImageLayout translateImageLayout(ResourceState state);
152
153VkAccessFlagBits calcAccessFlags(ResourceState state);
154VkPipelineStageFlagBits calcPipelineStageFlags(ResourceState state, bool src);
155VkAccessFlags translateAccelerationStructureAccessFlag(AccessFlag access);
156
157VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state);
158VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceStateSet states);
159VkImageUsageFlagBits _calcImageUsageFlags(ResourceState state);
160VkImageViewType _calcImageViewType(ITextureResource::Type type, const ITextureResource::Desc& desc);
161VkImageUsageFlagBits _calcImageUsageFlags(ResourceStateSet states);
162VkImageUsageFlags _calcImageUsageFlags(
163    ResourceStateSet states,
164    MemoryType memoryType,
165    const void* initData);
166
167VkAccessFlags calcAccessFlagsFromImageLayout(VkImageLayout layout);
168VkPipelineStageFlags calcPipelineStageFlagsFromImageLayout(VkImageLayout layout);
169
170VkImageAspectFlags getAspectMaskFromFormat(VkFormat format);
171
172AdapterLUID getAdapterLUID(VulkanApi api, VkPhysicalDevice physicaDevice);
173
174} // namespace vk
175
176Result SLANG_MCALL getVKAdapters(List<AdapterInfo>& outAdapters);
177
178Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer);
179
180} // namespace gfx