Plasma Engine  2.0
Loading...
Searching...
No Matches
ConversionUtilsVulkan.inl.h
1#include <RendererFoundation/Resources/ResourceFormats.h>
2#include <RendererVulkan/Utils/ConversionUtilsVulkan.h>
3
4
5namespace
6{
7 bool IsArrayViewInternal(const plGALTextureCreationDescription& texDesc, const plGALTextureResourceViewCreationDescription& viewDesc)
8 {
9 return texDesc.m_uiArraySize > 1 || viewDesc.m_uiFirstArraySlice > 0;
10 }
11 bool IsArrayViewInternal(const plGALTextureCreationDescription& texDesc, const plGALTextureUnorderedAccessViewCreationDescription& viewDesc)
12 {
13 return texDesc.m_uiArraySize > 1 || viewDesc.m_uiFirstArraySlice > 0;
14 }
15} // namespace
16
17PL_ALWAYS_INLINE vk::SampleCountFlagBits plConversionUtilsVulkan::GetSamples(plEnum<plGALMSAASampleCount> samples)
18{
19 switch (samples)
20 {
21 case plGALMSAASampleCount::None:
22 return vk::SampleCountFlagBits::e1;
23 case plGALMSAASampleCount::TwoSamples:
24 return vk::SampleCountFlagBits::e2;
25 case plGALMSAASampleCount::FourSamples:
26 return vk::SampleCountFlagBits::e4;
27 case plGALMSAASampleCount::EightSamples:
28 return vk::SampleCountFlagBits::e8;
29 default:
30 PL_ASSERT_NOT_IMPLEMENTED;
31 return vk::SampleCountFlagBits::e1;
32 }
33}
34
35PL_ALWAYS_INLINE vk::PresentModeKHR plConversionUtilsVulkan::GetPresentMode(plEnum<plGALPresentMode> presentMode, const plDynamicArray<vk::PresentModeKHR>& supportedModes)
36{
37 switch (presentMode)
38 {
39 case plGALPresentMode::Immediate:
40 {
41 if (supportedModes.Contains(vk::PresentModeKHR::eImmediate))
42 return vk::PresentModeKHR::eImmediate;
43 else if (supportedModes.Contains(vk::PresentModeKHR::eMailbox))
44 return vk::PresentModeKHR::eMailbox;
45 else
46 return vk::PresentModeKHR::eFifo;
47 }
48 case plGALPresentMode::VSync:
49 return vk::PresentModeKHR::eFifo; // FIFO must be supported according to the standard.
50 default:
51 PL_ASSERT_NOT_IMPLEMENTED;
52 return vk::PresentModeKHR::eFifo;
53 }
54}
55
56PL_ALWAYS_INLINE vk::ImageSubresourceRange plConversionUtilsVulkan::GetSubresourceRange(const plGALTextureCreationDescription& texDesc, const plGALRenderTargetViewCreationDescription& viewDesc)
57{
58 vk::ImageSubresourceRange range;
59 plGALResourceFormat::Enum viewFormat = viewDesc.m_OverrideViewFormat == plGALResourceFormat::Invalid ? texDesc.m_Format : viewDesc.m_OverrideViewFormat;
60 range.aspectMask = plGALResourceFormat::IsDepthFormat(viewFormat) ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor;
61 range.setBaseMipLevel(viewDesc.m_uiMipLevel).setLevelCount(1).setBaseArrayLayer(viewDesc.m_uiFirstSlice).setLayerCount(viewDesc.m_uiSliceCount);
62 return range;
63}
64
65PL_ALWAYS_INLINE vk::ImageSubresourceRange plConversionUtilsVulkan::GetSubresourceRange(const plGALTextureCreationDescription& texDesc, const plGALTextureResourceViewCreationDescription& viewDesc)
66{
67 vk::ImageSubresourceRange range;
68
69 const bool bIsArrayView = IsArrayViewInternal(texDesc, viewDesc);
70
71 plGALResourceFormat::Enum viewFormat = viewDesc.m_OverrideViewFormat == plGALResourceFormat::Invalid ? texDesc.m_Format : viewDesc.m_OverrideViewFormat;
72 range.aspectMask = plGALResourceFormat::IsDepthFormat(viewFormat) ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor;
73 if (viewFormat == plGALResourceFormat::D24S8)
74 {
75 range.aspectMask |= vk::ImageAspectFlagBits::eStencil;
76 }
77 range.baseMipLevel = viewDesc.m_uiMostDetailedMipLevel;
78 range.levelCount = plMath::Min(viewDesc.m_uiMipLevelsToUse, texDesc.m_uiMipLevelCount - range.baseMipLevel);
79
80 switch (texDesc.m_Type)
81 {
82 case plGALTextureType::Texture2D:
83 case plGALTextureType::Texture2DProxy:
84 case plGALTextureType::Texture2DShared:
85 range.layerCount = viewDesc.m_uiArraySize;
86 range.baseArrayLayer = viewDesc.m_uiFirstArraySlice;
87 break;
88 case plGALTextureType::TextureCube:
89 range.baseArrayLayer = viewDesc.m_uiFirstArraySlice;
90 range.layerCount = viewDesc.m_uiArraySize * 6;
91 break;
92 case plGALTextureType::Texture3D:
93 range.layerCount = 1;
94 break;
95 default:
96 PL_ASSERT_NOT_IMPLEMENTED;
97 }
98 return range;
99}
100
101
102PL_ALWAYS_INLINE vk::ImageSubresourceRange plConversionUtilsVulkan::GetSubresourceRange(const plGALTextureCreationDescription& texDesc, const plGALTextureUnorderedAccessViewCreationDescription& viewDesc)
103{
104 vk::ImageSubresourceRange range;
105
106 const bool bIsArrayView = IsArrayViewInternal(texDesc, viewDesc);
107
108 plGALResourceFormat::Enum viewFormat = viewDesc.m_OverrideViewFormat == plGALResourceFormat::Invalid ? texDesc.m_Format : viewDesc.m_OverrideViewFormat;
109 range.aspectMask = plGALResourceFormat::IsDepthFormat(viewFormat) ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor;
110 if (viewFormat == plGALResourceFormat::D24S8)
111 {
112 range.aspectMask |= vk::ImageAspectFlagBits::eStencil;
113 }
114
115 range.baseMipLevel = viewDesc.m_uiMipLevelToUse;
116 range.levelCount = 1;
117 range.layerCount = viewDesc.m_uiArraySize;
118
119 switch (texDesc.m_Type)
120 {
121 case plGALTextureType::Texture2D:
122 case plGALTextureType::Texture2DProxy:
123 case plGALTextureType::Texture2DShared:
124 range.baseArrayLayer = viewDesc.m_uiFirstArraySlice;
125 break;
126 case plGALTextureType::TextureCube:
127 range.baseArrayLayer = viewDesc.m_uiFirstArraySlice;
128 break;
129 case plGALTextureType::Texture3D:
130 if (bIsArrayView)
131 {
132 PL_ASSERT_NOT_IMPLEMENTED;
133 }
134 else
135 {
136 range.baseArrayLayer = viewDesc.m_uiFirstArraySlice;
137 }
138 break;
139 default:
140 PL_ASSERT_NOT_IMPLEMENTED;
141 }
142 return range;
143}
144
145PL_ALWAYS_INLINE vk::ImageSubresourceRange plConversionUtilsVulkan::GetSubresourceRange(
146 const vk::ImageSubresourceLayers& layers)
147{
148 vk::ImageSubresourceRange range;
149 range.aspectMask = layers.aspectMask;
150 range.baseMipLevel = layers.mipLevel;
151 range.levelCount = 1;
152 range.baseArrayLayer = layers.baseArrayLayer;
153 range.layerCount = layers.layerCount;
154 return range;
155}
156
157PL_ALWAYS_INLINE vk::ImageViewType plConversionUtilsVulkan::GetImageViewType(plEnum<plGALTextureType> texType, bool bIsArrayView)
158{
159 switch (texType)
160 {
161 case plGALTextureType::Texture2D:
162 case plGALTextureType::Texture2DProxy:
163 case plGALTextureType::Texture2DShared:
164 if (!bIsArrayView)
165 {
166 return vk::ImageViewType::e2D;
167 }
168 else
169 {
170 return vk::ImageViewType::e2DArray;
171 }
172 case plGALTextureType::TextureCube:
173 if (!bIsArrayView)
174 {
175 return vk::ImageViewType::eCube;
176 }
177 else
178 {
179 return vk::ImageViewType::eCubeArray;
180 }
181 case plGALTextureType::Texture3D:
182 return vk::ImageViewType::e3D;
183
184 default:
185 PL_ASSERT_NOT_IMPLEMENTED;
186 return vk::ImageViewType::e1D;
187 }
188}
189
190PL_ALWAYS_INLINE bool plConversionUtilsVulkan::IsDepthFormat(vk::Format format)
191{
192 switch (format)
193 {
194 case vk::Format::eD16Unorm:
195 case vk::Format::eD32Sfloat:
196 case vk::Format::eD16UnormS8Uint:
197 case vk::Format::eD24UnormS8Uint:
198 case vk::Format::eD32SfloatS8Uint:
199 return true;
200 default:
201 return false;
202 }
203}
204
205PL_ALWAYS_INLINE bool plConversionUtilsVulkan::IsStencilFormat(vk::Format format)
206{
207 switch (format)
208 {
209 case vk::Format::eS8Uint:
210 case vk::Format::eD16UnormS8Uint:
211 case vk::Format::eD24UnormS8Uint:
212 case vk::Format::eD32SfloatS8Uint:
213 return true;
214 default:
215 return false;
216 }
217}
218
219PL_ALWAYS_INLINE vk::ImageLayout plConversionUtilsVulkan::GetDefaultLayout(vk::Format format)
220{
221 return IsDepthFormat(format) ? vk::ImageLayout::eDepthStencilReadOnlyOptimal : vk::ImageLayout::eShaderReadOnlyOptimal;
222}
223
224PL_ALWAYS_INLINE vk::PrimitiveTopology plConversionUtilsVulkan::GetPrimitiveTopology(plEnum<plGALPrimitiveTopology> topology)
225{
226 switch (topology)
227 {
228 case plGALPrimitiveTopology::Points:
229 return vk::PrimitiveTopology::ePointList;
230 case plGALPrimitiveTopology::Lines:
231 return vk::PrimitiveTopology::eLineList;
232 case plGALPrimitiveTopology::Triangles:
233 return vk::PrimitiveTopology::eTriangleList;
234 default:
235 PL_ASSERT_NOT_IMPLEMENTED;
236 return vk::PrimitiveTopology::ePointList;
237 }
238}
239
240PL_ALWAYS_INLINE vk::ShaderStageFlagBits plConversionUtilsVulkan::GetShaderStage(plGALShaderStage::Enum stage)
241{
242 switch (stage)
243 {
244 case plGALShaderStage::VertexShader:
245 return vk::ShaderStageFlagBits::eVertex;
246 case plGALShaderStage::HullShader:
247 return vk::ShaderStageFlagBits::eTessellationControl;
248 case plGALShaderStage::DomainShader:
249 return vk::ShaderStageFlagBits::eTessellationEvaluation;
250 case plGALShaderStage::GeometryShader:
251 return vk::ShaderStageFlagBits::eGeometry;
252 case plGALShaderStage::PixelShader:
253 return vk::ShaderStageFlagBits::eFragment;
254 default:
255 PL_ASSERT_NOT_IMPLEMENTED;
256 [[fallthrough]];
257 case plGALShaderStage::ComputeShader:
258 return vk::ShaderStageFlagBits::eCompute;
259 }
260}
261
262PL_ALWAYS_INLINE vk::PipelineStageFlags plConversionUtilsVulkan::GetPipelineStage(plGALShaderStage::Enum stage)
263{
264 switch (stage)
265 {
266 case plGALShaderStage::VertexShader:
267 return vk::PipelineStageFlagBits::eVertexShader;
268 case plGALShaderStage::HullShader:
269 return vk::PipelineStageFlagBits::eTessellationControlShader;
270 case plGALShaderStage::DomainShader:
271 return vk::PipelineStageFlagBits::eTessellationEvaluationShader;
272 case plGALShaderStage::GeometryShader:
273 return vk::PipelineStageFlagBits::eGeometryShader;
274 case plGALShaderStage::PixelShader:
275 return vk::PipelineStageFlagBits::eFragmentShader;
276 default:
277 PL_ASSERT_NOT_IMPLEMENTED;
278 [[fallthrough]];
279 case plGALShaderStage::ComputeShader:
280 return vk::PipelineStageFlagBits::eComputeShader;
281 }
282}
283
284PL_ALWAYS_INLINE vk::PipelineStageFlags plConversionUtilsVulkan::GetPipelineStage(vk::ShaderStageFlags flags)
285{
286 vk::PipelineStageFlags res;
287 if (flags & vk::ShaderStageFlagBits::eVertex)
288 res |= vk::PipelineStageFlagBits::eVertexShader;
289 if (flags & vk::ShaderStageFlagBits::eTessellationControl)
290 res |= vk::PipelineStageFlagBits::eTessellationControlShader;
291 if (flags & vk::ShaderStageFlagBits::eTessellationEvaluation)
292 res |= vk::PipelineStageFlagBits::eTessellationEvaluationShader;
293 if (flags & vk::ShaderStageFlagBits::eGeometry)
294 res |= vk::PipelineStageFlagBits::eGeometryShader;
295 if (flags & vk::ShaderStageFlagBits::eFragment)
296 res |= vk::PipelineStageFlagBits::eFragmentShader;
297 if (flags & vk::ShaderStageFlagBits::eCompute)
298 res |= vk::PipelineStageFlagBits::eComputeShader;
299
300 return res;
301}
302
303PL_ALWAYS_INLINE vk::DescriptorType plConversionUtilsVulkan::GetDescriptorType(plGALShaderResourceType::Enum type)
304{
305 switch (type)
306 {
307 case plGALShaderResourceType::Unknown:
308 PL_REPORT_FAILURE("Unknown descriptor type");
309 break;
310 case plGALShaderResourceType::PushConstants:
311 PL_REPORT_FAILURE("Push constants should never appear as shader resources");
312 break;
314 return vk::DescriptorType::eSampler;
316 return vk::DescriptorType::eUniformBuffer;
318 return vk::DescriptorType::eSampledImage;
320 return vk::DescriptorType::eCombinedImageSampler;
322 return vk::DescriptorType::eUniformTexelBuffer;
324 return vk::DescriptorType::eStorageBuffer;
326 return vk::DescriptorType::eStorageImage;
328 return vk::DescriptorType::eStorageTexelBuffer;
330 return vk::DescriptorType::eStorageBuffer;
331 }
332
333 return vk::DescriptorType::eMutableVALVE;
334}
335
336PL_ALWAYS_INLINE vk::ShaderStageFlagBits plConversionUtilsVulkan::GetShaderStages(plBitflags<plGALShaderStageFlags> stages)
337{
338 return (vk::ShaderStageFlagBits)stages.GetValue();
339}
340
341PL_ALWAYS_INLINE vk::PipelineStageFlags plConversionUtilsVulkan::GetPipelineStages(plBitflags<plGALShaderStageFlags> stages)
342{
343 vk::PipelineStageFlags res;
344 for (int i = 0; i < plGALShaderStage::ENUM_COUNT; ++i)
345 {
346 plGALShaderStageFlags::Enum flag = plGALShaderStageFlags::MakeFromShaderStage((plGALShaderStage::Enum)i);
347 if (stages.IsSet(flag))
348 {
349 res |= GetPipelineStage((plGALShaderStage::Enum)i);
350 }
351 }
352 return res;
353}
354
355static_assert((plUInt32)vk::ShaderStageFlagBits::eVertex == (plUInt32)plGALShaderStageFlags::VertexShader);
356static_assert((plUInt32)vk::ShaderStageFlagBits::eTessellationControl == (plUInt32)plGALShaderStageFlags::HullShader);
357static_assert((plUInt32)vk::ShaderStageFlagBits::eTessellationEvaluation == (plUInt32)plGALShaderStageFlags::DomainShader);
358static_assert((plUInt32)vk::ShaderStageFlagBits::eGeometry == (plUInt32)plGALShaderStageFlags::GeometryShader);
359static_assert((plUInt32)vk::ShaderStageFlagBits::eFragment == (plUInt32)plGALShaderStageFlags::PixelShader);
360static_assert((plUInt32)vk::ShaderStageFlagBits::eCompute == (plUInt32)plGALShaderStageFlags::ComputeShader);
bool Contains(const T &value) const
Checks whether the given value can be found in the array. O(n) complexity.
Definition ArrayBase_inl.h:191
Definition DynamicArray.h:81
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
The plBitflags class allows you to work with type-safe bitflags.
Definition Bitflags.h:82
PL_ALWAYS_INLINE StorageType GetValue() const
Returns the stored value as the underlying integer type.
Definition Bitflags.h:199
PL_ALWAYS_INLINE bool IsSet(Enum flag) const
Checks if certain flags are set within the bitfield.
Definition Bitflags.h:127
A custom enum implementation that allows to define the underlying storage type to control its memory ...
Definition Enum.h:37
Definition Descriptors.h:220
static bool IsDepthFormat(plGALResourceFormat::Enum format)
Returns whether the given resource format is a depth format.
Definition ResourceFormats_inl.h:15
Enum
Definition Enumerations.h:12
@ TextureRW
Read-write texture view. When set, plGALShaderTextureType is also set. HLSL: RWTexture*.
Definition Enumerations.h:39
@ StructuredBufferRW
Read-write array of structs. HLSL: RWStructuredBuffer<T>, RWByteAddressBuffer, AppendStructuredBuffer...
Definition Enumerations.h:43
@ ConstantBuffer
Read-only struct (plGALBufferHandle). HLSL: cbuffer, ConstantBuffer.
Definition Enumerations.h:18
@ StructuredBuffer
Read-only array of structs. HLSL: StructuredBuffer<T>, ByteAddressBuffer.
Definition Enumerations.h:32
@ Sampler
Texture sampler (plGALSamplerStateHandle). HLSL: SamplerState, SamplerComparisonState.
Definition Enumerations.h:15
@ Texture
Read-only texture view. When set, plGALShaderTextureType is also set. HLSL: Texture*.
Definition Enumerations.h:26
@ TextureAndSampler
Read-only texture view with attached sampler. When set, plGALShaderTextureType is also set....
Definition Enumerations.h:28
@ TexelBuffer
Read-only texel buffer. It's like a 1D texture. HLSL: Buffer.
Definition Enumerations.h:30
@ TexelBufferRW
Read-write texel buffer. It's like a 1D texture. HLSL: RWBuffer.
Definition Enumerations.h:41
Definition Descriptors.h:177
plUInt16 m_uiMipLevelToUse
Which MipLevel is accessed with this UAV.
Definition Descriptors.h:238
plUInt32 m_uiArraySize
Number of depth slices for 3D textures.
Definition Descriptors.h:237
plUInt32 m_uiFirstArraySlice
First depth slice for 3D Textures.
Definition Descriptors.h:236