-
Notifications
You must be signed in to change notification settings - Fork 131
/
PipelineState.h
1259 lines (1008 loc) · 53 KB
/
PipelineState.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright 2019-2024 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* 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.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/
#pragma once
// clang-format off
/// \file
/// Definition of the Diligent::IPipelineState interface and related data structures
#include "../../../Primitives/interface/Object.h"
#include "../../../Platforms/interface/PlatformDefinitions.h"
#include "../../../Common/interface/StringTools.h"
#include "GraphicsTypes.h"
#include "BlendState.h"
#include "RasterizerState.h"
#include "DepthStencilState.h"
#include "InputLayout.h"
#include "ShaderResourceBinding.h"
#include "ShaderResourceVariable.h"
#include "Shader.h"
#include "Sampler.h"
#include "RenderPass.h"
#include "PipelineResourceSignature.h"
#include "PipelineStateCache.h"
DILIGENT_BEGIN_NAMESPACE(Diligent)
/// Sample description
/// This structure is used by GraphicsPipelineDesc to describe multisampling parameters
struct SampleDesc
{
/// Sample count
Uint8 Count DEFAULT_INITIALIZER(1);
/// Quality
Uint8 Quality DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
constexpr SampleDesc() noexcept {}
constexpr SampleDesc(Uint8 _Count, Uint8 _Quality) noexcept :
Count {_Count },
Quality {_Quality}
{}
/// Comparison operator tests if two structures are equivalent
/// \param [in] RHS - reference to the structure to perform comparison with
/// \return
/// - True if all members of the two structures are equal.
/// - False otherwise.
constexpr bool operator==(const SampleDesc& RHS) const
{
return Count == RHS.Count && Quality == RHS.Quality;
}
constexpr bool operator!=(const SampleDesc& RHS) const
{
return !(*this == RHS);
}
#endif
};
typedef struct SampleDesc SampleDesc;
/// Shader variable property flags.
DILIGENT_TYPED_ENUM(SHADER_VARIABLE_FLAGS, Uint8)
{
/// Shader variable has no special properties.
SHADER_VARIABLE_FLAG_NONE = 0,
/// Indicates that dynamic buffers will never be bound to the resource
/// variable. Applies to SHADER_RESOURCE_TYPE_CONSTANT_BUFFER,
/// SHADER_RESOURCE_TYPE_BUFFER_UAV, SHADER_RESOURCE_TYPE_BUFFER_SRV resources.
///
/// \remarks This flag directly translates to the PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS
/// flag in the internal pipeline resource signature.
SHADER_VARIABLE_FLAG_NO_DYNAMIC_BUFFERS = 1u << 0,
/// Indicates that the resource is an input attachment in general layout, which allows simultaneously
/// reading from the resource through the input attachment and writing to it via color or depth-stencil
/// attachment.
///
/// \note This flag is only valid in Vulkan.
SHADER_VARIABLE_FLAG_GENERAL_INPUT_ATTACHMENT = 1u << 1,
SHADER_VARIABLE_FLAG_LAST = SHADER_VARIABLE_FLAG_GENERAL_INPUT_ATTACHMENT
};
DEFINE_FLAG_ENUM_OPERATORS(SHADER_VARIABLE_FLAGS);
/// Describes shader variable
struct ShaderResourceVariableDesc
{
/// Shader variable name
const Char* Name DEFAULT_INITIALIZER(nullptr);
/// Shader stages this resources variable applies to. If more than one shader stage is specified,
/// the variable will be shared between these stages. Shader stages used by different variables
/// with the same name must not overlap.
SHADER_TYPE ShaderStages DEFAULT_INITIALIZER(SHADER_TYPE_UNKNOWN);
/// Shader variable type. See Diligent::SHADER_RESOURCE_VARIABLE_TYPE for a list of allowed types
SHADER_RESOURCE_VARIABLE_TYPE Type DEFAULT_INITIALIZER(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
SHADER_VARIABLE_FLAGS Flags DEFAULT_INITIALIZER(SHADER_VARIABLE_FLAG_NONE);
#if DILIGENT_CPP_INTERFACE
constexpr ShaderResourceVariableDesc() noexcept {}
constexpr ShaderResourceVariableDesc(SHADER_TYPE _ShaderStages,
const Char* _Name,
SHADER_RESOURCE_VARIABLE_TYPE _Type,
SHADER_VARIABLE_FLAGS _Flags = SHADER_VARIABLE_FLAG_NONE) noexcept :
Name {_Name },
ShaderStages{_ShaderStages},
Type {_Type },
Flags {_Flags }
{}
/// Comparison operator tests if two structures are equivalent
/// \param [in] RHS - reference to the structure to perform comparison with
/// \return
/// - True if all members of the two structures are equal.
/// - False otherwise.
bool operator==(const ShaderResourceVariableDesc& RHS) const noexcept
{
return ShaderStages == RHS.ShaderStages &&
Type == RHS.Type &&
Flags == RHS.Flags &&
SafeStrEqual(Name, RHS.Name);
}
bool operator!=(const ShaderResourceVariableDesc& RHS) const noexcept
{
return !(*this == RHS);
}
#endif
};
typedef struct ShaderResourceVariableDesc ShaderResourceVariableDesc;
/// Pipeline state shading rate flags.
DILIGENT_TYPED_ENUM(PIPELINE_SHADING_RATE_FLAGS, Uint8)
{
/// Shading rate is not used.
PIPELINE_SHADING_RATE_FLAG_NONE = 0,
/// Indicates that the pipeline state will be used with per draw or per primitive shading rate.
/// See IDeviceContext::SetShadingRate().
PIPELINE_SHADING_RATE_FLAG_PER_PRIMITIVE = 1u << 0u,
/// Indicates that the pipeline state will be used with texture-based shading rate.
/// See IDeviceContext::SetShadingRate() and IDeviceContext::SetRenderTargetsExt().
PIPELINE_SHADING_RATE_FLAG_TEXTURE_BASED = 1u << 1u,
PIPELINE_SHADING_RATE_FLAG_LAST = PIPELINE_SHADING_RATE_FLAG_TEXTURE_BASED,
};
DEFINE_FLAG_ENUM_OPERATORS(PIPELINE_SHADING_RATE_FLAGS);
/// Pipeline layout description
struct PipelineResourceLayoutDesc
{
/// Default shader resource variable type. This type will be used if shader
/// variable description is not found in the Variables array
/// or if Variables == nullptr
SHADER_RESOURCE_VARIABLE_TYPE DefaultVariableType DEFAULT_INITIALIZER(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
/// By default, all variables not found in the Variables array define separate resources.
/// For example, if there is resource "g_Texture" in the vertex and pixel shader stages, there
/// will be two separate resources in both stages. This member defines shader stages
/// in which default variables will be combined.
/// For example, if DefaultVariableMergeStages == SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL,
/// then both resources in the example above will be combined into a single one.
/// If there is another "g_Texture" in geometry shader, it will be separate from combined
/// vertex-pixel "g_Texture".
/// This member has no effect on variables defined in Variables array.
SHADER_TYPE DefaultVariableMergeStages DEFAULT_INITIALIZER(SHADER_TYPE_UNKNOWN);
/// Number of elements in Variables array
Uint32 NumVariables DEFAULT_INITIALIZER(0);
/// Array of shader resource variable descriptions
/// There may be multiple variables with the same name that use different shader stages,
/// but the stages must not overlap.
const ShaderResourceVariableDesc* Variables DEFAULT_INITIALIZER(nullptr);
/// Number of immutable samplers in ImmutableSamplers array
Uint32 NumImmutableSamplers DEFAULT_INITIALIZER(0);
/// Array of immutable sampler descriptions
const ImmutableSamplerDesc* ImmutableSamplers DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
/// Returns true if two resource layout descriptions are equal, and false otherwise.
/// Optionally ignores variable descriptions and/or sampler descriptions.
static bool IsEqual(const PipelineResourceLayoutDesc& Desc1,
const PipelineResourceLayoutDesc& Desc2,
bool IgnoreVariables = false,
bool IgnoreSamplers = false)
{
if (!(Desc1.DefaultVariableType == Desc2.DefaultVariableType &&
Desc1.DefaultVariableMergeStages == Desc2.DefaultVariableMergeStages &&
Desc1.NumVariables == Desc2.NumVariables &&
Desc1.NumImmutableSamplers == Desc2.NumImmutableSamplers))
return false;
if (!IgnoreVariables)
{
for (Uint32 i = 0; i < Desc1.NumVariables; ++i)
if (Desc1.Variables[i] != Desc2.Variables[i])
return false;
}
if (!IgnoreSamplers)
{
for (Uint32 i = 0; i < Desc1.NumImmutableSamplers; ++i)
if (Desc1.ImmutableSamplers[i] != Desc2.ImmutableSamplers[i])
return false;
}
return true;
}
/// Comparison operator tests if two structures are equivalent
bool operator==(const PipelineResourceLayoutDesc& RHS) const noexcept
{
return IsEqual(*this, RHS);
}
bool operator!=(const PipelineResourceLayoutDesc& RHS) const noexcept
{
return !(*this == RHS);
}
#endif
};
typedef struct PipelineResourceLayoutDesc PipelineResourceLayoutDesc;
/// Graphics pipeline state description
/// This structure describes the graphics pipeline state and is part of the GraphicsPipelineStateCreateInfo structure.
struct GraphicsPipelineDesc
{
/// Blend state description.
BlendStateDesc BlendDesc;
/// 32-bit sample mask that determines which samples get updated
/// in all the active render targets. A sample mask is always applied;
/// it is independent of whether multisampling is enabled, and does not
/// depend on whether an application uses multisample render targets.
Uint32 SampleMask DEFAULT_INITIALIZER(0xFFFFFFFF);
/// Rasterizer state description.
RasterizerStateDesc RasterizerDesc;
/// Depth-stencil state description.
DepthStencilStateDesc DepthStencilDesc;
/// Input layout, ignored in a mesh pipeline.
InputLayoutDesc InputLayout;
/// Primitive topology type, ignored in a mesh pipeline.
PRIMITIVE_TOPOLOGY PrimitiveTopology DEFAULT_INITIALIZER(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
/// The number of viewports used by this pipeline
Uint8 NumViewports DEFAULT_INITIALIZER(1);
/// The number of render targets in the RTVFormats array.
/// Must be 0 when pRenderPass is not null.
Uint8 NumRenderTargets DEFAULT_INITIALIZER(0);
/// When pRenderPass is not null, the subpass
/// index within the render pass.
/// When pRenderPass is null, this member must be 0.
Uint8 SubpassIndex DEFAULT_INITIALIZER(0);
/// Shading rate flags that specify which type of the shading rate will be used with this pipeline.
PIPELINE_SHADING_RATE_FLAGS ShadingRateFlags DEFAULT_INITIALIZER(PIPELINE_SHADING_RATE_FLAG_NONE);
/// Render target formats.
/// All formats must be TEX_FORMAT_UNKNOWN when pRenderPass is not null.
TEXTURE_FORMAT RTVFormats[DILIGENT_MAX_RENDER_TARGETS] DEFAULT_INITIALIZER({});
/// Depth-stencil format.
/// Must be TEX_FORMAT_UNKNOWN when pRenderPass is not null.
TEXTURE_FORMAT DSVFormat DEFAULT_INITIALIZER(TEX_FORMAT_UNKNOWN);
/// Indicates that the pipeline will be used with read-only depth-stencil buffer.
/// Must be false when pRenderPass is not null.
Bool ReadOnlyDSV DEFAULT_INITIALIZER(False);
/// Multisampling parameters.
SampleDesc SmplDesc;
/// Pointer to the render pass object.
/// When non-null render pass is specified, NumRenderTargets must be 0,
/// and all RTV formats as well as DSV format must be TEX_FORMAT_UNKNOWN.
IRenderPass* pRenderPass DEFAULT_INITIALIZER(nullptr);
/// Node mask.
Uint32 NodeMask DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
bool operator==(const GraphicsPipelineDesc& Rhs) const noexcept
{
if (!(BlendDesc == Rhs.BlendDesc &&
SampleMask == Rhs.SampleMask &&
RasterizerDesc == Rhs.RasterizerDesc &&
DepthStencilDesc == Rhs.DepthStencilDesc &&
InputLayout == Rhs.InputLayout &&
PrimitiveTopology == Rhs.PrimitiveTopology &&
NumViewports == Rhs.NumViewports &&
NumRenderTargets == Rhs.NumRenderTargets &&
SubpassIndex == Rhs.SubpassIndex &&
ShadingRateFlags == Rhs.ShadingRateFlags &&
DSVFormat == Rhs.DSVFormat &&
ReadOnlyDSV == Rhs.ReadOnlyDSV &&
SmplDesc == Rhs.SmplDesc &&
NodeMask == Rhs.NodeMask))
return false;
for (Uint32 i = 0; i < NumRenderTargets; ++i)
{
if (RTVFormats[i] != Rhs.RTVFormats[i])
return false;
}
if ((pRenderPass != nullptr) != (Rhs.pRenderPass != nullptr))
return false;
if (pRenderPass != nullptr)
{
if (!(pRenderPass->GetDesc() == Rhs.pRenderPass->GetDesc()))
return false;
}
return true;
}
bool operator!=(const GraphicsPipelineDesc& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct GraphicsPipelineDesc GraphicsPipelineDesc;
/// Ray tracing general shader group description
struct RayTracingGeneralShaderGroup
{
/// Unique group name.
const Char* Name DEFAULT_INITIALIZER(nullptr);
/// Shader type must be SHADER_TYPE_RAY_GEN, SHADER_TYPE_RAY_MISS or SHADER_TYPE_CALLABLE.
IShader* pShader DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
constexpr RayTracingGeneralShaderGroup() noexcept
{}
constexpr RayTracingGeneralShaderGroup(const Char* _Name,
IShader* _pShader) noexcept:
Name {_Name },
pShader{_pShader}
{}
bool operator==(const RayTracingGeneralShaderGroup& Rhs) const noexcept
{
return SafeStrEqual(Name, Rhs.Name) && pShader == Rhs.pShader;
}
bool operator!=(const RayTracingGeneralShaderGroup& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct RayTracingGeneralShaderGroup RayTracingGeneralShaderGroup;
/// Ray tracing triangle hit shader group description.
struct RayTracingTriangleHitShaderGroup
{
/// Unique group name.
const Char* Name DEFAULT_INITIALIZER(nullptr);
/// Closest hit shader.
/// The shader type must be SHADER_TYPE_RAY_CLOSEST_HIT.
IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr);
/// Any-hit shader. Can be null.
/// The shader type must be SHADER_TYPE_RAY_ANY_HIT.
IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
#if DILIGENT_CPP_INTERFACE
constexpr RayTracingTriangleHitShaderGroup() noexcept
{}
constexpr RayTracingTriangleHitShaderGroup(const Char* _Name,
IShader* _pClosestHitShader,
IShader* _pAnyHitShader = nullptr) noexcept:
Name {_Name },
pClosestHitShader{_pClosestHitShader},
pAnyHitShader {_pAnyHitShader }
{}
bool operator==(const RayTracingTriangleHitShaderGroup& Rhs) const noexcept
{
return SafeStrEqual(Name, Rhs.Name) &&
pClosestHitShader == Rhs.pClosestHitShader &&
pAnyHitShader == Rhs.pAnyHitShader;
}
bool operator!=(const RayTracingTriangleHitShaderGroup& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct RayTracingTriangleHitShaderGroup RayTracingTriangleHitShaderGroup;
/// Ray tracing procedural hit shader group description.
struct RayTracingProceduralHitShaderGroup
{
/// Unique group name.
const Char* Name DEFAULT_INITIALIZER(nullptr);
/// Intersection shader.
/// The shader type must be SHADER_TYPE_RAY_INTERSECTION.
IShader* pIntersectionShader DEFAULT_INITIALIZER(nullptr);
/// Closest hit shader. Can be null.
/// The shader type must be SHADER_TYPE_RAY_CLOSEST_HIT.
IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr);
/// Any-hit shader. Can be null.
/// The shader type must be SHADER_TYPE_RAY_ANY_HIT.
IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
constexpr RayTracingProceduralHitShaderGroup() noexcept
{}
constexpr RayTracingProceduralHitShaderGroup(const Char* _Name,
IShader* _pIntersectionShader,
IShader* _pClosestHitShader = nullptr,
IShader* _pAnyHitShader = nullptr) noexcept:
Name {_Name },
pIntersectionShader{_pIntersectionShader},
pClosestHitShader {_pClosestHitShader },
pAnyHitShader {_pAnyHitShader }
{}
bool operator==(const RayTracingProceduralHitShaderGroup& Rhs) const noexcept
{
return SafeStrEqual(Name, Rhs.Name) &&
pIntersectionShader == Rhs.pIntersectionShader &&
pClosestHitShader == Rhs.pClosestHitShader &&
pAnyHitShader == Rhs.pAnyHitShader;
}
bool operator!=(const RayTracingProceduralHitShaderGroup& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct RayTracingProceduralHitShaderGroup RayTracingProceduralHitShaderGroup;
/// This structure describes the ray tracing pipeline state and is part of the RayTracingPipelineStateCreateInfo structure.
struct RayTracingPipelineDesc
{
/// Size of the additional data passed to the shader.
/// Shader record size plus shader group size (32 bytes) must be aligned to 32 bytes.
/// Shader record size plus shader group size (32 bytes) must not exceed 4096 bytes.
Uint16 ShaderRecordSize DEFAULT_INITIALIZER(0);
/// Number of recursive calls of TraceRay() in HLSL or traceRay() in GLSL.
/// Zero means no tracing of rays at all, only ray-gen shader will be executed.
/// See DeviceProperties::MaxRayTracingRecursionDepth.
Uint8 MaxRecursionDepth DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
/// Comparison operator tests if two structures are equivalent
constexpr bool operator==(const RayTracingPipelineDesc& RHS) const
{
return ShaderRecordSize == RHS.ShaderRecordSize &&
MaxRecursionDepth == RHS.MaxRecursionDepth;
}
constexpr bool operator!=(const RayTracingPipelineDesc& RHS) const
{
return !(*this == RHS);
}
#endif
};
typedef struct RayTracingPipelineDesc RayTracingPipelineDesc;
/// Pipeline type
DILIGENT_TYPED_ENUM(PIPELINE_TYPE, Uint8)
{
/// Graphics pipeline, which is used by IDeviceContext::Draw(), IDeviceContext::DrawIndexed(),
/// IDeviceContext::DrawIndirect(), IDeviceContext::DrawIndexedIndirect().
PIPELINE_TYPE_GRAPHICS,
/// Compute pipeline, which is used by IDeviceContext::DispatchCompute(), IDeviceContext::DispatchComputeIndirect().
PIPELINE_TYPE_COMPUTE,
/// Mesh pipeline, which is used by IDeviceContext::DrawMesh(), IDeviceContext::DrawMeshIndirect().
PIPELINE_TYPE_MESH,
/// Ray tracing pipeline, which is used by IDeviceContext::TraceRays().
PIPELINE_TYPE_RAY_TRACING,
/// Tile pipeline, which is used by IDeviceContext::DispatchTile().
PIPELINE_TYPE_TILE,
PIPELINE_TYPE_LAST = PIPELINE_TYPE_TILE,
PIPELINE_TYPE_COUNT,
PIPELINE_TYPE_INVALID = 0xFF
};
/// Pipeline state description
struct PipelineStateDesc DILIGENT_DERIVE(DeviceObjectAttribs)
/// Pipeline type
PIPELINE_TYPE PipelineType DEFAULT_INITIALIZER(PIPELINE_TYPE_GRAPHICS);
/// Shader resource binding allocation granularity
/// This member defines allocation granularity for internal resources required by the shader resource
/// binding object instances.
/// Has no effect if the PSO is created with explicit pipeline resource signature(s).
Uint32 SRBAllocationGranularity DEFAULT_INITIALIZER(1);
/// Defines which immediate contexts are allowed to execute commands that use this pipeline state.
/// When ImmediateContextMask contains a bit at position n, the pipeline state may be
/// used in the immediate context with index n directly (see DeviceContextDesc::ContextId).
/// It may also be used in a command list recorded by a deferred context that will be executed
/// through that immediate context.
///
/// \remarks Only specify these bits that will indicate those immediate contexts where the PSO
/// will actually be used. Do not set unnecessary bits as this will result in extra overhead.
Uint64 ImmediateContextMask DEFAULT_INITIALIZER(1);
/// Pipeline layout description
PipelineResourceLayoutDesc ResourceLayout;
#if DILIGENT_CPP_INTERFACE
constexpr PipelineStateDesc() noexcept {}
explicit constexpr PipelineStateDesc(const Char* _Name, PIPELINE_TYPE Type = PipelineStateDesc{}.PipelineType) :
DeviceObjectAttribs{_Name},
PipelineType {Type }
{}
/// Tests if two pipeline state descriptions are equal.
/// \param [in] RHS - reference to the structure to compare with.
///
/// \return true if all members of the two structures *except for the Name* are equal,
/// and false otherwise.
///
/// \note The operator ignores the Name field as it is used for debug purposes and
/// doesn't affect the pipeline state properties.
bool operator==(const PipelineStateDesc& RHS) const noexcept
{
// Ignore Name. This is consistent with the hasher (HashCombiner<HasherType, PipelineStateDesc>).
return PipelineType == RHS.PipelineType &&
SRBAllocationGranularity == RHS.SRBAllocationGranularity &&
ImmediateContextMask == RHS.ImmediateContextMask &&
ResourceLayout == RHS.ResourceLayout;
}
bool operator!=(const PipelineStateDesc& RHS) const noexcept
{
return !(*this == RHS);
}
bool IsAnyGraphicsPipeline() const { return PipelineType == PIPELINE_TYPE_GRAPHICS || PipelineType == PIPELINE_TYPE_MESH; }
bool IsComputePipeline() const { return PipelineType == PIPELINE_TYPE_COMPUTE; }
bool IsRayTracingPipeline() const { return PipelineType == PIPELINE_TYPE_RAY_TRACING; }
bool IsTilePipeline() const { return PipelineType == PIPELINE_TYPE_TILE; }
#endif
};
typedef struct PipelineStateDesc PipelineStateDesc;
/// Pipeline state creation flags
DILIGENT_TYPED_ENUM(PSO_CREATE_FLAGS, Uint32)
{
/// Null flag.
PSO_CREATE_FLAG_NONE = 0u,
/// Ignore missing variables.
/// By default, the engine outputs a warning for every variable
/// provided as part of the pipeline resource layout description
/// that is not found in any of the designated shader stages.
/// Use this flag to silence these warnings.
PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES = 1u << 0u,
/// Ignore missing immutable samplers.
/// By default, the engine outputs a warning for every immutable sampler
/// provided as part of the pipeline resource layout description
/// that is not found in any of the designated shader stages.
/// Use this flag to silence these warnings.
PSO_CREATE_FLAG_IGNORE_MISSING_IMMUTABLE_SAMPLERS = 1u << 1u,
/// Do not remap shader resources when creating the pipeline.
/// Resource bindings in all shaders must match the bindings expected
/// by the PSO's resource signatures.
PSO_CREATE_FLAG_DONT_REMAP_SHADER_RESOURCES = 1u << 2u,
/// Create the pipeline state asynchronously.
/// \remarks When this flag is set to true and if the devices supports
/// AsyncShaderCompilation feature, the pipeline will be created
/// asynchronously in the background. An application should use
/// the IPipelineState::GetStatus() method to check the pipeline status.
/// If the device does not support asynchronous shader compilation,
/// the flag is ignored and the pipeline is created synchronously.
PSO_CREATE_FLAG_ASYNCHRONOUS = 1u << 3u,
PSO_CREATE_FLAG_LAST = PSO_CREATE_FLAG_ASYNCHRONOUS
};
DEFINE_FLAG_ENUM_OPERATORS(PSO_CREATE_FLAGS);
/// Pipeline state creation attributes
struct PipelineStateCreateInfo
{
/// Pipeline state description
PipelineStateDesc PSODesc;
/// Pipeline state creation flags, see Diligent::PSO_CREATE_FLAGS.
PSO_CREATE_FLAGS Flags DEFAULT_INITIALIZER(PSO_CREATE_FLAG_NONE);
/// The number of elements in ppResourceSignatures array.
Uint32 ResourceSignaturesCount DEFAULT_INITIALIZER(0);
/// An array of ResourceSignaturesCount shader resource signatures that
/// define the layout of shader resources in this pipeline state object.
/// See Diligent::IPipelineResourceSignature.
///
/// \remarks When this member is null, the pipeline resource layout will be defined
/// by PSODesc.ResourceLayout member. In this case the PSO will implicitly
/// create a resource signature that can be queried through GetResourceSignature()
/// method.
/// When ppResourceSignatures is not null, PSODesc.ResourceLayout is ignored and
/// should be in it default state.
IPipelineResourceSignature** ppResourceSignatures DEFAULT_INITIALIZER(nullptr);
/// Optional pipeline state cache that is used to accelerate
/// PSO creation. If PSODesc.Name is found in the cache, the cache
/// data is used to create the PSO. Otherwise, the PSO
/// is added to the cache.
IPipelineStateCache* pPSOCache DEFAULT_INITIALIZER(nullptr);
/// For internal use only. Must always be null.
void* pInternalData DEFAULT_INITIALIZER(nullptr);
#ifdef DILIGENT_PLATFORM_32
Uint32 _Padding DEFAULT_INITIALIZER(0);
#endif
#if DILIGENT_CPP_INTERFACE
constexpr PipelineStateCreateInfo() noexcept {}
constexpr PipelineStateCreateInfo(const Char* Name, PIPELINE_TYPE Type) :
PSODesc{Name, Type}
{}
bool operator==(const PipelineStateCreateInfo& RHS) const noexcept
{
if (PSODesc != RHS.PSODesc ||
Flags != RHS.Flags ||
ResourceSignaturesCount != RHS.ResourceSignaturesCount)
return false;
if (ppResourceSignatures != RHS.ppResourceSignatures)
{
if ((ppResourceSignatures == nullptr) != (RHS.ppResourceSignatures == nullptr))
return false;
for (Uint32 i = 0; i < ResourceSignaturesCount; ++i)
{
const auto* pSign0 = ppResourceSignatures[i];
const auto* pSign1 = RHS.ppResourceSignatures[i];
if (pSign0 == pSign1)
continue;
if ((pSign0 == nullptr) != (pSign1 == nullptr))
return false;
if (!pSign0->IsCompatibleWith(pSign1))
return false;
}
}
// Ignore PSO cache and pInternalData
return true;
}
bool operator!=(const PipelineStateCreateInfo& RHS) const noexcept
{
return !(*this == RHS);
}
#endif
};
typedef struct PipelineStateCreateInfo PipelineStateCreateInfo;
/// Graphics pipeline state initialization information.
struct GraphicsPipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
/// Graphics pipeline state description.
GraphicsPipelineDesc GraphicsPipeline;
/// Vertex shader to be used with the pipeline.
IShader* pVS DEFAULT_INITIALIZER(nullptr);
/// Pixel shader to be used with the pipeline.
IShader* pPS DEFAULT_INITIALIZER(nullptr);
/// Domain shader to be used with the pipeline.
IShader* pDS DEFAULT_INITIALIZER(nullptr);
/// Hull shader to be used with the pipeline.
IShader* pHS DEFAULT_INITIALIZER(nullptr);
/// Geometry shader to be used with the pipeline.
IShader* pGS DEFAULT_INITIALIZER(nullptr);
/// Amplification shader to be used with the pipeline.
IShader* pAS DEFAULT_INITIALIZER(nullptr);
/// Mesh shader to be used with the pipeline.
IShader* pMS DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
constexpr GraphicsPipelineStateCreateInfo() noexcept
{
PSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS;
}
explicit constexpr GraphicsPipelineStateCreateInfo(const Char* Name) :
PipelineStateCreateInfo{Name, PIPELINE_TYPE_GRAPHICS}
{}
bool operator==(const GraphicsPipelineStateCreateInfo& Rhs) const noexcept
{
if (static_cast<const PipelineStateCreateInfo&>(*this) != static_cast<const PipelineStateCreateInfo&>(Rhs))
return false;
if (GraphicsPipeline != Rhs.GraphicsPipeline)
return false;
return (pVS == Rhs.pVS &&
pPS == Rhs.pPS &&
pDS == Rhs.pDS &&
pHS == Rhs.pHS &&
pGS == Rhs.pGS &&
pAS == Rhs.pAS &&
pMS == Rhs.pMS);
}
bool operator!=(const GraphicsPipelineStateCreateInfo& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct GraphicsPipelineStateCreateInfo GraphicsPipelineStateCreateInfo;
/// Compute pipeline state description.
struct ComputePipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
/// Compute shader to be used with the pipeline
IShader* pCS DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
ComputePipelineStateCreateInfo() noexcept
{
PSODesc.PipelineType = PIPELINE_TYPE_COMPUTE;
}
explicit constexpr ComputePipelineStateCreateInfo(const Char* Name) :
PipelineStateCreateInfo{Name, PIPELINE_TYPE_COMPUTE}
{}
bool operator==(const ComputePipelineStateCreateInfo& Rhs) const noexcept
{
if (static_cast<const PipelineStateCreateInfo&>(*this) != static_cast<const PipelineStateCreateInfo&>(Rhs))
return false;
return pCS == Rhs.pCS;
}
bool operator!=(const ComputePipelineStateCreateInfo& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct ComputePipelineStateCreateInfo ComputePipelineStateCreateInfo;
/// Ray tracing pipeline state initialization information.
struct RayTracingPipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
/// Ray tracing pipeline description.
RayTracingPipelineDesc RayTracingPipeline;
/// A pointer to an array of GeneralShaderCount RayTracingGeneralShaderGroup structures that contain shader group description.
const RayTracingGeneralShaderGroup* pGeneralShaders DEFAULT_INITIALIZER(nullptr);
/// The number of general shader groups.
Uint32 GeneralShaderCount DEFAULT_INITIALIZER(0);
/// A pointer to an array of TriangleHitShaderCount RayTracingTriangleHitShaderGroup structures that contain shader group description.
/// Can be null.
const RayTracingTriangleHitShaderGroup* pTriangleHitShaders DEFAULT_INITIALIZER(nullptr);
/// The number of triangle hit shader groups.
Uint32 TriangleHitShaderCount DEFAULT_INITIALIZER(0);
/// A pointer to an array of ProceduralHitShaderCount RayTracingProceduralHitShaderGroup structures that contain shader group description.
/// Can be null.
const RayTracingProceduralHitShaderGroup* pProceduralHitShaders DEFAULT_INITIALIZER(nullptr);
/// The number of procedural shader groups.
Uint32 ProceduralHitShaderCount DEFAULT_INITIALIZER(0);
/// Direct3D12 only: the name of the constant buffer that will be used by the local root signature.
/// Ignored if RayTracingPipelineDesc::ShaderRecordSize is zero.
/// In Vulkan backend in HLSL add [[vk::shader_record_ext]] attribute to the constant buffer, in GLSL add shaderRecord layout to buffer.
const Char* pShaderRecordName DEFAULT_INITIALIZER(nullptr);
/// Direct3D12 only: the maximum hit shader attribute size in bytes.
/// If zero then maximum allowed size will be used.
Uint32 MaxAttributeSize DEFAULT_INITIALIZER(0);
/// Direct3D12 only: the maximum payload size in bytes.
/// If zero then maximum allowed size will be used.
Uint32 MaxPayloadSize DEFAULT_INITIALIZER(0);
#if DILIGENT_CPP_INTERFACE
RayTracingPipelineStateCreateInfo() noexcept
{
PSODesc.PipelineType = PIPELINE_TYPE_RAY_TRACING;
}
explicit constexpr RayTracingPipelineStateCreateInfo(const Char* Name) :
PipelineStateCreateInfo{Name, PIPELINE_TYPE_RAY_TRACING}
{}
bool operator==(const RayTracingPipelineStateCreateInfo& RHS)const noexcept
{
if (static_cast<const PipelineStateCreateInfo&>(*this) != static_cast<const PipelineStateCreateInfo&>(RHS))
return false;
if (RayTracingPipeline != RHS.RayTracingPipeline ||
GeneralShaderCount != RHS.GeneralShaderCount ||
TriangleHitShaderCount != RHS.TriangleHitShaderCount ||
ProceduralHitShaderCount != RHS.ProceduralHitShaderCount ||
MaxAttributeSize != RHS.MaxAttributeSize ||
MaxPayloadSize != RHS.MaxPayloadSize)
return false;
if (!((IsNullOrEmptyStr(pShaderRecordName) && IsNullOrEmptyStr(RHS.pShaderRecordName)) || SafeStrEqual(pShaderRecordName, RHS.pShaderRecordName)))
return false;
for (Uint32 i = 0; i < GeneralShaderCount; ++i)
{
if (pGeneralShaders[i] != RHS.pGeneralShaders[i])
return false;
}
for (Uint32 i = 0; i < TriangleHitShaderCount; ++i)
{
if (pTriangleHitShaders[i] != RHS.pTriangleHitShaders[i])
return false;
}
for (Uint32 i = 0; i < ProceduralHitShaderCount; ++i)
{
if (pProceduralHitShaders[i] != RHS.pProceduralHitShaders[i])
return false;
}
return true;
}
bool operator!=(const RayTracingPipelineStateCreateInfo& RHS)const noexcept
{
return !(*this == RHS);
}
#endif
};
typedef struct RayTracingPipelineStateCreateInfo RayTracingPipelineStateCreateInfo;
/// Tile pipeline state description
struct TilePipelineDesc
{
/// The number of render targets in the RTVFormats array.
Uint8 NumRenderTargets DEFAULT_INITIALIZER(0);
/// The number of samples in render targets.
Uint8 SampleCount DEFAULT_INITIALIZER(1);
/// Render target formats.
TEXTURE_FORMAT RTVFormats[DILIGENT_MAX_RENDER_TARGETS] DEFAULT_INITIALIZER({});
#if DILIGENT_CPP_INTERFACE
/// Comparison operator tests if two structures are equivalent
constexpr bool operator==(const TilePipelineDesc& RHS) const
{
if (!(NumRenderTargets == RHS.NumRenderTargets && SampleCount == RHS.SampleCount))
return false;
for (Uint32 i = 0; i < NumRenderTargets; i++)
if (RTVFormats[i] != RHS.RTVFormats[i])
return false;
return true;
}
constexpr bool operator!=(const TilePipelineDesc& RHS) const
{
return !(*this == RHS);
}
#endif
};
typedef struct TilePipelineDesc TilePipelineDesc;
/// Tile pipeline state initialization information.
struct TilePipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
/// Tile pipeline description, see Diligent::TilePipelineDesc.
TilePipelineDesc TilePipeline;
/// Tile shader to be used with the pipeline.
IShader* pTS DEFAULT_INITIALIZER(nullptr);
#if DILIGENT_CPP_INTERFACE
TilePipelineStateCreateInfo() noexcept
{
PSODesc.PipelineType = PIPELINE_TYPE_TILE;
}
explicit constexpr TilePipelineStateCreateInfo(const Char* Name) :
PipelineStateCreateInfo{Name, PIPELINE_TYPE_TILE}
{}
bool operator==(const TilePipelineStateCreateInfo& Rhs) const noexcept
{
if (static_cast<const PipelineStateCreateInfo&>(*this) != static_cast<const PipelineStateCreateInfo&>(Rhs))
return false;
if (TilePipeline != Rhs.TilePipeline)
return false;
return pTS == Rhs.pTS;
}
bool operator!=(const TilePipelineStateCreateInfo& Rhs) const noexcept
{
return !(*this == Rhs);
}
#endif
};
typedef struct TilePipelineStateCreateInfo TilePipelineStateCreateInfo;