git.s-ol.nu ~forks/DiligentCore / 8e02181
Added support for local root signature & shader record. Bug fix for ray tracing. azhirnov 10 months ago
37 changed file(s) with 395 addition(s) and 402 deletion(s). Raw diff Collapse all Expand all
288288 m_ReservedSize = 0;
289289 m_CurrAlignment = 0;
290290 m_pAllocator = nullptr;
291
292 #if DILIGENT_DEBUG
293 m_DbgCurrAllocation = 0;
294 m_DbgAllocations.clear();
295 #endif
291296 }
292297
293298 uint8_t* m_pDataStart = nullptr;
165165
166166 bool ValidateContent() const
167167 {
168 // AZ TODO
168169 return true;
169170 }
170171 #endif // DILIGENT_DEVELOPMENT
278278 // clang-format on
279279 #endif
280280
281 bool BuildBLAS(const BLASBuildAttribs& Attribs, int) const;
282 bool BuildTLAS(const TLASBuildAttribs& Attribs, int) const;
281 bool BuildBLAS(const BuildBLASAttribs& Attribs, int) const;
282 bool BuildTLAS(const BuildTLASAttribs& Attribs, int) const;
283283 bool CopyBLAS(const CopyBLASAttribs& Attribs, int) const;
284284 bool CopyTLAS(const CopyTLASAttribs& Attribs, int) const;
285285 bool WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs, int) const;
19691969 #endif // DILIGENT_DEVELOPMENT
19701970
19711971 template <typename BaseInterface, typename ImplementationTraits>
1972 bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BLASBuildAttribs& Attribs, int) const
1972 bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildBLAS(const BuildBLASAttribs& Attribs, int) const
19731973 {
19741974 if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
19751975 {
22102210 }
22112211
22122212 template <typename BaseInterface, typename ImplementationTraits>
2213 bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const TLASBuildAttribs& Attribs, int) const
2213 bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const BuildTLASAttribs& Attribs, int) const
22142214 {
22152215 if (m_pDevice->GetDeviceCaps().Features.RayTracing != DEVICE_FEATURE_STATE_ENABLED)
22162216 {
22862286 if (Attribs.pInstances[i].pBLAS == nullptr)
22872287 {
22882288 LOG_ERROR_MESSAGE("IDeviceContext::BuildTLAS: pInstances[", i, "].pBLAS must not be null");
2289 return false;
2290 }
2291
2292 if (!ValidatedCast<BottomLevelASType>(Attribs.pInstances[i].pBLAS)->ValidateContent())
2293 {
2294 LOG_ERROR_MESSAGE("IDeviceContext::BuildTLAS: pInstances[", i, "].pBLAS is not valid");
22892295 return false;
22902296 }
22912297
4545
4646 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false);
4747 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false);
48 void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false);
48 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false);
4949
5050 void CorrectGraphicsPipelineDesc(GraphicsPipelineDesc& GraphicsPipeline) noexcept;
5151
121121 bool bIsDeviceInternal = false) :
122122 PipelineStateBase{pRefCounters, pDevice, RayTracingPipelineCI.PSODesc, bIsDeviceInternal}
123123 {
124 ValidateRayTracingPipelineCreateInfo(RayTracingPipelineCI);
124 ValidateRayTracingPipelineCreateInfo(pDevice, RayTracingPipelineCI);
125125 }
126126
127127
343343 void ReserveSpaceForPipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo,
344344 LinearAllocator& MemPool) const noexcept
345345 {
346 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
347 {
348 MemPool.AddSpaceForString(CreateInfo.pGeneralShaders[i].Name);
349 }
350 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
351 {
352 MemPool.AddSpaceForString(CreateInfo.pTriangleHitShaders[i].Name);
353 }
354 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
355 {
356 MemPool.AddSpaceForString(CreateInfo.pProceduralHitShaders[i].Name);
357 }
358
346359 ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
347
348 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
349 {
350 MemPool.AddSpaceForString(CreateInfo.pGeneralShaders[i].Name);
351 }
352 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
353 {
354 MemPool.AddSpaceForString(CreateInfo.pTriangleHitShaders[i].Name);
355 }
356 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
357 {
358 MemPool.AddSpaceForString(CreateInfo.pProceduralHitShaders[i].Name);
359 }
360360
361361 size_t RTDataSize = sizeof(RayTracingPipelineData);
362362 // reserve size for shader handles
280280 BindingTable& HitShaderBindingTable,
281281 BindingTable& CallableShaderBindingTable)
282282 {
283 const auto ShaderGroupBaseAlignment = GetDevice()->GetShaderGroupBaseAlignment();
283 const auto ShaderGroupBaseAlignment = this->m_pDevice->GetShaderGroupBaseAlignment();
284284
285285 const auto AlignToLarger = [ShaderGroupBaseAlignment](size_t offset) -> Uint32 {
286286 return Align(static_cast<Uint32>(offset), ShaderGroupBaseAlignment);
297297 {
298298 this->m_pBuffer = nullptr;
299299
300 String BuffName = String{GetDesc().Name} + " - internal buffer";
300 String BuffName = String{this->m_Desc.Name} + " - internal buffer";
301301 BufferDesc BuffDesc;
302302 BuffDesc.Name = BuffName.c_str();
303303 BuffDesc.Usage = USAGE_DEFAULT;
304304 BuffDesc.BindFlags = BIND_RAY_TRACING;
305305 BuffDesc.uiSizeInBytes = BufSize;
306306
307 GetDevice()->CreateBuffer(BuffDesc, nullptr, &this->m_pBuffer);
307 this->m_pDevice->CreateBuffer(BuffDesc, nullptr, &this->m_pBuffer);
308308 VERIFY_EXPR(this->m_pBuffer != nullptr);
309309 }
310310
398398 Uint32 m_ShaderRecordStride = 0;
399399 bool m_Changed = true;
400400
401 static const Uint8 EmptyElem = 0xA7;
401 static const Uint8 EmptyElem;
402402 };
403403
404 template <class BaseInterface, class PipelineStateImplType, class RenderDeviceImplType>
405 const Uint8 ShaderBindingTableBase<BaseInterface, PipelineStateImplType, RenderDeviceImplType>::EmptyElem = 0xA7;
406
404407 } // namespace Diligent
3232 #include <unordered_map>
3333
3434 #include "TopLevelAS.h"
35 #include "BottomLevelAS.h"
3635 #include "DeviceObjectBase.hpp"
3736 #include "RenderDeviceBase.hpp"
3837 #include "StringPool.hpp"
157156 if (iter != this->m_Instances.end())
158157 {
159158 Result.ContributionToHitGroupIndex = iter->second.ContributionToHitGroupIndex;
160 Result.pBLAS = iter->second.pBLAS.RawPtr<IBottomLevelAS>();
159 Result.pBLAS = iter->second.pBLAS.template RawPtr<IBottomLevelAS>();
161160 }
162161 else
163162 {
198197
199198 if (m_Instances.empty())
200199 {
201 LOG_ERROR_MESSAGE("TLAS with name ('", GetDesc().Name, "') doesn't have instances, use IDeviceContext::BuildTLAS() or IDeviceContext::CopyTLAS() to initialize TLAS content");
200 LOG_ERROR_MESSAGE("TLAS with name ('", this->m_Desc.Name, "') doesn't have instances, use IDeviceContext::BuildTLAS() or IDeviceContext::CopyTLAS() to initialize TLAS content");
202201 result = false;
203202 }
204203
875875
876876
877877 /// This structure is used by IDeviceContext::BuildBLAS().
878 struct BLASBuildAttribs
878 struct BuildBLASAttribs
879879 {
880880 /// Target bottom-level AS.
881881 IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
912912 RESOURCE_STATE_TRANSITION_MODE ScratchBufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
913913
914914 #if DILIGENT_CPP_INTERFACE
915 BLASBuildAttribs() noexcept {}
916 #endif
917 };
918 typedef struct BLASBuildAttribs BLASBuildAttribs;
915 BuildBLASAttribs() noexcept {}
916 #endif
917 };
918 typedef struct BuildBLASAttribs BuildBLASAttribs;
919919
920920
921921 /// Can be used in TLASBuildInstanceData::ContributionToHitGroupIndex to calculate index
972972 typedef struct InstanceMatrix InstanceMatrix;
973973
974974
975 /// This structure is used by TLASBuildAttribs.
975 /// This structure is used by BuildTLASAttribs.
976976 struct TLASBuildInstanceData
977977 {
978978 /// Instance name that used to map instance to hit group in shader binding table.
10081008
10091009
10101010 /// Instance size in GPU side.
1011 /// Used to calculate size of TLASBuildAttribs::pInstanceBuffer.
1011 /// Used to calculate size of BuildTLASAttribs::pInstanceBuffer.
10121012 static const Uint32 TLAS_INSTANCE_DATA_SIZE = 64;
10131013
10141014
10151015 /// This structure is used by IDeviceContext::BuildTLAS().
1016 struct TLASBuildAttribs
1016 struct BuildTLASAttribs
10171017 {
10181018 /// Target top-level AS.
10191019 ITopLevelAS* pTLAS DEFAULT_INITIALIZER(nullptr);
10571057 RESOURCE_STATE_TRANSITION_MODE ScratchBufferTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE);
10581058
10591059 #if DILIGENT_CPP_INTERFACE
1060 TLASBuildAttribs() noexcept {}
1061 #endif
1062 };
1063 typedef struct TLASBuildAttribs TLASBuildAttribs;
1060 BuildTLASAttribs() noexcept {}
1061 #endif
1062 };
1063 typedef struct BuildTLASAttribs BuildTLASAttribs;
10641064
10651065
10661066 /// This structure is used by IDeviceContext::CopyBLAS().
20842084
20852085 /// Build Bottom-level acceleration structure with the specified geometries.
20862086
2087 /// \param [in] Attribs - Structure describing build BLAS command attributes, see Diligent::BLASBuildAttribs for details.
2087 /// \param [in] Attribs - Structure describing build BLAS command attributes, see Diligent::BuildBLASAttribs for details.
20882088 VIRTUAL void METHOD(BuildBLAS)(THIS_
2089 const BLASBuildAttribs REF Attribs) PURE;
2089 const BuildBLASAttribs REF Attribs) PURE;
20902090
20912091
20922092 /// Build Top-level acceleration structure with the specified instances.
20932093
2094 /// \param [in] Attribs - Structure describing build TLAS command attributes, see Diligent::TLASBuildAttribs for details.
2094 /// \param [in] Attribs - Structure describing build TLAS command attributes, see Diligent::BuildTLASAttribs for details.
20952095 VIRTUAL void METHOD(BuildTLAS)(THIS_
2096 const TLASBuildAttribs REF Attribs) PURE;
2096 const BuildTLASAttribs REF Attribs) PURE;
20972097
20982098
20992099 /// Copies data from one acceleration structure to another.
471471
472472 /// Direct3D12 only: set name of constant buffer that will be used by local root signature.
473473 /// Ignored if RayTracingPipelineDesc::ShaderRecordSize is zero.
474 const char* ShaderRecordName DEFAULT_INITIALIZER(nullptr);
474 const char* pShaderRecordName DEFAULT_INITIALIZER(nullptr);
475
476 /// Direct3D12 only: set max hit shader attribute size in bytes.
477 Uint32 MaxAttributeSize DEFAULT_INITIALIZER(0);
478
479 /// Direct3D12 only: set max payload size in bytes.
480 Uint32 MaxPayloadSize DEFAULT_INITIALIZER(0);
475481 };
476482 typedef struct RayTracingPipelineStateCreateInfo RayTracingPipelineStateCreateInfo;
477483
248248 VALIDATE_SHADER_TYPE(CreateInfo.pCS, SHADER_TYPE_COMPUTE, "compute");
249249 }
250250
251 void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
251 void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
252252 {
253253 const auto& PSODesc = CreateInfo.PSODesc;
254254 if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING)
255255 LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING");
256
257 if (pDevice->GetDeviceCaps().DevType == RENDER_DEVICE_TYPE_D3D12)
258 {
259 if ((CreateInfo.pShaderRecordName != nullptr) != (CreateInfo.RayTracingPipeline.ShaderRecordSize > 0))
260 LOG_PSO_ERROR_AND_THROW("pShaderRecordName must not be null if RayTracingPipeline.ShaderRecordSize is not zero");
261 }
256262
257263 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
258264 {
250250 virtual void DILIGENT_CALL_TYPE Flush() override final;
251251
252252 /// Implementation of IDeviceContext::BuildBLAS().
253 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
253 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final;
254254
255255 /// Implementation of IDeviceContext::BuildTLAS().
256 virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
256 virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final;
257257
258258 /// Implementation of IDeviceContext::CopyBLAS().
259259 virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
22982298 m_pd3d11DeviceContext->ResolveSubresource(pDstTexD3D11->GetD3D11Texture(), DstSubresIndex, pSrcTexD3D11->GetD3D11Texture(), SrcSubresIndex, DXGIFmt);
22992299 }
23002300
2301 void DeviceContextD3D11Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
2301 void DeviceContextD3D11Impl::BuildBLAS(const BuildBLASAttribs& Attribs)
23022302 {
23032303 UNSUPPORTED("BuildBLAS is not supported in DirectX 11");
23042304 }
23052305
2306 void DeviceContextD3D11Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
2306 void DeviceContextD3D11Impl::BuildTLAS(const BuildTLASAttribs& Attribs)
23072307 {
23082308 UNSUPPORTED("BuildTLAS is not supported in DirectX 11");
23092309 }
261261 virtual void DILIGENT_CALL_TYPE TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final;
262262
263263 /// Implementation of IDeviceContext::BuildBLAS() in Direct3D12 backend.
264 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
264 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final;
265265
266266 /// Implementation of IDeviceContext::BuildTLAS() in Direct3D12 backend.
267 virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
267 virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final;
268268
269269 /// Implementation of IDeviceContext::CopyBLAS() in Direct3D12 backend.
270270 virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
138138 using TShaderStages = std::vector<ShaderStageInfo>;
139139
140140 template <typename PSOCreateInfoType, typename InitPSODescType>
141 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc);
142 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages);
141 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc);
142 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot);
143143
144144 void Destruct();
145145
146 void CreateLocalRootSignature(const RayTracingPipelineDesc& Desc);
147
148 CComPtr<ID3D12DeviceChild> m_pd3d12PSO;
149 RootSignature m_RootSig;
150 CComPtr<ID3D12RootSignature> m_LocalRootSignature;
146 CComPtr<ID3D12DeviceChild> m_pd3d12PSO;
147 RootSignature m_RootSig;
151148
152149 // Must be defined before default SRB
153150 SRBMemoryAllocator m_SRBMemAllocator;
586586 }
587587 }
588588
589
590 class LocalRootSignature
591 {
592 public:
593 LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize);
594
595 bool SetOrMerge(const D3DShaderResourceAttribs& CB);
596
597 ID3D12RootSignature* Create(ID3D12Device* pDevice);
598
599 private:
600 static constexpr Uint32 InvalidBindPoint = ~0u;
601
602 const char* m_pName = nullptr;
603 Uint32 m_BindPoint = InvalidBindPoint;
604 const Uint32 m_ShaderRecordSize = 0;
605 CComPtr<ID3D12RootSignature> m_LocalRootSignature;
606 };
607
589608 } // namespace Diligent
139139 const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
140140 Uint32 NumAllowedTypes,
141141 ShaderResourceCacheD3D12* pResourceCache,
142 class RootSignature* pRootSig);
142 class RootSignature* pRootSig,
143 class LocalRootSignature* pLocalRootSig);
143144
144145 // clang-format off
145146 ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete;
22712271 CmdCtx.ResolveSubresource(pDstTexD3D12->GetD3D12Resource(), DstSubresIndex, pSrcTexD3D12->GetD3D12Resource(), SrcSubresIndex, DXGIFmt);
22722272 }
22732273
2274 void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
2274 void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs)
22752275 {
22762276 if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
22772277 return;
23432343 auto* const pTB = ValidatedCast<BufferD3D12Impl>(SrcTris.pTransformBuffer);
23442344 d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset;
23452345
2346 VERIFY_EXPR(d3d12Tris.Transform3x4 % D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT == 0);
2347
23462348 TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
23472349 }
23482350 else
23772379 d3d12AABs.AABBs.StartAddress = pBB->GetGPUAddress() + SrcBoxes.BoxOffset;
23782380 d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride;
23792381
2382 VERIFY_EXPR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0);
2383
23802384 TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
23812385 }
23822386 }
23882392 d3d12BuildASInputs.pGeometryDescs = Geometries.data();
23892393
23902394 d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress();
2391 d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
2395 d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset;
23922396 d3d12BuildASDesc.SourceAccelerationStructureData = 0;
2397
2398 VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
23932399
23942400 CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr);
23952401 ++m_State.NumCommands;
23992405 #endif
24002406 }
24012407
2402 void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
2408 void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs)
24032409 {
24042410 if (!TDeviceContextBase::BuildTLAS(Attribs, 0))
24052411 return;
24502456 d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD12->GetDesc().Flags);
24512457 d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
24522458 d3d12BuildASInputs.NumDescs = Attribs.InstanceCount;
2453 d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress();
2459 d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress() + Attribs.InstanceBufferOffset;
24542460
24552461 d3d12BuildASDesc.DestAccelerationStructureData = pTLASD12->GetGPUAddress();
2456 d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
2462 d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset;
24572463 d3d12BuildASDesc.SourceAccelerationStructureData = 0;
2464
2465 VERIFY_EXPR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0);
2466 VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
24582467
24592468 CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr);
24602469 ++m_State.NumCommands;
207207
208208 VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex);
209209
210 if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH)
211 LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH);
210 const Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1;
211 if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit)
212 LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than or equal to ", RecursionDepthLimit);
212213
213214 auto& PipelineConfig = *TempPool.Construct<D3D12_RAYTRACING_PIPELINE_CONFIG>();
214 // for compatibility with Vulkan set minimal recursion depth to 1
215 PipelineConfig.MaxTraceRecursionDepth = std::max<Uint32>(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth);
215 // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all.
216 PipelineConfig.MaxTraceRecursionDepth = CreateInfo.RayTracingPipeline.MaxRecursionDepth + 1;
216217 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig});
217218
218219 auto& ShaderConfig = *TempPool.Construct<D3D12_RAYTRACING_SHADER_CONFIG>();
219 ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES;
220 ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO
220 ShaderConfig.MaxAttributeSizeInBytes = CreateInfo.MaxAttributeSize == 0 ? D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES : CreateInfo.MaxAttributeSize;
221 ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? 32 : CreateInfo.MaxPayloadSize;
221222 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig});
222223 #undef LOG_PSO_ERROR_AND_THROW
223224 }
303304 template <typename PSOCreateInfoType, typename InitPSODescType>
304305 void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
305306 TShaderStages& ShaderStages,
307 LocalRootSignature* pLocalRoot,
306308 InitPSODescType InitPSODesc)
307309 {
308310 m_ResourceLayoutIndex.fill(-1);
342344 // It is important to construct all objects before initializing them because if an exception is thrown,
343345 // destructors will be called for all objects
344346
345 InitResourceLayouts(CreateInfo, ShaderStages);
347 InitResourceLayouts(CreateInfo, ShaderStages, pLocalRoot);
346348 }
347349
348350
355357 try
356358 {
357359 TShaderStages ShaderStages;
358 InitInternalObjects(CreateInfo, ShaderStages,
360 InitInternalObjects(CreateInfo, ShaderStages, nullptr,
359361 [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
360362 {
361363 InitializePipelineDesc(CreateInfo, MemPool);
566568 try
567569 {
568570 TShaderStages ShaderStages;
569 InitInternalObjects(CreateInfo, ShaderStages,
571 InitInternalObjects(CreateInfo, ShaderStages, nullptr,
570572 [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
571573 {
572574 InitializePipelineDesc(CreateInfo, MemPool);
624626 {
625627 try
626628 {
627 CreateLocalRootSignature(CreateInfo.RayTracingPipeline);
628
629 LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize};
629630 TShaderStages ShaderStages;
630631 std::vector<D3D12_STATE_SUBOBJECT> Subobjects;
631632 DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10};
632 InitInternalObjects(CreateInfo, ShaderStages,
633
634 InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig,
633635 [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
634636 {
635637 TNameToGroupIndexMap NameToGroupIndex;
638640 } //
639641 );
640642
643 auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
644
641645 D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()};
642646 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot});
643647
644 D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {m_LocalRootSignature};
645 if (m_LocalRootSignature)
648 D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device)};
649 if (LocalRoot.pLocalRootSignature)
646650 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot});
647651
648652 D3D12_STATE_OBJECT_DESC RTPipelineDesc = {};
650654 RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size());
651655 RTPipelineDesc.pSubobjects = Subobjects.data();
652656
653 auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
654 HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO));
657 HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO));
655658 if (FAILED(hr))
656659 LOG_ERROR_AND_THROW("Failed to create ray tracing state object");
657660
673676 }
674677 }
675678
676 void PipelineStateD3D12Impl::CreateLocalRootSignature(const RayTracingPipelineDesc& Desc)
677 {
678 // AZ TODO
679 /*if (Desc.ShaderRecordSize == 0)
680 return;
681
682 D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {};
683 D3D12_ROOT_PARAMETER d3d12Params = {};
684
685 d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
686 d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
687 d3d12Params.Constants.Num32BitValues = Desc.ShaderRecordSize / 4;
688 d3d12Params.Constants.RegisterSpace = Desc.LocalRootRegisterSpace;
689 d3d12Params.Constants.ShaderRegister = 0;
690
691 d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
692 d3d12RootSignatureDesc.NumParameters = 1;
693 d3d12RootSignatureDesc.pParameters = &d3d12Params;
694
695 CComPtr<ID3DBlob> signature;
696 auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr);
697 CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature");
698
699 auto pd3d12Device = GetDevice()->GetD3D12Device();
700
701 hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature));
702 CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");*/
703 }
704
705679 PipelineStateD3D12Impl::~PipelineStateD3D12Impl()
706680 {
707681 Destruct();
748722
749723
750724 void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
751 TShaderStages& ShaderStages)
725 TShaderStages& ShaderStages,
726 LocalRootSignature* pLocalRoot)
752727 {
753728 auto pd3d12Device = GetDevice()->GetD3D12Device();
754729 const auto& ResourceLayout = m_Desc.ResourceLayout;
785760 nullptr,
786761 0,
787762 nullptr,
788 &m_RootSig //
763 &m_RootSig,
764 pLocalRoot //
789765 );
790766
791767 const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
798774 StaticVarType,
799775 _countof(StaticVarType),
800776 m_pStaticResourceCaches + s,
801 nullptr //
777 nullptr,
778 pLocalRoot //
802779 );
803780
804781 m_pStaticVarManagers[s].Initialize(
11081108 );
11091109 }
11101110
1111
1112 LocalRootSignature::LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize) :
1113 m_pName{pCBName},
1114 m_ShaderRecordSize{ShaderRecordSize}
1115 {
1116 VERIFY_EXPR((m_pName != nullptr) == (m_ShaderRecordSize > 0));
1117 }
1118
1119 bool LocalRootSignature::SetOrMerge(const D3DShaderResourceAttribs& CB)
1120 {
1121 if (m_ShaderRecordSize > 0 &&
1122 CB.GetInputType() == D3D_SIT_CBUFFER &&
1123 strcmp(m_pName, CB.Name) == 0)
1124 {
1125 if (m_BindPoint == InvalidBindPoint)
1126 m_BindPoint = CB.BindPoint;
1127
1128 VERIFY_EXPR(CB.BindCount == 1);
1129 VERIFY_EXPR(m_BindPoint == CB.BindPoint);
1130
1131 return true;
1132 }
1133 return false;
1134 }
1135
1136 ID3D12RootSignature* LocalRootSignature::Create(ID3D12Device* pDevice)
1137 {
1138 if (m_ShaderRecordSize == 0 || m_BindPoint == InvalidBindPoint)
1139 return nullptr;
1140
1141 D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {};
1142 D3D12_ROOT_PARAMETER d3d12Params = {};
1143
1144 d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
1145 d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
1146 d3d12Params.Constants.Num32BitValues = m_ShaderRecordSize / 4;
1147 d3d12Params.Constants.RegisterSpace = 0;
1148 d3d12Params.Constants.ShaderRegister = m_BindPoint;
1149
1150 d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
1151 d3d12RootSignatureDesc.NumParameters = 1;
1152 d3d12RootSignatureDesc.pParameters = &d3d12Params;
1153
1154 CComPtr<ID3DBlob> signature;
1155 auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr);
1156 CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature");
1157
1158 hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature));
1159 CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");
1160
1161 return m_LocalRootSignature;
1162 }
1163
11111164 } // namespace Diligent
134134 const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
135135 Uint32 NumAllowedTypes,
136136 ShaderResourceCacheD3D12* pResourceCache,
137 RootSignature* pRootSig)
137 RootSignature* pRootSig,
138 LocalRootSignature* pLocalRootSig)
138139 {
139140 m_pd3d12Device = pd3d12Device;
140141
169170 auto VarType = pResources->FindVariableType(Res, ResourceLayout);
170171 if (IsAllowedType(VarType, AllowedTypeBits))
171172 {
173 if (pLocalRootSig && pLocalRootSig->SetOrMerge(Res))
174 return;
175
172176 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second;
173177 if (IsUniqueName)
174178 {
312316 pResources->ProcessResources(
313317 [&](const D3DShaderResourceAttribs& CB, Uint32) //
314318 {
319 if (pLocalRootSig && pLocalRootSig->SetOrMerge(CB))
320 return;
321
315322 auto VarType = pResources->FindVariableType(CB, ResourceLayout);
316323 if (IsAllowedType(VarType, AllowedTypeBits))
317324 AddResource(CB, CachedResourceType::CBV, VarType);
247247 virtual void DILIGENT_CALL_TYPE Flush() override final;
248248
249249 /// Implementation of IDeviceContext::BuildBLAS() in OpenGL backend.
250 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
250 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final;
251251
252252 /// Implementation of IDeviceContext::BuildTLAS() in OpenGL backend.
253 virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
253 virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final;
254254
255255 /// Implementation of IDeviceContext::CopyBLAS() in OpenGL backend.
256256 virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
17191719 CommitRenderTargets();
17201720 }
17211721
1722 void DeviceContextGLImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
1722 void DeviceContextGLImpl::BuildBLAS(const BuildBLASAttribs& Attribs)
17231723 {
17241724 UNSUPPORTED("BuildBLAS is not supported in OpenGL");
17251725 }
17261726
1727 void DeviceContextGLImpl::BuildTLAS(const TLASBuildAttribs& Attribs)
1727 void DeviceContextGLImpl::BuildTLAS(const BuildTLASAttribs& Attribs)
17281728 {
17291729 UNSUPPORTED("BuildTLAS is not supported in OpenGL");
17301730 }
254254 virtual void DILIGENT_CALL_TYPE Flush() override final;
255255
256256 /// Implementation of IDeviceContext::BuildBLAS() in Vulkan backend.
257 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
257 virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final;
258258
259259 /// Implementation of IDeviceContext::BuildTLAS() in Vulkan backend.
260 virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
260 virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final;
261261
262262 /// Implementation of IDeviceContext::CopyBLAS() in Vulkan backend.
263263 virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
27912791 1, &ResolveRegion);
27922792 }
27932793
2794 void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs)
2794 void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs)
27952795 {
27962796 if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
27972797 return;
29442944 #endif
29452945 }
29462946
2947 void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs)
2947 void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs)
29482948 {
29492949 if (!TDeviceContextBase::BuildTLAS(Attribs, 0))
29502950 return;
29662966
29672967 // copy instance data into instance buffer
29682968 {
2969 size_t Size = Attribs.InstanceCount * sizeof(VkAccelerationStructureInstanceKHR);
2970 auto TmpSpace = m_UploadHeap.Allocate(Size, 16);
2971 void* pMappedInstances = TmpSpace.CPUAddress;
2969 size_t Size = Attribs.InstanceCount * sizeof(VkAccelerationStructureInstanceKHR);
2970 auto TmpSpace = m_UploadHeap.Allocate(Size, 16);
29722971
29732972 for (Uint32 i = 0; i < Attribs.InstanceCount; ++i)
29742973 {
29752974 const auto& Inst = Attribs.pInstances[i];
2976 auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(pMappedInstances)[i];
2975 auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(TmpSpace.CPUAddress)[i];
29772976 auto* const pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Inst.pBLAS);
29782977
29792978 static_assert(sizeof(vkASInst.transform) == sizeof(Inst.Transform), "size mismatch");
4444 public:
4545 ResourceTypeToVkDescriptorType()
4646 {
47 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please add the corresponding decriptor type");
48 m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
49 m_Map[SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
50 m_Map[SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
51 m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
52 m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
53 m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageImage] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
54 m_Map[SPIRVShaderResourceAttribs::ResourceType::SampledImage] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
55 m_Map[SPIRVShaderResourceAttribs::ResourceType::AtomicCounter] = VK_DESCRIPTOR_TYPE_MAX_ENUM; // atomic counter doesn't exist in Vulkan
56 m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateImage] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
57 m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateSampler] = VK_DESCRIPTOR_TYPE_SAMPLER;
58 m_Map[SPIRVShaderResourceAttribs::ResourceType::InputAttachment] = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
59 m_Map[SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure] = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
47 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please add the corresponding decriptor type");
48 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::UniformBuffer}] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
49 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer}] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
50 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer}] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
51 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer}] = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
52 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer}] = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
53 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::StorageImage}] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
54 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::SampledImage}] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
55 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::AtomicCounter}] = VK_DESCRIPTOR_TYPE_MAX_ENUM; // atomic counter doesn't exist in Vulkan
56 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::SeparateImage}] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
57 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::SeparateSampler}] = VK_DESCRIPTOR_TYPE_SAMPLER;
58 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::InputAttachment}] = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
59 m_Map[Uint32{SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure}] = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
6060 }
6161
6262 VkDescriptorType operator[](SPIRVShaderResourceAttribs::ResourceType ResType) const
6565 }
6666
6767 private:
68 std::array<VkDescriptorType, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes> m_Map = {};
68 std::array<VkDescriptorType, Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes}> m_Map = {};
6969 };
7070
7171 VkDescriptorType PipelineLayout::GetVkDescriptorType(SPIRVShaderResourceAttribs::ResourceType Type)
760760 const auto& LogicalDevice = GetDevice()->GetLogicalDevice();
761761 const auto ShaderGroupHandleSize = pDeviceVk->GetShaderGroupHandleSize();
762762
763 if (LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing == VK_FALSE)
764 LOG_ERROR_AND_THROW("Ray tracing is not supported by this device");
765
766763 std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages;
767764 std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules;
768765 std::vector<VkRayTracingShaderGroupCreateInfoKHR> ShaderGroups;
155155 for (Uint32 res = 0; res < m_TotalResources; ++res)
156156 {
157157 auto& Res = pResources[res];
158 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below");
158 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please handle the new resource type below");
159159 switch (Res.Type)
160160 {
161161 case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer:
299299 // For immutable separate samplers we allocate VkResource instances, but they are never exposed to the app
300300 }
301301
302 Uint32 Binding = Attribs.Type;
302 Uint32 Binding = Uint32{Attribs.Type};
303303 Uint32 DescriptorSet = 0;
304304 Uint32 CacheOffset = StaticResCacheSize;
305305 StaticResCacheSize += Attribs.ArraySize;
11601160
11611161 if (pObj)
11621162 {
1163 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below");
1163 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please handle the new resource type below");
11641164 switch (Type)
11651165 {
11661166 case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer:
12641264 // Get resource attributes
12651265 const auto& DstRes = GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r);
12661266 const auto& SrcRes = SrcLayout.GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r);
1267 VERIFY(SrcRes.Binding == SrcRes.Type, "Unexpected binding");
1267 VERIFY(SrcRes.Binding == Uint32{SrcRes.Type}, "Unexpected binding");
12681268 VERIFY(SrcRes.ArraySize == DstRes.ArraySize, "Inconsistent array size");
12691269
12701270 if (DstRes.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler &&
14111411 WriteDescrSetIt->descriptorType = PipelineLayout::GetVkDescriptorType(Res.Type);
14121412
14131413 // For every resource type, try to batch as many descriptor updates as we can
1414 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below");
1414 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please handle the new resource type below");
14151415 switch (Res.Type)
14161416 {
14171417 case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer:
5454 PFN_vkCreateBuffer Origin_vkCreateBuffer = nullptr;
5555 PFN_vkDestroyBuffer Origin_vkDestroyBuffer = nullptr;
5656 PFN_vkGetBufferDeviceAddressKHR Origin_vkGetBufferDeviceAddressKHR = nullptr;
57 PFN_vkAllocateMemory Origin_vkAllocateMemory = nullptr;
58
5759
5860 VKAPI_ATTR VkResult VKAPI_CALL Wrap_vkCreateBuffer(VkDevice device,
5961 const VkBufferCreateInfo* pCreateInfo,
6062 const VkAllocationCallbacks* pAllocator,
6163 VkBuffer* pBuffer)
6264 {
63 const_cast<VkBufferCreateInfo*>(pCreateInfo)->usage &= ~VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
64 return Origin_vkCreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
65 VkBufferCreateInfo CreateInfo = *pCreateInfo;
66 CreateInfo.usage &= ~VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
67 return Origin_vkCreateBuffer(device, &CreateInfo, pAllocator, pBuffer);
68 }
69
70 VKAPI_ATTR VkResult VKAPI_PTR Wrap_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
71 {
72 VkMemoryAllocateInfo AllocInfo = *pAllocateInfo;
73
74 for (auto* pNext = static_cast<VkBaseOutStructure*>(const_cast<void*>(AllocInfo.pNext)); pNext;)
75 {
76 // remove VkMemoryAllocateFlagsInfo because VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is removed from buffer create info.
77 if (pNext->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO)
78 pNext->pNext = pNext->pNext;
79
80 pNext = pNext->pNext;
81 }
82
83 return Origin_vkAllocateMemory(device, &AllocInfo, pAllocator, pMemory);
6584 }
6685
6786 VKAPI_ATTR void VKAPI_CALL Wrap_vkDestroyBuffer(VkDevice device,
508527
509528 void EnableRayTracingKHRviaNV()
510529 {
530 LOG_WARNING_MESSAGE("This is fallback implementation, you should use VK_KHR_ray_tracing instead");
531
511532 vkCreateAccelerationStructureKHR = &Redirect_vkCreateAccelerationStructureKHR;
512533 vkGetAccelerationStructureMemoryRequirementsKHR = &Redirect_vkGetAccelerationStructureMemoryRequirementsKHR;
513534 vkBindAccelerationStructureMemoryKHR = &Redirect_vkBindAccelerationStructureMemoryKHR;
522543 Origin_vkGetBufferDeviceAddressKHR = vkGetBufferDeviceAddressKHR;
523544 Origin_vkCreateBuffer = vkCreateBuffer;
524545 Origin_vkDestroyBuffer = vkDestroyBuffer;
546 Origin_vkAllocateMemory = vkAllocateMemory;
525547 vkCreateBuffer = &Wrap_vkCreateBuffer;
526548 vkDestroyBuffer = &Wrap_vkDestroyBuffer;
549 vkAllocateMemory = Wrap_vkAllocateMemory;
527550 vkGetBufferDeviceAddressKHR = &Wrap_vkGetBufferDeviceAddressKHR;
528551 vkGetBufferDeviceAddress = &Wrap_vkGetBufferDeviceAddressKHR;
529552 vkGetBufferDeviceAddressEXT = &Wrap_vkGetBufferDeviceAddressKHR;
5757 // sizeof(SPIRVShaderResourceAttribs) == 32, msvc x64
5858 struct SPIRVShaderResourceAttribs
5959 {
60 enum ResourceType : Uint8
60 enum class ResourceType : Uint8
6161 {
6262 UniformBuffer = 0,
6363 ROStorageBuffer,
110110
111111 bool IsValidSepSamplerAssigned() const
112112 {
113 VERIFY_EXPR(Type == SeparateImage);
113 VERIFY_EXPR(Type == ResourceType::SeparateImage);
114114 return SepSmplrOrImgInd != InvalidSepSmplrOrImgInd;
115115 }
116116
117117 bool IsValidSepImageAssigned() const
118118 {
119 VERIFY_EXPR(Type == SeparateSampler);
119 VERIFY_EXPR(Type == ResourceType::SeparateSampler);
120120 return SepSmplrOrImgInd != InvalidSepSmplrOrImgInd;
121121 }
122122
123123 Uint32 GetAssignedSepSamplerInd() const
124124 {
125 VERIFY_EXPR(Type == SeparateImage);
125 VERIFY_EXPR(Type == ResourceType::SeparateImage);
126126 return SepSmplrOrImgInd;
127127 }
128128
129129 Uint32 GetAssignedSepImageInd() const
130130 {
131 VERIFY_EXPR(Type == SeparateSampler);
131 VERIFY_EXPR(Type == ResourceType::SeparateSampler);
132132 return SepSmplrOrImgInd;
133133 }
134134
135135 void AssignSeparateSampler(Uint32 SemSamplerInd)
136136 {
137 VERIFY_EXPR(Type == SeparateImage);
137 VERIFY_EXPR(Type == ResourceType::SeparateImage);
138138 SepSmplrOrImgInd = SemSamplerInd;
139139 }
140140
141141 void AssignSeparateImage(Uint32 SepImageInd)
142142 {
143 VERIFY_EXPR(Type == SeparateSampler);
143 VERIFY_EXPR(Type == ResourceType::SeparateSampler);
144144 SepSmplrOrImgInd = SepImageInd;
145145 }
146146
336336 HandleAccelStruct(AccelStruct, n);
337337 }
338338
339 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type here, if needed");
339 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please handle the new resource type here, if needed");
340340 }
341341
342342 template <typename THandler>
701701 });
702702
703703 if (ShaderCI.Desc.ShaderType & RayTracingStages)
704 DxilArgs.push_back(L"-fspv-target-env=vulkan1.2");
704 {
705 DxilArgs.push_back(L"-fspv-extension=SPV_NV_ray_tracing");
706 DxilArgs.push_back(L"-fspv-extension=SPV_GOOGLE_hlsl_functionality1");
707 DxilArgs.push_back(L"-fspv-extension=SPV_GOOGLE_user_type");
708 //DxilArgs.push_back(L"-fspv-target-env=vulkan1.2");
709 }
705710 }
706711 else
707712 {
132132
133133 SHADER_RESOURCE_TYPE SPIRVShaderResourceAttribs::GetShaderResourceType(ResourceType Type)
134134 {
135 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please handle the new resource type below");
135 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please handle the new resource type below");
136136 switch (Type)
137137 {
138138 case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer:
290290 size_t ResourceNamesPoolSize = 0;
291291 for (const auto& ub : resources.uniform_buffers)
292292 ResourceNamesPoolSize += GetUBName(Compiler, ub, ParsedIRSource).length() + 1;
293 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please account for the new resource type below");
293 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please account for the new resource type below");
294294 for (auto* pResType :
295295 {
296296 &resources.storage_buffers,
370370 ResCounters.NumSepImgs = static_cast<Uint32>(resources.separate_images.size());
371371 ResCounters.NumInptAtts = static_cast<Uint32>(resources.subpass_inputs.size());
372372 ResCounters.NumAccelStructs = static_cast<Uint32>(resources.acceleration_structures.size());
373 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please set the new resource type counter here");
373 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please set the new resource type counter here");
374374
375375 // Resource names pool is only needed to facilitate string allocation.
376376 StringPool ResourceNamesPool;
557557 VERIFY_EXPR(CurrAccelStruct == GetNumAccelStructs());
558558 }
559559
560 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please initialize SPIRVShaderResourceAttribs for the new resource type here");
560 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please initialize SPIRVShaderResourceAttribs for the new resource type here");
561561
562562 if (CombinedSamplerSuffix != nullptr)
563563 {
625625 m_InputAttachmentOffset = AdvanceOffset(Counters.NumInptAtts);
626626 m_AccelStructOffset = AdvanceOffset(Counters.NumAccelStructs);
627627 m_TotalResources = AdvanceOffset(0);
628 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please update the new resource type offset");
628 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please update the new resource type offset");
629629
630630 VERIFY(NumShaderStageInputs <= MaxOffset, "Max offset exceeded");
631631 m_NumShaderStageInputs = static_cast<OffsetType>(NumShaderStageInputs);
647647 VERIFY_EXPR(GetNumSepImgs() == Counters.NumSepImgs);
648648 VERIFY_EXPR(GetNumInptAtts() == Counters.NumInptAtts);
649649 VERIFY_EXPR(GetNumAccelStructs() == Counters.NumAccelStructs);
650 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please update the new resource count verification");
650 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please update the new resource count verification");
651651 // clang-format on
652652
653653 if (MemorySize)
693693 for (Uint32 n = 0; n < GetNumAccelStructs(); ++n)
694694 GetAccelStruct(n).~SPIRVShaderResourceAttribs();
695695
696 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please add destructor for the new resource");
696 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please add destructor for the new resource");
697697 }
698698
699699
835835 return false;
836836 // clang-format on
837837 VERIFY_EXPR(GetTotalResources() == Resources.GetTotalResources());
838 static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 12, "Please update comparison with the new resource");
838 static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12, "Please update comparison with the new resource");
839839
840840 bool IsCompatible = true;
841841 ProcessResources(
9191
9292 void main()
9393 {
94 const vec3 barycentrics = vec3(1.0f - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);
94 const vec3 barycentrics = vec3(1.0 - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);
9595 payload = vec4(barycentrics, 1.0);
9696 }
9797 )glsl"
173173
174174 void main()
175175 {
176 const vec3 barycentrics = vec3(1.0f - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);
176 const vec3 barycentrics = vec3(1.0 - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);
177177 if (barycentrics.y > barycentrics.x)
178178 ignoreIntersectionEXT();
179179 else
336336 layout(shaderRecordEXT) buffer ShaderRecord
337337 {
338338 vec4 Weights;
339 uint GeometryID; // same as gl_GeometryIndexEXT but compatible with VK_NV_ray_tracing
339340 };
340341
341342 layout(location=0) rayPayloadInEXT vec4 payload;
365366 R"glsl(
366367 void main()
367368 {
368 vec3 barycentrics = vec3(1.0f - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);// * Weights.xyz;
369 vec3 barycentrics = vec3(1.0 - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y) * Weights.xyz;
369370 uint primOffset = g_PerInstance[gl_InstanceID].PrimitiveOffsets[gl_GeometryIndexEXT];
370371 uvec4 triFace = g_Primitives[primOffset + gl_PrimitiveID];
371372 Vertex v0 = g_Vertices[triFace.x];
380381 R"glsl(
381382 void main()
382383 {
383 vec3 barycentrics = vec3(1.0f - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y);// * Weights.xyz;
384 vec3 barycentrics = vec3(1.0 - hitAttribs.x - hitAttribs.y, hitAttribs.x, hitAttribs.y) * Weights.xyz;
384385 uint primOffset = g_PerInstance[gl_InstanceID].PrimitiveOffsets[gl_GeometryIndexEXT];
385386 uvec4 triFace = g_Primitives[primOffset + gl_PrimitiveID];
386387 Vertex v0 = g_Vertices[triFace.x];
297297 struct LocalRootConst
298298 {
299299 float4 Weight;
300 };
301 //[[vk::shader_record_ext]]
302 //ConstantBuffer<LocalRootConst> g_LocalRoot : register(b0);
300 uint GeometryID; // same as GeometryIndex() in DXR 1.1
301 };
302 #ifdef VULKAN
303 [[vk::shader_record_nv]]
304 #endif
305 ConstantBuffer<LocalRootConst> g_LocalRoot : register(b0);
303306 )hlsl";
304307
305308 const std::string RayTracingTest4_RCH1 = RayTracingTest4_Uniforms +
307310 [shader("closesthit")]
308311 void main(inout RTPayload payload, in BuiltInTriangleIntersectionAttributes attr)
309312 {
310 float3 barycentrics = float3(1.0 - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y);// * g_LocalRoot.Weight.xyz;
311 uint primOffset = g_PerInstance[InstanceIndex()][GeometryIndex()];
313 float3 barycentrics = float3(1.0 - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y) * g_LocalRoot.Weight.xyz;
314 uint primOffset = g_PerInstance[InstanceIndex()][g_LocalRoot.GeometryID];
312315 uint4 triFace = g_Primitives[primOffset + PrimitiveIndex()];
313316 Vertex v0 = g_Vertices[triFace.x];
314317 Vertex v1 = g_Vertices[triFace.y];
323326 [shader("closesthit")]
324327 void main(inout RTPayload payload, in BuiltInTriangleIntersectionAttributes attr)
325328 {
326 float3 barycentrics = float3(1.0 - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y);// * g_LocalRoot.Weight.xyz;
327 uint primOffset = g_PerInstance[InstanceIndex()][GeometryIndex()]; // AZ TODO: GeometryIndex required DXR 1.1
329 float3 barycentrics = float3(1.0 - attr.barycentrics.x - attr.barycentrics.y, attr.barycentrics.x, attr.barycentrics.y) * g_LocalRoot.Weight.xyz;
330 uint primOffset = g_PerInstance[InstanceIndex()][g_LocalRoot.GeometryID];
328331 uint4 triFace = g_Primitives[primOffset + PrimitiveIndex()];
329332 Vertex v0 = g_Vertices[triFace.x];
330333 Vertex v1 = g_Vertices[triFace.y];
128128 struct ShaderRecord
129129 {
130130 float4 Weight;
131 float4 Padding;
131 uint GeometryID;
132 uint padding[3];
133
134 ShaderRecord(const float4& w, uint id) {}
132135 };
133136 static const ShaderRecord Weights[] =
134137 {
135 ShaderRecord{{1.0f, 0.4f, 0.4f, 1.0f}, {}},
136 ShaderRecord{{0.4f, 1.0f, 0.4f, 1.0f}, {}},
137 ShaderRecord{{0.4f, 0.4f, 1.0f, 1.0f}, {}}
138 ShaderRecord{{1.0f, 0.4f, 0.4f, 1.0f}, 0},
139 ShaderRecord{{0.4f, 1.0f, 0.4f, 1.0f}, 1},
140 ShaderRecord{{0.4f, 0.4f, 1.0f, 1.0f}, 2},
141 ShaderRecord{{0.4f, 1.0f, 0.4f, 1.0f}, 0},
142 ShaderRecord{{0.4f, 0.4f, 1.0f, 1.0f}, 1},
143 ShaderRecord{{1.0f, 0.4f, 0.4f, 1.0f}, 2},
138144 };
139145 static constexpr Uint32 ShaderRecordSize = sizeof(Weights[0]);
140146 static constexpr Uint32 InstanceCount = 2;
144150 static_assert(_countof(Primitives) == 9, "Update array size in shaders");
145151 static_assert(_countof(Indices) % 3 == 0, "Invalid index count");
146152 static_assert(_countof(Indices) / 3 == _countof(Primitives), "Primitive count mismatch");
153 static_assert(ShaderRecordSize == 32, "bust be 32 bytes");
147154
148155 } // namespace MultiGeometry
149156
243243 Param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
244244 Param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
245245 Param.Constants.Num32BitValues = ShaderRecordSize / 4;
246 Param.Constants.RegisterSpace = 1;
246 Param.Constants.RegisterSpace = 0;
247247 Param.Constants.ShaderRegister = 0;
248248
249249 RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
12591259 UpdateBuffer(Ctx, Ctx.pSBTBuffer, Offset + handleSize, ShaderRecord, sizeof(Weights[0]));
12601260 };
12611261 // instance 1
1262 SetHitGroup(0, L"HitGroup1", &Weights[2]); // geometry 1
1263 SetHitGroup(1, L"HitGroup1", &Weights[0]); // geometry 2
1264 SetHitGroup(2, L"HitGroup1", &Weights[1]); // geometry 3
1262 SetHitGroup(0, L"HitGroup1", &Weights[0]); // geometry 1
1263 SetHitGroup(1, L"HitGroup1", &Weights[1]); // geometry 2
1264 SetHitGroup(2, L"HitGroup1", &Weights[2]); // geometry 3
12651265 // instance 2
1266 SetHitGroup(3, L"HitGroup2", &Weights[2]); // geometry 1
1267 SetHitGroup(4, L"HitGroup2", &Weights[1]); // geometry 2
1268 SetHitGroup(5, L"HitGroup2", &Weights[0]); // geometry 3
1266 SetHitGroup(3, L"HitGroup2", &Weights[3]); // geometry 1
1267 SetHitGroup(4, L"HitGroup2", &Weights[4]); // geometry 2
1268 SetHitGroup(5, L"HitGroup2", &Weights[5]); // geometry 3
12691269
12701270 SBTBufferBarrier(Ctx);
12711271
108108 VERIFY_EXPR(ScratchBuffer != nullptr);
109109
110110 // Build
111 BLASBuildAttribs Attribs;
111 BuildBLASAttribs Attribs;
112112 Attribs.pBLAS = pBLAS;
113113 Attribs.BLASTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
114114 Attribs.GeometryTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
156156 VERIFY_EXPR(ScratchBuffer != nullptr);
157157
158158 // Build
159 BLASBuildAttribs Attribs;
159 BuildBLASAttribs Attribs;
160160 Attribs.pBLAS = pBLAS;
161161 Attribs.BLASTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
162162 Attribs.GeometryTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
204204 VERIFY_EXPR(InstanceBuffer != nullptr);
205205
206206 // Build
207 TLASBuildAttribs Attribs;
207 BuildTLASAttribs Attribs;
208208 Attribs.pTLAS = pTLAS;
209209 Attribs.pInstances = Instances;
210210 Attribs.InstanceCount = InstanceCount;
10801080 PSOCreateInfo.RayTracingPipeline.MaxRecursionDepth = 0;
10811081
10821082 PSOCreateInfo.RayTracingPipeline.ShaderRecordSize = TestingConstants::MultiGeometry::ShaderRecordSize;
1083 PSOCreateInfo.ShaderRecordName = "g_LocalRoot";
1083 PSOCreateInfo.pShaderRecordName = "g_LocalRoot";
10841084
10851085 PSOCreateInfo.PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE;
10861086
12091209
12101210 pSBT->BindRayGenShader("Main");
12111211 pSBT->BindMissShader("Miss", 0);
1212 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 1", 0, "HitGroup1", &Weights[2], sizeof(Weights[0]));
1213 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 2", 0, "HitGroup1", &Weights[0], sizeof(Weights[0]));
1214 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 3", 0, "HitGroup1", &Weights[1], sizeof(Weights[0]));
1215 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 1", 0, "HitGroup2", &Weights[2], sizeof(Weights[0]));
1216 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 2", 0, "HitGroup2", &Weights[1], sizeof(Weights[0]));
1217 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 3", 0, "HitGroup2", &Weights[0], sizeof(Weights[0]));
1212 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 1", 0, "HitGroup1", &Weights[0], sizeof(Weights[0]));
1213 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 2", 0, "HitGroup1", &Weights[1], sizeof(Weights[0]));
1214 pSBT->BindHitGroup(pTLAS, "Instance 1", "Geom 3", 0, "HitGroup1", &Weights[2], sizeof(Weights[0]));
1215 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 1", 0, "HitGroup2", &Weights[3], sizeof(Weights[0]));
1216 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 2", 0, "HitGroup2", &Weights[4], sizeof(Weights[0]));
1217 pSBT->BindHitGroup(pTLAS, "Instance 2", "Geom 3", 0, "HitGroup2", &Weights[5], sizeof(Weights[0]));
12181218
12191219 pRayTracingSRB->GetVariableByName(SHADER_TYPE_RAY_GEN, "g_TLAS")->Set(pTLAS);
12201220 pRayTracingSRB->GetVariableByName(SHADER_TYPE_RAY_GEN, "g_ColorBuffer")->Set(pTestingSwapChain->GetCurrentBackBufferUAV());
177177 vkCreatePipelineLayout(Ctx.vkDevice, &PipelineLayoutCI, nullptr, &Ctx.vkLayout);
178178 ASSERT_TRUE(Ctx.vkLayout != VK_NULL_HANDLE);
179179
180 PipelineCI.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
181 PipelineCI.flags = 0;
182 PipelineCI.stageCount = static_cast<Uint32>(Helper.Stages.size());
183 PipelineCI.pStages = Helper.Stages.data();
184 PipelineCI.groupCount = static_cast<Uint32>(Helper.Groups.size());
185 PipelineCI.pGroups = Helper.Groups.data();
186 PipelineCI.maxRecursionDepth = 0;
187 PipelineCI.layout = Ctx.vkLayout;
188 PipelineCI.libraries.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
189 PipelineCI.libraries.pNext = nullptr;
190 PipelineCI.libraries.libraryCount = 0;
191 PipelineCI.libraries.pLibraries = nullptr;
180 PipelineCI.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
181 PipelineCI.stageCount = static_cast<Uint32>(Helper.Stages.size());
182 PipelineCI.pStages = Helper.Stages.data();
183 PipelineCI.groupCount = static_cast<Uint32>(Helper.Groups.size());
184 PipelineCI.pGroups = Helper.Groups.data();
185 PipelineCI.maxRecursionDepth = 0;
186 PipelineCI.layout = Ctx.vkLayout;
187 PipelineCI.libraries.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
192188
193189 res = vkCreateRayTracingPipelinesKHR(Ctx.vkDevice, VK_NULL_HANDLE, 1, &PipelineCI, nullptr, &Ctx.vkPipeline);
194190 ASSERT_GE(res, 0);
280276
281277 BLASCI.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
282278 BLASCI.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
283 BLASCI.flags = 0;
284279 BLASCI.maxGeometryCount = GeometryCount;
285 BLASCI.compactedSize = 0;
286280 BLASCI.pGeometryInfos = pGeometries;
287281
288282 res = vkCreateAccelerationStructureKHR(Ctx.vkDevice, &BLASCI, nullptr, &BLAS.vkAS);
313307
314308 BindInfo.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR;
315309 BindInfo.memory = BLAS.vkMemory;
316 BindInfo.memoryOffset = 0;
317 BindInfo.deviceIndexCount = 0;
318 BindInfo.pDeviceIndices = nullptr;
319310 BindInfo.accelerationStructure = BLAS.vkAS;
320311
321312 res = vkBindAccelerationStructureMemoryKHR(Ctx.vkDevice, 1, &BindInfo);
607598 vkCmdClearColorImage(Ctx.vkCmdBuffer, Ctx.vkRenderTarget, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ClearValue, 1, &Range);
608599
609600 pTestingSwapChainVk->TransitionRenderTarget(Ctx.vkCmdBuffer, VK_IMAGE_LAYOUT_GENERAL, 0);
601 }
602
603 void PrepareForTraceRays(const RTContext& Ctx)
604 {
605 // Barrier for TLAS & SBT
606 VkMemoryBarrier Barrier = {};
607 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
608 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
609 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
610 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
611 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
612 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
613 0, 1, &Barrier, 0, nullptr, 0, nullptr);
614
615 vkCmdBindPipeline(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkPipeline);
616 vkCmdBindDescriptorSets(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkLayout, 0, 1, &Ctx.vkDescriptorSet, 0, nullptr);
617 }
618
619 void AccelStructBarrier(const RTContext& Ctx)
620 {
621 // Barrier for vertex & index buffers, BLAS, scratch buffer, instance buffer
622 VkMemoryBarrier Barrier = {};
623 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
624 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
625 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
626 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
627 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
628 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
629 0, 1, &Barrier, 0, nullptr, 0, nullptr);
610630 }
611631 } // namespace
612632
719739 rtGroups.SetStage(RAYGEN_SHADER, SHADER_TYPE_RAY_GEN, GLSL::RayTracingTest1_RG);
720740 rtGroups.SetStage(MISS_SHADER, SHADER_TYPE_RAY_MISS, GLSL::RayTracingTest1_RM);
721741 rtGroups.SetStage(HIT_SHADER, SHADER_TYPE_RAY_CLOSEST_HIT, GLSL::RayTracingTest1_RCH);
742
722743 rtGroups.SetGeneralGroup(RAYGEN_GROUP, RAYGEN_SHADER);
723744 rtGroups.SetGeneralGroup(MISS_GROUP, MISS_SHADER);
724745 rtGroups.SetTriangleHitGroup(HIT_GROUP, HIT_SHADER);
726747
727748 // Create acceleration structures
728749 {
729 VkMemoryBarrier Barrier = {};
730 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
731
732750 const auto& Vertices = TestingConstants::TriangleClosestHit::Vertices;
733751
734752 VkAccelerationStructureCreateGeometryTypeInfoKHR GeometryCI = {};
746764 CreateRTBuffers(Ctx, sizeof(Vertices), 0, 1, 1, 1);
747765
748766 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkVertexBuffer, 0, sizeof(Vertices), Vertices);
749
750 // barrier for vertex & index buffers
751 Barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
752 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
753 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
754 VK_PIPELINE_STAGE_TRANSFER_BIT,
755 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
756 0, 1, &Barrier, 0, nullptr, 0, nullptr);
767 AccelStructBarrier(Ctx);
757768
758769 VkAccelerationStructureBuildGeometryInfoKHR ASBuildInfo = {};
759770 VkAccelerationStructureBuildOffsetInfoKHR Offset = {};
770781 Geometry.geometry.triangles.vertexData.deviceAddress = Ctx.vkVertexBufferAddress;
771782 Geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_KHR;
772783
773 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
774 Offset.firstVertex = 0;
775 Offset.primitiveOffset = 0;
776 Offset.transformOffset = 0;
784 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
777785
778786 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
779787 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
780 ASBuildInfo.flags = 0;
781788 ASBuildInfo.update = VK_FALSE;
782789 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
783790 ASBuildInfo.dstAccelerationStructure = Ctx.BLAS.vkAS;
789796 vkCmdBuildAccelerationStructureKHR(Ctx.vkCmdBuffer, 1, &ASBuildInfo, &OffsetPtr);
790797
791798 VkAccelerationStructureInstanceKHR InstanceData = {};
792 InstanceData.instanceCustomIndex = 0;
793799 InstanceData.instanceShaderBindingTableRecordOffset = 0;
794800 InstanceData.mask = 0xFF;
795 InstanceData.flags = 0;
796801 InstanceData.accelerationStructureReference = Ctx.BLAS.vkAddress;
797802 InstanceData.transform.matrix[0][0] = 1.0f;
798803 InstanceData.transform.matrix[1][1] = 1.0f;
799804 InstanceData.transform.matrix[2][2] = 1.0f;
800805
801806 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkInstanceBuffer, 0, sizeof(InstanceData), &InstanceData);
802
803 // barrier for BLAS, scratch buffer, instance buffer
804 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
805 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
806 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
807 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
808 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
809 0, 1, &Barrier, 0, nullptr, 0, nullptr);
807 AccelStructBarrier(Ctx);
810808
811809 Geometry.flags = 0;
812810 Geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
815813 Geometry.geometry.instances.arrayOfPointers = VK_FALSE;
816814 Geometry.geometry.instances.data.deviceAddress = Ctx.vkInstanceBufferAddress;
817815
818 Offset.primitiveCount = 1;
819 Offset.firstVertex = 0;
820 Offset.primitiveOffset = 0;
821 Offset.transformOffset = 0;
816 Offset.primitiveCount = 1;
822817
823818 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
824819 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
825 ASBuildInfo.flags = 0;
826820 ASBuildInfo.update = VK_FALSE;
827821 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
828822 ASBuildInfo.dstAccelerationStructure = Ctx.TLAS.vkAS;
873867 vkGetRayTracingShaderGroupHandlesKHR(Ctx.vkDevice, Ctx.vkPipeline, HIT_GROUP, 1, ShaderGroupHandleSize, ShaderHandle);
874868 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkSBTBuffer, HitShaderBindingTable.offset, ShaderGroupHandleSize, ShaderHandle);
875869
876 // Barriers for TLAS & SBT
877 VkMemoryBarrier Barrier = {};
878 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
879 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
880 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
881 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
882 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
883 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
884 0, 1, &Barrier, 0, nullptr, 0, nullptr);
885
886 vkCmdBindPipeline(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkPipeline);
887 vkCmdBindDescriptorSets(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkLayout, 0, 1, &Ctx.vkDescriptorSet, 0, nullptr);
888
870 PrepareForTraceRays(Ctx);
889871 vkCmdTraceRaysKHR(Ctx.vkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, SCDesc.Width, SCDesc.Height, 1);
890872
891873 pTestingSwapChainVk->TransitionRenderTarget(Ctx.vkCmdBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0);
929911 rtGroups.SetStage(MISS_SHADER, SHADER_TYPE_RAY_MISS, GLSL::RayTracingTest2_RM);
930912 rtGroups.SetStage(HIT_SHADER, SHADER_TYPE_RAY_CLOSEST_HIT, GLSL::RayTracingTest2_RCH);
931913 rtGroups.SetStage(ANY_HIT_SHADER, SHADER_TYPE_RAY_ANY_HIT, GLSL::RayTracingTest2_RAH);
914
932915 rtGroups.SetGeneralGroup(RAYGEN_GROUP, RAYGEN_SHADER);
933916 rtGroups.SetGeneralGroup(MISS_GROUP, MISS_SHADER);
934917 rtGroups.SetTriangleHitGroup(HIT_GROUP, HIT_SHADER, ANY_HIT_SHADER);
935918 });
936919
937 // create acceleration structurea
938 {
939 VkMemoryBarrier Barrier = {};
940 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
941
920 // Create acceleration structurea
921 {
942922 const auto& Vertices = TestingConstants::TriangleAnyHit::Vertices;
943923
944924 VkAccelerationStructureCreateGeometryTypeInfoKHR GeometryCI = {};
956936 CreateRTBuffers(Ctx, sizeof(Vertices), 0, 1, 1, 1);
957937
958938 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkVertexBuffer, 0, sizeof(Vertices), Vertices);
959
960 // barrier for vertex & index buffers
961 Barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
962 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
963 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
964 VK_PIPELINE_STAGE_TRANSFER_BIT,
965 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
966 0, 1, &Barrier, 0, nullptr, 0, nullptr);
939 AccelStructBarrier(Ctx);
967940
968941 VkAccelerationStructureBuildGeometryInfoKHR ASBuildInfo = {};
969942 VkAccelerationStructureBuildOffsetInfoKHR Offset = {};
980953 Geometry.geometry.triangles.vertexData.deviceAddress = Ctx.vkVertexBufferAddress;
981954 Geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_KHR;
982955
983 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
984 Offset.firstVertex = 0;
985 Offset.primitiveOffset = 0;
986 Offset.transformOffset = 0;
956 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
987957
988958 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
989959 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
990 ASBuildInfo.flags = 0;
991960 ASBuildInfo.update = VK_FALSE;
992961 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
993962 ASBuildInfo.dstAccelerationStructure = Ctx.BLAS.vkAS;
999968 vkCmdBuildAccelerationStructureKHR(Ctx.vkCmdBuffer, 1, &ASBuildInfo, &OffsetPtr);
1000969
1001970 VkAccelerationStructureInstanceKHR InstanceData = {};
1002 InstanceData.instanceCustomIndex = 0;
1003971 InstanceData.instanceShaderBindingTableRecordOffset = 0;
1004972 InstanceData.mask = 0xFF;
1005 InstanceData.flags = 0;
1006973 InstanceData.accelerationStructureReference = Ctx.BLAS.vkAddress;
1007974 InstanceData.transform.matrix[0][0] = 1.0f;
1008975 InstanceData.transform.matrix[1][1] = 1.0f;
1009976 InstanceData.transform.matrix[2][2] = 1.0f;
1010977
1011978 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkInstanceBuffer, 0, sizeof(InstanceData), &InstanceData);
1012
1013 // barrier for BLAS, scratch buffer, instance buffer
1014 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1015 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
1016 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1017 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1018 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
1019 0, 1, &Barrier, 0, nullptr, 0, nullptr);
979 AccelStructBarrier(Ctx);
1020980
1021981 Geometry.flags = 0;
1022982 Geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
1025985 Geometry.geometry.instances.arrayOfPointers = VK_FALSE;
1026986 Geometry.geometry.instances.data.deviceAddress = Ctx.vkInstanceBufferAddress;
1027987
1028 Offset.primitiveCount = 1;
1029 Offset.firstVertex = 0;
1030 Offset.primitiveOffset = 0;
1031 Offset.transformOffset = 0;
988 Offset.primitiveCount = 1;
1032989
1033990 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
1034991 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
1035 ASBuildInfo.flags = 0;
1036992 ASBuildInfo.update = VK_FALSE;
1037993 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
1038994 ASBuildInfo.dstAccelerationStructure = Ctx.TLAS.vkAS;
10831039 vkGetRayTracingShaderGroupHandlesKHR(Ctx.vkDevice, Ctx.vkPipeline, HIT_GROUP, 1, ShaderGroupHandleSize, ShaderHandle);
10841040 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkSBTBuffer, HitShaderBindingTable.offset, ShaderGroupHandleSize, ShaderHandle);
10851041
1086 // Barriers for TLAS & SBT
1087 VkMemoryBarrier Barrier = {};
1088 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
1089 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1090 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1091 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1092 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1093 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
1094 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1095
1096 vkCmdBindPipeline(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkPipeline);
1097 vkCmdBindDescriptorSets(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkLayout, 0, 1, &Ctx.vkDescriptorSet, 0, nullptr);
1098
1042 PrepareForTraceRays(Ctx);
10991043 vkCmdTraceRaysKHR(Ctx.vkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, SCDesc.Width, SCDesc.Height, 1);
11001044
11011045 pTestingSwapChainVk->TransitionRenderTarget(Ctx.vkCmdBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0);
11391083 rtGroups.SetStage(MISS_SHADER, SHADER_TYPE_RAY_MISS, GLSL::RayTracingTest3_RM);
11401084 rtGroups.SetStage(HIT_SHADER, SHADER_TYPE_RAY_CLOSEST_HIT, GLSL::RayTracingTest3_RCH);
11411085 rtGroups.SetStage(INTERSECTION_SHADER, SHADER_TYPE_RAY_INTERSECTION, GLSL::RayTracingTest3_RI);
1086
11421087 rtGroups.SetGeneralGroup(RAYGEN_GROUP, RAYGEN_SHADER);
11431088 rtGroups.SetGeneralGroup(MISS_GROUP, MISS_SHADER);
11441089 rtGroups.SetProceduralHitGroup(HIT_GROUP, INTERSECTION_SHADER, HIT_SHADER);
11451090 });
11461091
1147 // create acceleration structurea
1148 {
1149 VkMemoryBarrier Barrier = {};
1150 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
1151
1092 // Create acceleration structurea
1093 {
11521094 const auto& Boxes = TestingConstants::ProceduralIntersection::Boxes;
11531095
11541096 VkAccelerationStructureCreateGeometryTypeInfoKHR GeometryCI = {};
11631105 CreateRTBuffers(Ctx, sizeof(Boxes), 0, 1, 1, 1);
11641106
11651107 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkVertexBuffer, 0, sizeof(Boxes), Boxes);
1166
1167 // barrier for vertex & index buffers
1168 Barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1169 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
1170 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1171 VK_PIPELINE_STAGE_TRANSFER_BIT,
1172 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
1173 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1108 AccelStructBarrier(Ctx);
11741109
11751110 VkAccelerationStructureBuildGeometryInfoKHR ASBuildInfo = {};
11761111 VkAccelerationStructureBuildOffsetInfoKHR Offset = {};
11861121 Geometry.geometry.aabbs.data.deviceAddress = Ctx.vkVertexBufferAddress;
11871122 Geometry.geometry.aabbs.stride = sizeof(float3) * 2;
11881123
1189 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
1190 Offset.firstVertex = 0;
1191 Offset.primitiveOffset = 0;
1192 Offset.transformOffset = 0;
1124 Offset.primitiveCount = GeometryCI.maxPrimitiveCount;
11931125
11941126 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
11951127 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
1196 ASBuildInfo.flags = 0;
11971128 ASBuildInfo.update = VK_FALSE;
11981129 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
11991130 ASBuildInfo.dstAccelerationStructure = Ctx.BLAS.vkAS;
12051136 vkCmdBuildAccelerationStructureKHR(Ctx.vkCmdBuffer, 1, &ASBuildInfo, &OffsetPtr);
12061137
12071138 VkAccelerationStructureInstanceKHR InstanceData = {};
1208 InstanceData.instanceCustomIndex = 0;
12091139 InstanceData.instanceShaderBindingTableRecordOffset = 0;
12101140 InstanceData.mask = 0xFF;
1211 InstanceData.flags = 0;
12121141 InstanceData.accelerationStructureReference = Ctx.BLAS.vkAddress;
12131142 InstanceData.transform.matrix[0][0] = 1.0f;
12141143 InstanceData.transform.matrix[1][1] = 1.0f;
12151144 InstanceData.transform.matrix[2][2] = 1.0f;
12161145
12171146 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkInstanceBuffer, 0, sizeof(InstanceData), &InstanceData);
1218
1219 // Barrier for BLAS, scratch buffer, instance buffer
1220 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1221 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
1222 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1223 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1224 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
1225 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1147 AccelStructBarrier(Ctx);
12261148
12271149 Geometry.flags = 0;
12281150 Geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
12311153 Geometry.geometry.instances.arrayOfPointers = VK_FALSE;
12321154 Geometry.geometry.instances.data.deviceAddress = Ctx.vkInstanceBufferAddress;
12331155
1234 Offset.primitiveCount = 1;
1235 Offset.firstVertex = 0;
1236 Offset.primitiveOffset = 0;
1237 Offset.transformOffset = 0;
1156 Offset.primitiveCount = 1;
12381157
12391158 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
12401159 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
1241 ASBuildInfo.flags = 0;
12421160 ASBuildInfo.update = VK_FALSE;
12431161 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
12441162 ASBuildInfo.dstAccelerationStructure = Ctx.TLAS.vkAS;
12891207 vkGetRayTracingShaderGroupHandlesKHR(Ctx.vkDevice, Ctx.vkPipeline, HIT_GROUP, 1, ShaderGroupHandleSize, ShaderHandle);
12901208 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkSBTBuffer, HitShaderBindingTable.offset, ShaderGroupHandleSize, ShaderHandle);
12911209
1292 // barrier for TLAS & SBT
1293 VkMemoryBarrier Barrier = {};
1294 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
1295 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1296 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1297 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1298 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1299 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
1300 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1301
1302 vkCmdBindPipeline(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkPipeline);
1303 vkCmdBindDescriptorSets(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkLayout, 0, 1, &Ctx.vkDescriptorSet, 0, nullptr);
1304
1210 PrepareForTraceRays(Ctx);
13051211 vkCmdTraceRaysKHR(Ctx.vkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, SCDesc.Width, SCDesc.Height, 1);
13061212
13071213 pTestingSwapChainVk->TransitionRenderTarget(Ctx.vkCmdBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0);
13501256 rtGroups.SetStage(MISS_SHADER, SHADER_TYPE_RAY_MISS, GLSL::RayTracingTest4_RM);
13511257 rtGroups.SetStage(HIT_SHADER_1, SHADER_TYPE_RAY_CLOSEST_HIT, GLSL::RayTracingTest4_RCH1);
13521258 rtGroups.SetStage(HIT_SHADER_2, SHADER_TYPE_RAY_CLOSEST_HIT, GLSL::RayTracingTest4_RCH2);
1259
13531260 rtGroups.SetGeneralGroup(RAYGEN_GROUP, RAYGEN_SHADER);
13541261 rtGroups.SetGeneralGroup(MISS_GROUP, MISS_SHADER);
13551262 rtGroups.SetTriangleHitGroup(HIT_GROUP_1, HIT_SHADER_1);
13561263 rtGroups.SetTriangleHitGroup(HIT_GROUP_2, HIT_SHADER_2);
1264
13571265 rtGroups.AddBinding(2u, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, InstanceCount, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
13581266 rtGroups.AddBinding(3u, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
13591267 rtGroups.AddBinding(4u, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
13621270 const auto& PrimitiveOffsets = TestingConstants::MultiGeometry::PrimitiveOffsets;
13631271 const auto& Primitives = TestingConstants::MultiGeometry::Primitives;
13641272
1365 // create acceleration structurea
1366 {
1367 VkMemoryBarrier Barrier = {};
1368 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
1369
1273 // Create acceleration structurea
1274 {
13701275 const auto& Vertices = TestingConstants::MultiGeometry::Vertices;
13711276 const auto& Indices = TestingConstants::MultiGeometry::Indices;
13721277
14021307
14031308 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkVertexBuffer, 0, sizeof(Vertices), Vertices);
14041309 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkIndexBuffer, 0, sizeof(Indices), Indices);
1405
1406 // barrier for vertex & index buffers
1407 Barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1408 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
1409 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1410 VK_PIPELINE_STAGE_TRANSFER_BIT,
1411 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
1412 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1310 AccelStructBarrier(Ctx);
14131311
14141312 VkAccelerationStructureBuildGeometryInfoKHR ASBuildInfo = {};
14151313 VkAccelerationStructureBuildOffsetInfoKHR Offsets[3] = {};
14561354
14571355 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
14581356 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
1459 ASBuildInfo.flags = 0;
14601357 ASBuildInfo.update = VK_FALSE;
14611358 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
14621359 ASBuildInfo.dstAccelerationStructure = Ctx.BLAS.vkAS;
14691366
14701367 VkAccelerationStructureInstanceKHR InstanceData[2] = {};
14711368
1472 InstanceData[0].instanceCustomIndex = 0;
14731369 InstanceData[0].instanceShaderBindingTableRecordOffset = 0;
14741370 InstanceData[0].mask = 0xFF;
1475 InstanceData[0].flags = 0;
14761371 InstanceData[0].accelerationStructureReference = Ctx.BLAS.vkAddress;
14771372 InstanceData[0].transform.matrix[0][0] = 1.0f;
14781373 InstanceData[0].transform.matrix[1][1] = 1.0f;
14791374 InstanceData[0].transform.matrix[2][2] = 1.0f;
14801375
1481 InstanceData[1].instanceCustomIndex = 2;
14821376 InstanceData[1].instanceShaderBindingTableRecordOffset = HitGroupCount / 2;
14831377 InstanceData[1].mask = 0xFF;
1484 InstanceData[1].flags = 0;
14851378 InstanceData[1].accelerationStructureReference = Ctx.BLAS.vkAddress;
14861379 InstanceData[1].transform.matrix[0][0] = 1.0f;
14871380 InstanceData[1].transform.matrix[1][1] = 1.0f;
14911384 InstanceData[1].transform.matrix[2][3] = 0.0f;
14921385
14931386 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkInstanceBuffer, 0, sizeof(InstanceData), InstanceData);
1494
1495 // barrier for BLAS, scratch buffer, instance buffer
1496 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1497 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
1498 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1499 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1500 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
1501 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1387 AccelStructBarrier(Ctx);
15021388
15031389 VkAccelerationStructureBuildOffsetInfoKHR InstOffsets = {};
15041390 VkAccelerationStructureGeometryKHR Instances[2] = {};
15091395 OffsetPtr = &InstOffsets;
15101396 InstOffsets.primitiveCount = _countof(Instances);
15111397
1512 Instances[0].flags = 0;
15131398 Instances[0].geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
15141399 Instances[0].geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
1515 Instances[0].geometry.instances.pNext = nullptr;
15161400 Instances[0].geometry.instances.arrayOfPointers = VK_FALSE;
15171401 Instances[0].geometry.instances.data.deviceAddress = Ctx.vkInstanceBufferAddress;
15181402
1519 Instances[1].flags = 0;
15201403 Instances[1].geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
15211404 Instances[1].geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
1522 Instances[1].geometry.instances.pNext = nullptr;
15231405 Instances[1].geometry.instances.arrayOfPointers = VK_FALSE;
15241406 Instances[1].geometry.instances.data.deviceAddress = Ctx.vkInstanceBufferAddress + sizeof(VkAccelerationStructureInstanceKHR);
15251407
15261408 ASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
15271409 ASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
1528 ASBuildInfo.flags = 0;
15291410 ASBuildInfo.update = VK_FALSE;
15301411 ASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
15311412 ASBuildInfo.dstAccelerationStructure = Ctx.TLAS.vkAS;
15771458 vkUpdateDescriptorSets(Ctx.vkDevice, 1, &DescriptorWrite, 0, nullptr);
15781459 }
15791460
1580 // trace rays
1461 // Trace rays
15811462 {
15821463 VkStridedBufferRegionKHR RaygenShaderBindingTable = {};
15831464 VkStridedBufferRegionKHR MissShaderBindingTable = {};
16191500 vkCmdUpdateBuffer(Ctx.vkCmdBuffer, Ctx.vkSBTBuffer, Offset + ShaderGroupHandleSize, sizeof(Weights[0]), ShaderRecord);
16201501 };
16211502 // instance 1
1622 SetHitGroup(0, HIT_GROUP_1, &Weights[2]); // geometry 1
1623 SetHitGroup(1, HIT_GROUP_1, &Weights[0]); // geometry 2
1624 SetHitGroup(2, HIT_GROUP_1, &Weights[1]); // geometry 3
1503 SetHitGroup(0, HIT_GROUP_1, &Weights[0]); // geometry 1
1504 SetHitGroup(1, HIT_GROUP_1, &Weights[1]); // geometry 2
1505 SetHitGroup(2, HIT_GROUP_1, &Weights[2]); // geometry 3
16251506 // instance 2
1626 SetHitGroup(3, HIT_GROUP_2, &Weights[2]); // geometry 1
1627 SetHitGroup(4, HIT_GROUP_2, &Weights[1]); // geometry 2
1628 SetHitGroup(5, HIT_GROUP_2, &Weights[0]); // geometry 3
1629
1630 // barrier for TLAS & SBT
1631 VkMemoryBarrier Barrier = {};
1632 Barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
1633 Barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
1634 Barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
1635 vkCmdPipelineBarrier(Ctx.vkCmdBuffer,
1636 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT,
1637 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
1638 0, 1, &Barrier, 0, nullptr, 0, nullptr);
1639
1640 vkCmdBindPipeline(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkPipeline);
1641 vkCmdBindDescriptorSets(Ctx.vkCmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, Ctx.vkLayout, 0, 1, &Ctx.vkDescriptorSet, 0, nullptr);
1642
1507 SetHitGroup(3, HIT_GROUP_2, &Weights[3]); // geometry 1
1508 SetHitGroup(4, HIT_GROUP_2, &Weights[4]); // geometry 2
1509 SetHitGroup(5, HIT_GROUP_2, &Weights[5]); // geometry 3
1510
1511 PrepareForTraceRays(Ctx);
16431512 vkCmdTraceRaysKHR(Ctx.vkCmdBuffer, &RaygenShaderBindingTable, &MissShaderBindingTable, &HitShaderBindingTable, &CallableShaderBindingTable, SCDesc.Width, SCDesc.Height, 1);
16441513
16451514 pTestingSwapChainVk->TransitionRenderTarget(Ctx.vkCmdBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0);