From d93698d97eb37e6d1dca32b6037b933d052e3eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sun, 25 Aug 2024 12:29:23 +0200 Subject: [PATCH] planar reflection MSAA and some fixes --- Editor/Editor.cpp | 2 +- Editor/GraphicsWindow.cpp | 2 +- WickedEngine/offlineshadercompiler.cpp | 4 +- WickedEngine/shaders/ShaderInterop_Renderer.h | 20 ++++----- WickedEngine/shaders/depth_pyramidCS.hlsl | 2 +- WickedEngine/shaders/depth_reprojectCS.hlsl | 2 +- WickedEngine/wiRenderPath3D.cpp | 43 ++++++++++++++----- WickedEngine/wiRenderPath3D.h | 6 ++- WickedEngine/wiRenderer.cpp | 24 ++++++++++- WickedEngine/wiScene_Components.cpp | 2 +- WickedEngine/wiVersion.cpp | 2 +- 11 files changed, 77 insertions(+), 32 deletions(-) diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 0806c5b7f..d87fca97e 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -104,7 +104,7 @@ void Editor::HotReload() wi::jobsystem::Wait(hotreload_ctx); hotreload_ctx.priority = wi::jobsystem::Priority::Streaming; - if (wi::shadercompiler::GetRegisteredShaderCount() > 0) + if (wi::shadercompiler::GetRegisteredShaderCount() > 0 && !wi::renderer::IsPipelineCreationActive()) { wi::jobsystem::Execute(hotreload_ctx, [](wi::jobsystem::JobArgs args) { wi::backlog::post("[Shader check] Started checking " + std::to_string(wi::shadercompiler::GetRegisteredShaderCount()) + " registered shaders for changes..."); diff --git a/Editor/GraphicsWindow.cpp b/Editor/GraphicsWindow.cpp index f2fdb5511..a445fa0a2 100644 --- a/Editor/GraphicsWindow.cpp +++ b/Editor/GraphicsWindow.cpp @@ -131,7 +131,7 @@ void GraphicsWindow::Create(EditorComponent* _editor) AddWidget(&visibilityComputeShadingCheckBox); meshShaderCheckBox.Create("Allow Mesh Shader: "); - meshShaderCheckBox.SetTooltip("Allow using mesh shaders to render objects (Requires support from GPU)."); + meshShaderCheckBox.SetTooltip("Allow using mesh shaders to render objects (Requires support from GPU).\nNote: scene must be reloaded for this to take effect, as this will require additional mesh processing!"); meshShaderCheckBox.SetPos(XMFLOAT2(x, y += step)); meshShaderCheckBox.SetSize(XMFLOAT2(itemheight, itemheight)); if (editor->main->config.GetSection("graphics").Has("mesh_shader")) diff --git a/WickedEngine/offlineshadercompiler.cpp b/WickedEngine/offlineshadercompiler.cpp index acbcbdf9b..bb6f55c9b 100644 --- a/WickedEngine/offlineshadercompiler.cpp +++ b/WickedEngine/offlineshadercompiler.cpp @@ -575,12 +575,12 @@ int main(int argc, char* argv[]) // if shader format cannot support shader model, then we cancel the task without returning error return; } - if (target.format == ShaderFormat::PS5 && (input.minshadermodel >= ShaderModel::SM_6_5 || input.stage == ShaderStage::MS)) + if (target.format == ShaderFormat::PS5 && (input.minshadermodel >= ShaderModel::SM_6_5 || input.stage == ShaderStage::MS || input.stage == ShaderStage::AS)) { // TODO PS5 raytracing, mesh shader return; } - if (target.format == ShaderFormat::HLSL6_XS && input.stage == ShaderStage::MS) + if (target.format == ShaderFormat::HLSL6_XS && (input.stage == ShaderStage::MS || input.stage == ShaderStage::AS)) { // TODO Xbox mesh shader return; diff --git a/WickedEngine/shaders/ShaderInterop_Renderer.h b/WickedEngine/shaders/ShaderInterop_Renderer.h index 79c8b7bf1..2e0a7a3dd 100644 --- a/WickedEngine/shaders/ShaderInterop_Renderer.h +++ b/WickedEngine/shaders/ShaderInterop_Renderer.h @@ -536,20 +536,20 @@ struct alignas(16) ShaderMeshlet struct ShaderClusterTriangle { - uint packed; + uint raw; void init(uint i0, uint i1, uint i2, uint flags = 0u) { - packed = 0; - packed |= i0 & 0xFF; - packed |= (i1 & 0xFF) << 8u; - packed |= (i2 & 0xFF) << 16u; - packed |= (flags & 0xFF) << 24u; + raw = 0; + raw |= i0 & 0xFF; + raw |= (i1 & 0xFF) << 8u; + raw |= (i2 & 0xFF) << 16u; + raw |= (flags & 0xFF) << 24u; } - uint i0() { return packed & 0xFF; } - uint i1() { return (packed >> 8u) & 0xFF; } - uint i2() { return (packed >> 16u) & 0xFF; } + uint i0() { return raw & 0xFF; } + uint i1() { return (raw >> 8u) & 0xFF; } + uint i2() { return (raw >> 16u) & 0xFF; } uint3 tri() { return uint3(i0(), i1(), i2()); } - uint flags() { return packed >> 24u; } + uint flags() { return raw >> 24u; } }; struct alignas(16) ShaderCluster { diff --git a/WickedEngine/shaders/depth_pyramidCS.hlsl b/WickedEngine/shaders/depth_pyramidCS.hlsl index f634b7a4f..6c152d0c3 100644 --- a/WickedEngine/shaders/depth_pyramidCS.hlsl +++ b/WickedEngine/shaders/depth_pyramidCS.hlsl @@ -11,7 +11,7 @@ RWTexture2D output_mip1 : register(u1); void main(uint2 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) { const uint2 GTid = remap_lane_8x8(groupIndex); - const uint2 pixel = clamp(Gid.xy * 8 + GTid.xy, 0, push.resolution - 1); + const uint2 pixel = clamp(Gid.xy * 8 + GTid.xy, uint2(0, 0), push.resolution - 1); float2 uv = (pixel + 0.5) * push.resolution_rcp; float4 depths = input_depth.GatherRed(sampler_linear_clamp, uv, 0); float depth = min(depths.x, min(depths.y, min(depths.z, depths.w))); diff --git a/WickedEngine/shaders/depth_reprojectCS.hlsl b/WickedEngine/shaders/depth_reprojectCS.hlsl index 1a52fc537..e50066a86 100644 --- a/WickedEngine/shaders/depth_reprojectCS.hlsl +++ b/WickedEngine/shaders/depth_reprojectCS.hlsl @@ -14,7 +14,7 @@ void main(uint2 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) { ShaderCamera camera = GetCamera(); const uint2 GTid = remap_lane_8x8(groupIndex); - const uint2 pixel = clamp(Gid.xy * 8 + GTid.xy, 0, push.resolution - 1); + const uint2 pixel = clamp(Gid.xy * 8 + GTid.xy, uint2(0, 0), push.resolution - 1); float2 uv = (pixel + 0.5) * push.resolution_rcp; float2 velocity = input_velocity[pixel].xy; float2 uv_prev = uv + velocity; diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index 444142f81..f0120d815 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -746,8 +746,8 @@ namespace wi camera->texture_normal_index = device->GetDescriptorIndex(&visibilityResources.texture_normals, SubresourceType::SRV); camera->texture_roughness_index = device->GetDescriptorIndex(&visibilityResources.texture_roughness, SubresourceType::SRV); camera->buffer_entitytiles_index = device->GetDescriptorIndex(&tiledLightResources.entityTiles, SubresourceType::SRV); - camera->texture_reflection_index = device->GetDescriptorIndex(&rtReflection, SubresourceType::SRV); - camera->texture_reflection_depth_index = device->GetDescriptorIndex(&depthBuffer_Reflection, SubresourceType::SRV); + camera->texture_reflection_index = device->GetDescriptorIndex(&rtReflection_resolved, SubresourceType::SRV); + camera->texture_reflection_depth_index = device->GetDescriptorIndex(&depthBuffer_Reflection_resolved, SubresourceType::SRV); camera->texture_refraction_index = device->GetDescriptorIndex(&rtSceneCopy, SubresourceType::SRV); camera->texture_waterriples_index = device->GetDescriptorIndex(&rtWaterRipple, SubresourceType::SRV); camera->texture_ao_index = device->GetDescriptorIndex(&rtAO, SubresourceType::SRV); @@ -1273,10 +1273,10 @@ namespace wi &depthBuffer_Reflection, RenderPassImage::LoadOp::CLEAR, RenderPassImage::StoreOp::STORE, - ResourceState::DEPTHSTENCIL, + ResourceState::SHADER_RESOURCE, ResourceState::DEPTHSTENCIL, ResourceState::SHADER_RESOURCE - ), + ) }; device->RenderPassBegin(rp, arraysize(rp), cmd); @@ -1299,6 +1299,8 @@ namespace wi device->RenderPassEnd(cmd); + wi::renderer::ResolveMSAADepthBuffer(depthBuffer_Reflection_resolved, depthBuffer_Reflection, cmd); + if (scene->weather.IsRealisticSky() && scene->weather.IsRealisticSkyAerialPerspective()) { wi::renderer::Postprocess_AerialPerspective( @@ -1353,16 +1355,19 @@ namespace wi RenderPassImage::RenderTarget( &rtReflection, RenderPassImage::LoadOp::DONTCARE, - RenderPassImage::StoreOp::STORE, - ResourceState::SHADER_RESOURCE, - ResourceState::SHADER_RESOURCE + RenderPassImage::StoreOp::DONTCARE, + ResourceState::RENDERTARGET, + ResourceState::RENDERTARGET ), RenderPassImage::DepthStencil( &depthBuffer_Reflection, RenderPassImage::LoadOp::LOAD, RenderPassImage::StoreOp::STORE, + ResourceState::SHADER_RESOURCE, + ResourceState::DEPTHSTENCIL, ResourceState::SHADER_RESOURCE ), + RenderPassImage::Resolve(&rtReflection_resolved) }; device->RenderPassBegin(rp, arraysize(rp), cmd); @@ -2769,19 +2774,35 @@ namespace wi return; TextureDesc desc; - desc.bind_flags = BindFlag::RENDER_TARGET | BindFlag::SHADER_RESOURCE; + desc.sample_count = 4; + desc.bind_flags = BindFlag::RENDER_TARGET; desc.format = wi::renderer::format_rendertarget_main; - desc.width = internalResolution.x / 2; - desc.height = internalResolution.y / 2; + desc.width = internalResolution.x / 4; + desc.height = internalResolution.y / 4; + desc.misc_flags = ResourceMiscFlag::TRANSIENT_ATTACHMENT; + desc.layout = ResourceState::RENDERTARGET; device->CreateTexture(&desc, nullptr, &rtReflection); device->SetName(&rtReflection, "rtReflection"); + desc.misc_flags = ResourceMiscFlag::NONE; desc.bind_flags = BindFlag::DEPTH_STENCIL | BindFlag::SHADER_RESOURCE; desc.format = wi::renderer::format_depthbuffer_main; - desc.layout = ResourceState::DEPTHSTENCIL; + desc.layout = ResourceState::SHADER_RESOURCE; device->CreateTexture(&desc, nullptr, &depthBuffer_Reflection); device->SetName(&depthBuffer_Reflection, "depthBuffer_Reflection"); + + desc.sample_count = 1; + desc.format = wi::renderer::format_rendertarget_main; + desc.bind_flags = BindFlag::RENDER_TARGET | BindFlag::SHADER_RESOURCE; + device->CreateTexture(&desc, nullptr, &rtReflection_resolved); + device->SetName(&rtReflection_resolved, "rtReflection_resolved"); + + desc.format = Format::R16_UNORM; + desc.bind_flags = BindFlag::UNORDERED_ACCESS | BindFlag::SHADER_RESOURCE; + device->CreateTexture(&desc, nullptr, &depthBuffer_Reflection_resolved); + device->SetName(&depthBuffer_Reflection_resolved, "depthBuffer_Reflection_resolved"); + wi::renderer::CreateTiledLightResources(tiledLightResources_planarReflection, XMUINT2(depthBuffer_Reflection.desc.width, depthBuffer_Reflection.desc.height)); } else diff --git a/WickedEngine/wiRenderPath3D.h b/WickedEngine/wiRenderPath3D.h index 970073f1c..93b535bb6 100644 --- a/WickedEngine/wiRenderPath3D.h +++ b/WickedEngine/wiRenderPath3D.h @@ -91,7 +91,8 @@ namespace wi wi::graphics::Texture rtPrimitiveID; wi::graphics::Texture rtPrimitiveID_render; // can be MSAA wi::graphics::Texture rtVelocity; // optional R16G16_FLOAT - wi::graphics::Texture rtReflection; // contains the scene rendered for planar reflections + wi::graphics::Texture rtReflection; // contains the scene rendered for planar reflections, MSAA + wi::graphics::Texture rtReflection_resolved; // contains the scene rendered for planar reflections, MSAA wi::graphics::Texture rtRaytracedDiffuse; // raytraced diffuse screen space texture wi::graphics::Texture rtSSR; // standard screen-space reflection results wi::graphics::Texture rtSSGI; // standard screen-space GI results @@ -117,7 +118,8 @@ namespace wi wi::graphics::Texture depthBuffer_Main; // used for depth-testing, can be MSAA wi::graphics::Texture depthBuffer_Copy; // used for shader resource, single sample wi::graphics::Texture depthBuffer_Copy1; // used for disocclusion check - wi::graphics::Texture depthBuffer_Reflection; // used for reflection, single sample + wi::graphics::Texture depthBuffer_Reflection; // used for reflection, MSAA + wi::graphics::Texture depthBuffer_Reflection_resolved; // used for reflection, single sample wi::graphics::Texture rtLinearDepth; // linear depth result + mipchain (max filter) wi::graphics::Texture reprojectedDepth; // prev frame depth reprojected into current, and downsampled for meshlet occlusion culling diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 652648155..079aa36bc 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -2104,6 +2104,12 @@ void LoadShaders() } bool IsPipelineCreationActive() { + if (wi::jobsystem::IsBusy(raytracing_ctx)) + return true; + if (wi::jobsystem::IsBusy(objectps_ctx)) + return true; + if (wi::jobsystem::IsBusy(mesh_shader_ctx)) + return true; for (uint32_t renderPass = 0; renderPass < RENDERPASS_COUNT; ++renderPass) { for (uint32_t mesh_shader = 0; mesh_shader <= (IsMeshShaderAllowed() ? 1u : 0u); ++mesh_shader) @@ -2682,6 +2688,17 @@ void SetShaderSourcePath(const std::string& path) } void ReloadShaders() { + wi::jobsystem::Wait(raytracing_ctx); + wi::jobsystem::Wait(objectps_ctx); + wi::jobsystem::Wait(mesh_shader_ctx); + for (uint32_t renderPass = 0; renderPass < RENDERPASS_COUNT; ++renderPass) + { + for (uint32_t mesh_shader = 0; mesh_shader <= (IsMeshShaderAllowed() ? 1u : 0u); ++mesh_shader) + { + wi::jobsystem::Wait(object_pso_job_ctx[renderPass][mesh_shader]); + } + } + device->ClearPipelineStateCache(); SHADER_ERRORS.store(0); SHADER_MISSING.store(0); @@ -9509,12 +9526,17 @@ void ResolveMSAADepthBuffer(const Texture& dst, const Texture& src, CommandList device->BindResource(&src, 0, cmd); device->BindUAV(&dst, 0, cmd); + device->Barrier(GPUBarrier::Image(&dst, dst.desc.layout, ResourceState::UNORDERED_ACCESS), cmd); + + device->ClearUAV(&dst, 0, cmd); + device->Barrier(GPUBarrier::Memory(&dst), cmd); + const TextureDesc& desc = src.GetDesc(); device->BindComputeShader(&shaders[CSTYPE_RESOLVEMSAADEPTHSTENCIL], cmd); device->Dispatch((desc.width + 7) / 8, (desc.height + 7) / 8, 1, cmd); - + device->Barrier(GPUBarrier::Image(&dst, ResourceState::UNORDERED_ACCESS, dst.desc.layout), cmd); device->EventEnd(cmd); } diff --git a/WickedEngine/wiScene_Components.cpp b/WickedEngine/wiScene_Components.cpp index 868b506ba..568f14df5 100644 --- a/WickedEngine/wiScene_Components.cpp +++ b/WickedEngine/wiScene_Components.cpp @@ -833,7 +833,7 @@ namespace wi::scene wi::vector cluster_bounds; cluster_ranges.clear(); - if (device->CheckCapability(GraphicsDeviceCapability::MESH_SHADER)) + if (wi::renderer::IsMeshShaderAllowed()) { const size_t max_vertices = MESHLET_VERTEX_COUNT; const size_t max_triangles = MESHLET_TRIANGLE_COUNT; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index f6d079479..9f4808d57 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 555; + const int revision = 556; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);