diff --git a/Documentation/WickedEngine-Documentation.md b/Documentation/WickedEngine-Documentation.md index 1e643730d..ce9c69e77 100644 --- a/Documentation/WickedEngine-Documentation.md +++ b/Documentation/WickedEngine-Documentation.md @@ -59,6 +59,8 @@ This is a reference for the C++ features of Wicked Engine 12. [GPU Buffers](#gpu-buffers) 13. [Updating GPU buffers](#updating-gpu-buffers) 14. [GPU Queries](#gpu-queries) + 15. [RayTracingAccelerationStructure](#raytracingaccelerationstructure) + 16. [RayTracingPipelineState](#raytracingpipelinestate) 2. [GraphicsDevice_DX11](#wigraphicsdevice_dx11) 3. [GraphicsDevice_DX12](#wigraphicsdevice_dx12) 4. [GraphicsDevice_Vulkan](#wigraphicsdevice_vulkan) @@ -582,6 +584,12 @@ float time_range_milliseconds = float(b.result_timestamp - a.result_timestamp) / Use the `GraphicsDevice::QueryRead()` function to retrieve results. However, note that the GPU Queries are designed to be running on the GPU timeline, so they shouldn't be read by the CPU immediately, but only after some frames of latency. The `wiRenderer::GPUQueryRing` helper can be used for this purpose. +##### RayTracingAccelerationStructure +The acceleration strucuture can be bottom level or top level, and decided by the description strucutre's `type` field. Depending on the `type`, either the `toplevel` or `bottomlevel` member must be filled out before creating the acceleration structure. When creating the acceleration structure with the grpahics device (`GraphicsDevice::CreateRaytracingAccelerationStructure()`), sufficient backing memory is allocated, but the acceleration structure is not built. Building the acceleration structure is performed on the GPU timeline, via the `GraphicsDevice::BuildRaytracingAccelerationStructure()`. To build it from scratch, leave the `src` argument of this function to `nullptr`. To update the acceleration structure without doing a full rebuild, specify a `src` argument. The `src` can be the same acceleration structure, in this case the update will be performed in place. To be able to update an acceleration structure, it must have been created with the `RaytracingAccelerationStructureDesc::FLAG_ALLOW_UPDATE` flag. + +##### RayTracingPipelineState +Binding a ray tracing pipeline state is required to dispatch ray tracing shaders. A ray tracing pipeline state holds a collection of shader libraries and hitgroup definitions. It also declares information about max resource usage of the pipeline. + #### GraphicsDevice_DX11 [[Header]](../WickedEngine/wiGraphicsDevice_DX11.h) [[Cpp]](../WickedEngine/wiGraphicsDevice_DX11.cpp) @@ -673,8 +681,14 @@ This function prepares the scene for rendering. It must be called once every fra #### UpdateRenderData Begin rendering the frame on GPU. This means that GPU compute jobs are kicked, such as particle simulations, texture packing, mipmap generation tasks that were queued up, updating per frame GPU buffer data, animation vertex skinning and other things. -#### Ray tracing -Ray tracing can be used in multiple ways torender the scene. The `RayTraceScene()` function will render the scene with the rays that are provided as the `RayBuffers` type argument. For example, to render the scene from the camera perspective, first create rays that originate from the camera and shoot towards the caera far plane for every pixel. The `GenerateScreenRayBuffers()` helper function implements this functionality, by expecting a [CameraComponent](#cameracomponent) argument and returns a `RayBuffers` structure. The result will be written to a texture that is provided as parameter. The texture must have been created with `BIND_UNORDERED_ACCESS` bind flags, because it will be written in compute shaders. The scene BVH structure must have been already built to use this, it can be accomplished by calling [wiRenderer::BuildSceneBVH()](#build-scene-bvh). The [RenderPath3D_Pathracing](#renderpath3d_pathtracing) uses this ray tracing functionality to render a path traced scene. +#### Ray tracing (hardware accelerated) + +Hardware accelerated ray tracing API is now available, so a variety of renderer features are available using that. If the hardware support is available, the `Scene` will allocate a top level acceleration structure, and the meshes will allocate bottom level acceleration structures for themselves. Updating these is done by simply calling `wiRenderer::UpdateRaytracingAccelerationStructures(cmd)`. The updates will happen on the GPU timeline, so provide a [CommandList](#work-submission) as argument. The top level acceleration structure will be rebuilt from scratch. The bottom level acceleration structures will be rebuilt from scratch once, and then they will be updated (refitted). + +After the acceleration structures are updated, ray tracing shaders can use it after binding to a shader resource slot. + +#### Ray tracing (legacy) +Ray tracing can be used in multiple ways to render the scene. The `RayTraceScene()` function will render the scene with the rays that are provided as the `RayBuffers` type argument. For example, to render the scene from the camera perspective, first create rays that originate from the camera and shoot towards the caera far plane for every pixel. The `GenerateScreenRayBuffers()` helper function implements this functionality, by expecting a [CameraComponent](#cameracomponent) argument and returns a `RayBuffers` structure. The result will be written to a texture that is provided as parameter. The texture must have been created with `BIND_UNORDERED_ACCESS` bind flags, because it will be written in compute shaders. The scene BVH structure must have been already built to use this, it can be accomplished by calling [wiRenderer::BuildSceneBVH()](#build-scene-bvh). The [RenderPath3D_Pathracing](#renderpath3d_pathtracing) uses this ray tracing functionality to render a path traced scene. Other than path tracing, the scene BVH can be rendered by using the `RayTraceSceneBVH` function. This will render the bounding box hierarchy to the screen as a heatmap. Blue colors mean that few boxes were hit per pixel, and with more bounding box hits the colors go to green, yellow, red, and finaly white. This is useful to determine how expensive a the scene is with regards to ray tracing performance. @@ -815,7 +829,7 @@ This is a GPU sorting facility using the Bitonic Sort algorithm. It can be used ### wiGPUBVH [[Header]](../WickedEngine/wiGPUBVH.h) [[Cpp]](../WickedEngine/wiGPUBVH.cpp) -This facility can generate a BVH (Bounding Volume Hierarcy) on the GPU for a [Scene](#scene). The BVH structure can be used to perform efficient RAY-triangle intersections on the GPU, for example in ray tracing. +This facility can generate a BVH (Bounding Volume Hierarcy) on the GPU for a [Scene](#scene). The BVH structure can be used to perform efficient RAY-triangle intersections on the GPU, for example in ray tracing. This is not using the ray tracing API hardware acceleration, but implemented in compute, so it has wide hardware support. ## GUI @@ -1258,6 +1272,15 @@ uint previous_value; InterlockedAdd(myStructuredbuffer[42].value2, 1, previous_value); ``` +- RAYTRACINGACCELERATIONSTRUCTURE(name, slot)
+Declares a ray tracing acceleration structure. Only usabe in HLSL 6.1+ shader model. Requires hardware support for ray tracing. +The binding slot is read only resource type (t slot). +```cpp +RAYTRACINGACCELERATIONSTRUCTURE(Scene, 0); + +TraceRay(Scene, ...); +``` + - SAMPLERSTATE(name, slot)
Declares a sampler used to sample from textures ```cpp diff --git a/Editor/Editor_UWP.vcxproj b/Editor/Editor_UWP.vcxproj index ba4f3761c..376f4b6b3 100644 --- a/Editor/Editor_UWP.vcxproj +++ b/Editor/Editor_UWP.vcxproj @@ -42,7 +42,7 @@ 14.0 true Windows Store - 10.0.18362.0 + 10.0 10.0.17763.0 10.0 false @@ -105,8 +105,8 @@ - + @@ -136,42 +136,42 @@ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false @@ -420,6 +420,11 @@ + + + Document + + diff --git a/Editor/PostprocessWindow.cpp b/Editor/PostprocessWindow.cpp index e1ecb1b72..abc8b2511 100644 --- a/Editor/PostprocessWindow.cpp +++ b/Editor/PostprocessWindow.cpp @@ -13,7 +13,7 @@ PostprocessWindow::PostprocessWindow(EditorComponent* editor) : GUI(&editor->Get assert(GUI && "Invalid GUI!"); ppWindow = new wiWindow(GUI, "PostProcess Window"); - ppWindow->SetSize(XMFLOAT2(400, 550)); + ppWindow->SetSize(XMFLOAT2(400, 600)); GUI->AddWidget(ppWindow); float x = 150; @@ -59,9 +59,33 @@ PostprocessWindow::PostprocessWindow(EditorComponent* editor) : GUI(&editor->Get aoComboBox->AddItem("SSAO"); aoComboBox->AddItem("HBAO"); aoComboBox->AddItem("MSAO"); + aoComboBox->AddItem("RTAO"); aoComboBox->SetSelected(editor->renderPath->getAO()); aoComboBox->OnSelect([=](wiEventArgs args) { editor->renderPath->setAO((RenderPath3D::AO)args.iValue); + + switch (editor->renderPath->getAO()) + { + case RenderPath3D::AO_SSAO: + aoRangeSlider->SetEnabled(true); + aoRangeSlider->SetValue(2.0f); + aoSampleCountSlider->SetEnabled(true); + aoSampleCountSlider->SetValue(9.0f); + break; + case RenderPath3D::AO_RTAO: + aoRangeSlider->SetEnabled(true); + aoRangeSlider->SetValue(10.0f); + aoSampleCountSlider->SetEnabled(true); + aoSampleCountSlider->SetValue(2.0f); + break; + default: + aoRangeSlider->SetEnabled(false); + aoSampleCountSlider->SetEnabled(false); + break; + } + + editor->renderPath->setAORange(aoRangeSlider->GetValue()); + editor->renderPath->setAOSampleCount((uint32_t)aoSampleCountSlider->GetValue()); }); ppWindow->AddWidget(aoComboBox); @@ -75,6 +99,26 @@ PostprocessWindow::PostprocessWindow(EditorComponent* editor) : GUI(&editor->Get }); ppWindow->AddWidget(aoPowerSlider); + aoRangeSlider = new wiSlider(1.0f, 100.0f, 1, 1000, "Range: "); + aoRangeSlider->SetTooltip("Set AO ray length. Only for SSAO and RTAO"); + aoRangeSlider->SetSize(XMFLOAT2(100, 20)); + aoRangeSlider->SetPos(XMFLOAT2(x + 100, y += step)); + aoRangeSlider->SetValue((float)editor->renderPath->getAOPower()); + aoRangeSlider->OnSlide([=](wiEventArgs args) { + editor->renderPath->setAORange(args.fValue); + }); + ppWindow->AddWidget(aoRangeSlider); + + aoSampleCountSlider = new wiSlider(1, 16, 9, 15, "Sample Count: "); + aoSampleCountSlider->SetTooltip("Set AO ray count. Only for SSAO and RTAO"); + aoSampleCountSlider->SetSize(XMFLOAT2(100, 20)); + aoSampleCountSlider->SetPos(XMFLOAT2(x + 100, y += step)); + aoSampleCountSlider->SetValue((float)editor->renderPath->getAOPower()); + aoSampleCountSlider->OnSlide([=](wiEventArgs args) { + editor->renderPath->setAOSampleCount(args.iValue); + }); + ppWindow->AddWidget(aoSampleCountSlider); + ssrCheckBox = new wiCheckBox("SSR: "); ssrCheckBox->SetTooltip("Enable Screen Space Reflections."); ssrCheckBox->SetScriptTip("RenderPath3D::SetSSREnabled(bool value)"); diff --git a/Editor/PostprocessWindow.h b/Editor/PostprocessWindow.h index 248af9287..a489abf00 100644 --- a/Editor/PostprocessWindow.h +++ b/Editor/PostprocessWindow.h @@ -24,6 +24,8 @@ public: wiCheckBox* lightShaftsCheckBox; wiComboBox* aoComboBox; wiSlider* aoPowerSlider; + wiSlider* aoRangeSlider; + wiSlider* aoSampleCountSlider; wiCheckBox* ssrCheckBox; wiCheckBox* sssCheckBox; wiCheckBox* eyeAdaptionCheckBox; diff --git a/README.md b/README.md index c4b02294d..c17128990 100644 --- a/README.md +++ b/README.md @@ -230,8 +230,7 @@ You can specify command line arguments to switch between render devices or other Python script which will generate the SPIR-V shader building program "build_SPIRV.bat". Run "build_SPIRV.bat" to build all HLSL shaders as SPIR-V bytecode format for Vulkan. Shader loading after this is automatic if you start the application with Vulkan support. -* **To load HLSL 6 shaders, first, run the "generate_shader_buildtask_hlsl6.py" -Python script which will generate the HLSL6 shader building program "build_HLSL6.bat". Run "build_HLSL6.bat" to build all HLSL shaders as HLSL6 bytecode format for DirectX12. +* **To load HLSL 6 shaders, first compile the Shaders_HLSL6 project in Visual Studio
diff --git a/Template_UWP/Template_UWP.vcxproj b/Template_UWP/Template_UWP.vcxproj index b8a96b1d7..eb7fb277e 100644 --- a/Template_UWP/Template_UWP.vcxproj +++ b/Template_UWP/Template_UWP.vcxproj @@ -42,7 +42,7 @@ 14.0 true Windows Store - 10.0.18362.0 + 10.0 10.0.17763.0 10.0 false @@ -104,7 +104,7 @@
- + @@ -134,42 +134,42 @@ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false $(SolutionDir)BUILD\$(Platform)\$(Configuration)\$(ProjectName)\ $(ProjectName)\$(Platform)\$(Configuration)\ - true + false @@ -482,6 +482,11 @@ + + + Document + + diff --git a/WickedEngine.sln b/WickedEngine.sln index 4f0324a0c..fdc10bf2f 100644 --- a/WickedEngine.sln +++ b/WickedEngine.sln @@ -27,27 +27,66 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_Windows", "Wic EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_UWP", "WickedEngine\WickedEngine_UWP.vcxproj", "{60DA258F-E95F-4CF4-A46B-17D80644464B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_SHADERS", "WickedEngine\WickedEngine_SHADERS.vcxitems", "{92E86448-0724-4387-ABAC-96E63EDF4190}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Content", "Content.vcxitems", "{C48F6BFF-F91B-4DB5-98B5-15287DFB7C95}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_Linux", "WickedEngine\WickedEngine_Linux.vcxproj", "{D294C41D-D886-4B95-9FD6-EE13EEE8D976}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shaders_SOURCE", "WickedEngine\Shaders_SOURCE.vcxitems", "{92E86448-0724-4387-ABAC-96E63EDF4190}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shaders_HLSL6", "WickedEngine\Shaders_HLSL6.vcxproj", "{9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Supplementary", "Supplementary", "{BF8FCAB8-D7D3-4DAE-92DE-4B5037E9A0ED}" + ProjectSection(SolutionItems) = preProject + appveyor.yml = appveyor.yml + features.txt = features.txt + generate_shader_buildtask_hlsl6.py = generate_shader_buildtask_hlsl6.py + generate_shader_buildtask_spirv.py = generate_shader_buildtask_spirv.py + LICENSE.md = LICENSE.md + other_licenses.txt = other_licenses.txt + README.md = README.md + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shaders_SPIRV", "WickedEngine\Shaders_SPIRV.vcxproj", "{DF832DE3-02FA-4D00-B853-1229A9505E14}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{6C5B74BD-2300-47A1-8FE1-DB88D6F55959}" + ProjectSection(SolutionItems) = preProject + Documentation\ScriptingAPI-Documentation.md = Documentation\ScriptingAPI-Documentation.md + Documentation\WickedEngine-Documentation.md = Documentation\WickedEngine-Documentation.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{3257CB8C-789A-4370-88CB-6DB5D77D300D}" + ProjectSection(SolutionItems) = preProject + scripts\camera_animation_clamped.lua = scripts\camera_animation_clamped.lua + scripts\camera_animation_repeat.lua = scripts\camera_animation_repeat.lua + scripts\character_controller_tps.lua = scripts\character_controller_tps.lua + scripts\debug_draw.lua = scripts\debug_draw.lua + scripts\dungeon_generator.lua = scripts\dungeon_generator.lua + scripts\emitter_burst.lua = scripts\emitter_burst.lua + scripts\fighting_game.lua = scripts\fighting_game.lua + scripts\move_object.lua = scripts\move_object.lua + scripts\pick.lua = scripts\pick.lua + scripts\rotate_model.lua = scripts\rotate_model.lua + scripts\set_material_color.lua = scripts\set_material_color.lua + scripts\set_material_emissive.lua = scripts\set_material_emissive.lua + EndProjectSection +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution - WickedEngine\WickedEngine_SHADERS.vcxitems*{06163dcb-b183-4ed9-9c62-13ef1658e049}*SharedItemsImports = 4 + WickedEngine\Shaders_SOURCE.vcxitems*{06163dcb-b183-4ed9-9c62-13ef1658e049}*SharedItemsImports = 4 WickedEngine\WickedEngine_SOURCE.vcxitems*{06163dcb-b183-4ed9-9c62-13ef1658e049}*SharedItemsImports = 4 WickedEngine\WickedEngine_SOURCE.vcxitems*{45d41acc-2c3c-43d2-bc10-02aa73ffc7c7}*SharedItemsImports = 9 Editor\Editor_SOURCE.vcxitems*{5fe97b9b-a445-4eea-a42d-9de60b891d48}*SharedItemsImports = 4 WickedEngine\WickedEngine_SOURCE.vcxitems*{60da258f-e95f-4cf4-a46b-17d80644464b}*SharedItemsImports = 4 Editor\Editor_SOURCE.vcxitems*{867febca-09c4-4fe7-8a4c-4d9b1c27e7d0}*SharedItemsImports = 9 - WickedEngine\WickedEngine_SHADERS.vcxitems*{92e86448-0724-4387-abac-96e63edf4190}*SharedItemsImports = 9 - WickedEngine\WickedEngine_SHADERS.vcxitems*{c222218b-b6d1-406b-b2c0-8c1ced4a8d19}*SharedItemsImports = 4 + WickedEngine\Shaders_SOURCE.vcxitems*{92e86448-0724-4387-abac-96e63edf4190}*SharedItemsImports = 9 + WickedEngine\Shaders_SOURCE.vcxitems*{9c8f8910-cca3-41cb-a2fa-3545cdd5d8bf}*SharedItemsImports = 4 + WickedEngine\Shaders_SOURCE.vcxitems*{c222218b-b6d1-406b-b2c0-8c1ced4a8d19}*SharedItemsImports = 4 Content.vcxitems*{c48f6bff-f91b-4db5-98b5-15287dfb7c95}*SharedItemsImports = 9 WickedEngine\WickedEngine_SOURCE.vcxitems*{d294c41d-d886-4b95-9fd6-ee13eee8d976}*SharedItemsImports = 4 + WickedEngine\Shaders_SOURCE.vcxitems*{df832de3-02fa-4d00-b853-1229a9505e14}*SharedItemsImports = 4 Content.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 Editor\Editor_SOURCE.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 - WickedEngine\WickedEngine_SHADERS.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 + WickedEngine\Shaders_SOURCE.vcxitems*{fa78bfad-4b23-4a6b-92fa-a48ce56bed03}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -196,10 +235,46 @@ Global {D294C41D-D886-4B95-9FD6-EE13EEE8D976}.Release|x64.ActiveCfg = Release|x64 {D294C41D-D886-4B95-9FD6-EE13EEE8D976}.Release|x64.Build.0 = Release|x64 {D294C41D-D886-4B95-9FD6-EE13EEE8D976}.Release|x64.Deploy.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|ARM.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|ARM.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|ARM64.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|ARM64.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|Win32.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|Win32.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|x64.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Debug|x64.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|ARM.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|ARM.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|ARM64.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|ARM64.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|Win32.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|Win32.Build.0 = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|x64.ActiveCfg = Release|x64 + {9C8F8910-CCA3-41CB-A2FA-3545CDD5D8BF}.Release|x64.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|ARM.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|ARM.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|ARM64.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|ARM64.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|Win32.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|Win32.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|x64.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Debug|x64.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|ARM.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|ARM.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|ARM64.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|ARM64.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|Win32.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|Win32.Build.0 = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|x64.ActiveCfg = Release|x64 + {DF832DE3-02FA-4D00-B853-1229A9505E14}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6C5B74BD-2300-47A1-8FE1-DB88D6F55959} = {BF8FCAB8-D7D3-4DAE-92DE-4B5037E9A0ED} + {3257CB8C-789A-4370-88CB-6DB5D77D300D} = {BF8FCAB8-D7D3-4DAE-92DE-4B5037E9A0ED} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E3FF044A-B72E-4ED5-BE05-AB641BA048CD} EndGlobalSection diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index f8d683348..327b24a91 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -362,6 +362,11 @@ void RenderPath3D::RenderFrameSetUp(CommandList cmd) const { GraphicsDevice* device = wiRenderer::GetDevice(); + if (getAO() == AO_RTAO) + { + wiRenderer::UpdateRaytracingAccelerationStructures(cmd); + } + device->BindResource(CS, &depthBuffer_Copy, TEXSLOT_DEPTH, cmd); wiRenderer::UpdateRenderData(cmd); @@ -469,6 +474,17 @@ void RenderPath3D::RenderAO(CommandList cmd) const getAOPower() ); break; + case AO_RTAO: + wiRenderer::Postprocess_RTAO( + depthBuffer_Copy, + rtLinearDepth, + rtAO, + cmd, + getAORange(), + getAOSampleCount(), + getAOPower() + ); + break; } } } diff --git a/WickedEngine/RenderPath3D.h b/WickedEngine/RenderPath3D.h index ea6770cd8..dd5300560 100644 --- a/WickedEngine/RenderPath3D.h +++ b/WickedEngine/RenderPath3D.h @@ -16,6 +16,7 @@ public: AO_SSAO, // simple brute force screen space ambient occlusion AO_HBAO, // horizon based screen space ambient occlusion AO_MSAO, // multi scale screen space ambient occlusion + AO_RTAO, // ray traced ambient occlusion // Don't alter order! (bound to lua manually) }; private: diff --git a/WickedEngine/RenderPath3D_BindLua.cpp b/WickedEngine/RenderPath3D_BindLua.cpp index 41afd7f28..042318359 100644 --- a/WickedEngine/RenderPath3D_BindLua.cpp +++ b/WickedEngine/RenderPath3D_BindLua.cpp @@ -395,5 +395,6 @@ void RenderPath3D_BindLua::Bind() wiLua::GetGlobal()->RunText("AO_SSAO = 1"); wiLua::GetGlobal()->RunText("AO_HBAO = 2"); wiLua::GetGlobal()->RunText("AO_MSAO = 3"); + wiLua::GetGlobal()->RunText("AO_RTAO = 4"); } } diff --git a/WickedEngine/ShaderInterop.h b/WickedEngine/ShaderInterop.h index 71009aa64..cc6affeb0 100644 --- a/WickedEngine/ShaderInterop.h +++ b/WickedEngine/ShaderInterop.h @@ -63,28 +63,30 @@ typedef XMINT4 int4; #define RWSTRUCTUREDBUFFER(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_UNTYPEDBUFFER + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWStructuredBuffer< type > name #define ROVSTRUCTUREDBUFFER(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_UNTYPEDBUFFER + slot, VULKAN_DESCRIPTOR_SET_ID)]] RasterizerOrderedStructuredBuffer< type > name - -#define TEXTURE1D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture1D< type > name; -#define TEXTURE1DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture1DArray< type > name; -#define RWTEXTURE1D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture1D< type > name; - -#define TEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2D< type > name; -#define TEXTURE2DMS(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2DMS< type > name; -#define TEXTURE2DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2DArray< type > name; -#define RWTEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture2D< type > name; -#define RWTEXTURE2DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture2DArray< type > name; -#define ROVTEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RasterizerOrderedTexture2D< type > name; - -#define TEXTURECUBE(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] TextureCube< type > name; -#define TEXTURECUBEARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] TextureCubeArray< type > name; - -#define TEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture3D< type > name; -#define RWTEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture3D< type > name; -#define ROVTEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RasterizerOrderedTexture3D< type > name; +#define RAYTRACINGACCELERATIONSTRUCTURE(name, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_UNTYPEDBUFFER + slot, VULKAN_DESCRIPTOR_SET_ID)]] RaytracingAccelerationStructure name -#define SAMPLERSTATE(name, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SAMPLER + slot, VULKAN_DESCRIPTOR_SET_ID)]] SamplerState name; -#define SAMPLERCOMPARISONSTATE(name, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SAMPLER + slot, VULKAN_DESCRIPTOR_SET_ID)]] SamplerComparisonState name; +#define TEXTURE1D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture1D< type > name +#define TEXTURE1DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture1DArray< type > name +#define RWTEXTURE1D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture1D< type > name + +#define TEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2D< type > name +#define TEXTURE2DMS(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2DMS< type > name +#define TEXTURE2DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture2DArray< type > name +#define RWTEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture2D< type > name +#define RWTEXTURE2DARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture2DArray< type > name +#define ROVTEXTURE2D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RasterizerOrderedTexture2D< type > name + +#define TEXTURECUBE(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] TextureCube< type > name +#define TEXTURECUBEARRAY(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] TextureCubeArray< type > name + +#define TEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SRV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] Texture3D< type > name +#define RWTEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RWTexture3D< type > name +#define ROVTEXTURE3D(name, type, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_UAV_TEXTURE + slot, VULKAN_DESCRIPTOR_SET_ID)]] RasterizerOrderedTexture3D< type > name + + +#define SAMPLERSTATE(name, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SAMPLER + slot, VULKAN_DESCRIPTOR_SET_ID)]] SamplerState name +#define SAMPLERCOMPARISONSTATE(name, slot) [[vk::binding(VULKAN_DESCRIPTOR_SET_OFFSET_SAMPLER + slot, VULKAN_DESCRIPTOR_SET_ID)]] SamplerComparisonState name // Don't have access to wave-intrinsics in Vulkan yet: #define WaveReadLaneFirst(a) (a) @@ -105,28 +107,30 @@ typedef XMINT4 int4; #define RWSTRUCTUREDBUFFER(name, type, slot) RWStructuredBuffer< type > name : register(u ## slot) #define ROVSTRUCTUREDBUFFER(name, type, slot) RasterizerOrderedStructuredBuffer< type > name : register(u ## slot) - -#define TEXTURE1D(name, type, slot) Texture1D< type > name : register(t ## slot); -#define TEXTURE1DARRAY(name, type, slot) Texture1DArray< type > name : register(t ## slot); -#define RWTEXTURE1D(name, type, slot) RWTexture1D< type > name : register(u ## slot); - -#define TEXTURE2D(name, type, slot) Texture2D< type > name : register(t ## slot); -#define TEXTURE2DMS(name, type, slot) Texture2DMS< type > name : register(t ## slot); -#define TEXTURE2DARRAY(name, type, slot) Texture2DArray< type > name : register(t ## slot); -#define RWTEXTURE2D(name, type, slot) RWTexture2D< type > name : register(u ## slot); -#define RWTEXTURE2DARRAY(name, type, slot) RWTexture2DArray< type > name : register(u ## slot); -#define ROVTEXTURE2D(name, type, slot) RasterizerOrderedTexture2D< type > name : register(u ## slot); - -#define TEXTURECUBE(name, type, slot) TextureCube< type > name : register(t ## slot); -#define TEXTURECUBEARRAY(name, type, slot) TextureCubeArray< type > name : register(t ## slot); - -#define TEXTURE3D(name, type, slot) Texture3D< type > name : register(t ## slot); -#define RWTEXTURE3D(name, type, slot) RWTexture3D< type > name : register(u ## slot); -#define ROVTEXTURE3D(name, type, slot) RasterizerOrderedTexture3D< type > name : register(u ## slot); +#define RAYTRACINGACCELERATIONSTRUCTURE(name, slot) RaytracingAccelerationStructure name : register(t ## slot) -#define SAMPLERSTATE(name, slot) SamplerState name : register(s ## slot); -#define SAMPLERCOMPARISONSTATE(name, slot) SamplerComparisonState name : register(s ## slot); +#define TEXTURE1D(name, type, slot) Texture1D< type > name : register(t ## slot) +#define TEXTURE1DARRAY(name, type, slot) Texture1DArray< type > name : register(t ## slot) +#define RWTEXTURE1D(name, type, slot) RWTexture1D< type > name : register(u ## slot) + +#define TEXTURE2D(name, type, slot) Texture2D< type > name : register(t ## slot) +#define TEXTURE2DMS(name, type, slot) Texture2DMS< type > name : register(t ## slot) +#define TEXTURE2DARRAY(name, type, slot) Texture2DArray< type > name : register(t ## slot) +#define RWTEXTURE2D(name, type, slot) RWTexture2D< type > name : register(u ## slot) +#define RWTEXTURE2DARRAY(name, type, slot) RWTexture2DArray< type > name : register(u ## slot) +#define ROVTEXTURE2D(name, type, slot) RasterizerOrderedTexture2D< type > name : register(u ## slot) + +#define TEXTURECUBE(name, type, slot) TextureCube< type > name : register(t ## slot) +#define TEXTURECUBEARRAY(name, type, slot) TextureCubeArray< type > name : register(t ## slot) + +#define TEXTURE3D(name, type, slot) Texture3D< type > name : register(t ## slot) +#define RWTEXTURE3D(name, type, slot) RWTexture3D< type > name : register(u ## slot) +#define ROVTEXTURE3D(name, type, slot) RasterizerOrderedTexture3D< type > name : register(u ## slot) + + +#define SAMPLERSTATE(name, slot) SamplerState name : register(s ## slot) +#define SAMPLERCOMPARISONSTATE(name, slot) SamplerComparisonState name : register(s ## slot) #ifndef SHADER_MODEL_6 // Don't have access to wave-intrinsics in pre-SM6: diff --git a/WickedEngine/ShaderInterop_Postprocess.h b/WickedEngine/ShaderInterop_Postprocess.h index 789fada42..22a18049a 100644 --- a/WickedEngine/ShaderInterop_Postprocess.h +++ b/WickedEngine/ShaderInterop_Postprocess.h @@ -24,6 +24,10 @@ CBUFFER(PostProcessCB, CBSLOT_RENDERER_POSTPROCESS) #define ssao_samplecount xPPParams0.y #define ssao_power xPPParams0.z +#define rtao_range ssao_range +#define rtao_samplecount ssao_samplecount +#define rtao_power ssao_power + static const uint POSTPROCESS_HBAO_THREADCOUNT = 320; #define hbao_direction xPPParams0.xy #define hbao_power xPPParams0.z diff --git a/WickedEngine/Shaders_HLSL6.vcxproj b/WickedEngine/Shaders_HLSL6.vcxproj new file mode 100644 index 000000000..713c9fb0c --- /dev/null +++ b/WickedEngine/Shaders_HLSL6.vcxproj @@ -0,0 +1,65 @@ + + + + + Release + x64 + + + + 16.0 + Win32Proj + {9c8f8910-cca3-41cb-a2fa-3545cdd5d8bf} + ShadersHLSL6 + 10.0 + + + + Utility + false + v142 + true + Unicode + + + + + + + + + + + + + false + $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ + $(ProjectName)\$(Platform)\$(Configuration)\ + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + 6.4 + shaders/hlsl6/%(Filename).cso + -flegacy-macro-expansion %(AdditionalOptions) + + + + + + + + \ No newline at end of file diff --git a/WickedEngine/WickedEngine_SHADERS.vcxitems b/WickedEngine/Shaders_SOURCE.vcxitems similarity index 98% rename from WickedEngine/WickedEngine_SHADERS.vcxitems rename to WickedEngine/Shaders_SOURCE.vcxitems index b5c52f9c5..5a878b512 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxitems +++ b/WickedEngine/Shaders_SOURCE.vcxitems @@ -615,6 +615,49 @@ Pixel Pixel + + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + + + Library + 6.4 + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + -flegacy-macro-expansion %(AdditionalOptions) + Document + Pixel Pixel diff --git a/WickedEngine/WickedEngine_SHADERS.vcxitems.filters b/WickedEngine/Shaders_SOURCE.vcxitems.filters similarity index 99% rename from WickedEngine/WickedEngine_SHADERS.vcxitems.filters rename to WickedEngine/Shaders_SOURCE.vcxitems.filters index 3e674aeb7..1750800a1 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxitems.filters +++ b/WickedEngine/Shaders_SOURCE.vcxitems.filters @@ -22,6 +22,9 @@ {9f327310-fe88-414c-a23a-22839ea58475} + + {1c9fec3c-c842-4bb0-9e03-69baf6cc090e} + @@ -977,5 +980,8 @@ CS + + RT + \ No newline at end of file diff --git a/WickedEngine/Shaders_SPIRV.vcxproj b/WickedEngine/Shaders_SPIRV.vcxproj new file mode 100644 index 000000000..2771af441 --- /dev/null +++ b/WickedEngine/Shaders_SPIRV.vcxproj @@ -0,0 +1,65 @@ + + + + + Release + x64 + + + + 16.0 + Win32Proj + {DF832DE3-02FA-4D00-B853-1229A9505E14} + ShadersHLSL6 + 10.0 + + + + Utility + false + v142 + true + Unicode + + + + + + + + + + + + + false + $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ + $(ProjectName)\$(Platform)\$(Configuration)\ + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + 6.4 + shaders/spirv/%(Filename).cso + -flegacy-macro-expansion -spirv -fvk-use-dx-layout %(AdditionalOptions) + + + + + + + + \ No newline at end of file diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems b/WickedEngine/WickedEngine_SOURCE.vcxitems index 9bf0a1265..309652a1c 100644 --- a/WickedEngine/WickedEngine_SOURCE.vcxitems +++ b/WickedEngine/WickedEngine_SOURCE.vcxitems @@ -700,22 +700,6 @@ - - false - false - false - false - false - false - - - false - false - false - false - false - false - false false @@ -726,37 +710,6 @@ - - - - - false - false - false - false - false - false - - - false - false - false - false - false - false - - - - - - - - - - - - - diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters index b1bf00706..80c04c96a 100644 --- a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters +++ b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters @@ -55,18 +55,12 @@ {4cb4ddc4-c5a9-483b-b6cf-2c4382340e7a} - - {052d6b54-4254-4260-ba34-79b6fb943b4a} - {f9156b5b-9cc8-436c-9faa-536f7dce4f27} {a25b4076-72bb-4c78-8bc1-84c59a8984fd} - - {0b9a1138-b94c-416f-838b-89f81f53fbc3} - @@ -1912,56 +1906,9 @@ - - - - - Documentation - - - Documentation - - - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - - - scripts - UTILITY diff --git a/WickedEngine/WickedEngine_Windows.vcxproj b/WickedEngine/WickedEngine_Windows.vcxproj index aa6e6b6ee..6bb458ae5 100644 --- a/WickedEngine/WickedEngine_Windows.vcxproj +++ b/WickedEngine/WickedEngine_Windows.vcxproj @@ -56,7 +56,7 @@ - + @@ -74,22 +74,22 @@ $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ - true + false $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ - true + false $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ - true + false $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)BUILD\$(Platform)\$(Configuration)\ - true + false diff --git a/WickedEngine/envMap_skyPS_static.hlsl b/WickedEngine/envMap_skyPS_static.hlsl index 417e9833a..70c75a501 100644 --- a/WickedEngine/envMap_skyPS_static.hlsl +++ b/WickedEngine/envMap_skyPS_static.hlsl @@ -1,7 +1,7 @@ #include "envMapHF.hlsli" #include "skyHF.hlsli" -TEXTURECUBE(texture_sky, float4, TEXSLOT_ONDEMAND0) +TEXTURECUBE(texture_sky, float4, TEXSLOT_ONDEMAND0); float4 main(PSIn_Sky_EnvmapRendering input) : SV_TARGET { diff --git a/WickedEngine/fontPS.hlsl b/WickedEngine/fontPS.hlsl index 4197c86a7..60d7820d5 100644 --- a/WickedEngine/fontPS.hlsl +++ b/WickedEngine/fontPS.hlsl @@ -2,7 +2,7 @@ #include "ShaderInterop_Font.h" TEXTURE2D(texture_font, float, TEXSLOT_FONTATLAS); -SAMPLERSTATE(sampler_font, SSLOT_ONDEMAND1) +SAMPLERSTATE(sampler_font, SSLOT_ONDEMAND1); struct VertextoPixel { diff --git a/WickedEngine/globals.hlsli b/WickedEngine/globals.hlsli index 00509a849..f548a60bf 100644 --- a/WickedEngine/globals.hlsli +++ b/WickedEngine/globals.hlsli @@ -3,47 +3,47 @@ #include "ShaderInterop.h" #include "ShaderInterop_Renderer.h" -TEXTURE2D(texture_depth, float, TEXSLOT_DEPTH) -TEXTURE2D(texture_lineardepth, float, TEXSLOT_LINEARDEPTH) -TEXTURE2D(texture_gbuffer0, float4, TEXSLOT_GBUFFER0) -TEXTURE2D(texture_gbuffer1, float4, TEXSLOT_GBUFFER1) -TEXTURE2D(texture_gbuffer2, float4, TEXSLOT_GBUFFER2) -TEXTURECUBE(texture_globalenvmap, float4, TEXSLOT_GLOBALENVMAP) -TEXTURE2D(texture_globallightmap, float4, TEXSLOT_GLOBALLIGHTMAP) -TEXTURECUBEARRAY(texture_envmaparray, float4, TEXSLOT_ENVMAPARRAY) -TEXTURE2D(texture_decalatlas, float4, TEXSLOT_DECALATLAS) -TEXTURE2DARRAY(texture_shadowarray_2d, float, TEXSLOT_SHADOWARRAY_2D) -TEXTURECUBEARRAY(texture_shadowarray_cube, float, TEXSLOT_SHADOWARRAY_CUBE) -TEXTURE2DARRAY(texture_shadowarray_transparent, float4, TEXSLOT_SHADOWARRAY_TRANSPARENT) -TEXTURE3D(texture_voxelradiance, float4, TEXSLOT_VOXELRADIANCE) +TEXTURE2D(texture_depth, float, TEXSLOT_DEPTH); +TEXTURE2D(texture_lineardepth, float, TEXSLOT_LINEARDEPTH); +TEXTURE2D(texture_gbuffer0, float4, TEXSLOT_GBUFFER0); +TEXTURE2D(texture_gbuffer1, float4, TEXSLOT_GBUFFER1); +TEXTURE2D(texture_gbuffer2, float4, TEXSLOT_GBUFFER2); +TEXTURECUBE(texture_globalenvmap, float4, TEXSLOT_GLOBALENVMAP); +TEXTURE2D(texture_globallightmap, float4, TEXSLOT_GLOBALLIGHTMAP); +TEXTURECUBEARRAY(texture_envmaparray, float4, TEXSLOT_ENVMAPARRAY); +TEXTURE2D(texture_decalatlas, float4, TEXSLOT_DECALATLAS); +TEXTURE2DARRAY(texture_shadowarray_2d, float, TEXSLOT_SHADOWARRAY_2D); +TEXTURECUBEARRAY(texture_shadowarray_cube, float, TEXSLOT_SHADOWARRAY_CUBE); +TEXTURE2DARRAY(texture_shadowarray_transparent, float4, TEXSLOT_SHADOWARRAY_TRANSPARENT); +TEXTURE3D(texture_voxelradiance, float4, TEXSLOT_VOXELRADIANCE); STRUCTUREDBUFFER(EntityTiles, uint, SBSLOT_ENTITYTILES); STRUCTUREDBUFFER(EntityArray, ShaderEntity, SBSLOT_ENTITYARRAY); STRUCTUREDBUFFER(MatrixArray, float4x4, SBSLOT_MATRIXARRAY); -TEXTURE2D(texture_0, float4, TEXSLOT_ONDEMAND0) -TEXTURE2D(texture_1, float4, TEXSLOT_ONDEMAND1) -TEXTURE2D(texture_2, float4, TEXSLOT_ONDEMAND2) -TEXTURE2D(texture_3, float4, TEXSLOT_ONDEMAND3) -TEXTURE2D(texture_4, float4, TEXSLOT_ONDEMAND4) -TEXTURE2D(texture_5, float4, TEXSLOT_ONDEMAND5) -TEXTURE2D(texture_6, float4, TEXSLOT_ONDEMAND6) -TEXTURE2D(texture_7, float4, TEXSLOT_ONDEMAND7) -TEXTURE2D(texture_8, float4, TEXSLOT_ONDEMAND8) -TEXTURE2D(texture_9, float4, TEXSLOT_ONDEMAND9) +TEXTURE2D(texture_0, float4, TEXSLOT_ONDEMAND0); +TEXTURE2D(texture_1, float4, TEXSLOT_ONDEMAND1); +TEXTURE2D(texture_2, float4, TEXSLOT_ONDEMAND2); +TEXTURE2D(texture_3, float4, TEXSLOT_ONDEMAND3); +TEXTURE2D(texture_4, float4, TEXSLOT_ONDEMAND4); +TEXTURE2D(texture_5, float4, TEXSLOT_ONDEMAND5); +TEXTURE2D(texture_6, float4, TEXSLOT_ONDEMAND6); +TEXTURE2D(texture_7, float4, TEXSLOT_ONDEMAND7); +TEXTURE2D(texture_8, float4, TEXSLOT_ONDEMAND8); +TEXTURE2D(texture_9, float4, TEXSLOT_ONDEMAND9); -SAMPLERSTATE( sampler_linear_clamp, SSLOT_LINEAR_CLAMP ) -SAMPLERSTATE( sampler_linear_wrap, SSLOT_LINEAR_WRAP ) -SAMPLERSTATE( sampler_linear_mirror, SSLOT_LINEAR_MIRROR ) -SAMPLERSTATE( sampler_point_clamp, SSLOT_POINT_CLAMP ) -SAMPLERSTATE( sampler_point_wrap, SSLOT_POINT_WRAP ) -SAMPLERSTATE( sampler_point_mirror, SSLOT_POINT_MIRROR ) -SAMPLERSTATE( sampler_aniso_clamp, SSLOT_ANISO_CLAMP ) -SAMPLERSTATE( sampler_aniso_wrap, SSLOT_ANISO_WRAP ) -SAMPLERSTATE( sampler_aniso_mirror, SSLOT_ANISO_MIRROR ) -SAMPLERCOMPARISONSTATE( sampler_cmp_depth, SSLOT_CMP_DEPTH ) -SAMPLERSTATE( sampler_objectshader, SSLOT_OBJECTSHADER ) +SAMPLERSTATE( sampler_linear_clamp, SSLOT_LINEAR_CLAMP ); +SAMPLERSTATE( sampler_linear_wrap, SSLOT_LINEAR_WRAP ); +SAMPLERSTATE( sampler_linear_mirror, SSLOT_LINEAR_MIRROR ); +SAMPLERSTATE( sampler_point_clamp, SSLOT_POINT_CLAMP ); +SAMPLERSTATE( sampler_point_wrap, SSLOT_POINT_WRAP ); +SAMPLERSTATE( sampler_point_mirror, SSLOT_POINT_MIRROR ); +SAMPLERSTATE( sampler_aniso_clamp, SSLOT_ANISO_CLAMP ); +SAMPLERSTATE( sampler_aniso_wrap, SSLOT_ANISO_WRAP ); +SAMPLERSTATE( sampler_aniso_mirror, SSLOT_ANISO_MIRROR ); +SAMPLERCOMPARISONSTATE( sampler_cmp_depth, SSLOT_CMP_DEPTH ); +SAMPLERSTATE( sampler_objectshader, SSLOT_OBJECTSHADER ); static const float PI = 3.14159265358979323846; static const float SQRT2 = 1.41421356237309504880; diff --git a/WickedEngine/resolveMSAADepthStencilCS.hlsl b/WickedEngine/resolveMSAADepthStencilCS.hlsl index 0ef554cf3..f933b39f4 100644 --- a/WickedEngine/resolveMSAADepthStencilCS.hlsl +++ b/WickedEngine/resolveMSAADepthStencilCS.hlsl @@ -1,8 +1,8 @@ #include "globals.hlsli" // Resolve MSAA depth buffer to a non MSAA texture -TEXTURE2DMS(input, float, TEXSLOT_ONDEMAND0) -RWTEXTURE2D(output, float, 0) +TEXTURE2DMS(input, float, TEXSLOT_ONDEMAND0); +RWTEXTURE2D(output, float, 0); [numthreads(8, 8, 1)] void main(uint3 dispatchThreadId : SV_DispatchThreadID) diff --git a/WickedEngine/rtaoLIB.hlsl b/WickedEngine/rtaoLIB.hlsl new file mode 100644 index 000000000..a6ccbb637 --- /dev/null +++ b/WickedEngine/rtaoLIB.hlsl @@ -0,0 +1,70 @@ +#include "globals.hlsli" +#include "ShaderInterop_Postprocess.h" +#include "raytracingHF.hlsli" + +RAYTRACINGACCELERATIONSTRUCTURE(Scene, TEXSLOT_ONDEMAND0); +RWTEXTURE2D(output, unorm float, 0); + +typedef BuiltInTriangleIntersectionAttributes MyAttributes; +struct RayPayload +{ + float color; +}; + +[shader("raygeneration")] +void RTAO_Raygen() +{ + const float2 uv = ((float2)DispatchRaysIndex() + 0.5f) / (float2)DispatchRaysDimensions(); + const float depth = texture_depth.SampleLevel(sampler_point_clamp, uv, 0); + if (depth == 0.0f) + return; + + const float3 P = reconstructPosition(uv, depth); + + float2 uv0 = uv; // center + float2 uv1 = uv + float2(1, 0) / (float2)DispatchRaysDimensions(); // right + float2 uv2 = uv + float2(0, 1) / (float2)DispatchRaysDimensions(); // top + + float depth0 = texture_depth.SampleLevel(sampler_point_clamp, uv0, 0).r; + float depth1 = texture_depth.SampleLevel(sampler_point_clamp, uv1, 0).r; + float depth2 = texture_depth.SampleLevel(sampler_point_clamp, uv2, 0).r; + + float3 P0 = reconstructPosition(uv0, depth0); + float3 P1 = reconstructPosition(uv1, depth1); + float3 P2 = reconstructPosition(uv2, depth2); + + float3 N = normalize(cross(P1 - P0, P2 - P0)); + + float seed = 666; + + RayDesc ray; + ray.TMin = 0.001; + ray.TMax = rtao_range; + ray.Origin = P + N * 0.1; + + RayPayload payload = { 0 }; + + for (uint i = 0; i < (uint)rtao_samplecount; ++i) + { + ray.Direction = SampleHemisphere_cos(N, seed, uv); + TraceRay(Scene, + RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | + RAY_FLAG_SKIP_CLOSEST_HIT_SHADER + , ~0, 0, 1, 0, ray, payload); + } + payload.color /= rtao_samplecount; + + output[DispatchRaysIndex().xy] = pow(saturate(payload.color), rtao_power); +} + +[shader("closesthit")] +void RTAO_ClosestHit(inout RayPayload payload, in MyAttributes attr) +{ + //payload.color = 0; +} + +[shader("miss")] +void RTAO_Miss(inout RayPayload payload) +{ + payload.color += 1; +} diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index 254082dc0..b56e69c3f 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -364,6 +364,12 @@ enum CSTYPES CSTYPE_POSTPROCESS_DOWNSAMPLE4X, CSTYPE_COUNT }; +// raytracing shaders +enum RTTYPES +{ + RTTYPE_RTAO, + RTTYPE_COUNT +}; // input layouts enum ILTYPES diff --git a/WickedEngine/wiGraphics.h b/WickedEngine/wiGraphics.h index 1da614ab6..055e7b07a 100644 --- a/WickedEngine/wiGraphics.h +++ b/WickedEngine/wiGraphics.h @@ -292,6 +292,7 @@ namespace wiGraphics BUFFER_STATE_UNORDERED_ACCESS, // shader resource, write enabled BUFFER_STATE_COPY_SRC, // copy from BUFFER_STATE_COPY_DST, // copy to + BUFFER_STATE_RAYTRACING_ACCELERATION_STRUCTURE, }; // Flags //////////////////////////////////////////// @@ -620,6 +621,7 @@ namespace wiGraphics { BUFFER, TEXTURE, + RAYTRACING_ACCELERATION_STRUCTURE, UNKNOWN_TYPE, } type = GPU_RESOURCE_TYPE::UNKNOWN_TYPE; inline bool IsTexture() const { return type == GPU_RESOURCE_TYPE::TEXTURE; } @@ -688,4 +690,144 @@ namespace wiGraphics const RenderPassDesc& GetDesc() const { return desc; } }; + + + struct RaytracingAccelerationStructureDesc + { + enum FLAGS + { + FLAG_EMPTY = 0, + FLAG_ALLOW_UPDATE = 1 << 0, + FLAG_ALLOW_COMPACTION = 1 << 1, + FLAG_PREFER_FAST_TRACE = 1 << 2, + FLAG_PREFER_FAST_BUILD = 1 << 3, + FLAG_MINIMIZE_MEMORY = 1 << 4, + }; + uint32_t _flags = FLAG_EMPTY; + + enum TYPE + { + BOTTOMLEVEL, + TOPLEVEL, + } type = BOTTOMLEVEL; + + struct BottomLevel + { + struct Geometry + { + enum FLAGS + { + FLAG_EMPTY = 0, + FLAG_OPAQUE = 1 << 0, + FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 1 << 1, + FLAG_USE_TRANSFORM = 1 << 2, + }; + uint32_t _flags = FLAG_EMPTY; + + enum TYPE + { + TRIANGLES, + PROCEDURAL_AABBS, + } type = TRIANGLES; + + struct Triangles + { + GPUBuffer vertexBuffer; + GPUBuffer indexBuffer; + uint32_t indexCount = 0; + uint32_t indexOffset = 0; + uint32_t vertexCount = 0; + uint32_t vertexByteOffset = 0; + uint32_t vertexStride = 0; + INDEXBUFFER_FORMAT indexFormat = INDEXFORMAT_32BIT; + FORMAT vertexFormat = FORMAT_R32G32B32_FLOAT; + GPUBuffer transform3x4Buffer; + uint32_t transform3x4BufferOffset = 0; + } triangles; + struct Procedural_AABBs + { + GPUBuffer aabbBuffer; + uint32_t offset = 0; + uint32_t count = 0; + uint32_t stride = 0; + } aabbs; + + }; + std::vector geometries; + } bottomlevel; + + struct TopLevel + { + struct Instance + { + XMFLOAT3X4 transform; + uint32_t InstanceID : 24; + uint32_t InstanceMask : 8; + uint32_t InstanceContributionToHitGroupIndex : 24; + uint32_t Flags : 8; + GPUResource bottomlevel; + }; + GPUBuffer instanceBuffer; + uint32_t offset = 0; + uint32_t count = 0; + } toplevel; + }; + struct RaytracingAccelerationStructure : public GPUResource + { + RaytracingAccelerationStructureDesc desc; + GPUBuffer scratch; + + const RaytracingAccelerationStructureDesc& GetDesc() const { return desc; } + }; + + struct ShaderLibrary + { + const Shader* shader = nullptr; + std::vector export_functions; + }; + struct ShaderHitGroup + { + enum TYPE + { + TRIANGLES, + PROCEDURAL, + } type = TRIANGLES; + std::string name; + std::string closesthit_shader_name; + std::string anyhit_shader_name; + std::string intersection_shader_name; + }; + struct RaytracingPipelineStateDesc + { + std::vector shaderlibraries; + std::vector hitgroups; + uint32_t max_trace_recursion_depth = 1; + uint32_t max_attribute_size_in_bytes = 0; + uint32_t max_payload_size_in_bytes = 0; + }; + struct RaytracingPipelineState : public GraphicsDeviceChild + { + RaytracingPipelineStateDesc desc; + + const RaytracingPipelineStateDesc& GetDesc() const { return desc; } + }; + + struct ShaderTable + { + const GPUBuffer* buffer = nullptr; + uint64_t offset = 0; + uint64_t size = 0; + uint64_t stride = 0; + }; + struct DispatchRaysDesc + { + ShaderTable raygeneration; + ShaderTable miss; + ShaderTable hitgroup; + ShaderTable callable; + uint32_t Width = 1; + uint32_t Height = 1; + uint32_t Depth = 1; + }; + } diff --git a/WickedEngine/wiGraphicsDevice.cpp b/WickedEngine/wiGraphicsDevice.cpp index e56e4ef99..7e9272bee 100644 --- a/WickedEngine/wiGraphicsDevice.cpp +++ b/WickedEngine/wiGraphicsDevice.cpp @@ -27,6 +27,8 @@ bool GraphicsDevice::CheckCapability(GRAPHICSDEVICE_CAPABILITY capability) const return UAV_LOAD_FORMAT_R11G11B10_FLOAT; case wiGraphics::GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RENDERTARGET_AND_VIEWPORT_ARRAYINDEX_WITHOUT_GS: return RENDERTARGET_AND_VIEWPORT_ARRAYINDEX_WITHOUT_GS; + case wiGraphics::GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING: + return RAYTRACING; } return false; } diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index d3f69c672..4e8d16d34 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -27,6 +27,9 @@ namespace wiGraphics bool UAV_LOAD_FORMAT_COMMON = false; bool UAV_LOAD_FORMAT_R11G11B10_FLOAT = false; bool RENDERTARGET_AND_VIEWPORT_ARRAYINDEX_WITHOUT_GS = false; + bool RAYTRACING = false; + size_t SHADER_IDENTIFIER_SIZE = 0; + size_t TOPLEVEL_ACCELERATION_STRUCTURE_INSTANCE_SIZE = 0; public: virtual bool CreateBuffer(const GPUBufferDesc *pDesc, const SubresourceData* pInitialData, GPUBuffer *pBuffer) = 0; @@ -40,12 +43,17 @@ namespace wiGraphics virtual bool CreateQuery(const GPUQueryDesc *pDesc, GPUQuery *pQuery) = 0; virtual bool CreatePipelineState(const PipelineStateDesc* pDesc, PipelineState* pso) = 0; virtual bool CreateRenderPass(const RenderPassDesc* pDesc, RenderPass* renderpass) = 0; + virtual bool CreateRaytracingAccelerationStructure(const RaytracingAccelerationStructureDesc* pDesc, RaytracingAccelerationStructure* bvh) { return false; } + virtual bool CreateRaytracingPipelineState(const RaytracingPipelineStateDesc* pDesc, RaytracingPipelineState* rtpso) { return false; } virtual int CreateSubresource(Texture* texture, SUBRESOURCE_TYPE type, uint32_t firstSlice, uint32_t sliceCount, uint32_t firstMip, uint32_t mipCount) = 0; + virtual void WriteTopLevelAccelerationStructureInstance(const RaytracingAccelerationStructureDesc::TopLevel::Instance* instance, void* dest) {} + virtual bool DownloadResource(const GPUResource* resourceToDownload, const GPUResource* resourceDest, void* dataDest) = 0; virtual void SetName(GPUResource* pResource, const char* name) = 0; + virtual void* GetShaderIdentifier(const RaytracingPipelineState* rtpso, const char* name) { return nullptr; } virtual void PresentBegin(CommandList cmd) = 0; virtual void PresentEnd(CommandList cmd) = 0; @@ -84,6 +92,7 @@ namespace wiGraphics GRAPHICSDEVICE_CAPABILITY_UAV_LOAD_FORMAT_COMMON, // eg: R16G16B16A16_FLOAT, R8G8B8A8_UNORM and more common ones GRAPHICSDEVICE_CAPABILITY_UAV_LOAD_FORMAT_R11G11B10_FLOAT, GRAPHICSDEVICE_CAPABILITY_RENDERTARGET_AND_VIEWPORT_ARRAYINDEX_WITHOUT_GS, + GRAPHICSDEVICE_CAPABILITY_RAYTRACING, GRAPHICSDEVICE_CAPABILITY_COUNT, }; bool CheckCapability(GRAPHICSDEVICE_CAPABILITY capability) const; @@ -102,6 +111,9 @@ namespace wiGraphics inline bool IsDebugDevice() const { return DEBUGDEVICE; } + inline size_t GetShaderIdentifierSize() const { return SHADER_IDENTIFIER_SIZE; } + inline size_t GetTopLevelAccelerationStructureInstanceSize() const { return TOPLEVEL_ACCELERATION_STRUCTURE_INSTANCE_SIZE; } + ///////////////Thread-sensitive//////////////////////// @@ -139,6 +151,9 @@ namespace wiGraphics virtual void QueryEnd(const GPUQuery *query, CommandList cmd) = 0; virtual bool QueryRead(const GPUQuery *query, GPUQueryResult* result) = 0; virtual void Barrier(const GPUBarrier* barriers, uint32_t numBarriers, CommandList cmd) = 0; + virtual void BuildRaytracingAccelerationStructure(const RaytracingAccelerationStructure* dst, CommandList cmd, const RaytracingAccelerationStructure* src = nullptr) {} + virtual void BindRaytracingPipelineState(const RaytracingPipelineState* rtpso, CommandList cmd) {} + virtual void DispatchRays(const DispatchRaysDesc* desc, CommandList cmd) {} struct GPUAllocation { diff --git a/WickedEngine/wiGraphicsDevice_DX11.cpp b/WickedEngine/wiGraphicsDevice_DX11.cpp index 9278eaec2..9e92c31a8 100644 --- a/WickedEngine/wiGraphicsDevice_DX11.cpp +++ b/WickedEngine/wiGraphicsDevice_DX11.cpp @@ -2469,7 +2469,7 @@ void GraphicsDevice_DX11::commit_allocations(CommandList cmd) if (frame_allocators[cmd].dirty) { - auto internal_state = std::static_pointer_cast(frame_allocators[cmd].buffer.internal_state); + auto internal_state = to_internal(&frame_allocators[cmd].buffer); deviceContexts[cmd]->Unmap(internal_state->resource.Get(), 0); frame_allocators[cmd].dirty = false; } @@ -3095,13 +3095,13 @@ GraphicsDevice::GPUAllocation GraphicsDevice_DX11::AllocateGPU(size_t dataSize, { // If allocation too large, grow the allocator: allocator.buffer.desc.ByteWidth = uint32_t((dataSize + 1) * 2); - bool success = CreateBuffer(&allocator.buffer.desc, nullptr, &frame_allocators[cmd].buffer); + bool success = CreateBuffer(&allocator.buffer.desc, nullptr, &allocator.buffer); assert(success); - SetName(&frame_allocators[cmd].buffer, "frame_allocator"); + SetName(&allocator.buffer, "frame_allocator"); allocator.byteOffset = 0; } - auto internal_state = std::static_pointer_cast(allocator.buffer.internal_state); + auto internal_state = to_internal(&allocator.buffer); allocator.dirty = true; diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index 333a54e68..49e4b4806 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -671,6 +671,8 @@ namespace DX12_Internal return D3D12_RESOURCE_STATE_COPY_SOURCE; case wiGraphics::BUFFER_STATE_COPY_DST: return D3D12_RESOURCE_STATE_COPY_DEST; + case wiGraphics::BUFFER_STATE_RAYTRACING_ACCELERATION_STRUCTURE: + return D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE; } return D3D12_RESOURCE_STATE_COMMON; @@ -1017,6 +1019,29 @@ namespace DX12_Internal allocationhandler->destroylocker.unlock(); } }; + struct BVH_DX12 : public Resource_DX12 + { + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS desc = {}; + std::vector geometries; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {}; + + ~BVH_DX12() override + { + } + }; + struct RTPipelineState_DX12 + { + std::shared_ptr allocationhandler; + ComPtr resource; + + ~RTPipelineState_DX12() + { + allocationhandler->destroylocker.lock(); + uint64_t framecount = allocationhandler->framecount; + if (resource) allocationhandler->destroyer_stateobjects.push_back(std::make_pair(resource, framecount)); + allocationhandler->destroylocker.unlock(); + } + }; Resource_DX12* to_internal(const GPUResource* param) { @@ -1047,6 +1072,14 @@ namespace DX12_Internal { return static_cast(param->internal_state.get()); } + BVH_DX12* to_internal(const RaytracingAccelerationStructure* param) + { + return static_cast(param->internal_state.get()); + } + RTPipelineState_DX12* to_internal(const RaytracingPipelineState* param) + { + return static_cast(param->internal_state.get()); + } } using namespace DX12_Internal; @@ -1482,64 +1515,13 @@ using namespace DX12_Internal; } - void GraphicsDevice_DX12::UploadBuffer::init(GraphicsDevice_DX12* device, size_t size) - { - this->device = device; - - HRESULT hr; - - D3D12MA::ALLOCATION_DESC allocationDesc = {}; - allocationDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; - - CD3DX12_RESOURCE_DESC resdesc = CD3DX12_RESOURCE_DESC::Buffer(size); - - hr = device->allocationhandler->allocator->CreateResource( - &allocationDesc, - &resdesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - &allocation, - IID_PPV_ARGS(&resource) - ); - assert(SUCCEEDED(hr)); - - void* pData; - CD3DX12_RANGE readRange(0, 0); - resource->Map(0, &readRange, &pData); - dataCur = dataBegin = reinterpret_cast(pData); - dataEnd = dataBegin + size; - } - uint8_t* GraphicsDevice_DX12::UploadBuffer::allocate(size_t dataSize, size_t alignment) - { - lock.lock(); - - dataCur = reinterpret_cast(Align(reinterpret_cast(dataCur), alignment)); - - assert(dataCur + dataSize <= dataEnd); - - uint8_t* retVal = dataCur; - - dataCur += dataSize; - - lock.unlock(); - - return retVal; - } - void GraphicsDevice_DX12::UploadBuffer::clear() - { - lock.lock(); - dataCur = dataBegin; - lock.unlock(); - } - uint64_t GraphicsDevice_DX12::UploadBuffer::calculateOffset(uint8_t* address) - { - assert(address >= dataBegin && address < dataEnd); - return static_cast(address - dataBegin); - } // Engine functions GraphicsDevice_DX12::GraphicsDevice_DX12(wiPlatform::window_type window, bool fullscreen, bool debuglayer) { + SHADER_IDENTIFIER_SIZE = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + TOPLEVEL_ACCELERATION_STRUCTURE_INSTANCE_SIZE = sizeof(D3D12_RAYTRACING_INSTANCE_DESC); + DEBUGDEVICE = debuglayer; FULLSCREEN = fullscreen; @@ -1577,7 +1559,7 @@ using namespace DX12_Internal; } #endif - hr = D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); + hr = D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_1, IID_PPV_ARGS(&device)); if (FAILED(hr)) { std::stringstream ss(""); @@ -1730,10 +1712,6 @@ using namespace DX12_Internal; null_sampler_heap_dest.ptr += sampler_descriptor_size; } - // Create resource upload buffer - bufferUploader.init(this, 256 * 1024 * 1024); - textureUploader.init(this, 256 * 1024 * 1024); - // Create frame-resident resources: for (uint32_t fr = 0; fr < BACKBUFFER_COUNT; ++fr) @@ -1788,6 +1766,9 @@ using namespace DX12_Internal; } } + D3D12_FEATURE_DATA_D3D12_OPTIONS5 features_5; + hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &features_5, sizeof(features_5)); + RAYTRACING = features_5.RaytracingTier >= D3D12_RAYTRACING_TIER_1_0; // Generate default root signature: @@ -2127,6 +2108,11 @@ using namespace DX12_Internal; D3D12MA::ALLOCATION_DESC allocationDesc = {}; allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT; + if (pDesc->Usage == USAGE_STAGING) + { + allocationDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; + resourceState = D3D12_RESOURCE_STATE_GENERIC_READ; + } hr = allocationhandler->allocator->CreateResource( &allocationDesc, @@ -2142,12 +2128,24 @@ using namespace DX12_Internal; // Issue data copy on request: if (pInitialData != nullptr) { + GPUBufferDesc uploaddesc; + uploaddesc.ByteWidth = pDesc->ByteWidth; + uploaddesc.Usage = USAGE_STAGING; + GPUBuffer uploadbuffer; + bool upload_success = CreateBuffer(&uploaddesc, nullptr, &uploadbuffer); + assert(upload_success); + ID3D12Resource* upload_resource = to_internal(&uploadbuffer)->resource.Get(); + + void* pData; + CD3DX12_RANGE readRange(0, 0); + hr = upload_resource->Map(0, &readRange, &pData); + assert(SUCCEEDED(hr)); + copyQueueLock.lock(); { - uint8_t* dest = bufferUploader.allocate(pDesc->ByteWidth, 1); - memcpy(dest, pInitialData->pSysMem, pDesc->ByteWidth); + memcpy(pData, pInitialData->pSysMem, pDesc->ByteWidth); static_cast(copyCommandList.Get())->CopyBufferRegion( - internal_state->resource.Get(), 0, bufferUploader.resource.Get(), bufferUploader.calculateOffset(dest), pDesc->ByteWidth); + internal_state->resource.Get(), 0, upload_resource, 0, pDesc->ByteWidth); } copyQueueLock.unlock(); } @@ -2376,10 +2374,21 @@ using namespace DX12_Internal; copyQueueLock.lock(); { - uint8_t* dest = textureUploader.allocate(static_cast(RequiredSize), D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); + GPUBufferDesc uploaddesc; + uploaddesc.ByteWidth = (uint32_t)RequiredSize; + uploaddesc.Usage = USAGE_STAGING; + GPUBuffer uploadbuffer; + bool upload_success = CreateBuffer(&uploaddesc, nullptr, &uploadbuffer); + assert(upload_success); + ID3D12Resource* upload_resource = to_internal(&uploadbuffer)->resource.Get(); + void* pData; + CD3DX12_RANGE readRange(0, 0); + hr = upload_resource->Map(0, &readRange, &pData); + assert(SUCCEEDED(hr)); + UINT64 dataSize = UpdateSubresources(static_cast(copyCommandList.Get()), internal_state->resource.Get(), - textureUploader.resource.Get(), textureUploader.calculateOffset(dest), 0, dataCount, data.data()); + upload_resource, 0, 0, dataCount, data.data()); } copyQueueLock.unlock(); } @@ -2576,6 +2585,269 @@ using namespace DX12_Internal; return S_OK; } + bool GraphicsDevice_DX12::CreateRaytracingAccelerationStructure(const RaytracingAccelerationStructureDesc* pDesc, RaytracingAccelerationStructure* bvh) + { + auto internal_state = std::make_shared(); + internal_state->allocationhandler = allocationhandler; + bvh->internal_state = internal_state; + bvh->type = GPUResource::GPU_RESOURCE_TYPE::RAYTRACING_ACCELERATION_STRUCTURE; + + bvh->desc = *pDesc; + + if (pDesc->_flags & RaytracingAccelerationStructureDesc::FLAG_ALLOW_UPDATE) + { + internal_state->desc.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; + } + if (pDesc->_flags & RaytracingAccelerationStructureDesc::FLAG_ALLOW_COMPACTION) + { + internal_state->desc.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION; + } + if (pDesc->_flags & RaytracingAccelerationStructureDesc::FLAG_PREFER_FAST_TRACE) + { + internal_state->desc.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE; + } + if (pDesc->_flags & RaytracingAccelerationStructureDesc::FLAG_PREFER_FAST_BUILD) + { + internal_state->desc.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD; + } + if (pDesc->_flags & RaytracingAccelerationStructureDesc::FLAG_MINIMIZE_MEMORY) + { + internal_state->desc.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY; + } + + + switch (pDesc->type) + { + case RaytracingAccelerationStructureDesc::BOTTOMLEVEL: + { + internal_state->desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + internal_state->desc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + + for (auto& x : pDesc->bottomlevel.geometries) + { + internal_state->geometries.emplace_back(); + auto& geometry = internal_state->geometries.back(); + geometry = {}; + if (x._flags & RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_OPAQUE) + { + geometry.Flags |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; + } + if (x._flags & RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_NO_DUPLICATE_ANYHIT_INVOCATION) + { + geometry.Flags |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; + } + + if (x.type == RaytracingAccelerationStructureDesc::BottomLevel::Geometry::TRIANGLES) + { + geometry.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + geometry.Triangles.VertexBuffer.StartAddress = to_internal(&x.triangles.vertexBuffer)->resource->GetGPUVirtualAddress() + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.vertexByteOffset; + geometry.Triangles.VertexBuffer.StrideInBytes = (UINT64)x.triangles.vertexStride; + geometry.Triangles.VertexCount = x.triangles.vertexCount; + geometry.Triangles.VertexFormat = _ConvertFormat(x.triangles.vertexFormat); + geometry.Triangles.IndexFormat = (x.triangles.indexFormat == INDEXBUFFER_FORMAT::INDEXFORMAT_16BIT ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT); + geometry.Triangles.IndexBuffer = to_internal(&x.triangles.indexBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.indexOffset * (x.triangles.indexFormat == INDEXBUFFER_FORMAT::INDEXFORMAT_16BIT ? sizeof(uint16_t) : sizeof(uint32_t)); + geometry.Triangles.IndexCount = x.triangles.indexCount; + + if (x._flags & RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_USE_TRANSFORM) + { + geometry.Triangles.Transform3x4 = to_internal(&x.triangles.transform3x4Buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.transform3x4BufferOffset; + } + } + else if (x.type == RaytracingAccelerationStructureDesc::BottomLevel::Geometry::PROCEDURAL_AABBS) + { + geometry.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; + geometry.AABBs.AABBs.StartAddress = to_internal(&x.aabbs.aabbBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.aabbs.offset; + geometry.AABBs.AABBs.StrideInBytes = (UINT64)x.aabbs.stride; + geometry.AABBs.AABBCount = x.aabbs.count; + } + } + + internal_state->desc.pGeometryDescs = internal_state->geometries.data(); + internal_state->desc.NumDescs = (UINT)internal_state->geometries.size(); + } + break; + case RaytracingAccelerationStructureDesc::TOPLEVEL: + { + internal_state->desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + internal_state->desc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + + internal_state->desc.InstanceDescs = to_internal(&pDesc->toplevel.instanceBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)pDesc->toplevel.offset; + internal_state->desc.NumDescs = (UINT)pDesc->toplevel.count; + } + break; + } + + device->GetRaytracingAccelerationStructurePrebuildInfo(&internal_state->desc, &internal_state->info); + + + uint32_t alignment = 16; + size_t alignedSize = Align(internal_state->info.ResultDataMaxSizeInBytes, alignment); + + D3D12_RESOURCE_DESC desc; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.Width = (UINT64)alignedSize; + desc.Height = 1; + desc.MipLevels = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.DepthOrArraySize = 1; + desc.Alignment = 0; + desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + + D3D12_RESOURCE_STATES resourceState = D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE; + + D3D12MA::ALLOCATION_DESC allocationDesc = {}; + allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT; + allocationDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED; + + HRESULT hr = allocationhandler->allocator->CreateResource( + &allocationDesc, + &desc, + resourceState, + nullptr, + &internal_state->allocation, + IID_PPV_ARGS(&internal_state->resource) + ); + assert(SUCCEEDED(hr)); + + D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {}; + srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE; + srv_desc.RaytracingAccelerationStructure.Location = internal_state->resource->GetGPUVirtualAddress(); + + internal_state->srv = allocationhandler->ResourceAllocator.allocate(); + device->CreateShaderResourceView(nullptr, &srv_desc, internal_state->srv); + + GPUBufferDesc scratch_desc; + scratch_desc.ByteWidth = (uint32_t)std::max(internal_state->info.ScratchDataSizeInBytes, internal_state->info.UpdateScratchDataSizeInBytes); + + return CreateBuffer(&scratch_desc, nullptr, &bvh->scratch); + } + bool GraphicsDevice_DX12::CreateRaytracingPipelineState(const RaytracingPipelineStateDesc* pDesc, RaytracingPipelineState* rtpso) + { + auto internal_state = std::make_shared(); + internal_state->allocationhandler = allocationhandler; + rtpso->internal_state = internal_state; + + rtpso->desc = *pDesc; + + D3D12_STATE_OBJECT_DESC desc = {}; + desc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; + + std::vector subobjects; + + D3D12_RAYTRACING_PIPELINE_CONFIG pipeline_config = {}; + { + subobjects.emplace_back(); + auto& subobject = subobjects.back(); + subobject = {}; + subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; + pipeline_config.MaxTraceRecursionDepth = pDesc->max_trace_recursion_depth; + subobject.pDesc = &pipeline_config; + } + + D3D12_RAYTRACING_SHADER_CONFIG shader_config = {}; + { + subobjects.emplace_back(); + auto& subobject = subobjects.back(); + subobject = {}; + subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; + shader_config.MaxAttributeSizeInBytes = pDesc->max_attribute_size_in_bytes; + shader_config.MaxPayloadSizeInBytes = pDesc->max_payload_size_in_bytes; + subobject.pDesc = &shader_config; + } + + D3D12_GLOBAL_ROOT_SIGNATURE global_rootsig = {}; + { + subobjects.emplace_back(); + auto& subobject = subobjects.back(); + subobject = {}; + subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE; + global_rootsig.pGlobalRootSignature = computeRootSig.Get(); + subobject.pDesc = &global_rootsig; + } + + std::vector library_descs; + library_descs.reserve(pDesc->shaderlibraries.size()); + for(auto& x : pDesc->shaderlibraries) + { + subobjects.emplace_back(); + auto& subobject = subobjects.back(); + subobject = {}; + subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY; + library_descs.emplace_back(); + auto& library_desc = library_descs.back(); + library_desc = {}; + library_desc.DXILLibrary.pShaderBytecode = x.shader->code.data(); + library_desc.DXILLibrary.BytecodeLength = x.shader->code.size(); + // todo export functions + subobject.pDesc = &library_desc; + } + + std::vector hitgroup_strings; + std::vector hitgroup_descs; + hitgroup_descs.reserve(pDesc->hitgroups.size()); + for (auto& x : pDesc->hitgroups) + { + subobjects.emplace_back(); + auto& subobject = subobjects.back(); + subobject = {}; + subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; + hitgroup_descs.emplace_back(); + auto& hitgroup_desc = hitgroup_descs.back(); + hitgroup_desc = {}; + switch (x.type) + { + default: + case ShaderHitGroup::TRIANGLES: + hitgroup_desc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES; + break; + case ShaderHitGroup::PROCEDURAL: + hitgroup_desc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE; + break; + } + if (!x.name.empty()) + { + hitgroup_strings.emplace_back(); + wiHelper::StringConvert(x.name, hitgroup_strings.back()); + hitgroup_desc.HitGroupExport = hitgroup_strings.back().c_str(); + } + if (!x.closesthit_shader_name.empty()) + { + hitgroup_strings.emplace_back(); + wiHelper::StringConvert(x.closesthit_shader_name, hitgroup_strings.back()); + hitgroup_desc.ClosestHitShaderImport = hitgroup_strings.back().c_str(); + } + if (!x.anyhit_shader_name.empty()) + { + hitgroup_strings.emplace_back(); + wiHelper::StringConvert(x.anyhit_shader_name, hitgroup_strings.back()); + hitgroup_desc.AnyHitShaderImport = hitgroup_strings.back().c_str(); + } + if (!x.intersection_shader_name.empty()) + { + hitgroup_strings.emplace_back(); + wiHelper::StringConvert(x.intersection_shader_name, hitgroup_strings.back()); + hitgroup_desc.IntersectionShaderImport = hitgroup_strings.back().c_str(); + } + subobject.pDesc = &hitgroup_desc; + } + + desc.NumSubobjects = (UINT)subobjects.size(); + desc.pSubobjects = subobjects.data(); + + HRESULT hr = device->CreateStateObject(&desc, IID_PPV_ARGS(&internal_state->resource)); + assert(SUCCEEDED(hr)); + + return SUCCEEDED(hr); + } + int GraphicsDevice_DX12::CreateSubresource(Texture* texture, SUBRESOURCE_TYPE type, uint32_t firstSlice, uint32_t sliceCount, uint32_t firstMip, uint32_t mipCount) { @@ -2950,6 +3222,17 @@ using namespace DX12_Internal; return -1; } + void GraphicsDevice_DX12::WriteTopLevelAccelerationStructureInstance(const RaytracingAccelerationStructureDesc::TopLevel::Instance* instance, void* dest) + { + D3D12_RAYTRACING_INSTANCE_DESC* desc = (D3D12_RAYTRACING_INSTANCE_DESC*)dest; + desc->AccelerationStructure = to_internal(&instance->bottomlevel)->resource->GetGPUVirtualAddress(); + memcpy(desc->Transform, &instance->transform, sizeof(desc->Transform)); + desc->InstanceID = instance->InstanceID; + desc->InstanceMask = instance->InstanceMask; + desc->InstanceContributionToHitGroupIndex = instance->InstanceContributionToHitGroupIndex; + desc->Flags = instance->Flags; + } + bool GraphicsDevice_DX12::DownloadResource(const GPUResource* resourceToDownload, const GPUResource* resourceDest, void* dataDest) { return false; @@ -2964,7 +3247,18 @@ using namespace DX12_Internal; internal_state->resource->SetName(text); } } + void* GraphicsDevice_DX12::GetShaderIdentifier(const RaytracingPipelineState* rtpso, const char* name) + { + auto internal_state = to_internal(rtpso); + ComPtr stateObjectProperties; + HRESULT hr = internal_state->resource.As(&stateObjectProperties); + assert(SUCCEEDED(hr)); + + wchar_t wname[1024]; + wiHelper::StringConvert(name, wname); + return stateObjectProperties->GetShaderIdentifier(wname); + } void GraphicsDevice_DX12::PresentBegin(CommandList cmd) { @@ -3043,8 +3337,6 @@ using namespace DX12_Internal; result = copyAllocator->Reset(); result = static_cast(copyCommandList.Get())->Reset(copyAllocator.Get(), nullptr); - bufferUploader.clear(); - textureUploader.clear(); } copyQueueLock.unlock(); @@ -3129,7 +3421,7 @@ using namespace DX12_Internal; { hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frames[fr].commandAllocators[cmd])); hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frames[fr].commandAllocators[cmd].Get(), nullptr, IID_PPV_ARGS(&frames[fr].commandLists[cmd])); - hr = static_cast(frames[fr].commandLists[cmd].Get())->Close(); + hr = static_cast(frames[fr].commandLists[cmd].Get())->Close(); frames[fr].descriptors[cmd].init(this); frames[fr].resourceBuffer[cmd].init(this, 1024 * 1024); // 1 MB starting size @@ -4091,6 +4383,124 @@ using namespace DX12_Internal; GetDirectCommandList(cmd)->ResourceBarrier(numBarriers, barrierdescs); } + void GraphicsDevice_DX12::BuildRaytracingAccelerationStructure(const RaytracingAccelerationStructure* dst, CommandList cmd, const RaytracingAccelerationStructure* src) + { + auto dst_internal = to_internal(dst); + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC desc = {}; + desc.Inputs = dst_internal->desc; + + // The real GPU addresses get filled here: + switch (dst->desc.type) + { + case RaytracingAccelerationStructureDesc::BOTTOMLEVEL: + { + size_t i = 0; + for (auto& x : dst->desc.bottomlevel.geometries) + { + auto& geometry = dst_internal->geometries[i++]; + + if (x.type == RaytracingAccelerationStructureDesc::BottomLevel::Geometry::TRIANGLES) + { + geometry.Triangles.VertexBuffer.StartAddress = to_internal(&x.triangles.vertexBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.vertexByteOffset; + geometry.Triangles.IndexBuffer = to_internal(&x.triangles.indexBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.indexOffset * (x.triangles.indexFormat == INDEXBUFFER_FORMAT::INDEXFORMAT_16BIT ? sizeof(uint16_t) : sizeof(uint32_t)); + + if (x._flags & RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_USE_TRANSFORM) + { + geometry.Triangles.Transform3x4 = to_internal(&x.triangles.transform3x4Buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.triangles.transform3x4BufferOffset; + } + } + else if (x.type == RaytracingAccelerationStructureDesc::BottomLevel::Geometry::PROCEDURAL_AABBS) + { + geometry.AABBs.AABBs.StartAddress = to_internal(&x.aabbs.aabbBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)x.aabbs.offset; + } + } + } + break; + case RaytracingAccelerationStructureDesc::TOPLEVEL: + { + dst_internal->desc.InstanceDescs = to_internal(&dst->desc.toplevel.instanceBuffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)dst->desc.toplevel.offset; + } + break; + } + + if (src != nullptr) + { + desc.Inputs.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE; + + auto src_internal = to_internal(src); + desc.SourceAccelerationStructureData = src_internal->resource->GetGPUVirtualAddress(); + } + desc.DestAccelerationStructureData = dst_internal->resource->GetGPUVirtualAddress(); + desc.ScratchAccelerationStructureData = to_internal(&dst->scratch)->resource->GetGPUVirtualAddress(); + GetDirectCommandList(cmd)->BuildRaytracingAccelerationStructure(&desc, 0, nullptr); + } + void GraphicsDevice_DX12::BindRaytracingPipelineState(const RaytracingPipelineState* rtpso, CommandList cmd) + { + prev_pipeline_hash[cmd] = 0; + + auto internal_state = to_internal(rtpso); + GetDirectCommandList(cmd)->SetPipelineState1(internal_state->resource.Get()); + } + void GraphicsDevice_DX12::DispatchRays(const DispatchRaysDesc* desc, CommandList cmd) + { + GetFrameResources().descriptors[cmd].validate(cmd); + + D3D12_DISPATCH_RAYS_DESC dispatchrays_desc = {}; + + dispatchrays_desc.Width = desc->Width; + dispatchrays_desc.Height = desc->Height; + dispatchrays_desc.Depth = desc->Depth; + + if (desc->raygeneration.buffer != nullptr) + { + dispatchrays_desc.RayGenerationShaderRecord.StartAddress = + to_internal(desc->raygeneration.buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)desc->raygeneration.offset; + dispatchrays_desc.RayGenerationShaderRecord.SizeInBytes = + desc->raygeneration.size; + } + + if (desc->miss.buffer != nullptr) + { + dispatchrays_desc.MissShaderTable.StartAddress = + to_internal(desc->miss.buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)desc->miss.offset; + dispatchrays_desc.MissShaderTable.SizeInBytes = + desc->miss.size; + dispatchrays_desc.MissShaderTable.StrideInBytes = + desc->miss.stride; + } + + if (desc->hitgroup.buffer != nullptr) + { + dispatchrays_desc.HitGroupTable.StartAddress = + to_internal(desc->hitgroup.buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)desc->hitgroup.offset; + dispatchrays_desc.HitGroupTable.SizeInBytes = + desc->hitgroup.size; + dispatchrays_desc.HitGroupTable.StrideInBytes = + desc->hitgroup.stride; + } + + if (desc->callable.buffer != nullptr) + { + dispatchrays_desc.CallableShaderTable.StartAddress = + to_internal(desc->callable.buffer)->resource->GetGPUVirtualAddress() + + (D3D12_GPU_VIRTUAL_ADDRESS)desc->callable.offset; + dispatchrays_desc.CallableShaderTable.SizeInBytes = + desc->callable.size; + dispatchrays_desc.CallableShaderTable.StrideInBytes = + desc->callable.stride; + } + + GetDirectCommandList(cmd)->DispatchRays(&dispatchrays_desc); + } GraphicsDevice::GPUAllocation GraphicsDevice_DX12::AllocateGPU(size_t dataSize, CommandList cmd) { diff --git a/WickedEngine/wiGraphicsDevice_DX12.h b/WickedEngine/wiGraphicsDevice_DX12.h index 238ffc273..689f6a129 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.h +++ b/WickedEngine/wiGraphicsDevice_DX12.h @@ -29,7 +29,7 @@ namespace wiGraphics class GraphicsDevice_DX12 : public GraphicsDevice { private: - Microsoft::WRL::ComPtr device; + Microsoft::WRL::ComPtr device; Microsoft::WRL::ComPtr directQueue; Microsoft::WRL::ComPtr frameFence; HANDLE frameFenceEvent; @@ -160,7 +160,7 @@ namespace wiGraphics }; FrameResources frames[BACKBUFFER_COUNT]; FrameResources& GetFrameResources() { return frames[GetFrameCount() % BACKBUFFER_COUNT]; } - inline ID3D12GraphicsCommandList4* GetDirectCommandList(CommandList cmd) { return static_cast(GetFrameResources().commandLists[cmd].Get()); } + inline ID3D12GraphicsCommandList5* GetDirectCommandList(CommandList cmd) { return static_cast(GetFrameResources().commandLists[cmd].Get()); } struct DynamicResourceState { @@ -169,29 +169,6 @@ namespace wiGraphics }; std::unordered_map dynamic_constantbuffers[COMMANDLIST_COUNT]; - struct UploadBuffer - { - GraphicsDevice_DX12* device = nullptr; - Microsoft::WRL::ComPtr resource; - D3D12MA::Allocation* allocation = nullptr; - uint8_t* dataBegin = nullptr; - uint8_t* dataCur = nullptr; - uint8_t* dataEnd = nullptr; - wiSpinLock lock; - - void init(GraphicsDevice_DX12* device, size_t size); - ~UploadBuffer() - { - if (allocation) allocation->Release(); - } - - uint8_t* allocate(size_t dataSize, size_t alignment); - void clear(); - uint64_t calculateOffset(uint8_t* address); - }; - UploadBuffer bufferUploader; - UploadBuffer textureUploader; - Microsoft::WRL::ComPtr swapChain; PRIMITIVETOPOLOGY prev_pt[COMMANDLIST_COUNT] = {}; @@ -220,12 +197,17 @@ namespace wiGraphics bool CreateQuery(const GPUQueryDesc *pDesc, GPUQuery *pQuery) override; bool CreatePipelineState(const PipelineStateDesc* pDesc, PipelineState* pso) override; bool CreateRenderPass(const RenderPassDesc* pDesc, RenderPass* renderpass) override; + bool CreateRaytracingAccelerationStructure(const RaytracingAccelerationStructureDesc* pDesc, RaytracingAccelerationStructure* bvh) override; + bool CreateRaytracingPipelineState(const RaytracingPipelineStateDesc* pDesc, RaytracingPipelineState* rtpso) override; int CreateSubresource(Texture* texture, SUBRESOURCE_TYPE type, uint32_t firstSlice, uint32_t sliceCount, uint32_t firstMip, uint32_t mipCount) override; + void WriteTopLevelAccelerationStructureInstance(const RaytracingAccelerationStructureDesc::TopLevel::Instance* instance, void* dest) override; + bool DownloadResource(const GPUResource* resourceToDownload, const GPUResource* resourceDest, void* dataDest) override; void SetName(GPUResource* pResource, const char* name) override; + void* GetShaderIdentifier(const RaytracingPipelineState* rtpso, const char* name) override; void PresentBegin(CommandList cmd) override; void PresentEnd(CommandList cmd) override; @@ -275,6 +257,9 @@ namespace wiGraphics void QueryEnd(const GPUQuery *query, CommandList cmd) override; bool QueryRead(const GPUQuery* query, GPUQueryResult* result) override; void Barrier(const GPUBarrier* barriers, uint32_t numBarriers, CommandList cmd) override; + void BuildRaytracingAccelerationStructure(const RaytracingAccelerationStructure* dst, CommandList cmd, const RaytracingAccelerationStructure* src = nullptr) override; + void BindRaytracingPipelineState(const RaytracingPipelineState* rtpso, CommandList cmd) override; + void DispatchRays(const DispatchRaysDesc* desc, CommandList cmd) override; GPUAllocation AllocateGPU(size_t dataSize, CommandList cmd) override; @@ -298,6 +283,7 @@ namespace wiGraphics std::deque> destroyer_queries_timestamp; std::deque> destroyer_queries_occlusion; std::deque, uint64_t>> destroyer_pipelines; + std::deque, uint64_t>> destroyer_stateobjects; DescriptorAllocator RTAllocator; DescriptorAllocator DSAllocator; @@ -432,6 +418,18 @@ namespace wiGraphics break; } } + while (!destroyer_stateobjects.empty()) + { + if (destroyer_stateobjects.front().second + BACKBUFFER_COUNT < FRAMECOUNT) + { + destroyer_stateobjects.pop_front(); + // comptr auto delete + } + else + { + break; + } + } destroylocker.unlock(); } }; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index 30a5c4345..7d1cb7c09 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -1004,62 +1004,62 @@ using namespace Vulkan_Internal; - void GraphicsDevice_Vulkan::UploadBuffer::init(GraphicsDevice_Vulkan* device, const QueueFamilyIndices& queueIndices, size_t size) - { - this->device = device; + //void GraphicsDevice_Vulkan::UploadBuffer::init(GraphicsDevice_Vulkan* device, const QueueFamilyIndices& queueIndices, size_t size) + //{ + // this->device = device; - VkBufferCreateInfo bufferInfo = {}; - bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.size = size; - bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferInfo.flags = 0; + // VkBufferCreateInfo bufferInfo = {}; + // bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + // bufferInfo.size = size; + // bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + // bufferInfo.flags = 0; - bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + // bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - VkResult res; + // VkResult res; - VmaAllocationCreateInfo allocInfo = {}; - allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; - allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + // VmaAllocationCreateInfo allocInfo = {}; + // allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; + // allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - res = vmaCreateBuffer(device->allocationhandler->allocator, &bufferInfo, &allocInfo, &resource, &allocation, nullptr); - assert(res == VK_SUCCESS); + // res = vmaCreateBuffer(device->allocationhandler->allocator, &bufferInfo, &allocInfo, &resource, &allocation, nullptr); + // assert(res == VK_SUCCESS); - void* pData = allocation->GetMappedData(); - dataCur = dataBegin = reinterpret_cast< UINT8* >(pData); - dataEnd = dataBegin + size; - } - GraphicsDevice_Vulkan::UploadBuffer::~UploadBuffer() - { - vmaDestroyBuffer(device->allocationhandler->allocator, resource, allocation); - } - uint8_t* GraphicsDevice_Vulkan::UploadBuffer::allocate(size_t dataSize, size_t alignment) - { - lock.lock(); + // void* pData = allocation->GetMappedData(); + // dataCur = dataBegin = reinterpret_cast< UINT8* >(pData); + // dataEnd = dataBegin + size; + //} + //GraphicsDevice_Vulkan::UploadBuffer::~UploadBuffer() + //{ + // vmaDestroyBuffer(device->allocationhandler->allocator, resource, allocation); + //} + //uint8_t* GraphicsDevice_Vulkan::UploadBuffer::allocate(size_t dataSize, size_t alignment) + //{ + // lock.lock(); - dataCur = reinterpret_cast(Align(reinterpret_cast(dataCur), alignment)); + // dataCur = reinterpret_cast(Align(reinterpret_cast(dataCur), alignment)); - assert(dataCur + dataSize <= dataEnd); + // assert(dataCur + dataSize <= dataEnd); - uint8_t* retVal = dataCur; + // uint8_t* retVal = dataCur; - dataCur += dataSize; + // dataCur += dataSize; - lock.unlock(); + // lock.unlock(); - return retVal; - } - void GraphicsDevice_Vulkan::UploadBuffer::clear() - { - lock.lock(); - dataCur = dataBegin; - lock.unlock(); - } - uint64_t GraphicsDevice_Vulkan::UploadBuffer::calculateOffset(uint8_t* address) - { - assert(address >= dataBegin && address < dataEnd); - return static_cast(address - dataBegin); - } + // return retVal; + //} + //void GraphicsDevice_Vulkan::UploadBuffer::clear() + //{ + // lock.lock(); + // dataCur = dataBegin; + // lock.unlock(); + //} + //uint64_t GraphicsDevice_Vulkan::UploadBuffer::calculateOffset(uint8_t* address) + //{ + // assert(address >= dataBegin && address < dataEnd); + // return static_cast(address - dataBegin); + //} @@ -2302,11 +2302,6 @@ using namespace Vulkan_Internal; } - // Create resource upload buffers - bufferUploader.init(this, queueIndices, 256 * 1024 * 1024); - textureUploader.init(this, queueIndices, 256 * 1024 * 1024); - - // Create default null descriptors: { VkBufferCreateInfo bufferInfo = {}; @@ -2541,6 +2536,12 @@ using namespace Vulkan_Internal; VmaAllocationCreateInfo allocInfo = {}; allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + if (pDesc->Usage == USAGE_STAGING) + { + allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; + allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + } res = vmaCreateBuffer(allocationhandler->allocator, &bufferInfo, &allocInfo, &internal_state->resource, &internal_state->allocation, nullptr); assert(res == VK_SUCCESS); @@ -2548,14 +2549,25 @@ using namespace Vulkan_Internal; // Issue data copy on request: if (pInitialData != nullptr) { + GPUBufferDesc uploaddesc; + uploaddesc.ByteWidth = pDesc->ByteWidth; + uploaddesc.Usage = USAGE_STAGING; + GPUBuffer uploadbuffer; + bool upload_success = CreateBuffer(&uploaddesc, nullptr, &uploadbuffer); + assert(upload_success); + VkBuffer upload_resource = to_internal(&uploadbuffer)->resource; + VmaAllocation upload_allocation = to_internal(&uploadbuffer)->allocation; + + void* pData = upload_allocation->GetMappedData(); + assert(pData != nullptr); + copyQueueLock.lock(); { - uint8_t* dest = bufferUploader.allocate((size_t)internal_state->allocation->GetSize(), (size_t)internal_state->allocation->GetAlignment()); - memcpy(dest, pInitialData->pSysMem, pBuffer->desc.ByteWidth); + memcpy(pData, pInitialData->pSysMem, pBuffer->desc.ByteWidth); VkBufferCopy copyRegion = {}; copyRegion.size = pBuffer->desc.ByteWidth; - copyRegion.srcOffset = bufferUploader.calculateOffset(dest); + copyRegion.srcOffset = 0; copyRegion.dstOffset = 0; VkBufferMemoryBarrier barrier = {}; @@ -2578,7 +2590,7 @@ using namespace Vulkan_Internal; ); - vkCmdCopyBuffer(copyCommandBuffer, bufferUploader.resource, internal_state->resource, 1, ©Region); + vkCmdCopyBuffer(copyCommandBuffer, upload_resource, internal_state->resource, 1, ©Region); VkAccessFlags tmp = barrier.srcAccessMask; @@ -2740,10 +2752,20 @@ using namespace Vulkan_Internal; // Issue data copy on request: if (pInitialData != nullptr) { + GPUBufferDesc uploaddesc; + uploaddesc.ByteWidth = (uint32_t)internal_state->allocation->GetSize(); + uploaddesc.Usage = USAGE_STAGING; + GPUBuffer uploadbuffer; + bool upload_success = CreateBuffer(&uploaddesc, nullptr, &uploadbuffer); + assert(upload_success); + VkBuffer upload_resource = to_internal(&uploadbuffer)->resource; + VmaAllocation upload_allocation = to_internal(&uploadbuffer)->allocation; + + void* pData = upload_allocation->GetMappedData(); + assert(pData != nullptr); + copyQueueLock.lock(); { - uint8_t* dest = textureUploader.allocate((size_t)internal_state->allocation->GetSize(), (size_t)internal_state->allocation->GetAlignment()); - std::vector copyRegions; size_t cpyoffset = 0; @@ -2760,12 +2782,12 @@ using namespace Vulkan_Internal; { cpysize /= 4; } - uint8_t* cpyaddr = dest + cpyoffset; + uint8_t* cpyaddr = (uint8_t*)pData + cpyoffset; memcpy(cpyaddr, subresourceData.pSysMem, cpysize); cpyoffset += cpysize; VkBufferImageCopy copyRegion = {}; - copyRegion.bufferOffset = textureUploader.calculateOffset(cpyaddr); + copyRegion.bufferOffset = 0; copyRegion.bufferRowLength = 0; copyRegion.bufferImageHeight = 0; @@ -2813,7 +2835,7 @@ using namespace Vulkan_Internal; 1, &barrier ); - vkCmdCopyBufferToImage(copyCommandBuffer, textureUploader.resource, internal_state->resource, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)copyRegions.size(), copyRegions.data()); + vkCmdCopyBufferToImage(copyCommandBuffer, upload_resource, internal_state->resource, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)copyRegions.size(), copyRegions.data()); barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier.newLayout = _ConvertImageLayout(pTexture->desc.layout);; @@ -3724,8 +3746,6 @@ using namespace Vulkan_Internal; res = vkBeginCommandBuffer(copyCommandBuffer, &beginInfo); assert(res == VK_SUCCESS); - bufferUploader.clear(); - textureUploader.clear(); } // Transitions: diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index 0488d7536..a1f8343e9 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -203,26 +203,6 @@ namespace wiGraphics }; std::unordered_map dynamic_constantbuffers[COMMANDLIST_COUNT]; - struct UploadBuffer - { - GraphicsDevice_Vulkan* device = nullptr; - VkBuffer resource = VK_NULL_HANDLE; - VmaAllocation allocation; - uint8_t* dataBegin = nullptr; - uint8_t* dataCur = nullptr; - uint8_t* dataEnd = nullptr; - wiSpinLock lock; - - void init(GraphicsDevice_Vulkan* device, const QueueFamilyIndices& queueIndices, size_t size); - ~UploadBuffer(); - - uint8_t* allocate(size_t dataSize, size_t alignment); - void clear(); - uint64_t calculateOffset(uint8_t* address); - }; - UploadBuffer bufferUploader; - UploadBuffer textureUploader; - std::unordered_map pipelines_global; std::vector> pipelines_worker[COMMANDLIST_COUNT]; size_t prev_pipeline_hash[COMMANDLIST_COUNT] = {}; diff --git a/WickedEngine/wiHelper.cpp b/WickedEngine/wiHelper.cpp index bd89d4ee4..edd38e90a 100644 --- a/WickedEngine/wiHelper.cpp +++ b/WickedEngine/wiHelper.cpp @@ -214,13 +214,20 @@ namespace wiHelper #ifdef _WIN32 #include - std::string workingdir = std::string(_getcwd(NULL, 0)) + "/"; -#else - std::string workingdir = ""; // TODO -#endif - const std::string __originalWorkingDir = workingdir; +#endif // _WIN32 + static std::string workingdir; + static std::string __originalWorkingDir; string GetOriginalWorkingDirectory() { + static bool init = false; + if (!init) + { + init = true; +#ifdef _WIN32 + workingdir = std::string(_getcwd(NULL, 0)) + "/"; +#endif // _WIN32 + __originalWorkingDir = workingdir; + } return __originalWorkingDir; } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index ffeb68fda..0f7a0cd38 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -51,6 +51,7 @@ Shader geometryShaders[GSTYPE_COUNT]; Shader hullShaders[HSTYPE_COUNT]; Shader domainShaders[DSTYPE_COUNT]; Shader computeShaders[CSTYPE_COUNT]; +Shader raytracingShaders[RTTYPE_COUNT]; Texture textures[TEXTYPE_COUNT]; InputLayout inputLayouts[ILTYPE_COUNT]; RasterizerState rasterizers[RSTYPE_COUNT]; @@ -309,7 +310,15 @@ struct FrameCulling }; unordered_map frameCullings; -vector pendingMaterialUpdates; +vector pendingMaterialUpdates; + +enum AS_UPDATE_TYPE +{ + AS_COMPLETE, + AS_REBUILD, + AS_UPDATE, +}; +unordered_map pendingBottomLevelBuilds; struct Instance { @@ -984,6 +993,8 @@ PipelineState PSO_sss; PipelineState PSO_upsample_bilateral; PipelineState PSO_outline; +RaytracingPipelineState RTPSO_rtao; + enum SKYRENDERING { SKYRENDERING_STATIC, @@ -1415,6 +1426,11 @@ void LoadShaders() wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(DS, domainShaders[DSTYPE_OBJECT], "objectDS.cso"); }); + if (wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(SHADERSTAGE_COUNT, raytracingShaders[RTTYPE_RTAO], "rtaoLIB.cso"); }); + } + wiJobSystem::Wait(ctx); // default objectshaders: @@ -2155,6 +2171,28 @@ void LoadShaders() } + if (wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + wiJobSystem::Execute(ctx, [device](wiJobArgs args) { + + RaytracingPipelineStateDesc rtdesc; + rtdesc.shaderlibraries.emplace_back(); + rtdesc.shaderlibraries.back().shader = &raytracingShaders[RTTYPE_RTAO]; + + rtdesc.hitgroups.emplace_back(); + rtdesc.hitgroups.back().type = ShaderHitGroup::TRIANGLES; + rtdesc.hitgroups.back().name = "RTAO_Hitgroup"; + rtdesc.hitgroups.back().closesthit_shader_name = "RTAO_ClosestHit"; + + rtdesc.max_trace_recursion_depth = 1; + rtdesc.max_payload_size_in_bytes = sizeof(float); + rtdesc.max_attribute_size_in_bytes = sizeof(XMFLOAT2); // bary + bool success = device->CreateRaytracingPipelineState(&rtdesc, &RTPSO_rtao); + assert(success); + + }); + } + wiJobSystem::Wait(ctx); } @@ -2828,6 +2866,9 @@ void ClearWorld() packedDecals.clear(); packedLightmaps.clear(); + + pendingMaterialUpdates.clear(); + pendingBottomLevelBuilds.clear(); } static const uint32_t CASCADE_COUNT = 3; @@ -3672,7 +3713,6 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) // See which materials will need to update their GPU render data: wiJobSystem::Execute(ctx, [&](wiJobArgs args) { - pendingMaterialUpdates.clear(); for (size_t i = 0; i < scene.materials.GetCount(); ++i) { MaterialComponent& material = scene.materials[i]; @@ -3680,7 +3720,7 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) if (material.IsDirty()) { material.SetDirty(false); - pendingMaterialUpdates.push_back(uint32_t(i)); + pendingMaterialUpdates.push_back(i); if (!material.constantBuffer.IsValid()) { @@ -3698,43 +3738,8 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) // Need to swap prev and current vertex buffers for any dynamic meshes BEFORE render threads are kicked // and also create skinning bone buffers: wiJobSystem::Execute(ctx, [&](wiJobArgs args) { - for (size_t i = 0; i < scene.meshes.GetCount(); ++i) - { - Entity entity = scene.meshes.GetEntity(i); - MeshComponent& mesh = scene.meshes[i]; + const bool raytracing_api = device->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING); - if (mesh.IsSkinned() && scene.armatures.Contains(mesh.armatureID)) - { - const SoftBodyPhysicsComponent* softbody = scene.softbodies.GetComponent(entity); - if (softbody != nullptr && !softbody->vertex_positions_simulation.empty()) - { - // If soft body simulation is active, don't perform skinning. - // (Soft body animated vertices are skinned in simulation phase by physics system) - continue; - } - - ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID); - - if (!armature.boneBuffer.IsValid()) - { - GPUBufferDesc bd; - bd.Usage = USAGE_DYNAMIC; - bd.CPUAccessFlags = CPU_ACCESS_WRITE; - - bd.ByteWidth = sizeof(ArmatureComponent::ShaderBoneType) * (uint32_t)armature.boneCollection.size(); - bd.BindFlags = BIND_SHADER_RESOURCE; - bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED; - bd.StructureByteStride = sizeof(ArmatureComponent::ShaderBoneType); - - device->CreateBuffer(&bd, nullptr, &armature.boneBuffer); - } - if (!mesh.vertexBuffer_PRE.IsValid()) - { - device->CreateBuffer(&mesh.streamoutBuffer_POS.GetDesc(), nullptr, &mesh.vertexBuffer_PRE); - } - std::swap(mesh.streamoutBuffer_POS, mesh.vertexBuffer_PRE); - } - } for (size_t i = 0; i < scene.softbodies.GetCount(); ++i) { const SoftBodyPhysicsComponent& softbody = scene.softbodies[i]; @@ -3746,13 +3751,81 @@ void UpdatePerFrameData(float dt, uint32_t layerMask) Entity entity = scene.softbodies.GetEntity(i); MeshComponent& mesh = *scene.meshes.GetComponent(entity); + if (raytracing_api && !mesh.BLAS_build_pending) + { + pendingBottomLevelBuilds[entity] = AS_UPDATE; + } + if (!mesh.vertexBuffer_PRE.IsValid()) { device->CreateBuffer(&mesh.vertexBuffer_POS.GetDesc(), nullptr, &mesh.streamoutBuffer_POS); device->CreateBuffer(&mesh.vertexBuffer_POS.GetDesc(), nullptr, &mesh.vertexBuffer_PRE); + + if (raytracing_api) + { + mesh.BLAS.desc._flags |= RaytracingAccelerationStructureDesc::FLAG_ALLOW_UPDATE; + device->CreateRaytracingAccelerationStructure(&mesh.BLAS.desc, &mesh.BLAS); + } } std::swap(mesh.streamoutBuffer_POS, mesh.vertexBuffer_PRE); } + for (size_t i = 0; i < scene.meshes.GetCount(); ++i) + { + Entity entity = scene.meshes.GetEntity(i); + MeshComponent& mesh = scene.meshes[i]; + + if (mesh.IsSkinned() && scene.armatures.Contains(mesh.armatureID)) + { + const SoftBodyPhysicsComponent* softbody = scene.softbodies.GetComponent(entity); + if (softbody == nullptr || softbody->vertex_positions_simulation.empty()) + { + if (raytracing_api && !mesh.BLAS_build_pending) + { + pendingBottomLevelBuilds[entity] = AS_UPDATE; + } + + ArmatureComponent& armature = *scene.armatures.GetComponent(mesh.armatureID); + + if (!armature.boneBuffer.IsValid()) + { + GPUBufferDesc bd; + bd.Usage = USAGE_DYNAMIC; + bd.CPUAccessFlags = CPU_ACCESS_WRITE; + + bd.ByteWidth = sizeof(ArmatureComponent::ShaderBoneType) * (uint32_t)armature.boneCollection.size(); + bd.BindFlags = BIND_SHADER_RESOURCE; + bd.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED; + bd.StructureByteStride = sizeof(ArmatureComponent::ShaderBoneType); + + device->CreateBuffer(&bd, nullptr, &armature.boneBuffer); + } + if (!mesh.vertexBuffer_PRE.IsValid()) + { + device->CreateBuffer(&mesh.streamoutBuffer_POS.GetDesc(), nullptr, &mesh.vertexBuffer_PRE); + } + std::swap(mesh.streamoutBuffer_POS, mesh.vertexBuffer_PRE); + } + } + + if (raytracing_api) + { + if (mesh.streamoutBuffer_POS.IsValid()) + { + for (auto& geometry : mesh.BLAS.desc.bottomlevel.geometries) + { + // swapped dynamic vertex buffers in BLAS: + geometry.triangles.vertexBuffer = mesh.streamoutBuffer_POS; + } + } + + if (mesh.BLAS_build_pending) + { + mesh.BLAS_build_pending = false; + pendingBottomLevelBuilds[entity] = AS_REBUILD; + } + } + + } }); // Update Voxelization parameters: @@ -4152,6 +4225,7 @@ void UpdateRenderData(CommandList cmd) device->UpdateBuffer(&material.constantBuffer, &materialGPUData, cmd); } } + pendingMaterialUpdates.clear(); const FrameCulling& mainCameraCulling = frameCullings.at(&GetCamera()); @@ -4547,6 +4621,89 @@ void UpdateRenderData(CommandList cmd) RefreshEnvProbes(cmd); RefreshImpostors(cmd); } +void UpdateRaytracingAccelerationStructures(CommandList cmd) +{ + GraphicsDevice* device = GetDevice(); + const Scene& scene = GetScene(); + if (!device->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING) || !scene.TLAS.IsValid()) + { + return; + } + auto range = wiProfiler::BeginRangeGPU("Update Raytracing Acceleration Structures", cmd); + device->EventBegin("Update Raytracing Acceleration Structures", cmd); + + bool bottomlevel_sync = false; + + // Build bottom level: + for(auto& it : pendingBottomLevelBuilds) + { + AS_UPDATE_TYPE type = it.second; + if (type == AS_COMPLETE) + continue; + + Entity entity = it.first; + const MeshComponent* mesh = scene.meshes.GetComponent(entity); + + if (mesh != nullptr) + { + // If src param is nullptr, rebuild happens, else update (if src == dst, then update happens in place) + device->BuildRaytracingAccelerationStructure(&mesh->BLAS, cmd, type == AS_REBUILD ? nullptr : &mesh->BLAS); + bottomlevel_sync = true; + it.second = AS_COMPLETE; + } + } + + // Gather all instances for top level: + size_t instanceSize = device->GetTopLevelAccelerationStructureInstanceSize(); + size_t instanceArraySize = (size_t)scene.TLAS.desc.toplevel.count * instanceSize; + void* instanceArray = GetRenderFrameAllocator(cmd).allocate(instanceArraySize); + size_t instanceOffset = 0; + for (size_t i = 0; i < scene.objects.GetCount(); ++i) + { + const ObjectComponent& object = scene.objects[i]; + + if (object.meshID != INVALID_ENTITY) + { + const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); + + RaytracingAccelerationStructureDesc::TopLevel::Instance instance = {}; + const XMFLOAT4X4& transform = object.transform_index >= 0 ? scene.transforms[object.transform_index].world : IDENTITYMATRIX; + instance = {}; + instance.transform = XMFLOAT3X4( + transform._11, transform._21, transform._31, transform._41, + transform._12, transform._22, transform._32, transform._42, + transform._13, transform._23, transform._33, transform._43 + ); + instance.InstanceID = i; + instance.InstanceMask = 1; + instance.bottomlevel = mesh.BLAS; + + device->WriteTopLevelAccelerationStructureInstance(&instance, (void*)((size_t)instanceArray + instanceOffset)); + instanceOffset += instanceSize; + } + } + device->UpdateBuffer(&scene.TLAS.desc.toplevel.instanceBuffer, instanceArray, cmd, (int)instanceArraySize); + GetRenderFrameAllocator(cmd).free(instanceArraySize); + + // Sync with bottom level before building top level: + if (bottomlevel_sync) + { + GPUBarrier barriers[] = { + GPUBarrier::Memory(), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + } + + // Build top level: + device->BuildRaytracingAccelerationStructure(&scene.TLAS, cmd, nullptr); + GPUBarrier barriers[] = { + GPUBarrier::Memory(&scene.TLAS), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + + device->EventEnd(cmd); + wiProfiler::EndRange(range); +} void OcclusionCulling_Render(CommandList cmd) { if (!GetOcclusionCullingEnabled() || GetFreezeCullingCameraEnabled()) @@ -10079,7 +10236,11 @@ void Postprocess_MSAO( } device->Dispatch((HiWidth + 2 + 15) / 16, (HiHeight + 2 + 15) / 16, 1, cmd); - + + GPUBarrier barriers[] = { + GPUBarrier::Memory(), + }; + device->Barrier(barriers, arraysize(barriers), cmd); }; blur_and_upsample(texture_ao_smooth3, texture_lineardepth_downsize3, texture_lineardepth_downsize4, &texture_ao_merged4, @@ -10097,6 +10258,122 @@ void Postprocess_MSAO( wiProfiler::EndRange(prof_range); device->EventEnd(cmd); } +void Postprocess_RTAO( + const Texture& depthbuffer, + const Texture& lineardepth, + const Texture& output, + CommandList cmd, + float range, + uint32_t samplecount, + float power +) +{ + const Scene& scene = wiScene::GetScene(); + if (scene.objects.GetCount() <= 0) + { + return; + } + + GraphicsDevice* device = GetDevice(); + + device->EventBegin("Postprocess_RTAO", cmd); + auto prof_range = wiProfiler::BeginRangeGPU("RTAO", cmd); + + static TextureDesc saved_desc; + static Texture temp0; + static Texture temp1; + + const TextureDesc& lineardepth_desc = lineardepth.GetDesc(); + if (saved_desc.Width != lineardepth_desc.Width || saved_desc.Height != lineardepth_desc.Height) + { + saved_desc = lineardepth_desc; // <- this must already have SRV and UAV request flags set up! + saved_desc.MipLevels = 1; + + TextureDesc desc = saved_desc; + desc.Format = FORMAT_R8_UNORM; + desc.Width = (desc.Width + 1) / 2; + desc.Height = (desc.Height + 1) / 2; + device->CreateTexture(&desc, nullptr, &temp0); + device->CreateTexture(&desc, nullptr, &temp1); + } + + device->BindResource(CS, &depthbuffer, TEXSLOT_DEPTH, cmd); + device->BindResource(CS, &lineardepth, TEXSLOT_LINEARDEPTH, cmd); + + const TextureDesc& desc = temp0.GetDesc(); + + PostProcessCB cb; + cb.xPPResolution.x = desc.Width; + cb.xPPResolution.y = desc.Height; + cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x; + cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y; + cb.rtao_range = range; + cb.rtao_samplecount = (float)samplecount; + cb.rtao_power = power; + device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd); + device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd); + + const GPUResource* uavs[] = { + &temp0, + }; + device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd); + + if (device->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + size_t shaderIdentifierSize = device->GetShaderIdentifierSize(); + GraphicsDevice::GPUAllocation shadertable_raygen = device->AllocateGPU(shaderIdentifierSize, cmd); + GraphicsDevice::GPUAllocation shadertable_miss = device->AllocateGPU(shaderIdentifierSize, cmd); + GraphicsDevice::GPUAllocation shadertable_hitgroup = device->AllocateGPU(shaderIdentifierSize, cmd); + + void* rayGenShaderIdentifier = device->GetShaderIdentifier(&RTPSO_rtao, "RTAO_Raygen"); + void* missShaderIdentifier = device->GetShaderIdentifier(&RTPSO_rtao, "RTAO_Miss"); + void* hitGroupShaderIdentifier = device->GetShaderIdentifier(&RTPSO_rtao, "RTAO_Hitgroup"); + + memcpy(shadertable_raygen.data, rayGenShaderIdentifier, shaderIdentifierSize); + memcpy(shadertable_miss.data, missShaderIdentifier, shaderIdentifierSize); + memcpy(shadertable_hitgroup.data, hitGroupShaderIdentifier, shaderIdentifierSize); + + DispatchRaysDesc dispatchraysdesc; + dispatchraysdesc.raygeneration.buffer = shadertable_raygen.buffer; + dispatchraysdesc.raygeneration.offset = shadertable_raygen.offset; + dispatchraysdesc.raygeneration.size = shaderIdentifierSize; + + dispatchraysdesc.miss.buffer = shadertable_miss.buffer; + dispatchraysdesc.miss.offset = shadertable_miss.offset; + dispatchraysdesc.miss.size = shaderIdentifierSize; + dispatchraysdesc.miss.stride = shaderIdentifierSize; + + dispatchraysdesc.hitgroup.buffer = shadertable_hitgroup.buffer; + dispatchraysdesc.hitgroup.offset = shadertable_hitgroup.offset; + dispatchraysdesc.hitgroup.size = shaderIdentifierSize; + dispatchraysdesc.hitgroup.stride = shaderIdentifierSize; + + dispatchraysdesc.Width = desc.Width; + dispatchraysdesc.Height = desc.Height; + + device->BindResource(CS, &scene.TLAS, TEXSLOT_ONDEMAND0, cmd); + + device->BindRaytracingPipelineState(&RTPSO_rtao, cmd); + device->DispatchRays(&dispatchraysdesc, cmd); + } + else + { + assert(0); // TODO: non raytracing API implementation? + } + + GPUBarrier barriers[] = { + GPUBarrier::Memory(), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + + device->UnbindUAVs(0, arraysize(uavs), cmd); + + Postprocess_Blur_Bilateral(temp0, lineardepth, temp1, temp0, cmd, 1.2f, -1, -1, true); + Postprocess_Upsample_Bilateral(temp0, lineardepth, output, cmd); + + wiProfiler::EndRange(prof_range); + device->EventEnd(cmd); +} void Postprocess_SSR( const Texture& input, const Texture& depthbuffer, diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 5c6c50ea8..f15b5a80f 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -65,8 +65,10 @@ namespace wiRenderer // Updates the main scene, performs frustum culling for main camera and other tasks that are only done once per frame. Specify layerMask to only include specific entities in the render frame. void UpdatePerFrameData(float dt, uint32_t layerMask = ~0); - // Updates the GPU state according to the previously called UpatePerFrameData() + // Updates the GPU state according to the previously called UpdatePerFrameData() void UpdateRenderData(wiGraphics::CommandList cmd); + // Updates all acceleration structures for raytracing API + void UpdateRaytracingAccelerationStructures(wiGraphics::CommandList cmd); // Binds all common constant buffers and samplers that may be used in all shaders void BindCommonResources(wiGraphics::CommandList cmd); @@ -212,6 +214,15 @@ namespace wiRenderer wiGraphics::CommandList cmd, float power = 2.0f ); + void Postprocess_RTAO( + const wiGraphics::Texture& depthbuffer, + const wiGraphics::Texture& lineardepth, + const wiGraphics::Texture& output, + wiGraphics::CommandList cmd, + float range = 1.0f, + uint32_t samplecount = 16, + float power = 2.0f + ); void Postprocess_SSR( const wiGraphics::Texture& input, const wiGraphics::Texture& depthbuffer, diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index b1604530c..9fb12f863 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -552,6 +552,60 @@ namespace wiScene // vertexBuffer_PRE will be created on demand later! vertexBuffer_PRE = GPUBuffer(); + + if (wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + BLAS_build_pending = true; + + RaytracingAccelerationStructureDesc desc; + desc.type = RaytracingAccelerationStructureDesc::BOTTOMLEVEL; + + if (streamoutBuffer_POS.IsValid()) + { + desc._flags |= RaytracingAccelerationStructureDesc::FLAG_ALLOW_UPDATE; + desc._flags |= RaytracingAccelerationStructureDesc::FLAG_PREFER_FAST_BUILD; + } + else + { + desc._flags |= RaytracingAccelerationStructureDesc::FLAG_PREFER_FAST_TRACE; + } + +#if 0 + // Flattened subsets: + desc.bottomlevel.geometries.emplace_back(); + auto& geometry = desc.bottomlevel.geometries.back(); + geometry._flags = RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_OPAQUE; + geometry.type = RaytracingAccelerationStructureDesc::BottomLevel::Geometry::TRIANGLES; + geometry.triangles.vertexBuffer = streamoutBuffer_POS.IsValid() ? streamoutBuffer_POS : vertexBuffer_POS; + geometry.triangles.indexBuffer = indexBuffer; + geometry.triangles.indexFormat = GetIndexFormat(); + geometry.triangles.indexCount = (uint32_t)indices.size(); + geometry.triangles.indexOffset = 0; + geometry.triangles.vertexCount = (uint32_t)vertex_positions.size(); + geometry.triangles.vertexFormat = FORMAT_R32G32B32_FLOAT; + geometry.triangles.vertexStride = sizeof(MeshComponent::Vertex_POS); +#else + // One geometry per subset: + for (auto& subset : subsets) + { + desc.bottomlevel.geometries.emplace_back(); + auto& geometry = desc.bottomlevel.geometries.back(); + geometry._flags = RaytracingAccelerationStructureDesc::BottomLevel::Geometry::FLAG_OPAQUE; + geometry.type = RaytracingAccelerationStructureDesc::BottomLevel::Geometry::TRIANGLES; + geometry.triangles.vertexBuffer = streamoutBuffer_POS.IsValid() ? streamoutBuffer_POS : vertexBuffer_POS; + geometry.triangles.indexBuffer = indexBuffer; + geometry.triangles.indexFormat = GetIndexFormat(); + geometry.triangles.indexCount = subset.indexCount; + geometry.triangles.indexOffset = subset.indexOffset; + geometry.triangles.vertexCount = (uint32_t)vertex_positions.size(); + geometry.triangles.vertexFormat = FORMAT_R32G32B32_FLOAT; + geometry.triangles.vertexStride = sizeof(MeshComponent::Vertex_POS); + } +#endif + + bool success = device->CreateRaytracingAccelerationStructure(&desc, &BLAS); + assert(success); + } } void MeshComponent::ComputeNormals(COMPUTE_NORMALS compute) { @@ -1162,6 +1216,25 @@ namespace wiScene { bounds = AABB::Merge(bounds, group_bound); } + + if (wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + // Recreate top level acceleration structure if the object count changed: + if (dt > 0 && objects.GetCount() > 0 && objects.GetCount() != TLAS.desc.toplevel.count) + { + RaytracingAccelerationStructureDesc desc; + desc._flags = RaytracingAccelerationStructureDesc::FLAG_PREFER_FAST_BUILD; + desc.type = RaytracingAccelerationStructureDesc::TOPLEVEL; + desc.toplevel.count = (uint32_t)objects.GetCount(); + GPUBufferDesc bufdesc; + bufdesc.ByteWidth = desc.toplevel.count * (uint32_t)wiRenderer::GetDevice()->GetTopLevelAccelerationStructureInstanceSize(); + bool success = wiRenderer::GetDevice()->CreateBuffer(&bufdesc, nullptr, &desc.toplevel.instanceBuffer); + assert(success); + success = wiRenderer::GetDevice()->CreateRaytracingAccelerationStructure(&desc, &TLAS); + assert(success); + } + } + } void Scene::Clear() { @@ -1194,6 +1267,8 @@ namespace wiScene sounds.Clear(); inverse_kinematics.Clear(); springs.Clear(); + + TLAS = RaytracingAccelerationStructure(); } void Scene::Merge(Scene& other) { diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index c44dace88..16187713e 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -301,6 +301,8 @@ namespace wiScene wiGraphics::GPUBuffer vertexBuffer_SUB; std::vector vertex_subsets; + wiGraphics::RaytracingAccelerationStructure BLAS; + bool BLAS_build_pending = true; inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } } inline void SetDoubleSided(bool value) { if (value) { _flags |= DOUBLE_SIDED; } else { _flags &= ~DOUBLE_SIDED; } } @@ -1132,6 +1134,7 @@ namespace wiScene AABB bounds; std::vector parallel_bounds; WeatherComponent weather; + wiGraphics::RaytracingAccelerationStructure TLAS; // Update all components by a given timestep (in seconds): void Update(float dt); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 38d192c08..5eff35bb7 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -7,9 +7,9 @@ namespace wiVersion // main engine core const int major = 0; // minor features, major updates - const int minor = 42; + const int minor = 43; // minor bug fixes, alterations, refactors, updates - const int revision = 11; + const int revision = 0; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision); diff --git a/appveyor.yml b/appveyor.yml index 2f0a27e36..c9b9d30d7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,7 @@ build_script: - msbuild "C:\projects\wickedengine\WickedEngine.sln" /t:Tests /m /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - msbuild "C:\projects\wickedengine\WickedEngine.sln" /t:Template_Windows /m /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - msbuild "C:\projects\wickedengine\WickedEngine.sln" /t:Template_UWP /m /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + - msbuild "C:\projects\wickedengine\WickedEngine.sln" /t:Shaders_HLSL6 /m /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" platform: - x64 diff --git a/generate_shader_buildtask_hlsl6.py b/generate_shader_buildtask_hlsl6.py index 5f22372c2..6889bef67 100644 --- a/generate_shader_buildtask_hlsl6.py +++ b/generate_shader_buildtask_hlsl6.py @@ -44,8 +44,10 @@ for shader in root.iter(namespace + "FxCompile"): file.write("ds") if profile == "Compute": file.write("cs") + if profile == "Library": + file.write("lib") - file.write("_6_1 ") + file.write("_6_4 ") file.write(" -D SHADER_MODEL_6 "); diff --git a/generate_shader_buildtask_spirv.py b/generate_shader_buildtask_spirv.py index ed71f9051..f21167419 100644 --- a/generate_shader_buildtask_spirv.py +++ b/generate_shader_buildtask_spirv.py @@ -44,8 +44,10 @@ for shader in root.iter(namespace + "FxCompile"): file.write("ds") if profile == "Compute": file.write("cs") + if profile == "Library": + file.write("lib") - file.write("_6_0 ") + file.write("_6_4 ") file.write("-D SHADERCOMPILER_SPIRV -D "); @@ -59,7 +61,7 @@ for shader in root.iter(namespace + "FxCompile"): file.write("SPIRV_SHADERTYPE_HS") if profile == "Domain": file.write("SPIRV_SHADERTYPE_DS -fvk-invert-y") - if profile == "Compute": + if profile == "Compute" or profile == "Library": file.write("SPIRV_SHADERTYPE_CS") file.write(" -spirv -fvk-use-dx-layout -flegacy-macro-expansion -Fo " + "shaders/" + outputdir + "/" + os.path.splitext(name)[0] + ".cso ")