git.s-ol.nu ~forks/DiligentCore / a5aa4f7
Added resource signature creation failure test; fxied validation of resource flags. assiduous 6 months ago
7 changed file(s) with 399 addition(s) and 100 deletion(s). Raw diff Collapse all Expand all
382382
383383 const char* GetShaderCompilerTypeString(SHADER_COMPILER Compiler);
384384
385 String GetPipelineResourceFlagsString(PIPELINE_RESOURCE_FLAGS Flags, bool GetFullName = false);
385 String GetPipelineResourceFlagsString(PIPELINE_RESOURCE_FLAGS Flags, bool GetFullName = false, const char* DelimeterString = "|");
386
387 PIPELINE_RESOURCE_FLAGS GetValidPipelineResourceFlags(SHADER_RESOURCE_TYPE ResourceType);
386388
387389 Uint32 ComputeMipLevelsCount(Uint32 Width);
388390 Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height);
11751175 }
11761176 }
11771177
1178 String GetPipelineResourceFlagsString(PIPELINE_RESOURCE_FLAGS Flags, bool GetFullName /*= false*/)
1178 String GetPipelineResourceFlagsString(PIPELINE_RESOURCE_FLAGS Flags, bool GetFullName /*= false*/, const char* DelimeterString /*= "|"*/)
11791179 {
11801180 if (Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN)
11811181 return GetFullName ? "PIPELINE_RESOURCE_FLAG_UNKNOWN" : "UNKNOWN";
11831183 while (Flags != PIPELINE_RESOURCE_FLAG_UNKNOWN)
11841184 {
11851185 if (!Str.empty())
1186 Str += '|';
1186 Str += DelimeterString;
11871187
11881188 auto Flag = ExtractLSB(Flags);
11891189
12131213 return Str;
12141214 }
12151215
1216 PIPELINE_RESOURCE_FLAGS GetValidPipelineResourceFlags(SHADER_RESOURCE_TYPE ResourceType)
1217 {
1218
1219 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource type");
1220 switch (ResourceType)
1221 {
1222 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
1223 return PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1224
1225 case SHADER_RESOURCE_TYPE_TEXTURE_SRV:
1226 return PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER | PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1227
1228 case SHADER_RESOURCE_TYPE_BUFFER_SRV:
1229 return PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER | PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1230
1231 case SHADER_RESOURCE_TYPE_TEXTURE_UAV:
1232 return PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1233
1234 case SHADER_RESOURCE_TYPE_BUFFER_UAV:
1235 return PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER | PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1236
1237 case SHADER_RESOURCE_TYPE_SAMPLER:
1238 return PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1239
1240 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
1241 return PIPELINE_RESOURCE_FLAG_UNKNOWN;
1242
1243 case SHADER_RESOURCE_TYPE_ACCEL_STRUCT:
1244 return PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY;
1245
1246 default:
1247 UNEXPECTED("Unexpected resource type");
1248 return PIPELINE_RESOURCE_FLAG_UNKNOWN;
1249 }
1250 }
12161251
12171252 Uint32 ComputeMipLevelsCount(Uint32 Width)
12181253 {
8484
8585 if ((Res.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0 && !ShaderResourceRuntimeArraySupported)
8686 {
87 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags: RUNTIME_ARRAY can be used only if ShaderResourceRuntimeArray device feature is enabled.");
87 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags: RUNTIME_ARRAY can only be used if ShaderResourceRuntimeArray device feature is enabled.");
8888 }
8989
9090 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please add the new resource type to the switch below");
91 switch (Res.ResourceType)
92 {
93 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
94 if ((Res.Flags & ~PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) != 0)
95 {
96 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
97 "): NO_DYNAMIC_BUFFERS is the only valid flag for a constant buffer.");
98 }
99 break;
100
101 case SHADER_RESOURCE_TYPE_TEXTURE_SRV:
102 if ((Res.Flags & ~PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER) != 0)
103 {
104 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
105 "): COMBINED_SAMPLER is the only valid flag for a texture SRV.");
106 }
107 break;
108
109 case SHADER_RESOURCE_TYPE_BUFFER_SRV:
110 if ((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) != 0)
111 {
112 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
113 "): NO_DYNAMIC_BUFFERS and FORMATTED_BUFFER are the only valid flags for a buffer SRV.");
114 }
115 break;
116
117 case SHADER_RESOURCE_TYPE_TEXTURE_UAV:
118 if (Res.Flags != PIPELINE_RESOURCE_FLAG_UNKNOWN)
119 {
120 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
121 "): UNKNOWN is the only valid flag for a texture UAV.");
122 }
123 break;
124
125 case SHADER_RESOURCE_TYPE_BUFFER_UAV:
126 if ((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) != 0)
127 {
128 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
129 "): NO_DYNAMIC_BUFFERS and FORMATTED_BUFFER are the only valid flags for a buffer UAV.");
130 }
131 break;
132
133 case SHADER_RESOURCE_TYPE_SAMPLER:
134 if (Res.Flags != PIPELINE_RESOURCE_FLAG_UNKNOWN)
135 {
136 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
137 "): UNKNOWN is the only valid flag for a sampler.");
138 }
139 break;
140
141 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
142 if (Res.Flags != PIPELINE_RESOURCE_FLAG_UNKNOWN)
143 {
144 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
145 "): UNKNOWN is the only valid flag for an input attachment.");
146 }
147 break;
148
149 case SHADER_RESOURCE_TYPE_ACCEL_STRUCT:
150 if (Res.Flags != PIPELINE_RESOURCE_FLAG_UNKNOWN)
151 {
152 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
153 "): UNKNOWN is the only valid flag for an acceleration structure.");
154 }
155 break;
156
157 default:
158 UNEXPECTED("Unexpected resource type");
91
92 auto AllowedResourceFlags = GetValidPipelineResourceFlags(Res.ResourceType);
93 if ((Res.Flags & ~AllowedResourceFlags) != 0)
94 {
95 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (", GetPipelineResourceFlagsString(Res.Flags),
96 "). Only the following flags are valid for a ", GetShaderResourceTypeLiteralName(Res.ResourceType),
97 ": ", GetPipelineResourceFlagsString(AllowedResourceFlags, false, ", "), ".");
15998 }
16099
161100 ResourcesByName.emplace(Res.Name, Res);
332332 NumResources[d3d12DescriptorRangeType] += ResDesc.ArraySize;
333333 }
334334
335 const auto dbgValidResourceFlags = GetValidPipelineResourceFlags(ResDesc.ResourceType);
336 VERIFY((ResDesc.Flags & ~dbgValidResourceFlags) == 0, "Invalid resource flags. This error should've been caught by ValidatePipelineResourceSignatureDesc.");
337
335338 const auto UseDynamicOffset = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0;
336339 const auto IsFormattedBuffer = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0;
337340 const auto IsArray = ResDesc.ArraySize != 1;
340343 switch (ResDesc.ResourceType)
341344 {
342345 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
343 VERIFY(!IsFormattedBuffer, "Constant buffers can't be labeled as formatted. This error should've been cuaght by ValidatePipelineResourceSignatureDesc().");
346 VERIFY(!IsFormattedBuffer, "Constant buffers can't be labeled as formatted. This error should've been caught by ValidatePipelineResourceSignatureDesc().");
344347 d3d12RootParamType = UseDynamicOffset && !IsArray ? D3D12_ROOT_PARAMETER_TYPE_CBV : D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
345348 break;
346349
8484
8585 DescriptorType GetDescriptorType(const PipelineResourceDesc& Res)
8686 {
87 VERIFY((Res.Flags & ~GetValidPipelineResourceFlags(Res.ResourceType)) == 0,
88 "Invalid resource flags. This error should've been caught by ValidatePipelineResourceSignatureDesc.");
89
8790 const bool WithDynamicOffset = (Res.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0;
8891 const bool CombinedSampler = (Res.Flags & PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER) != 0;
8992 const bool UseTexelBuffer = (Res.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0;
9295 switch (Res.ResourceType)
9396 {
9497 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
95 VERIFY((Res.Flags & ~PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0,
96 "NO_DYNAMIC_BUFFERS is the only valid flag allowed for constant buffers. "
97 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
9898 return WithDynamicOffset ? DescriptorType::UniformBufferDynamic : DescriptorType::UniformBuffer;
9999
100100 case SHADER_RESOURCE_TYPE_TEXTURE_SRV:
101 VERIFY((Res.Flags & ~PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER) == 0,
102 "COMBINED_SAMPLER is the only valid flag for a texture SRV. "
103 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
104101 return CombinedSampler ? DescriptorType::CombinedImageSampler : DescriptorType::SeparateImage;
105102
106103 case SHADER_RESOURCE_TYPE_BUFFER_SRV:
107 VERIFY((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) == 0,
108 "NO_DYNAMIC_BUFFERS and FORMATTED_BUFFER are the only valid flags for a buffer SRV. "
109 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
110104 return UseTexelBuffer ? DescriptorType::UniformTexelBuffer :
111105 (WithDynamicOffset ? DescriptorType::StorageBufferDynamic_ReadOnly : DescriptorType::StorageBuffer_ReadOnly);
112106
113107 case SHADER_RESOURCE_TYPE_TEXTURE_UAV:
114 VERIFY(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN,
115 "UNKNOWN is the only valid flag for a texture UAV. "
116 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
117108 return DescriptorType::StorageImage;
118109
119110 case SHADER_RESOURCE_TYPE_BUFFER_UAV:
120 VERIFY((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) == 0,
121 "NO_DYNAMIC_BUFFERS and FORMATTED_BUFFER are the only valid flags for a buffer UAV. "
122 "This should've been caught by ValidatePipelineResourceSignatureDesc.");
123111 return UseTexelBuffer ? DescriptorType::StorageTexelBuffer :
124112 (WithDynamicOffset ? DescriptorType::StorageBufferDynamic : DescriptorType::StorageBuffer);
125113
126114 case SHADER_RESOURCE_TYPE_SAMPLER:
127 VERIFY(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN,
128 "UNKNOWN is the only valid flag for a sampler. "
129 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
130115 return DescriptorType::Sampler;
131116
132117 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
133 VERIFY(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN,
134 "UNKNOWN is the only valid flag for an input attachment. "
135 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
136118 return DescriptorType::InputAttachment;
137119
138120 case SHADER_RESOURCE_TYPE_ACCEL_STRUCT:
139 VERIFY(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN,
140 "UNKNOWN is the only valid flag for an acceleration structure. "
141 "This error should've been caught by ValidatePipelineResourceSignatureDesc.");
142121 return DescriptorType::AccelerationStructure;
143122
144123 default:
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #include <array>
28 #include <limits>
29
30 #include "TestingEnvironment.hpp"
31
32 #include "gtest/gtest.h"
33
34 using namespace Diligent;
35 using namespace Diligent::Testing;
36
37 namespace
38 {
39
40 static void TestCreatePRSFailure(PipelineResourceSignatureDesc CI, const char* ExpectedErrorSubstring)
41 {
42 auto* const pEnv = TestingEnvironment::GetInstance();
43 auto* const pDevice = pEnv->GetDevice();
44
45 RefCntAutoPtr<IPipelineResourceSignature> pSignature;
46 pEnv->SetErrorAllowance(2, "Errors below are expected: testing PRS creation failure\n");
47 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
48 pDevice->CreatePipelineResourceSignature(CI, &pSignature);
49 ASSERT_FALSE(pSignature);
50
51 CI.Name = nullptr;
52 pEnv->SetErrorAllowance(2);
53 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
54 pDevice->CreatePipelineResourceSignature(CI, &pSignature);
55 ASSERT_FALSE(pSignature);
56
57 pEnv->SetErrorAllowance(0);
58 }
59
60 TEST(PRSCreationFailureTest, InvalidBindingIndex)
61 {
62 PipelineResourceSignatureDesc PRSDesc;
63 PRSDesc.Name = "Invalid binding index";
64 PRSDesc.BindingIndex = std::numeric_limits<decltype(PRSDesc.BindingIndex)>::max();
65 TestCreatePRSFailure(PRSDesc, "Desc.BindingIndex (255) exceeds the maximum allowed value");
66 }
67
68 TEST(PRSCreationFailureTest, InvalidNumResources)
69 {
70 PipelineResourceSignatureDesc PRSDesc;
71 PRSDesc.Name = "Invalid NumResources";
72 PRSDesc.NumResources = std::numeric_limits<decltype(PRSDesc.NumResources)>::max();
73 TestCreatePRSFailure(PRSDesc, "Desc.NumResources (4294967295) exceeds the maximum allowed value");
74 }
75
76 TEST(PRSCreationFailureTest, NullResources)
77 {
78 PipelineResourceSignatureDesc PRSDesc;
79 PRSDesc.Name = "Null Resoruces";
80 PRSDesc.NumResources = 10;
81 PRSDesc.Resources = nullptr;
82 TestCreatePRSFailure(PRSDesc, "Desc.NumResources (10) is not zero, but Desc.Resources is null");
83 }
84
85 TEST(PRSCreationFailureTest, NullImmutableSamplers)
86 {
87 PipelineResourceSignatureDesc PRSDesc;
88 PRSDesc.Name = "Null Resoruces";
89 PRSDesc.NumImmutableSamplers = 12;
90 PRSDesc.ImmutableSamplers = nullptr;
91 TestCreatePRSFailure(PRSDesc, "Desc.NumImmutableSamplers (12) is not zero, but Desc.ImmutableSamplers is null");
92 }
93
94 TEST(PRSCreationFailureTest, NullCombinedSamplerSuffix)
95 {
96 PipelineResourceSignatureDesc PRSDesc;
97 PRSDesc.Name = "Null CombinedSamplerSuffix";
98 PRSDesc.UseCombinedTextureSamplers = true;
99 PRSDesc.CombinedSamplerSuffix = nullptr;
100 TestCreatePRSFailure(PRSDesc, "Desc.UseCombinedTextureSamplers is true, but Desc.CombinedSamplerSuffix is null or empty");
101
102 PRSDesc.Name = "Null CombinedSamplerSuffix 2";
103 PRSDesc.CombinedSamplerSuffix = "";
104 TestCreatePRSFailure(PRSDesc, "Desc.UseCombinedTextureSamplers is true, but Desc.CombinedSamplerSuffix is null or empty");
105 }
106
107 TEST(PRSCreationFailureTest, NullResourceName)
108 {
109 PipelineResourceSignatureDesc PRSDesc;
110 PRSDesc.Name = "Null resource name";
111 PipelineResourceDesc Resources[]{
112 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
113 {SHADER_TYPE_PIXEL, nullptr, 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
114 PRSDesc.Resources = Resources;
115 PRSDesc.NumResources = _countof(Resources);
116 TestCreatePRSFailure(PRSDesc, "Desc.Resources[1].Name must not be null");
117
118 PRSDesc.Name = "Null resource name 2";
119 Resources[1].Name = "";
120 TestCreatePRSFailure(PRSDesc, "Desc.Resources[1].Name must not be empty");
121 }
122
123 TEST(PRSCreationFailureTest, UnknownShaderStages)
124 {
125 PipelineResourceSignatureDesc PRSDesc;
126 PRSDesc.Name = "Unknown ShaderStages";
127 PipelineResourceDesc Resources[]{
128 {SHADER_TYPE_PIXEL, "g_Buffer", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
129 {SHADER_TYPE_UNKNOWN, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
130 PRSDesc.Resources = Resources;
131 PRSDesc.NumResources = _countof(Resources);
132 TestCreatePRSFailure(PRSDesc, "Desc.Resources[1].ShaderStages must not be SHADER_TYPE_UNKNOWN");
133 }
134
135 TEST(PRSCreationFailureTest, ZeroArraySize)
136 {
137 PipelineResourceSignatureDesc PRSDesc;
138 PRSDesc.Name = "Zero array size";
139 PipelineResourceDesc Resources[]{
140 {SHADER_TYPE_PIXEL, "g_Buffer", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
141 {SHADER_TYPE_PIXEL, "g_Texture", 0, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
142 PRSDesc.Resources = Resources;
143 PRSDesc.NumResources = _countof(Resources);
144 TestCreatePRSFailure(PRSDesc, "Desc.Resources[1].ArraySize must not be 0");
145 }
146
147 TEST(PRSCreationFailureTest, OverlappingStages)
148 {
149 PipelineResourceSignatureDesc PRSDesc;
150 PRSDesc.Name = "Overlapping Shader Stages";
151 PipelineResourceDesc Resources[]{
152 {SHADER_TYPE_VERTEX | SHADER_TYPE_GEOMETRY, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
153 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
154 PRSDesc.Resources = Resources;
155 PRSDesc.NumResources = _countof(Resources);
156 TestCreatePRSFailure(PRSDesc, "Multiple resources with name 'g_Texture' specify overlapping shader stages");
157 }
158
159 TEST(PRSCreationFailureTest, InvalidResourceFlag)
160 {
161 PipelineResourceSignatureDesc PRSDesc;
162 PRSDesc.Name = "Overlapping Shader Stages";
163 PipelineResourceDesc Resources[]{
164 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
165 {SHADER_TYPE_VERTEX, "g_Buffer", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER}};
166 PRSDesc.Resources = Resources;
167 PRSDesc.NumResources = _countof(Resources);
168 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (COMBINED_SAMPLER|FORMATTED_BUFFER). Only the following flags are valid for a constant buffer: NO_DYNAMIC_BUFFERS, RUNTIME_ARRAY");
169 }
170
171 TEST(PRSCreationFailureTest, InvalidTexSRVFlag)
172 {
173 PipelineResourceSignatureDesc PRSDesc;
174 PRSDesc.Name = "Invalid Tex SRV Flag";
175 PipelineResourceDesc Resources[]{
176 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
177 {SHADER_TYPE_VERTEX, "g_Texture2", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER}};
178 PRSDesc.Resources = Resources;
179 PRSDesc.NumResources = _countof(Resources);
180 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (NO_DYNAMIC_BUFFERS|COMBINED_SAMPLER|FORMATTED_BUFFER). Only the following flags are valid for a texture SRV: COMBINED_SAMPLER, RUNTIME_ARRAY");
181 }
182
183 TEST(PRSCreationFailureTest, InvalidBuffSRVFlag)
184 {
185 PipelineResourceSignatureDesc PRSDesc;
186 PRSDesc.Name = "Invalid Buff SRV Flag";
187 PipelineResourceDesc Resources[]{
188 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
189 {SHADER_TYPE_VERTEX, "g_Buffer", 1, SHADER_RESOURCE_TYPE_BUFFER_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER}};
190 PRSDesc.Resources = Resources;
191 PRSDesc.NumResources = _countof(Resources);
192 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (COMBINED_SAMPLER). Only the following flags are valid for a buffer SRV: NO_DYNAMIC_BUFFERS, FORMATTED_BUFFER, RUNTIME_ARRAY");
193 }
194
195 TEST(PRSCreationFailureTest, InvalidTexUAVFlag)
196 {
197 PipelineResourceSignatureDesc PRSDesc;
198 PRSDesc.Name = "Invalid Tex UAV Flag";
199 PipelineResourceDesc Resources[]{
200 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
201 {SHADER_TYPE_VERTEX, "g_Texture2", 1, SHADER_RESOURCE_TYPE_TEXTURE_UAV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER}};
202 PRSDesc.Resources = Resources;
203 PRSDesc.NumResources = _countof(Resources);
204 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (COMBINED_SAMPLER). Only the following flags are valid for a texture UAV: RUNTIME_ARRAY");
205 }
206
207 TEST(PRSCreationFailureTest, InvalidBuffUAVFlag)
208 {
209 PipelineResourceSignatureDesc PRSDesc;
210 PRSDesc.Name = "Invalid Buff UAV Flag";
211 PipelineResourceDesc Resources[]{
212 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
213 {SHADER_TYPE_VERTEX, "g_Buffer", 1, SHADER_RESOURCE_TYPE_BUFFER_UAV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER}};
214 PRSDesc.Resources = Resources;
215 PRSDesc.NumResources = _countof(Resources);
216 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (COMBINED_SAMPLER|FORMATTED_BUFFER). Only the following flags are valid for a buffer UAV: NO_DYNAMIC_BUFFERS, FORMATTED_BUFFER, RUNTIME_ARRAY");
217 }
218
219 TEST(PRSCreationFailureTest, InvalidSamplerFlag)
220 {
221 PipelineResourceSignatureDesc PRSDesc;
222 PRSDesc.Name = "Invalid sampler Flag";
223 PipelineResourceDesc Resources[]{
224 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
225 {SHADER_TYPE_VERTEX, "g_Sampler", 1, SHADER_RESOURCE_TYPE_SAMPLER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER}};
226 PRSDesc.Resources = Resources;
227 PRSDesc.NumResources = _countof(Resources);
228 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (NO_DYNAMIC_BUFFERS|FORMATTED_BUFFER). Only the following flags are valid for a sampler: RUNTIME_ARRAY");
229 }
230
231 TEST(PRSCreationFailureTest, InvalidInputAttachmentFlag)
232 {
233 PipelineResourceSignatureDesc PRSDesc;
234 PRSDesc.Name = "Invalid input attachment Flag";
235 PipelineResourceDesc Resources[]{
236 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
237 {SHADER_TYPE_PIXEL, "g_InputAttachment", 1, SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY}};
238 PRSDesc.Resources = Resources;
239 PRSDesc.NumResources = _countof(Resources);
240 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (RUNTIME_ARRAY). Only the following flags are valid for a input attachment: UNKNOWN");
241 }
242
243 TEST(PRSCreationFailureTest, InvalidAccelStructFlag)
244 {
245 PipelineResourceSignatureDesc PRSDesc;
246 PRSDesc.Name = "Invalid accel struct Flag";
247 PipelineResourceDesc Resources[]{
248 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
249 {SHADER_TYPE_PIXEL, "g_AS", 1, SHADER_RESOURCE_TYPE_ACCEL_STRUCT, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS}};
250 PRSDesc.Resources = Resources;
251 PRSDesc.NumResources = _countof(Resources);
252 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (NO_DYNAMIC_BUFFERS). Only the following flags are valid for a acceleration structure: RUNTIME_ARRAY");
253 }
254
255 TEST(PRSCreationFailureTest, InvalidAssignedSamplerResourceType)
256 {
257 PipelineResourceSignatureDesc PRSDesc;
258 PRSDesc.Name = "Invalid assigned sampler resource type";
259 PipelineResourceDesc Resources[]{
260 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
261 {SHADER_TYPE_PIXEL, "g_Texture_sampler", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
262 PRSDesc.UseCombinedTextureSamplers = true;
263 PRSDesc.Resources = Resources;
264 PRSDesc.NumResources = _countof(Resources);
265 TestCreatePRSFailure(PRSDesc, "Resource 'g_Texture_sampler' combined with texture 'g_Texture' is not a sampler");
266 }
267
268 TEST(PRSCreationFailureTest, InvalidAssignedSamplerStages)
269 {
270 PipelineResourceSignatureDesc PRSDesc;
271 PRSDesc.Name = "Invalid assigned sampler shader stage";
272 PipelineResourceDesc Resources[]{
273 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
274 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture_sampler", 1, SHADER_RESOURCE_TYPE_SAMPLER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
275 PRSDesc.UseCombinedTextureSamplers = true;
276 PRSDesc.Resources = Resources;
277 PRSDesc.NumResources = _countof(Resources);
278 TestCreatePRSFailure(PRSDesc, "Texture 'g_Texture' and sampler 'g_Texture_sampler' assigned to it use different shader stages");
279 }
280
281 TEST(PRSCreationFailureTest, InvalidAssignedSamplerVarType)
282 {
283 PipelineResourceSignatureDesc PRSDesc;
284 PRSDesc.Name = "Invalid assigned sampler var type";
285 PipelineResourceDesc Resources[]{
286 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE},
287 {SHADER_TYPE_PIXEL, "g_Texture_sampler", 1, SHADER_RESOURCE_TYPE_SAMPLER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
288 PRSDesc.UseCombinedTextureSamplers = true;
289 PRSDesc.Resources = Resources;
290 PRSDesc.NumResources = _countof(Resources);
291 TestCreatePRSFailure(PRSDesc, "The type (mutable) of texture resource 'g_Texture' does not match the type (static) of sampler 'g_Texture_sampler' that is assigned to it");
292 }
293
294 TEST(PRSCreationFailureTest, UnassignedSampler)
295 {
296 PipelineResourceSignatureDesc PRSDesc;
297 PRSDesc.Name = "Unassigned sampler";
298 PipelineResourceDesc Resources[]{
299 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE},
300 {SHADER_TYPE_PIXEL, "g_Texture2_sampler", 1, SHADER_RESOURCE_TYPE_SAMPLER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
301 PRSDesc.UseCombinedTextureSamplers = true;
302 PRSDesc.Resources = Resources;
303 PRSDesc.NumResources = _countof(Resources);
304 TestCreatePRSFailure(PRSDesc, "Sampler 'g_Texture2_sampler' is not assigned to any texture");
305 }
306
307 TEST(PRSCreationFailureTest, NullImmutableSamplerName)
308 {
309 PipelineResourceSignatureDesc PRSDesc;
310 PRSDesc.Name = "Null Immutable Sampler Name";
311 ImmutableSamplerDesc ImmutableSamplers[]{
312 {SHADER_TYPE_PIXEL, "g_ImmutableSampler", SamplerDesc{}},
313 {SHADER_TYPE_PIXEL, nullptr, SamplerDesc{}}};
314 PRSDesc.ImmutableSamplers = ImmutableSamplers;
315 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
316 TestCreatePRSFailure(PRSDesc, "Desc.ImmutableSamplers[1].SamplerOrTextureName must not be null");
317
318 PRSDesc.Name = "Null Immutable Sampler Name 2";
319
320 ImmutableSamplers[1].SamplerOrTextureName = "";
321 TestCreatePRSFailure(PRSDesc, "Desc.ImmutableSamplers[1].SamplerOrTextureName must not be empty");
322 }
323
324 TEST(PRSCreationFailureTest, OverlappingImmutableSamplerStages)
325 {
326 PipelineResourceSignatureDesc PRSDesc;
327 PRSDesc.Name = "Overlapping Immutable Sampler Stages";
328 ImmutableSamplerDesc ImmutableSamplers[]{
329 {SHADER_TYPE_PIXEL | SHADER_TYPE_VERTEX, "g_ImmutableSampler", SamplerDesc{}},
330 {SHADER_TYPE_PIXEL | SHADER_TYPE_HULL, "g_ImmutableSampler", SamplerDesc{}}};
331 PRSDesc.ImmutableSamplers = ImmutableSamplers;
332 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
333 TestCreatePRSFailure(PRSDesc, "ultiple immutable samplers with name 'g_ImmutableSampler' specify overlapping shader stages.");
334 }
335
336 } // namespace
2525 */
2626
2727 #include <array>
28 #include <limits>
2829
2930 #include "TestingEnvironment.hpp"
3031 #include "GraphicsAccessories.hpp"
449450 pEnv->SetErrorAllowance(2, "Errors below are expected: testing PSO creation failure\n");
450451 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
451452 pDevice->CreateGraphicsPipelineState(CI, &pPSO);
453 ASSERT_FALSE(pPSO);
452454
453455 CI.PSODesc.Name = nullptr;
454456 pEnv->SetErrorAllowance(2);
455457 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
456458 pDevice->CreateGraphicsPipelineState(CI, &pPSO);
459 ASSERT_FALSE(pPSO);
457460
458461 pEnv->SetErrorAllowance(0);
459 ASSERT_FALSE(pPSO);
460462 }
461463
462464 static void TestCreatePSOFailure(ComputePipelineStateCreateInfo CI, const char* ExpectedErrorSubstring)
469471 pEnv->SetErrorAllowance(2, "Errors below are expected: testing PSO creation failure\n");
470472 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
471473 pDevice->CreateComputePipelineState(CI, &pPSO);
474 ASSERT_FALSE(pPSO);
472475
473476 CI.PSODesc.Name = nullptr;
474477 pEnv->SetErrorAllowance(2);
475478 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
476479 pDevice->CreateComputePipelineState(CI, &pPSO);
480 ASSERT_FALSE(pPSO);
477481
478482 pEnv->SetErrorAllowance(0);
479 ASSERT_FALSE(pPSO);
480483 }
481484
482485 static void TestCreatePSOFailure(RayTracingPipelineStateCreateInfo CI, const char* ExpectedErrorSubstring)
489492 pEnv->SetErrorAllowance(2, "Errors below are expected: testing PSO creation failure\n");
490493 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
491494 pDevice->CreateRayTracingPipelineState(CI, &pPSO);
495 ASSERT_FALSE(pPSO);
492496
493497 CI.PSODesc.Name = nullptr;
494498 pEnv->SetErrorAllowance(2);
495499 pEnv->PushExpectedErrorSubstring(ExpectedErrorSubstring);
496500 pDevice->CreateRayTracingPipelineState(CI, &pPSO);
501 ASSERT_FALSE(pPSO);
497502
498503 pEnv->SetErrorAllowance(0);
499 ASSERT_FALSE(pPSO);
500504 }
501505
502506 protected: