git.s-ol.nu ~forks/DiligentCore / 176e4de
Reworked non-separable programs in GL; added more PSO and PRS validation assiduous 6 months ago
11 changed file(s) with 421 addition(s) and 131 deletion(s). Raw diff Collapse all Expand all
4747 namespace Diligent
4848 {
4949
50 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false);
51 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false);
52 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, Uint32 MaxRecursion, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false);
50 // Validates graphics pipeline create attributes and throws an exception in case of an error.
51 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo,
52 const DeviceFeatures& Features) noexcept(false);
53
54 // Validates compute pipeline create attributes and throws an exception in case of an error.
55 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo,
56 const DeviceFeatures& Features) noexcept(false);
57
58 // Validates ray-tracing pipeline create attributes and throws an exception in case of an error.
59 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice,
60 Uint32 MaxRecursion,
61 const RayTracingPipelineStateCreateInfo& CreateInfo,
62 const DeviceFeatures& Features) noexcept(false);
5363
5464 /// Validates that pipeline resource description 'ResDesc' is compatible with the actual resource
5565 /// attributes and throws an exception in case of an error.
137147 {
138148 try
139149 {
140 ValidateGraphicsPipelineCreateInfo(GraphicsPipelineCI);
150 ValidateGraphicsPipelineCreateInfo(GraphicsPipelineCI, pDevice->GetDeviceCaps().Features);
141151 }
142152 catch (...)
143153 {
161171 {
162172 try
163173 {
164 ValidateComputePipelineCreateInfo(ComputePipelineCI);
174 ValidateComputePipelineCreateInfo(ComputePipelineCI, pDevice->GetDeviceCaps().Features);
165175 }
166176 catch (...)
167177 {
185195 {
186196 try
187197 {
188 ValidateRayTracingPipelineCreateInfo(pDevice, pDevice->GetProperties().MaxRayTracingRecursionDepth, RayTracingPipelineCI);
198 ValidateRayTracingPipelineCreateInfo(pDevice, pDevice->GetProperties().MaxRayTracingRecursionDepth,
199 RayTracingPipelineCI, pDevice->GetDeviceCaps().Features);
189200 }
190201 catch (...)
191202 {
6363 const auto& Res = Desc.Resources[i];
6464
6565 if (Res.Name == nullptr)
66 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be null");
66 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be null.");
6767
6868 if (Res.Name[0] == '\0')
69 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be empty");
69 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be empty.");
7070
7171 if (Res.ShaderStages == SHADER_TYPE_UNKNOWN)
72 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN");
72 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
7373
7474 if (Res.ArraySize == 0)
75 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ArraySize must not be 0");
75 LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ArraySize must not be 0.");
7676
7777 auto& UsedStages = ResourceShaderStages[Res.Name];
7878 if ((UsedStages & Res.ShaderStages) != 0)
8080 LOG_PRS_ERROR_AND_THROW("Multiple resources with name '", Res.Name,
8181 "' specify overlapping shader stages. There may be multiple resources with the same name in different shader stages, "
8282 "but the stages must not overlap.");
83 }
84 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED && UsedStages != SHADER_TYPE_UNKNOWN)
85 {
86 LOG_PRS_ERROR_AND_THROW("This device does not support separable programs, but there are separate resources with the name '",
87 Res.Name, "' in shader stages ",
88 GetShaderStagesString(Res.ShaderStages), " and ",
89 GetShaderStagesString(UsedStages),
90 ". When separable programs are not supported, every resource is always shared between all stages. "
91 "Use distinct resource names for each stage or define a single resource for all stages.");
8392 }
8493 UsedStages |= Res.ShaderStages;
8594
173182 {
174183 const auto& SamDesc = Desc.ImmutableSamplers[i];
175184 if (SamDesc.SamplerOrTextureName == nullptr)
176 LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null");
185 LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null.");
177186
178187 if (SamDesc.SamplerOrTextureName[0] == '\0')
179 LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty");
188 LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty.");
189
190 if (SamDesc.ShaderStages == SHADER_TYPE_UNKNOWN)
191 LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
180192
181193 auto& UsedStages = ImtblSamShaderStages[SamDesc.SamplerOrTextureName];
182194 if ((UsedStages & SamDesc.ShaderStages) != 0)
184196 LOG_PRS_ERROR_AND_THROW("Multiple immutable samplers with name '", SamDesc.SamplerOrTextureName,
185197 "' specify overlapping shader stages. There may be multiple immutable samplers with the same name in different shader stages, "
186198 "but the stages must not overlap.");
199 }
200 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED && UsedStages != SHADER_TYPE_UNKNOWN)
201 {
202 LOG_PRS_ERROR_AND_THROW("This device does not support separable programs, but there are separate immutable samplers with the name '",
203 SamDesc.SamplerOrTextureName, "' in shader stages ",
204 GetShaderStagesString(SamDesc.ShaderStages), " and ",
205 GetShaderStagesString(UsedStages),
206 ". When separable programs are not supported, every resource is always shared between all stages. "
207 "Use distinct immutable sampler names for each stage or define a single sampler for all stages.");
187208 }
188209 UsedStages |= SamDesc.ShaderStages;
189210 }
2929 #include <unordered_set>
3030 #include <unordered_map>
3131 #include <array>
32 #include <vector>
3332
3433 #include "HashUtils.hpp"
3534 #include "StringTools.hpp"
159158 }
160159
161160
162 void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInfo) noexcept(false)
161 void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInfo,
162 const DeviceFeatures& Features) noexcept(false)
163163 {
164164 const auto& PSODesc = CreateInfo.PSODesc;
165165
190190 }
191191
192192
193 std::unordered_map<HashMapStringKey, std::vector<std::pair<SHADER_TYPE, const IPipelineResourceSignature*>>, HashMapStringKey::Hasher> AllResources;
194 std::unordered_map<HashMapStringKey, std::vector<std::pair<SHADER_TYPE, const IPipelineResourceSignature*>>, HashMapStringKey::Hasher> AllImtblSamplers;
193 std::unordered_multimap<HashMapStringKey, std::pair<SHADER_TYPE, const IPipelineResourceSignature*>, HashMapStringKey::Hasher> AllResources;
194 std::unordered_multimap<HashMapStringKey, std::pair<SHADER_TYPE, const IPipelineResourceSignature*>, HashMapStringKey::Hasher> AllImtblSamplers;
195195
196196 std::array<const IPipelineResourceSignature*, MAX_RESOURCE_SIGNATURES> ppSignatures = {};
197197 for (Uint32 i = 0; i < CreateInfo.ResourceSignaturesCount; ++i)
215215 for (Uint32 res = 0; res < SignDesc.NumResources; ++res)
216216 {
217217 const auto& ResDesc = SignDesc.Resources[res];
218
219 auto& StageSignatures = AllResources[ResDesc.Name];
220 for (auto& StageSig : StageSignatures)
218 VERIFY(ResDesc.Name != nullptr && ResDesc.Name[0] != '\0', "Resource name can't be null or empty. This should've been caught by ValidatePipelineResourceSignatureDesc()");
219 VERIFY(ResDesc.ShaderStages != SHADER_TYPE_UNKNOWN, "Shader stages can't be UNKNOWN. This should've been caught by ValidatePipelineResourceSignatureDesc()");
220
221 auto range = AllResources.equal_range(ResDesc.Name);
222 for (auto it = range.first; it != range.second; ++it)
221223 {
224 const auto& StageSig = it->second;
222225 if ((StageSig.first & ResDesc.ShaderStages) != 0)
223226 {
224227 VERIFY(StageSig.second != pSignature, "Overlapping resources in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
227230 "' and '", StageSig.second->GetDesc().Name,
228231 "') in the same shader stage. Every shader resource in the PSO must be unambiguously defined by only one resource signature.");
229232 }
233
234 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
235 {
236 VERIFY_EXPR(StageSig.first != SHADER_TYPE_UNKNOWN);
237 VERIFY(StageSig.second != pSignature, "Resources with the same name in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
238
239 LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but shader resource '", ResDesc.Name, "' is found in more than one resource signature ('",
240 SignDesc.Name, "' and '", StageSig.second->GetDesc().Name,
241 "') in different stages. When separable programs are not supported, every resource is always shared between all stages. "
242 "Use distinct resource names for each stage or define a single resource for all stages.");
243 }
230244 }
231 StageSignatures.emplace_back(ResDesc.ShaderStages, pSignature);
245 AllResources.emplace(ResDesc.Name, std::make_pair(ResDesc.ShaderStages, pSignature));
232246 }
233247
234248 for (Uint32 res = 0; res < SignDesc.NumImmutableSamplers; ++res)
235249 {
236250 const auto& SamDesc = SignDesc.ImmutableSamplers[res];
237
238 auto& StageSignatures = AllImtblSamplers[SamDesc.SamplerOrTextureName];
239 for (auto& StageSig : StageSignatures)
251 VERIFY(SamDesc.SamplerOrTextureName != nullptr && SamDesc.SamplerOrTextureName[0] != '\0', "Sampler name can't be null or empty. This should've been caught by ValidatePipelineResourceSignatureDesc()");
252 VERIFY(SamDesc.ShaderStages != SHADER_TYPE_UNKNOWN, "Shader stage can't be UNKNOWN. This should've been caught by ValidatePipelineResourceSignatureDesc()");
253
254 auto range = AllImtblSamplers.equal_range(SamDesc.SamplerOrTextureName);
255 for (auto it = range.first; it != range.second; ++it)
240256 {
257 const auto& StageSig = it->second;
241258 if ((StageSig.first & SamDesc.ShaderStages) != 0)
242259 {
243260 VERIFY(StageSig.second != pSignature, "Overlapping immutable samplers in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
246263 "' and '", StageSig.second->GetDesc().Name,
247264 "') in the same stage. Every immutable sampler in the PSO must be unambiguously defined by only one resource signature.");
248265 }
266
267 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
268 {
269 VERIFY_EXPR(StageSig.first != SHADER_TYPE_UNKNOWN);
270 VERIFY(StageSig.second != pSignature, "Immutable samplers with the same name in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
271
272 LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but immutable sampler '", SamDesc.SamplerOrTextureName, "' is found in more than one resource signature ('",
273 SignDesc.Name, "' and '", StageSig.second->GetDesc().Name,
274 "') in different stages. When separable programs are not supported, every resource is always shared between all stages. "
275 "Use distinct resource names for each stage or define a single immutable sampler for all stages.");
276 }
249277 }
250 StageSignatures.emplace_back(SamDesc.ShaderStages, pSignature);
251 }
252 }
253 }
254
255 void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexcept(false)
278 AllImtblSamplers.emplace(SamDesc.SamplerOrTextureName, std::make_pair(SamDesc.ShaderStages, pSignature));
279 }
280 }
281 }
282
283 void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc, const DeviceFeatures& Features) noexcept(false)
256284 {
257285 const auto& Layout = PSODesc.ResourceLayout;
258286 {
260288 for (Uint32 i = 0; i < Layout.NumVariables; ++i)
261289 {
262290 const auto& Var = Layout.Variables[i];
291
292 if (Var.Name == nullptr)
293 LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].Name must not be null.");
294
295 if (Var.Name[0] == '\0')
296 LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].Name must not be empty.");
297
298 if (Var.ShaderStages == SHADER_TYPE_UNKNOWN)
299 LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
263300
264301 auto range = UniqueVariables.equal_range(Var.Name);
265302 for (auto it = range.first; it != range.second; ++it)
270307 " and ", GetShaderStagesString(it->second),
271308 "). Multiple variables with the same name are allowed, but shader stages they use must not overlap.");
272309 }
310 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
311 {
312 VERIFY_EXPR(it->second != SHADER_TYPE_UNKNOWN);
313 LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but there are separate resources with the name '",
314 Var.Name, "' in shader stages ",
315 GetShaderStagesString(Var.ShaderStages), " and ",
316 GetShaderStagesString(it->second),
317 ". When separable programs are not supported, every resource is always shared between all stages. "
318 "Use distinct resource names for each stage or define a single resource for all stages.");
319 }
273320 }
274321 UniqueVariables.emplace(Var.Name, Var.ShaderStages);
275322 }
279326 for (Uint32 i = 0; i < Layout.NumImmutableSamplers; ++i)
280327 {
281328 const auto& Sam = Layout.ImmutableSamplers[i];
329
330 if (Sam.SamplerOrTextureName == nullptr)
331 LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null.");
332
333 if (Sam.SamplerOrTextureName[0] == '\0')
334 LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty.");
335
336 if (Sam.ShaderStages == SHADER_TYPE_UNKNOWN)
337 LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
282338
283339 auto range = UniqueSamplers.equal_range(Sam.SamplerOrTextureName);
284340 for (auto it = range.first; it != range.second; ++it)
289345 " and ", GetShaderStagesString(it->second),
290346 "). Multiple immutable samplers with the same name are allowed, but shader stages they use must not overlap.");
291347 }
348 if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
349 {
350 VERIFY_EXPR(it->second != SHADER_TYPE_UNKNOWN);
351 LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but there are separate immutable samplers with the name '",
352 Sam.SamplerOrTextureName, "' in shader stages ",
353 GetShaderStagesString(Sam.ShaderStages), " and ",
354 GetShaderStagesString(it->second),
355 ". When separable programs are not supported, every resource is always shared between all stages. "
356 "Use distinct immutable sampler names for each stage or define a single sampler for all stages.");
357 }
292358 }
293359 UniqueSamplers.emplace(Sam.SamplerOrTextureName, Sam.ShaderStages);
294360 }
303369 LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(Shader->GetDesc().ShaderType), " is not a valid type for ", ShaderName, " shader"); \
304370 }
305371
306 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false)
372 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo,
373 const DeviceFeatures& Features) noexcept(false)
307374 {
308375 const auto& PSODesc = CreateInfo.PSODesc;
309376 if (PSODesc.PipelineType != PIPELINE_TYPE_GRAPHICS && PSODesc.PipelineType != PIPELINE_TYPE_MESH)
310377 LOG_PSO_ERROR_AND_THROW("Pipeline type must be GRAPHICS or MESH.");
311378
312 ValidatePipelineResourceSignatures(CreateInfo);
379 ValidatePipelineResourceSignatures(CreateInfo, Features);
313380
314381 const auto& GraphicsPipeline = CreateInfo.GraphicsPipeline;
315382
316383 ValidateBlendStateDesc(PSODesc, GraphicsPipeline);
317384 ValidateRasterizerStateDesc(PSODesc, GraphicsPipeline);
318385 ValidateDepthStencilDesc(PSODesc, GraphicsPipeline);
319 ValidatePipelineResourceLayoutDesc(PSODesc);
386 ValidatePipelineResourceLayoutDesc(PSODesc, Features);
320387
321388
322389 if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS)
383450 }
384451 }
385452
386 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false)
453 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo,
454 const DeviceFeatures& Features) noexcept(false)
387455 {
388456 const auto& PSODesc = CreateInfo.PSODesc;
389457 if (PSODesc.PipelineType != PIPELINE_TYPE_COMPUTE)
390458 LOG_PSO_ERROR_AND_THROW("Pipeline type must be COMPUTE.");
391459
392 ValidatePipelineResourceSignatures(CreateInfo);
393 ValidatePipelineResourceLayoutDesc(PSODesc);
460 ValidatePipelineResourceSignatures(CreateInfo, Features);
461 ValidatePipelineResourceLayoutDesc(PSODesc, Features);
394462
395463 if (CreateInfo.pCS == nullptr)
396464 LOG_PSO_ERROR_AND_THROW("Compute shader must not be null.");
398466 VALIDATE_SHADER_TYPE(CreateInfo.pCS, SHADER_TYPE_COMPUTE, "compute")
399467 }
400468
401 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, Uint32 MaxRecursion, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
469 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice,
470 Uint32 MaxRecursion,
471 const RayTracingPipelineStateCreateInfo& CreateInfo,
472 const DeviceFeatures& Features) noexcept(false)
402473 {
403474 const auto& PSODesc = CreateInfo.PSODesc;
404475 if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING)
405476 LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING.");
406477
407 ValidatePipelineResourceSignatures(CreateInfo);
408 ValidatePipelineResourceLayoutDesc(PSODesc);
478 ValidatePipelineResourceSignatures(CreateInfo, Features);
479 ValidatePipelineResourceLayoutDesc(PSODesc, Features);
409480
410481 if (pDevice->GetDeviceCaps().DevType == RENDER_DEVICE_TYPE_D3D12)
411482 {
5757 ResourceDesc.Width = Size;
5858
5959 auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, &ResourceDesc,
60 DefaultUsage, nullptr, __uuidof(m_pd3d12Buffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Buffer)));
60 DefaultUsage, nullptr, __uuidof(m_pd3d12Buffer),
61 reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Buffer)));
6162 if (FAILED(hr))
6263 {
6364 LOG_D3D_ERROR(hr, "Failed to create dynamic page");
6262 // clang-format on
6363 }
6464
65 void ValidateD3D12PipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc) noexcept(false)
65 void ValidatePipelineResourceSignatureDescD3D12(const PipelineResourceSignatureDesc& Desc) noexcept(false)
6666 {
6767 {
6868 std::unordered_multimap<HashMapStringKey, SHADER_TYPE, HashMapStringKey::Hasher> ResNameToShaderStages;
112112 else
113113 {
114114 LOG_ERROR_AND_THROW("Pipeline resource signature '", (Desc.Name != nullptr ? Desc.Name : ""),
115 "' defines immutable sampler with the name '", Name, "' in shader stages ",
115 "' defines separate immutable samplers with the name '", Name, "' in shader stages ",
116116 GetShaderStagesString(multi_stage_it->second), " and ",
117117 GetShaderStagesString(it->second),
118118 ". In Direct3D12 backend, only one immutable sampler in the group of samplers with the same name can be shared between more than "
134134 TPipelineResourceSignatureBase{pRefCounters, pDevice, Desc, bIsDeviceInternal},
135135 m_SRBMemAllocator{GetRawAllocator()}
136136 {
137 ValidateD3D12PipelineResourceSignatureDesc(Desc);
138
139137 try
140138 {
139 ValidatePipelineResourceSignatureDescD3D12(Desc);
140
141141 auto& RawAllocator{GetRawAllocator()};
142142 auto MemPool = ReserveSpace(RawAllocator, Desc,
143143 [&Desc](FixedLinearAllocator& MemPool) //
228228 CComPtr<ID3D12Resource> UploadBuffer;
229229 hr = pd3d12Device->CreateCommittedResource(&UploadHeapProps, D3D12_HEAP_FLAG_NONE,
230230 &BufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
231 nullptr, __uuidof(UploadBuffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer)));
231 nullptr, __uuidof(UploadBuffer),
232 reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer)));
232233 if (FAILED(hr))
233234 LOG_ERROR_AND_THROW("Failed to create committed resource in an upload heap");
234235
332333 // on some ARM systems, to marshal data between the CPU and GPU through memory addresses with write-back behavior.
333334 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12resource-map
334335 auto hr = pd3d12Device->CreateCommittedResource(&StaginHeapProps, D3D12_HEAP_FLAG_NONE, &BufferDesc, D3D12State,
335 nullptr, __uuidof(m_pd3d12Resource), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
336 nullptr, __uuidof(m_pd3d12Resource),
337 reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
336338 if (FAILED(hr))
337339 LOG_ERROR_AND_THROW("Failed to create staging buffer");
338340
189189 #endif
190190
191191 private:
192 PipelineResourceSignatureGLImpl(IReferenceCounters* pRefCounters,
193 RenderDeviceGLImpl* pDevice,
194 const PipelineResourceSignatureDesc& Desc,
195 bool bIsDeviceInternal,
196 int Internal);
197
198192 // Copies static resources from the static resource cache to the destination cache
199193 void CopyStaticResources(ShaderResourceCacheGL& ResourceCache) const;
200194
3232
3333 namespace Diligent
3434 {
35
3536 namespace
3637 {
3738
4445 lhs.ImtblSamplerAssigned == rhs.ImtblSamplerAssigned;
4546 // clang-format on
4647 }
47
48 struct PatchedPipelineResourceSignatureDesc : PipelineResourceSignatureDesc
49 {
50 std::vector<ImmutableSamplerDesc> m_ImmutableSamplers;
51
52 PatchedPipelineResourceSignatureDesc(RenderDeviceGLImpl* pDeviceGL, const PipelineResourceSignatureDesc& Desc) :
53 PipelineResourceSignatureDesc{Desc}
54 {
55 if (NumImmutableSamplers > 0 && ImmutableSamplers != nullptr && !pDeviceGL->GetDeviceCaps().Features.SeparablePrograms)
56 {
57 m_ImmutableSamplers.resize(NumImmutableSamplers);
58
59 SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
60 for (Uint32 r = 0; r < NumResources; ++r)
61 ActiveStages |= Resources[r].ShaderStages;
62
63 for (Uint32 s = 0; s < NumImmutableSamplers; ++s)
64 {
65 m_ImmutableSamplers[s] = ImmutableSamplers[s];
66 m_ImmutableSamplers[s].ShaderStages |= ActiveStages;
67 }
68
69 ImmutableSamplers = m_ImmutableSamplers.data();
70 }
71 }
72 };
7348
7449 } // namespace
7550
11691 RenderDeviceGLImpl* pDeviceGL,
11792 const PipelineResourceSignatureDesc& Desc,
11893 bool bIsDeviceInternal) :
119 PipelineResourceSignatureGLImpl{pRefCounters, pDeviceGL, PatchedPipelineResourceSignatureDesc{pDeviceGL, Desc}, bIsDeviceInternal, 0}
120 {}
121
122 PipelineResourceSignatureGLImpl::PipelineResourceSignatureGLImpl(IReferenceCounters* pRefCounters,
123 RenderDeviceGLImpl* pDeviceGL,
124 const PipelineResourceSignatureDesc& Desc,
125 bool bIsDeviceInternal,
126 int) :
12794 TPipelineResourceSignatureBase{pRefCounters, pDeviceGL, Desc, bIsDeviceInternal},
12895 m_SRBMemAllocator{GetRawAllocator()}
12996 {
4747 {
4848 std::vector<PipelineResourceDesc> Resources;
4949
50 const auto& LayoutDesc = CreateInfo.PSODesc.ResourceLayout;
51 const auto DefaultVarType = LayoutDesc.DefaultVariableType;
52 ShaderResourcesGL ProgramResources;
50 const auto& LayoutDesc = CreateInfo.PSODesc.ResourceLayout;
51 const auto DefaultVarType = LayoutDesc.DefaultVariableType;
5352
5453 struct UniqueResource
5554 {
8281 ResDesc.VarType = DefaultVarType;
8382 ResDesc.Flags = Flags;
8483
85 if (m_IsProgramPipelineSupported)
86 {
87 const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, ResDesc.ShaderStages, nullptr);
88 if (VarIndex != InvalidPipelineResourceLayoutVariableIndex)
89 {
90 const auto& Var = LayoutDesc.Variables[VarIndex];
91 ResDesc.ShaderStages = Var.ShaderStages;
92 ResDesc.VarType = Var.Type;
93 }
94
95 auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ResDesc.ShaderStages});
96 if (IterAndAssigned.second)
97 {
98 Resources.push_back(ResDesc);
99 }
100 else
101 {
102 DEV_CHECK_ERR(IterAndAssigned.first->Attribs.ResourceType == Attribs.ResourceType,
103 "Shader variable '", Attribs.Name,
104 "' exists in multiple shaders from the same shader stage, but its type is not consistent between "
105 "shaders. All variables with the same name from the same shader stage must have the same type.");
106 }
84 const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, ResDesc.ShaderStages, nullptr);
85 if (VarIndex != InvalidPipelineResourceLayoutVariableIndex)
86 {
87 const auto& Var = LayoutDesc.Variables[VarIndex];
88 ResDesc.ShaderStages = Var.ShaderStages;
89 ResDesc.VarType = Var.Type;
90 }
91
92 auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ResDesc.ShaderStages});
93 if (IterAndAssigned.second)
94 {
95 Resources.push_back(ResDesc);
10796 }
10897 else
10998 {
110 for (Uint32 i = 0; i < LayoutDesc.NumVariables; ++i)
111 {
112 const auto& Var = LayoutDesc.Variables[i];
113 if ((Var.ShaderStages & Attribs.ShaderStages) != 0 &&
114 std::strcmp(Attribs.Name, Var.Name) == 0)
115 {
116 ResDesc.VarType = Var.Type;
117 break;
118 }
119 }
120 Resources.push_back(ResDesc);
99 DEV_CHECK_ERR(IterAndAssigned.first->Attribs.ResourceType == Attribs.ResourceType,
100 "Shader variable '", Attribs.Name,
101 "' exists in multiple shaders from the same shader stage, but its type is not consistent between "
102 "shaders. All variables with the same name from the same shader stage must have the same type.");
121103 }
122104 };
123105 const auto HandleUB = [&](const ShaderResourcesGL::UniformBufferInfo& Attribs) {
133115 HandleResource(Attribs, PIPELINE_RESOURCE_FLAG_UNKNOWN);
134116 };
135117
118 ShaderResourcesGL ProgramResources;
136119 if (m_IsProgramPipelineSupported)
137120 {
138121 for (size_t i = 0; i < ShaderStages.size(); ++i)
324307 ShaderCI.Source = "void main(){}";
325308 ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
326309 ShaderCI.Desc.Name = "Dummy fragment shader";
327 pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS)));
310 pDeviceGL->CreateShader(ShaderCI, pTempPS.DblPtr<IShader>());
328311
329312 Shaders.emplace_back(pTempPS);
330313 }
120120 TestCreatePRSFailure(PRSDesc, "Desc.Resources[1].Name must not be empty");
121121 }
122122
123 TEST(PRSCreationFailureTest, UnknownShaderStages)
124 {
125 PipelineResourceSignatureDesc PRSDesc;
126 PRSDesc.Name = "Unknown ShaderStages";
123 TEST(PRSCreationFailureTest, UnknownResourceShaderStages)
124 {
125 PipelineResourceSignatureDesc PRSDesc;
126 PRSDesc.Name = "Unknown resource ShaderStages";
127127 PipelineResourceDesc Resources[]{
128128 {SHADER_TYPE_PIXEL, "g_Buffer", 1, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
129129 {SHADER_TYPE_UNKNOWN, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
342342 {SHADER_TYPE_PIXEL | SHADER_TYPE_HULL, "g_ImmutableSampler", SamplerDesc{}}};
343343 PRSDesc.ImmutableSamplers = ImmutableSamplers;
344344 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
345 TestCreatePRSFailure(PRSDesc, "ultiple immutable samplers with name 'g_ImmutableSampler' specify overlapping shader stages.");
345 TestCreatePRSFailure(PRSDesc, "Multiple immutable samplers with name 'g_ImmutableSampler' specify overlapping shader stages.");
346 }
347
348 TEST(PRSCreationFailureTest, UnknownImmutableSamplerShareStages)
349 {
350 PipelineResourceSignatureDesc PRSDesc;
351 PRSDesc.Name = "Unknown Immutable Sampler ShaderStages";
352 ImmutableSamplerDesc ImmutableSamplers[]{
353 {SHADER_TYPE_PIXEL, "g_ImmutableSampler", SamplerDesc{}},
354 {SHADER_TYPE_UNKNOWN, "g_ImmutableSampler2", SamplerDesc{}}};
355 PRSDesc.ImmutableSamplers = ImmutableSamplers;
356 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
357 TestCreatePRSFailure(PRSDesc, "Desc.ImmutableSamplers[1].ShaderStages must not be SHADER_TYPE_UNKNOWN");
358 }
359
360
361
362 TEST(PRSCreationFailureTest, NonSeparableProgs_ResourceStages)
363 {
364 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
365 {
366 GTEST_SKIP() << "This test is specific for non-separable programs";
367 }
368
369 PipelineResourceSignatureDesc PRSDesc;
370 PRSDesc.Name = "Non-separable progs - resource stages";
371 PipelineResourceDesc Resources[]{
372 {SHADER_TYPE_VERTEX, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
373 {SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
374 PRSDesc.Resources = Resources;
375 PRSDesc.NumResources = _countof(Resources);
376 TestCreatePRSFailure(PRSDesc, "there are separate resources with the name 'g_Texture' in shader stages SHADER_TYPE_PIXEL and SHADER_TYPE_VERTEX");
377 }
378
379 TEST(PRSCreationFailureTest, NonSeparableProgs_ImtblSamplerStages)
380 {
381 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
382 {
383 GTEST_SKIP() << "This test is specific for non-separable programs";
384 }
385
386 PipelineResourceSignatureDesc PRSDesc;
387 PRSDesc.Name = "Non-separable progs - immutable sampler stages";
388 PipelineResourceDesc Resources[]{
389 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
390 PRSDesc.Resources = Resources;
391 PRSDesc.NumResources = _countof(Resources);
392
393 ImmutableSamplerDesc ImmutableSamplers[]{
394 {SHADER_TYPE_VERTEX, "g_Texture", SamplerDesc{}},
395 {SHADER_TYPE_PIXEL, "g_Texture", SamplerDesc{}}};
396 PRSDesc.ImmutableSamplers = ImmutableSamplers;
397 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
398 TestCreatePRSFailure(PRSDesc, "there are separate immutable samplers with the name 'g_Texture' in shader stages SHADER_TYPE_PIXEL and SHADER_TYPE_VERTEX");
399 }
400
401
402 TEST(PRSCreationFailureTest, D3D12_MultiStageResources)
403 {
404 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().DevType != RENDER_DEVICE_TYPE_D3D12)
405 {
406 GTEST_SKIP() << "This test is specific for Direct3D12";
407 }
408
409 PipelineResourceSignatureDesc PRSDesc;
410 PRSDesc.Name = "D3D12 - multi stage resources";
411 PipelineResourceDesc Resources[]{
412 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
413 {SHADER_TYPE_HULL | SHADER_TYPE_DOMAIN, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
414 PRSDesc.Resources = Resources;
415 PRSDesc.NumResources = _countof(Resources);
416 TestCreatePRSFailure(PRSDesc, "separate resources with the name 'g_Texture' in shader stages SHADER_TYPE_VERTEX, SHADER_TYPE_PIXEL and SHADER_TYPE_HULL, SHADER_TYPE_DOMAIN");
417 }
418
419 TEST(PRSCreationFailureTest, D3D12_MultiStageImtblSamplers)
420 {
421 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().DevType != RENDER_DEVICE_TYPE_D3D12)
422 {
423 GTEST_SKIP() << "This test is specific for Direct3D12";
424 }
425
426 PipelineResourceSignatureDesc PRSDesc;
427 PRSDesc.Name = "D3D12 - multi stage immutable samplers";
428 PipelineResourceDesc Resources[]{
429 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", 1, SHADER_RESOURCE_TYPE_TEXTURE_SRV, SHADER_RESOURCE_VARIABLE_TYPE_STATIC}};
430 PRSDesc.Resources = Resources;
431 PRSDesc.NumResources = _countof(Resources);
432
433 ImmutableSamplerDesc ImmutableSamplers[]{
434 {SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture_sampler", SamplerDesc{}},
435 {SHADER_TYPE_HULL | SHADER_TYPE_DOMAIN, "g_Texture_sampler", SamplerDesc{}}};
436 PRSDesc.ImmutableSamplers = ImmutableSamplers;
437 PRSDesc.NumImmutableSamplers = _countof(ImmutableSamplers);
438
439 TestCreatePRSFailure(PRSDesc, "separate immutable samplers with the name 'g_Texture_sampler' in shader stages SHADER_TYPE_VERTEX, SHADER_TYPE_PIXEL and SHADER_TYPE_HULL, SHADER_TYPE_DOMAIN");
346440 }
347441
348442 } // namespace
772772 TestCreatePSOFailure(PsoCI, "BlendDesc.RenderTargets[0].BlendOpAlpha must not be BLEND_OPERATION_UNDEFINED");
773773 }
774774
775 TEST_F(PSOCreationFailureTest, NullVariableName)
776 {
777 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - null variable name")};
778
779 ShaderResourceVariableDesc Variables[] //
780 {
781 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
782 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, nullptr, SHADER_RESOURCE_VARIABLE_TYPE_STATIC} //
783 };
784 PsoCI.PSODesc.ResourceLayout.Variables = Variables;
785 PsoCI.PSODesc.ResourceLayout.NumVariables = _countof(Variables);
786 TestCreatePSOFailure(PsoCI, "ResourceLayout.Variables[1].Name must not be null");
787 }
788
789 TEST_F(PSOCreationFailureTest, EmptyVariableName)
790 {
791 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - empty variable name")};
792
793 ShaderResourceVariableDesc Variables[] //
794 {
795 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
796 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "", SHADER_RESOURCE_VARIABLE_TYPE_STATIC} //
797 };
798 PsoCI.PSODesc.ResourceLayout.Variables = Variables;
799 PsoCI.PSODesc.ResourceLayout.NumVariables = _countof(Variables);
800 TestCreatePSOFailure(PsoCI, "ResourceLayout.Variables[1].Name must not be empty");
801 }
802
803 TEST_F(PSOCreationFailureTest, UnknownVariableShaderStage)
804 {
805 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - unknown variable shader stage")};
806
807 ShaderResourceVariableDesc Variables[] //
808 {
809 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
810 ShaderResourceVariableDesc{SHADER_TYPE_UNKNOWN, "g_Texture2", SHADER_RESOURCE_VARIABLE_TYPE_STATIC} //
811 };
812 PsoCI.PSODesc.ResourceLayout.Variables = Variables;
813 PsoCI.PSODesc.ResourceLayout.NumVariables = _countof(Variables);
814 TestCreatePSOFailure(PsoCI, "ResourceLayout.Variables[1].ShaderStages must not be SHADER_TYPE_UNKNOWN");
815 }
816
817
775818 TEST_F(PSOCreationFailureTest, OverlappingVariableStages)
776819 {
777820 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - Overlapping Variable Stages")};
786829 TestCreatePSOFailure(PsoCI, "'g_Texture' is defined in overlapping shader stages (SHADER_TYPE_VERTEX, SHADER_TYPE_GEOMETRY and SHADER_TYPE_VERTEX, SHADER_TYPE_PIXEL)");
787830 }
788831
832
833 TEST_F(PSOCreationFailureTest, NullImmutableSamplerName)
834 {
835 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - null immutable sampler name")};
836
837 ImmutableSamplerDesc ImtblSamplers[] //
838 {
839 ImmutableSamplerDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture_sampler", SamplerDesc{}},
840 ImmutableSamplerDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, nullptr, SamplerDesc{}} //
841 };
842 PsoCI.PSODesc.ResourceLayout.ImmutableSamplers = ImtblSamplers;
843 PsoCI.PSODesc.ResourceLayout.NumImmutableSamplers = _countof(ImtblSamplers);
844 TestCreatePSOFailure(PsoCI, "ResourceLayout.ImmutableSamplers[1].SamplerOrTextureName must not be null");
845 }
846
847 TEST_F(PSOCreationFailureTest, EmptyImmutableSamplerName)
848 {
849 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - empty immutable sampler name")};
850
851 ImmutableSamplerDesc ImtblSamplers[] //
852 {
853 ImmutableSamplerDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture_sampler", SamplerDesc{}},
854 ImmutableSamplerDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "", SamplerDesc{}} //
855 };
856 PsoCI.PSODesc.ResourceLayout.ImmutableSamplers = ImtblSamplers;
857 PsoCI.PSODesc.ResourceLayout.NumImmutableSamplers = _countof(ImtblSamplers);
858 TestCreatePSOFailure(PsoCI, "ResourceLayout.ImmutableSamplers[1].SamplerOrTextureName must not be empty");
859 }
860
861 TEST_F(PSOCreationFailureTest, UndefinedImmutableSamplerShaderStages)
862 {
863 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - undefined immutable sampler shader stages")};
864
865 ImmutableSamplerDesc ImtblSamplers[] //
866 {
867 ImmutableSamplerDesc{SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, "g_Texture_sampler", SamplerDesc{}},
868 ImmutableSamplerDesc{SHADER_TYPE_UNKNOWN, "g_Texture_sampler2", SamplerDesc{}} //
869 };
870 PsoCI.PSODesc.ResourceLayout.ImmutableSamplers = ImtblSamplers;
871 PsoCI.PSODesc.ResourceLayout.NumImmutableSamplers = _countof(ImtblSamplers);
872 TestCreatePSOFailure(PsoCI, "ResourceLayout.ImmutableSamplers[1].ShaderStages must not be SHADER_TYPE_UNKNOWN");
873 }
874
789875 TEST_F(PSOCreationFailureTest, OverlappingImmutableSamplerStages)
790876 {
791877 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - Overlapping Immutable Sampler Stages")};
905991 IPipelineResourceSignature* pSignatures[] = {sm_pSignature0, sm_pSignature1A};
906992 PsoCI.ppResourceSignatures = pSignatures;
907993 PsoCI.ResourceSignaturesCount = _countof(pSignatures);
908 TestCreatePSOFailure(PsoCI, "Immutable sampler 'g_Texture_sampler' is found in more than one resource signature ('PRS1A' and 'PRS0')");
994
995 // In case of non-separable programs, there is another error - a resource ("g_Texture") is found in different signatures
996 const auto* ExpectedError = TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.SeparablePrograms ?
997 "Immutable sampler 'g_Texture_sampler' is found in more than one resource signature ('PRS1A' and 'PRS0')" :
998 "shader resource 'g_Texture' is found in more than one resource signature ('PRS1A' and 'PRS0')";
999 TestCreatePSOFailure(PsoCI, ExpectedError);
9091000 }
9101001
9111002 TEST_F(PSOCreationFailureTest, InvalidComputePipelineType)
11941285
11951286 PsoCI.pPS = GetTexturePS();
11961287
1197 TestCreatePSOFailure(PsoCI, "Shader 'TexturePS (PSOCreationFailureTest)' contains resource 'g_Texture' that is not present in any pipeline resource signature");
1288 std::string ExpectedErrorString = "contains resource 'g_Texture' that is not present in any pipeline resource signature";
1289 if (pDevice->GetDeviceCaps().Features.SeparablePrograms)
1290 ExpectedErrorString = std::string{"Shader 'TexturePS (PSOCreationFailureTest)' "} + ExpectedErrorString;
1291 // In non-separable programs case, PSO name is used instead of the shader name
1292
1293 TestCreatePSOFailure(PsoCI, ExpectedErrorString.c_str());
11981294 }
11991295
12001296 TEST_F(PSOCreationFailureTest, InvalidResourceType)
12211317
12221318 PsoCI.pPS = GetTexturePS();
12231319
1224 TestCreatePSOFailure(PsoCI, "Shader 'TexturePS (PSOCreationFailureTest)' contains resource with name 'g_Texture' and type 'texture SRV' that is not compatible with type 'buffer SRV'");
1320 std::string ExpectedErrorString = "contains resource with name 'g_Texture' and type 'texture SRV' that is not compatible with type 'buffer SRV'";
1321 if (pDevice->GetDeviceCaps().Features.SeparablePrograms)
1322 ExpectedErrorString = std::string{"Shader 'TexturePS (PSOCreationFailureTest)' "} + ExpectedErrorString;
1323 // In non-separable programs case, PSO name is used of the shader name
1324
1325 TestCreatePSOFailure(PsoCI, ExpectedErrorString.c_str());
12251326 }
12261327
12271328 TEST_F(PSOCreationFailureTest, InvalidArraySize)
12681369
12691370 PsoCI.pPS = pPS;
12701371
1271 TestCreatePSOFailure(PsoCI, "Shader 'Invalid Array Size (PSOCreationFailureTest)' contains resource 'g_Texture' whose array size (3) is greater than the array size (2)");
1372 std::string ExpectedErrorString = "contains resource 'g_Texture' whose array size (3) is greater than the array size (2)";
1373 if (pDevice->GetDeviceCaps().Features.SeparablePrograms)
1374 ExpectedErrorString = std::string{"Shader 'Invalid Array Size (PSOCreationFailureTest)' "} + ExpectedErrorString;
1375 // In non-separable programs case, PSO name is used
1376
1377 TestCreatePSOFailure(PsoCI, ExpectedErrorString.c_str());
12721378 }
12731379
12741380
13351441 "but in the resource signature 'PSO Create Failure - Invalid Run-Time Array' the resource is defined without the PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY flag.");
13361442 }
13371443
1444 TEST_F(PSOCreationFailureTest, NonSeparablePrograms_SeparateResources)
1445 {
1446 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
1447 {
1448 GTEST_SKIP();
1449 }
1450
1451 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - Non Separable Programs - Separate Resources")};
1452
1453 ShaderResourceVariableDesc Variables[] //
1454 {
1455 ShaderResourceVariableDesc{SHADER_TYPE_VERTEX, "g_Texture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
1456 ShaderResourceVariableDesc{SHADER_TYPE_PIXEL, "g_Texture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC} //
1457 };
1458 PsoCI.PSODesc.ResourceLayout.Variables = Variables;
1459 PsoCI.PSODesc.ResourceLayout.NumVariables = _countof(Variables);
1460 TestCreatePSOFailure(PsoCI, "there are separate resources with the name 'g_Texture' in shader stages SHADER_TYPE_PIXEL and SHADER_TYPE_VERTEX");
1461 }
1462
1463 TEST_F(PSOCreationFailureTest, NonSeparablePrograms_SeparateImmutableSamplers)
1464 {
1465 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
1466 {
1467 GTEST_SKIP();
1468 }
1469
1470 auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - Non Separable Programs - Separate Immutable Samplers")};
1471
1472 ImmutableSamplerDesc ImtblSamplers[] //
1473 {
1474 ImmutableSamplerDesc{SHADER_TYPE_VERTEX, "g_Texture_sampler", SamplerDesc{}},
1475 ImmutableSamplerDesc{SHADER_TYPE_PIXEL, "g_Texture_sampler", SamplerDesc{}} //
1476 };
1477 PsoCI.PSODesc.ResourceLayout.ImmutableSamplers = ImtblSamplers;
1478 PsoCI.PSODesc.ResourceLayout.NumImmutableSamplers = _countof(ImtblSamplers);
1479
1480 TestCreatePSOFailure(PsoCI, "there are separate immutable samplers with the name 'g_Texture_sampler' in shader stages SHADER_TYPE_PIXEL and SHADER_TYPE_VERTEX");
1481 }
1482
1483
13381484 } // namespace