From f6bc286348feae1f04d5e2bd1b6b8dc24bad723d Mon Sep 17 00:00:00 2001 From: Benualdo Date: Mon, 6 Jan 2025 18:56:38 +0100 Subject: [PATCH] Editor outline + fix multithread crash in picking + fix crash when UIText containing '%' is edited --- Editor.xml | 2 +- data/Shaders/default/default.hlsl | 91 ++++++++++++++++--- data/Shaders/default/default.hlsl.h | 6 ++ data/Shaders/postprocess/postprocess.hlsl | 54 +++++++++++ data/Shaders/postprocess/postprocess.hlsli | 40 ++++---- data/Shaders/system/bindless.hlsli | 4 + data/Shaders/system/displaymodes.hlsli | 3 +- data/Shaders/system/editorpass.hlsli | 29 ++++++ data/Shaders/system/outlinemask.hlsli | 10 ++ data/Shaders/system/table.hlsli | 11 ++- data/Shaders/system/transparentPass.hlsli | 9 +- src/core/Scheduler/AssertMutex.h | 30 ++++++ src/core/core.vcxproj | 1 + src/core/core.vcxproj.filters | 3 + src/editor/ImGui/Window/ImGuiWindow.cpp | 2 +- .../Window/Statistics/ImGuiStatistics.hpp | 8 +- src/editor/ImGui/Window/View/ImGuiView.hpp | 4 +- src/engine/World/Scene/Scene.hpp | 2 +- src/gfx/BindlessTable/BindlessTable.cpp | 2 + src/gfx/FrameGraph/FrameGraph.cpp | 38 ++++++-- src/gfx/FrameGraph/FrameGraph.h | 3 +- src/gfx/FrameGraph/UserPass.h | 5 +- src/gfx/Resource/Texture.inl | 3 + src/gfx/Resource/Texture_consts.h | 3 + src/gfx/Resource/dx12/Texture_dx12.hpp | 9 ++ src/gfx/Resource/vulkan/Texture_vulkan.hpp | 9 ++ src/gfx/Shader/ComputeShaderKey.hpp | 1 + src/gfx/Shader/ShaderKey.hpp | 1 + src/renderer/IView.h | 3 +- src/renderer/Instance/Mesh/MeshInstance.hpp | 5 +- src/renderer/Job/Culling/ViewCullingJob.h | 2 +- src/renderer/Job/Culling/ViewCullingJob.hpp | 2 +- .../DefaultMaterial/DefaultMaterialModel.hpp | 10 ++ src/renderer/Model/Material/MaterialModel.cpp | 1 + src/renderer/Model/Material/MaterialModel.h | 3 +- src/renderer/Picking/PickingManager.cpp | 1 + .../ComputePostProcessPass.hpp | 14 +++ .../ComputeSkinning/ComputeSkinningPass.h | 2 +- .../ComputeSkinning/ComputeSkinningPass.hpp | 2 +- src/renderer/RenderPass/RenderContext.h | 4 +- .../RenderObjects/Editor/EditorPass.h | 14 ++- .../RenderObjects/Editor/EditorPass.hpp | 46 ++++++++-- .../Forward/ForwardTransparentPass.h | 2 +- .../Forward/ForwardTransparentPass.hpp | 18 ++-- .../Misc/Outline/OutlineMaskPass.hpp | 21 +++-- .../RenderObjects/RenderObjectsPass.hpp | 2 +- .../InstanceData/InstanceDataUpdatePass.h | 2 +- .../InstanceData/InstanceDataUpdatePass.hpp | 2 +- .../MaterialData/MaterialDataUpdatePass.h | 2 +- .../MaterialData/MaterialDataUpdatePass.hpp | 2 +- src/renderer/View/Lit/LitView.hpp | 11 +-- src/renderer/View/View.cpp | 20 +++- src/renderer/View/View.h | 5 +- src/version.h | 2 +- vgframework.sln | 2 + 55 files changed, 473 insertions(+), 110 deletions(-) create mode 100644 data/Shaders/system/editorpass.hlsli create mode 100644 data/Shaders/system/outlinemask.hlsli create mode 100644 src/core/Scheduler/AssertMutex.h diff --git a/Editor.xml b/Editor.xml index bf02ceb69..328fa5474 100644 --- a/Editor.xml +++ b/Editor.xml @@ -40,6 +40,6 @@ - + diff --git a/data/Shaders/default/default.hlsl b/data/Shaders/default/default.hlsl index 02fa70ebf..65049286b 100644 --- a/data/Shaders/default/default.hlsl +++ b/data/Shaders/default/default.hlsl @@ -9,10 +9,8 @@ #include "system/lighting.hlsli" #include "system/debugdisplay.hlsli" #include "system/instancedata.hlsli" - -#if _ALPHABLEND #include "system/transparentPass.hlsli" -#endif +#include "system/outlinemask.hlsli" #include "default.hlsli" @@ -22,6 +20,28 @@ #define EXPORT_VPOS 0 #endif +// TODO: move to transparentPass.hlsli? +void applyDepthTransparency(inout float _alpha, float2 _screenPos, float4 _vpos, float _invDepthFade) +{ + TransparentPassConstants transparentPassConstants; + transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS)); + + float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, _screenPos.xy, 0).y; + float linearZ = -_vpos.z; + float alpha = saturate((linearDepthBuffer - linearZ) * _invDepthFade ); + _alpha *= alpha; +} + +bool linearDepthTest(float2 _screenPos, float4 _vpos) +{ + TransparentPassConstants transparentPassConstants; + transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS)); + + float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, _screenPos.xy, 0).y; + float linearZ = -_vpos.z; + return linearZ < linearDepthBuffer + 0.01; +} + struct VS_Output { float4 pos : Position; @@ -49,7 +69,6 @@ VS_Output VS_Forward(uint _vertexID : VertexID) Vertex vert; vert.Load(getBuffer(rootConstants3D.getVertexBufferHandle()), rootConstants3D.getVertexFormat(), _vertexID, rootConstants3D.getVertexBufferOffset()); - //vert.Load(getBuffer(instanceData.getVertexBufferHandle()), instanceData.getVertexFormat(), _vertexID, instanceData.getVertexBufferOffset()); ViewConstants viewConstants; viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS)); @@ -177,13 +196,7 @@ PS_Output PS_Forward(VS_Output _input) #endif #if _ALPHABLEND - TransparentPassConstants transparentPassConstants; - transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS)); - - float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, screenPos.xy, 0).y; - float linearZ = -_input.vpos.z; - float alpha = saturate((linearDepthBuffer - linearZ) * materialData.getInvDepthFade()); - output.color0.a *= alpha; + applyDepthTransparency(output.color0.a, screenPos.xy, _input.vpos, materialData.getInvDepthFade()); #endif #if _TOOLMODE && !_ZONLY @@ -340,4 +353,60 @@ PS_OutputDeferred PS_Deferred(VS_Output _input) #else return output; #endif +} + +struct VS_Output_Outline +{ + float4 pos : Position; + float4 vpos : ViewPos; +}; + +//-------------------------------------------------------------------------------------- +VS_Output_Outline VS_Outline(uint _vertexID : VertexID) +{ + VS_Output_Outline output; + + uint instanceDataOffset = rootConstants3D.getGPUInstanceDataOffset(); + GPUInstanceData instanceData = getBuffer(RESERVEDSLOT_BUFSRV_INSTANCEDATA).Load(instanceDataOffset); + + Vertex vert; + vert.Load(getBuffer(rootConstants3D.getVertexBufferHandle()), rootConstants3D.getVertexFormat(), _vertexID, rootConstants3D.getVertexBufferOffset()); + + ViewConstants viewConstants; + viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS)); + + float4x4 view = viewConstants.getView(); + float4x4 proj = viewConstants.getProj(); + + float3 modelPos = vert.getPos(); + float3 worldPos = mul(float4(modelPos.xyz, 1.0f), rootConstants3D.getWorldMatrix()).xyz; + float4 viewPos = mul(float4(worldPos.xyz, 1.0f), view); + + viewPos.z += WIREFRAME_DEPTHBIAS; + output.vpos = viewPos; + output.pos = mul(viewPos, proj); + + return output; +} + +struct PS_Output_Outline +{ + uint4 id : Color0; +}; + +PS_Output_Outline PS_Outline(VS_Output_Outline _input) +{ + ViewConstants viewConstants; + viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS)); + + uint2 screenSize = viewConstants.getScreenSize(); + float3 screenPos = _input.pos.xyz / float3(screenSize.xy, 1); + + PS_Output_Outline output = (PS_Output_Outline)0; + output.id = rootConstants3D.getPickingID(); + + if (!linearDepthTest(screenPos.xy, _input.vpos)) + output.id |= (uint)OutlineMaskFlags::DepthFail; + + return output; } \ No newline at end of file diff --git a/data/Shaders/default/default.hlsl.h b/data/Shaders/default/default.hlsl.h index c405ff421..507b643b2 100644 --- a/data/Shaders/default/default.hlsl.h +++ b/data/Shaders/default/default.hlsl.h @@ -44,6 +44,12 @@ namespace vg::gfx deferred.vs = declVS("VS_Deferred"); deferred.ps = declPS("PS_Deferred"); } + + auto & outline = declTechnique("Outline"); + { + outline.vs = declVS("VS_Outline"); + outline.ps = declPS("PS_Outline"); + } } }; } \ No newline at end of file diff --git a/data/Shaders/postprocess/postprocess.hlsl b/data/Shaders/postprocess/postprocess.hlsl index 3409b5103..723a927d5 100644 --- a/data/Shaders/postprocess/postprocess.hlsl +++ b/data/Shaders/postprocess/postprocess.hlsl @@ -6,6 +6,7 @@ #include "system/msaa.hlsli" #include "system/instancedata.hlsli" #include "system/gamma.hlsli" +#include "system/outlinemask.hlsli" #if _FXAA #include "FXAA.hlsli" @@ -405,6 +406,49 @@ void CS_PostProcessMain(int2 dispatchThreadID : SV_DispatchThreadID) color = DebugRayTracing(color, uv, screenSize, viewConstants); #endif + // outline + { + + float2 pcf = (float2)0.0f; + for (int jj = -1; jj < 1; ++jj) + { + for (int ii = -1; ii < 1; ++ii) + { + uint4 center = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords.x + ii, coords.y + jj, 0)); + + bool visibleOutline = false; + bool hiddenOutline = false; + + for (int j = -1; j <= 1; ++j) + { + for (int i = -1; i <= 1; ++i) + { + uint4 sample = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords.x + ii + i, coords.y + jj + j,0)); + + if ((sample.a & ~(uint)OutlineMaskFlags::DepthFail) != (center.a & ~(uint)OutlineMaskFlags::DepthFail)) + { + if (0 != sample.a) + { + if (sample.a & (uint)OutlineMaskFlags::DepthFail) + hiddenOutline = true; + else + visibleOutline = true; + } + } + } + } + + if (visibleOutline) + pcf += 1; + + if (hiddenOutline) + pcf.y += 0.325; + } + } + + color.rgb = lerp(color.rgb, float3(0,1,0), saturate((pcf.x + pcf.y) / 4.0f)); + } + switch(viewConstants.getDisplayMode()) { default: @@ -452,6 +496,16 @@ void CS_PostProcessMain(int2 dispatchThreadID : SV_DispatchThreadID) case DisplayMode::Lighting_EnvironmentSpecularBRDF: color.rgb = getTexture2D(viewConstants.getSpecularBRDF()).SampleLevel(nearestClamp, uv, 0).rgb; break; + + case DisplayMode::PostProcess_OutlineMask: + { + uint sample = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords,0)).a; + uint id = sample & (uint)~0x80000000; + float alpha = (sample & 0x80000000) ? 0.5 : 1.0; + color.rgb = (0 != id.x) ? frac(float3(id.x * 31.0, id.x * 17.0, id.x * 59.0) / 255.0) : float3(0,0,0); + color.rgb *= alpha; + } + break; } #endif // _TOOLMODE diff --git a/data/Shaders/postprocess/postprocess.hlsli b/data/Shaders/postprocess/postprocess.hlsli index 80eca6288..cc6ecdd42 100644 --- a/data/Shaders/postprocess/postprocess.hlsli +++ b/data/Shaders/postprocess/postprocess.hlsli @@ -11,39 +11,45 @@ struct PostProcessConstants #ifdef __cplusplus PostProcessConstants() { - m_data = (uint4)0; - setScreenSize(uint2(0,0)); setSource(BINDLESS_TEXTURE_INVALID); setRWBufferOut(BINDLESS_RWTEXTURE_INVALID); setDepth(BINDLESS_TEXTURE_INVALID); setStencil(BINDLESS_TEXTURE_INVALID); setLinearDepth(BINDLESS_TEXTURE_INVALID); + setOutlineMask(BINDLESS_TEXTURE_INVALID); } #endif - void setScreenSize (uint2 _size) { m_data.x = packUint16(_size.xy);} - uint2 getScreenSize () { return unpackUint16(m_data.x); } + void setScreenSize (uint2 _size) { m_screensize = packUint16(_size.xy);} + uint2 getScreenSize () { return unpackUint16(m_screensize); } + + void setSource (uint _color) { m_src_dst = packUint16low(m_src_dst, _color); } + uint getSource () { return unpackUint16low(m_src_dst); } - void setSource (uint _color) { m_data.y = packUint16low(m_data.y, _color); } - uint getSource () { return unpackUint16low(m_data.y); } + void setRWBufferOut (uint _rwbuffer){ m_src_dst = packUint16high(m_src_dst, _rwbuffer); } + uint getRWBufferOut () { return unpackUint16high(m_src_dst); } - void setRWBufferOut (uint _rwbuffer){ m_data.y = packUint16high(m_data.y, _rwbuffer); } - uint getRWBufferOut () { return unpackUint16high(m_data.y); } + void setDepth (uint _depth) { m_depth_stencil = packUint16low(m_depth_stencil, _depth); } + uint getDepth () { return unpackUint16low(m_depth_stencil); } - void setDepth (uint _depth) { m_data.z = packUint16low(m_data.z, _depth); } - uint getDepth () { return unpackUint16low(m_data.z); } + void setStencil (uint _stencil) { m_depth_stencil = packUint16high(m_depth_stencil, _stencil); } + uint getStencil () { return unpackUint16high(m_depth_stencil); } - void setStencil (uint _stencil) { m_data.z = packUint16high(m_data.z, _stencil); } - uint getStencil () { return unpackUint16high(m_data.z); } + void setLinearDepth (uint _linearZ) { m_depth_temp = packUint16low(m_depth_temp, _linearZ); } + uint getLinearDepth () { return unpackUint16low(m_depth_temp); } - void setLinearDepth (uint _linearZ) { m_data.w = packUint16low(m_data.w, _linearZ); } - uint getLinearDepth () { return unpackUint16low(m_data.w); } + void setTemp (uint _temp) { m_depth_temp = packUint16high(m_depth_temp, _temp); } + uint getTemp () { return unpackUint16high(m_depth_temp); } - void setTemp (uint _temp) { m_data.w = packUint16high(m_data.w, _temp); } - uint getTemp () { return unpackUint16high(m_data.w); } + void setOutlineMask (uint _outline) { m_outline_unused = packUint16low(m_outline_unused, _outline); } + uint getOutlineMask () { return unpackUint16low(m_outline_unused); } - uint4 m_data; + uint m_screensize; + uint m_src_dst; + uint m_depth_stencil; + uint m_depth_temp; + uint m_outline_unused; }; #define PostProcessConstantsCount sizeof(PostProcessConstants)/sizeof(u32) diff --git a/data/Shaders/system/bindless.hlsli b/data/Shaders/system/bindless.hlsli index 8b311cb08..ba413f002 100644 --- a/data/Shaders/system/bindless.hlsli +++ b/data/Shaders/system/bindless.hlsli @@ -22,7 +22,9 @@ DECL_DESCRIPTOR_RANGE_RO(Texture1D, g_Texture1D, BIND DECL_DESCRIPTOR_RANGE_RO(Texture2D, g_Texture2D, BINDLESS_TEXTURE_BINDING_2D, BINDLESS_TEXTURE_START); DECL_DESCRIPTOR_RANGE_RO(TextureCube, g_TextureCube, BINDLESS_TEXTURE_BINDING_CUBE, BINDLESS_TEXTURE_START); DECL_DESCRIPTOR_RANGE_RO(Texture2DMS, g_Texture2DMS, BINDLESS_TEXTURE_BINDING_2DMS, BINDLESS_TEXTURE_START); +DECL_DESCRIPTOR_RANGE_RO(Texture2D, g_Texture2D_UInt, BINDLESS_TEXTURE_BINDING_2D_UINT, BINDLESS_TEXTURE_START); DECL_DESCRIPTOR_RANGE_RO(Texture2D, g_Texture2D_UInt2, BINDLESS_TEXTURE_BINDING_2D_UINT2, BINDLESS_TEXTURE_START); +DECL_DESCRIPTOR_RANGE_RO(Texture2D, g_Texture2D_UInt4, BINDLESS_TEXTURE_BINDING_2D_UINT4, BINDLESS_TEXTURE_START); DECL_DESCRIPTOR_RANGE_RO(Texture2DMS, g_Texture2DMS_UInt2, BINDLESS_TEXTURE_BINDING_2DMS_UINT2, BINDLESS_TEXTURE_START); DECL_DESCRIPTOR_RANGE_RO(Texture3D, g_Texture3D, BINDLESS_TEXTURE_BINDING_3D, BINDLESS_TEXTURE_START); @@ -52,7 +54,9 @@ DECL_DESCRIPTOR_RANGE_RO(RaytracingAccelerationStructure, g_TLAS, BINDLESS_TLAS_ #define getNonUniformTexture2D(_handle) (g_Texture2D[NonUniformResourceIndex(_handle - BINDLESS_TEXTURE_START)]) #define getTextureCube(_handle) (g_TextureCube[_handle - BINDLESS_TEXTURE_START]) #define getTexture2DMS(_handle) (g_Texture2DMS[_handle - BINDLESS_TEXTURE_START]) +#define getTexture2D_UInt(_handle) (g_Texture2D_UInt[_handle - BINDLESS_TEXTURE_START]) #define getTexture2D_UInt2(_handle) (g_Texture2D_UInt2[_handle - BINDLESS_TEXTURE_START]) +#define getTexture2D_UInt4(_handle) (g_Texture2D_UInt4[_handle - BINDLESS_TEXTURE_START]) #define getTexture2DMS_UInt2(_handle) (g_Texture2DMS_UInt2[_handle - BINDLESS_TEXTURE_START]) #define getTexture3D(_handle) (g_Texture3D[_handle - BINDLESS_TEXTURE_START]) diff --git a/data/Shaders/system/displaymodes.hlsli b/data/Shaders/system/displaymodes.hlsli index 7add70deb..12f598ecd 100644 --- a/data/Shaders/system/displaymodes.hlsli +++ b/data/Shaders/system/displaymodes.hlsli @@ -66,7 +66,8 @@ vg_enum_class(DisplayMode, uint, PostProcess_LinearDepth, PostProcess_DepthOfField, PostProcess_FXAAEdges, - PostProcess_WorldPos + PostProcess_WorldPos, + PostProcess_OutlineMask ); vg_enum(DisplayFlags, uint, diff --git a/data/Shaders/system/editorpass.hlsli b/data/Shaders/system/editorpass.hlsli new file mode 100644 index 000000000..84732ccd0 --- /dev/null +++ b/data/Shaders/system/editorpass.hlsli @@ -0,0 +1,29 @@ +//#ifndef _EDITOR_PASS__HLSLI_ +//#define _EDITOR_PASS__HLSLI_ +// +//#include "types.hlsli" +//#include "packing.hlsli" +//#include "displaymodes.hlsli" +// +//struct EditorPassConstants +//{ +// #ifdef __cplusplus +// EditorPassConstants() +// { +// m_data = 0; +// setOutlineMask(BINDLESS_TEXTURE_INVALID); +// } +// #else +// void Load(ByteAddressBuffer _buffer, uint _offset = 0) +// { +// m_data = _buffer.Load(_offset).m_data; +// } +// #endif +// +// uint m_data; +// +// void setOutlineMask (uint _outlineMask) { m_data = packUint16low(m_data, _outlineMask); } +// uint getOutlineMask () { return unpackUint16low(m_data); } +//}; +// +//#endif // _EDITOR_PASS__HLSLI_ \ No newline at end of file diff --git a/data/Shaders/system/outlinemask.hlsli b/data/Shaders/system/outlinemask.hlsli new file mode 100644 index 000000000..81f1c4bef --- /dev/null +++ b/data/Shaders/system/outlinemask.hlsli @@ -0,0 +1,10 @@ +#ifndef _OUTLINEMASK__HLSLI_ +#define _OUTLINEMASK__HLSLI_ + +#include "types.hlsli" + +vg_enum_class(OutlineMaskFlags, uint, + DepthFail = 0x8000 +); + +#endif // _OUTLINEMASK__HLSLI_ \ No newline at end of file diff --git a/data/Shaders/system/table.hlsli b/data/Shaders/system/table.hlsli index c759c9609..93a36149a 100644 --- a/data/Shaders/system/table.hlsli +++ b/data/Shaders/system/table.hlsli @@ -49,6 +49,7 @@ vg_enum_class(ReservedSlot, uint, LastTexture = InvalidTexture2D, // Buffer + EditorPassBufSrv = BINDLESS_BUFFER_INVALID - 7, TransparentPassBufSrv = BINDLESS_BUFFER_INVALID - 6, MaterialDataBufSrv = BINDLESS_BUFFER_INVALID - 5, InstanceDataBufSrv = BINDLESS_BUFFER_INVALID - 4, @@ -101,9 +102,11 @@ vg_enum_class(ReservedSlot, uint, #define BINDLESS_TEXTURE_BINDING_1D 10 #define BINDLESS_TEXTURE_BINDING_2D 20 #define BINDLESS_TEXTURE_BINDING_2DMS 21 -#define BINDLESS_TEXTURE_BINDING_2D_UINT2 22 -#define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 23 -#define BINDLESS_TEXTURE_BINDING_CUBE 24 +#define BINDLESS_TEXTURE_BINDING_2D_UINT 22 +#define BINDLESS_TEXTURE_BINDING_2D_UINT2 23 +#define BINDLESS_TEXTURE_BINDING_2D_UINT4 24 +#define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 25 +#define BINDLESS_TEXTURE_BINDING_CUBE 26 #define BINDLESS_TEXTURE_BINDING_3D 30 #define BINDLESS_RWTEXTURE_BINDING_1D 210 @@ -118,7 +121,9 @@ vg_enum_class(ReservedSlot, uint, #define BINDLESS_TEXTURE_BINDING_2D 0 #define BINDLESS_TEXTURE_BINDING_CUBE 0 #define BINDLESS_TEXTURE_BINDING_2DMS 0 +#define BINDLESS_TEXTURE_BINDING_2D_UINT 0 #define BINDLESS_TEXTURE_BINDING_2D_UINT2 0 +#define BINDLESS_TEXTURE_BINDING_2D_UINT4 0 #define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 0 #define BINDLESS_TEXTURE_BINDING_3D 0 diff --git a/data/Shaders/system/transparentPass.hlsli b/data/Shaders/system/transparentPass.hlsli index 4310c224e..58fab3231 100644 --- a/data/Shaders/system/transparentPass.hlsli +++ b/data/Shaders/system/transparentPass.hlsli @@ -10,8 +10,7 @@ struct TransparentPassConstants #ifdef __cplusplus TransparentPassConstants() { - m_data = (uint4)0; - + m_data = 0; setLinearDepth(BINDLESS_TEXTURE_INVALID); } #else @@ -21,10 +20,10 @@ struct TransparentPassConstants } #endif - uint4 m_data; + uint m_data; - void setLinearDepth (uint _linearZ) { m_data.x = packUint16low(m_data.x, _linearZ); } - uint getLinearDepth () { return unpackUint16low(m_data.x); } + void setLinearDepth (uint _linearZ) { m_data = packUint16low(m_data, _linearZ); } + uint getLinearDepth () { return unpackUint16low(m_data); } }; #endif // _TRANSPARENT_PASS__HLSLI_ \ No newline at end of file diff --git a/src/core/Scheduler/AssertMutex.h b/src/core/Scheduler/AssertMutex.h new file mode 100644 index 000000000..4b635e229 --- /dev/null +++ b/src/core/Scheduler/AssertMutex.h @@ -0,0 +1,30 @@ +#pragma once + +namespace vg::core +{ + class AssertMutex + { + public: + inline AssertMutex(const char * _name) : + m_name(_name), + m_isEntered(false) + { + } + + inline void lock() + { + bool expected = false; + if (!m_isEntered.compare_exchange_strong(expected, true)) + VG_ASSERT(false, "AssertMutex \"%s\" already entered", m_name); + } + + inline void unlock() + { + m_isEntered.store(false); + } + + private: + const char * m_name; + core::atomic m_isEntered; + }; +} \ No newline at end of file diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index c40fe77e6..cdd6744ed 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -159,6 +159,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index d68753d85..e63699fe7 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -465,6 +465,9 @@ Types + + Scheduler + diff --git a/src/editor/ImGui/Window/ImGuiWindow.cpp b/src/editor/ImGui/Window/ImGuiWindow.cpp index 036db6352..c44285e77 100644 --- a/src/editor/ImGui/Window/ImGuiWindow.cpp +++ b/src/editor/ImGui/Window/ImGuiWindow.cpp @@ -3086,7 +3086,7 @@ namespace vg::editor { bool edited = false; - sprintf_s(buffer, pString->c_str()); + strcpy_s(buffer, pString->c_str()); if (ImGui::InputText(getPropertyLabel(_label, _index).c_str(), buffer, countof(buffer), getImGuiInputTextFlags(_propContext, _prop))) edited = true; diff --git a/src/editor/ImGui/Window/Statistics/ImGuiStatistics.hpp b/src/editor/ImGui/Window/Statistics/ImGuiStatistics.hpp index b212384d6..ca6c9066d 100644 --- a/src/editor/ImGui/Window/Statistics/ImGuiStatistics.hpp +++ b/src/editor/ImGui/Window/Statistics/ImGuiStatistics.hpp @@ -69,8 +69,8 @@ namespace vg::editor ImGui::Text("Decal"); ImGui::EndDisabled(); - ImGui::BeginDisabled(!stats.selected); - ImGui::Text("Selected"); + ImGui::BeginDisabled(!stats.outline); + ImGui::Text("Outline"); ImGui::EndDisabled(); } ImGui::NextColumn(); @@ -93,8 +93,8 @@ namespace vg::editor ImGui::Text("%u", stats.decal); ImGui::EndDisabled(); - ImGui::BeginDisabled(!stats.selected); - ImGui::Text("%u", stats.selected); + ImGui::BeginDisabled(!stats.outline); + ImGui::Text("%u", stats.outline); ImGui::EndDisabled(); } ImGui::Columns(1); diff --git a/src/editor/ImGui/Window/View/ImGuiView.hpp b/src/editor/ImGui/Window/View/ImGuiView.hpp index 5e20c1990..4164f27dd 100644 --- a/src/editor/ImGui/Window/View/ImGuiView.hpp +++ b/src/editor/ImGui/Window/View/ImGuiView.hpp @@ -578,11 +578,11 @@ namespace vg::editor ImGui::SameLine(); ImGui::SetCursorPos(ImGui::GetWindowContentRegionMin() + pos); - text = fmt::sprintf("Selected %u", stats.selected); + text = fmt::sprintf("Outline %u", stats.outline); textSize = ImGui::CalcTextSize(text.c_str()); ImGui::GetWindowDrawList()->AddRectFilled(rectPos + pos, rectPos + pos + textSize, rectColor); pos.y += style::font::DefaultFontHeight; - ImGui::Text(text.c_str(), stats.selected); + ImGui::Text(text.c_str(), stats.outline); // Lights pos.y += style::font::DefaultFontHeight; diff --git a/src/engine/World/Scene/Scene.hpp b/src/engine/World/Scene/Scene.hpp index 0818ffaee..67107fd0b 100644 --- a/src/engine/World/Scene/Scene.hpp +++ b/src/engine/World/Scene/Scene.hpp @@ -17,7 +17,7 @@ namespace vg::engine //-------------------------------------------------------------------------------------- Scene::~Scene() { - + // TODO: unselect all scene objects otherwise we might crash at exit? } //-------------------------------------------------------------------------------------- diff --git a/src/gfx/BindlessTable/BindlessTable.cpp b/src/gfx/BindlessTable/BindlessTable.cpp index 4443eecd6..885f65a88 100644 --- a/src/gfx/BindlessTable/BindlessTable.cpp +++ b/src/gfx/BindlessTable/BindlessTable.cpp @@ -31,7 +31,9 @@ namespace vg::gfx m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2D, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_CUBE, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2DMS, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); + m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2D_UINT, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2D_UINT2, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); + m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2D_UINT4, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_2DMS_UINT2, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); m_tableDesc.addTextures(BINDLESS_TEXTURE_BINDING_3D, BINDLESS_TEXTURE_START, BINDLESS_TEXTURE_COUNT); #endif diff --git a/src/gfx/FrameGraph/FrameGraph.cpp b/src/gfx/FrameGraph/FrameGraph.cpp index bf3a1a6f5..425de5728 100644 --- a/src/gfx/FrameGraph/FrameGraph.cpp +++ b/src/gfx/FrameGraph/FrameGraph.cpp @@ -848,15 +848,14 @@ namespace vg::gfx } //-------------------------------------------------------------------------------------- - void FrameGraph::prepareNode(const UserPassInfoNode & _node) + void FrameGraph::beforeAll(const UserPassInfoNode & _node) { for (auto & child : _node.m_children) - prepareNode(child); + beforeAll(child); if (!_node.m_renderPass) return; - // TODO: refactor as we always have only one SubPass per UserPass? const auto & subPasses = _node.m_renderPass->getSubPasses(); VG_ASSERT(subPasses.size() == 1); @@ -864,7 +863,27 @@ namespace vg::gfx { SubPass * subPass = subPasses[i]; const auto & userPassInfo = subPass->getUserPassesInfos()[0]; - userPassInfo.m_userPass->Prepare(userPassInfo.m_renderContext); + userPassInfo.m_userPass->BeforeAll(userPassInfo.m_renderContext); + } + } + + //-------------------------------------------------------------------------------------- + void FrameGraph::afterAll(const UserPassInfoNode & _node) + { + for (auto & child : _node.m_children) + afterAll(child); + + if (!_node.m_renderPass) + return; + + const auto & subPasses = _node.m_renderPass->getSubPasses(); + VG_ASSERT(subPasses.size() == 1); + + for (uint i = 0; i < subPasses.size(); ++i) + { + SubPass * subPass = subPasses[i]; + const auto & userPassInfo = subPass->getUserPassesInfos()[0]; + userPassInfo.m_userPass->AfterAll(userPassInfo.m_renderContext); } } @@ -1087,11 +1106,10 @@ namespace vg::gfx for (auto & node : m_userPassInfoTree.m_children) gatherResources(node); - // TODO: find a better name than "Prepare"? { - VG_PROFILE_CPU("Prepare"); + VG_PROFILE_CPU("BeforeAll"); for (auto & node : m_userPassInfoTree.m_children) - prepareNode(node); + beforeAll(node); } if (maxRenderJobCount > 0) @@ -1491,6 +1509,12 @@ namespace vg::gfx } } + { + VG_PROFILE_CPU("AfterAll"); + for (auto & node : m_userPassInfoTree.m_children) + afterAll(node); + } + // All textures and buffers remaining in pool should be marked as 'unused' at this point for (uint i = 0; i < m_sharedTextures.size(); ++i) { diff --git a/src/gfx/FrameGraph/FrameGraph.h b/src/gfx/FrameGraph/FrameGraph.h index daf85ea89..ee605abef 100644 --- a/src/gfx/FrameGraph/FrameGraph.h +++ b/src/gfx/FrameGraph/FrameGraph.h @@ -82,8 +82,9 @@ namespace vg::gfx void buildNode (UserPassInfoNode & _node); void gatherNodes (UserPassInfoNode & _node, core::vector & _nodes, core::u64 & _totalEstimatedCost); void gatherResources (const UserPassInfoNode & _node); - void prepareNode (const UserPassInfoNode & _node); + void beforeAll (const UserPassInfoNode & _node); void renderNode (const UserPassInfoNode & _node, gfx::CommandList * _cmdList, bool _recur); + void afterAll (const UserPassInfoNode & _node); Texture * createRenderTargetFromPool (const core::string & _name, const FrameGraphTextureResourceDesc & _textureResourceDesc, core::uint _createPassIndex); Texture * createDepthStencilFromPool (const core::string & _name, const FrameGraphTextureResourceDesc & _textureResourceDesc, core::uint _createPassIndex); diff --git a/src/gfx/FrameGraph/UserPass.h b/src/gfx/FrameGraph/UserPass.h index d37241856..cedea786c 100644 --- a/src/gfx/FrameGraph/UserPass.h +++ b/src/gfx/FrameGraph/UserPass.h @@ -31,7 +31,7 @@ namespace vg::gfx virtual core::u64 GetCostEstimate (const RenderPassContext & _renderPassContext) const { return 1; } // Called on main thread for all nodes before rendering using multiple threads (e.g., compute offsets used in other RenderJobs) - virtual void Prepare (const RenderPassContext & _renderPassContext) {}; + virtual void BeforeAll (const RenderPassContext & _renderPassContext) {}; // Called before entering RenderPass (e.g., write buffers from CPU to the GPU) virtual void BeforeRender (const RenderPassContext & _renderPassContext, CommandList * _cmdList) {} @@ -42,6 +42,9 @@ namespace vg::gfx // Called after exiting RenderPass (e.g., read buffer from GPU to the CPU) virtual void AfterRender (const RenderPassContext & _renderPassContext, CommandList * _cmdList) {}; + // Called on main thread for all nodes after rendering using multiple threads (e.g., process GPU readback data) + virtual void AfterAll (const RenderPassContext & _renderPassContext) {}; + // Descriptor for framegraph texture/buffer const FrameGraphTextureResourceDesc * getTextureResourceDesc(const FrameGraphResourceID & _resID) const; const FrameGraphBufferResourceDesc * getBufferResourceDesc(const FrameGraphResourceID & _resID) const; diff --git a/src/gfx/Resource/Texture.inl b/src/gfx/Resource/Texture.inl index 55a50147e..7d7ad798b 100644 --- a/src/gfx/Resource/Texture.inl +++ b/src/gfx/Resource/Texture.inl @@ -67,8 +67,11 @@ namespace vg::gfx case PixelFormat::R10G10B10A2_unorm: case PixelFormat::R16G16B16A16_unorm: case PixelFormat::R16G16B16A16_float: + case PixelFormat::R16G16B16A16_uint: case PixelFormat::R16G16_float: case PixelFormat::R32G32B32A32_float: + case PixelFormat::R32_uint: + case PixelFormat::R32G32_uint: return false; case PixelFormat::D32S8: diff --git a/src/gfx/Resource/Texture_consts.h b/src/gfx/Resource/Texture_consts.h index efe2cafd2..4c9419155 100644 --- a/src/gfx/Resource/Texture_consts.h +++ b/src/gfx/Resource/Texture_consts.h @@ -25,8 +25,11 @@ namespace vg::gfx R10G10B10A2_unorm, R16G16B16A16_unorm, R16G16B16A16_float, + R16G16B16A16_uint, R16G16_float, R32G32B32A32_float, + R32_uint, + R32G32_uint, D32S8 ); diff --git a/src/gfx/Resource/dx12/Texture_dx12.hpp b/src/gfx/Resource/dx12/Texture_dx12.hpp index 1125ed38c..621d88919 100644 --- a/src/gfx/Resource/dx12/Texture_dx12.hpp +++ b/src/gfx/Resource/dx12/Texture_dx12.hpp @@ -24,12 +24,21 @@ namespace vg::gfx::dx12 case PixelFormat::R16G16B16A16_float: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case PixelFormat::R16G16B16A16_uint: + return DXGI_FORMAT_R16G16B16A16_UINT; + case PixelFormat::R16G16_float: return DXGI_FORMAT_R16G16_FLOAT; case PixelFormat::R32G32B32A32_float: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case PixelFormat::R32_uint: + return DXGI_FORMAT_R32_UINT; + + case PixelFormat::R32G32_uint: + return DXGI_FORMAT_R32G32_UINT; + case PixelFormat::D32S8: return DXGI_FORMAT_R32G8X24_TYPELESS; } diff --git a/src/gfx/Resource/vulkan/Texture_vulkan.hpp b/src/gfx/Resource/vulkan/Texture_vulkan.hpp index 3d7b54373..94e6879dc 100644 --- a/src/gfx/Resource/vulkan/Texture_vulkan.hpp +++ b/src/gfx/Resource/vulkan/Texture_vulkan.hpp @@ -27,12 +27,21 @@ namespace vg::gfx::vulkan case PixelFormat::R16G16B16A16_float: return VK_FORMAT_R16G16B16A16_SFLOAT; + case PixelFormat::R16G16B16A16_uint: + return VK_FORMAT_R16G16B16A16_UINT; + case PixelFormat::R16G16_float: return VK_FORMAT_R16G16_SFLOAT; case PixelFormat::R32G32B32A32_float: return VK_FORMAT_R32G32B32A32_SFLOAT; + case PixelFormat::R32_uint: + return VK_FORMAT_R32_UINT; + + case PixelFormat::R32G32_uint: + return VK_FORMAT_R32G32_UINT; + case PixelFormat::D32S8: return VK_FORMAT_D32_SFLOAT_S8_UINT; } diff --git a/src/gfx/Shader/ComputeShaderKey.hpp b/src/gfx/Shader/ComputeShaderKey.hpp index 29189a35b..30e7914de 100644 --- a/src/gfx/Shader/ComputeShaderKey.hpp +++ b/src/gfx/Shader/ComputeShaderKey.hpp @@ -12,6 +12,7 @@ namespace vg::gfx //-------------------------------------------------------------------------------------- void ComputeShaderKey::clear() { + file = ComputeShaderKey::File(-1); cs = ComputeShaderKey::CS(-1); flags = ComputeShaderKey::File(0x0000); } diff --git a/src/gfx/Shader/ShaderKey.hpp b/src/gfx/Shader/ShaderKey.hpp index ed9f6472c..a2a0ef392 100644 --- a/src/gfx/Shader/ShaderKey.hpp +++ b/src/gfx/Shader/ShaderKey.hpp @@ -12,6 +12,7 @@ namespace vg::gfx //-------------------------------------------------------------------------------------- void ShaderKey::clear() { + file = ShaderKey::File(-1); vs = ShaderKey::VS(-1); hs = ShaderKey::HS(-1); ds = ShaderKey::DS(-1); diff --git a/src/renderer/IView.h b/src/renderer/IView.h index 76be261da..5297426de 100644 --- a/src/renderer/IView.h +++ b/src/renderer/IView.h @@ -35,7 +35,7 @@ namespace vg::renderer core::uint alphatest = 0; core::uint transparent = 0; core::uint decal = 0; - core::uint selected = 0; + core::uint outline = 0; core::uint directional = 0; core::uint omni = 0; core::uint spot = 0; @@ -130,6 +130,7 @@ namespace vg::renderer virtual bool IsLit () const = 0; virtual bool IsUsingRayTracing () const = 0; virtual bool IsComputePostProcessNeeded () const = 0; + virtual bool IsOutlinePassNeeded () const = 0; virtual void SetPickingData (const PickingData & _pickingData) = 0; virtual const PickingHit & GetPickingHit (core::uint _index) const = 0; diff --git a/src/renderer/Instance/Mesh/MeshInstance.hpp b/src/renderer/Instance/Mesh/MeshInstance.hpp index 1069f6723..6b8cdbf0e 100644 --- a/src/renderer/Instance/Mesh/MeshInstance.hpp +++ b/src/renderer/Instance/Mesh/MeshInstance.hpp @@ -164,7 +164,7 @@ namespace vg::renderer const ObjectFlags objectFlags = this->getObjectFlags(); if (asBool(ObjectFlags::Selected & objectFlags)) - _cullingResult->m_output->add(GraphicInstanceListType::Selected, this); + _cullingResult->m_output->add(GraphicInstanceListType::Outline, this); return true; } @@ -481,7 +481,7 @@ namespace vg::renderer auto surfaceType = material->getSurfaceType(); - if (_renderContext.m_surfaceType != surfaceType && !_renderContext.m_wireframe) + if (_renderContext.m_surfaceType != surfaceType && !_renderContext.m_wireframe && !_renderContext.m_outline) continue; switch (_renderContext.m_shaderPass) @@ -493,6 +493,7 @@ namespace vg::renderer case ShaderPass::ZOnly: case ShaderPass::Forward: case ShaderPass::Deferred: + case ShaderPass::Outline: material->Setup(_renderContext, _cmdList, &root3D, i); break; diff --git a/src/renderer/Job/Culling/ViewCullingJob.h b/src/renderer/Job/Culling/ViewCullingJob.h index 4c37afafa..c17706abf 100644 --- a/src/renderer/Job/Culling/ViewCullingJob.h +++ b/src/renderer/Job/Culling/ViewCullingJob.h @@ -24,7 +24,7 @@ namespace vg::renderer AlphaTest, Transparent, Decal, - Selected + Outline ); struct ViewCullingJobOutput diff --git a/src/renderer/Job/Culling/ViewCullingJob.hpp b/src/renderer/Job/Culling/ViewCullingJob.hpp index a472e9223..0004e054a 100644 --- a/src/renderer/Job/Culling/ViewCullingJob.hpp +++ b/src/renderer/Job/Culling/ViewCullingJob.hpp @@ -138,7 +138,7 @@ namespace vg::renderer } break; - case GraphicInstanceListType::Selected: + case GraphicInstanceListType::Outline: break; } } diff --git a/src/renderer/Model/Material/DefaultMaterial/DefaultMaterialModel.hpp b/src/renderer/Model/Material/DefaultMaterial/DefaultMaterialModel.hpp index 6658752a4..f58edf5b1 100644 --- a/src/renderer/Model/Material/DefaultMaterial/DefaultMaterialModel.hpp +++ b/src/renderer/Model/Material/DefaultMaterial/DefaultMaterialModel.hpp @@ -86,6 +86,7 @@ namespace vg::renderer _root3D->setMatID(_index); auto key = m_shaderKey[asInteger(_renderContext.m_shaderPass)]; + VG_ASSERT(0xFF != key.file, "Undefined ShaderKey for pass \"%s\"", asString(_renderContext.m_shaderPass).c_str()); RasterizerState rs(FillMode::Solid, CullMode::Back); @@ -166,6 +167,15 @@ namespace vg::renderer key.setFlag(DefaultHLSLDesc::Toolmode, false); } break; + + case ShaderPass::Outline: + { + BlendState bs(BlendFactor::One, BlendFactor::Zero, BlendOp::Add); + _cmdList->setBlendState(bs); + + key.setFlag(DefaultHLSLDesc::Toolmode, false); + } + break; } CullMode cullMode; diff --git a/src/renderer/Model/Material/MaterialModel.cpp b/src/renderer/Model/Material/MaterialModel.cpp index a718f5050..93f0a1837 100644 --- a/src/renderer/Model/Material/MaterialModel.cpp +++ b/src/renderer/Model/Material/MaterialModel.cpp @@ -57,6 +57,7 @@ namespace vg::renderer m_shaderKey[asInteger(ShaderPass::Forward)] = ShaderKey(shaderFile, "Forward"); m_shaderKey[asInteger(ShaderPass::Deferred)] = ShaderKey(shaderFile, "Deferred"); m_shaderKey[asInteger(ShaderPass::Transparent)] = ShaderKey(shaderFile, "Forward"); + m_shaderKey[asInteger(ShaderPass::Outline)] = ShaderKey(shaderFile, "Outline"); } //-------------------------------------------------------------------------------------- diff --git a/src/renderer/Model/Material/MaterialModel.h b/src/renderer/Model/Material/MaterialModel.h index f39efbc99..70846aa6a 100644 --- a/src/renderer/Model/Material/MaterialModel.h +++ b/src/renderer/Model/Material/MaterialModel.h @@ -29,7 +29,8 @@ namespace vg ZOnly = 0, Forward, Deferred, - Transparent + Transparent, + Outline ); class MaterialModel : public IMaterialModel diff --git a/src/renderer/Picking/PickingManager.cpp b/src/renderer/Picking/PickingManager.cpp index 65b6d9aa2..2ae5ccbd6 100644 --- a/src/renderer/Picking/PickingManager.cpp +++ b/src/renderer/Picking/PickingManager.cpp @@ -47,6 +47,7 @@ namespace vg::renderer // Alloc new slot id = (PickingID)m_pickingID.size(); m_pickingID.push_back(_object); + VG_ASSERT(id < 32768); // Only 15 bits because upper bit is used for "ZTest" in Outline return id; } diff --git a/src/renderer/RenderPass/Compute/ComputePostProcess/ComputePostProcessPass.hpp b/src/renderer/RenderPass/Compute/ComputePostProcess/ComputePostProcessPass.hpp index 1d322c5a7..94dae7a36 100644 --- a/src/renderer/RenderPass/Compute/ComputePostProcess/ComputePostProcessPass.hpp +++ b/src/renderer/RenderPass/Compute/ComputePostProcess/ComputePostProcessPass.hpp @@ -98,6 +98,12 @@ namespace vg::renderer createRWTexture(dstID, uavDesc); writeRWTexture(dstID); } + + if (view->IsOutlinePassNeeded()) + { + const auto outlineMaskID = _renderPassContext.getFrameGraphID("OutlineMask"); + readRenderTarget(outlineMaskID); + } } //-------------------------------------------------------------------------------------- @@ -291,6 +297,14 @@ namespace vg::renderer postProcess.setStencil(stencil); postProcess.setLinearDepth(linearDepth); + if (view->IsOutlinePassNeeded()) + { + auto outlineMaskTex = getRenderTarget(_renderPassContext.getFrameGraphID("OutlineMask")); + auto outlineMask = outlineMaskTex->getTextureHandle(); + + postProcess.setOutlineMask(outlineMask); + } + _cmdList->setComputeRootConstants(0, (u32 *)&postProcess, PostProcessConstantsCount); _cmdList->dispatch(threadGroupCount); diff --git a/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.h b/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.h index e6504d8e9..0cf32a323 100644 --- a/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.h +++ b/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.h @@ -18,7 +18,7 @@ namespace vg::renderer core::u64 GetCostEstimate (const gfx::RenderPassContext & _renderContext) const; void Setup (const gfx::RenderPassContext & _renderContext) final override; - void Prepare (const gfx::RenderPassContext & _renderContext) final override; + void BeforeAll (const gfx::RenderPassContext & _renderContext) final override; void Render (const gfx::RenderPassContext & _renderContext, gfx::CommandList * _cmdList) const final override; private: diff --git a/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.hpp b/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.hpp index 9142a0842..4c793c02b 100644 --- a/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.hpp +++ b/src/renderer/RenderPass/Compute/ComputeSkinning/ComputeSkinningPass.hpp @@ -63,7 +63,7 @@ namespace vg::renderer } //-------------------------------------------------------------------------------------- - void ComputeSkinningPass::Prepare(const RenderPassContext & _renderContext) + void ComputeSkinningPass::BeforeAll(const RenderPassContext & _renderContext) { VG_PROFILE_CPU("Skinning"); const auto & skinnedMeshes = Renderer::get()->getSharedCullingJobOutput()->m_skins; diff --git a/src/renderer/RenderPass/RenderContext.h b/src/renderer/RenderPass/RenderContext.h index a8b36ff1a..605633508 100644 --- a/src/renderer/RenderPass/RenderContext.h +++ b/src/renderer/RenderPass/RenderContext.h @@ -20,7 +20,8 @@ namespace vg::renderer m_shaderPass((ShaderPass)0), m_toolmode(false), m_raytracing(false), - m_wireframe(false) + m_wireframe(false), + m_outline(false) { } @@ -32,6 +33,7 @@ namespace vg::renderer bool m_toolmode : 1; bool m_raytracing : 1; bool m_wireframe : 1; + bool m_outline : 1; gfx::SurfaceType m_surfaceType = (gfx::SurfaceType)-1; }; } \ No newline at end of file diff --git a/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.h b/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.h index 0e6406fdd..1e76cdf5e 100644 --- a/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.h +++ b/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.h @@ -5,7 +5,7 @@ namespace vg::renderer { //-------------------------------------------------------------------------------------- - class EditorPass : public RenderObjectsPass + class EditorPass final : public RenderObjectsPass { public: const char * GetClassName() const final { return "EditorPass"; } @@ -13,12 +13,16 @@ namespace vg::renderer EditorPass(); ~EditorPass(); - void Setup (const gfx::RenderPassContext & _renderPassContext) override; - void BeforeRender(const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) override; - void Render (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) const override; - void AfterRender (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) override; + void Setup (const gfx::RenderPassContext & _renderPassContext) final override; + void BeforeRender(const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) final override; + void Render (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) const final override; + void AfterRender (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) final override; + void AfterAll (const gfx::RenderPassContext & _renderPassContext) final override; private: + //static gfx::Buffer * s_editorPassConstantsBuffer; + gfx::Buffer * m_toolmodeRWBufferStaging = nullptr; + PickingData m_pickingData; }; } \ No newline at end of file diff --git a/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.hpp b/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.hpp index f97eb2902..26c4ee33f 100644 --- a/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.hpp +++ b/src/renderer/RenderPass/RenderObjects/Editor/EditorPass.hpp @@ -9,20 +9,36 @@ #include "renderer/Instance/GraphicInstance.h" #include "Shaders/system/toolmode.hlsl.h" +#include "Shaders/system/editorpass.hlsli" namespace vg::renderer { + //gfx::Buffer * EditorPass::s_editorPassConstantsBuffer = nullptr; + //-------------------------------------------------------------------------------------- EditorPass::EditorPass() : RenderObjectsPass("EditorPass") { - + auto * device = Device::get(); + + //if (nullptr == s_editorPassConstantsBuffer) + //{ + // BufferDesc editorPassConstantsBufferDesc = BufferDesc(Usage::Default, BindFlags::ShaderResource, CPUAccessFlags::Write, BufferFlags::None, sizeof(EditorPassConstants)); + // s_editorPassConstantsBuffer = device->createBuffer(editorPassConstantsBufferDesc, "EditorPassConstants", nullptr, ReservedSlot::EditorPassBufSrv); + //} + //else + //{ + // VG_SAFE_INCREASE_REFCOUNT(s_editorPassConstantsBuffer); + //} } //-------------------------------------------------------------------------------------- EditorPass::~EditorPass() { VG_SAFE_DELETE(m_toolmodeRWBufferStaging); + + //if (s_editorPassConstantsBuffer && !s_editorPassConstantsBuffer->Release()) + // s_editorPassConstantsBuffer = nullptr; } //-------------------------------------------------------------------------------------- @@ -31,8 +47,6 @@ namespace vg::renderer writeRenderTarget(0, _renderPassContext.getFrameGraphID("Color")); writeDepthStencil(_renderPassContext.getFrameGraphID("DepthStencil")); writeRWBuffer(_renderPassContext.getFrameGraphID("ToolmodeRWBuffer")); - - readRenderTarget(_renderPassContext.getFrameGraphID("OutlineMask")); readRWBuffer("SkinningRWBuffer"); } @@ -40,6 +54,15 @@ namespace vg::renderer void EditorPass::BeforeRender(const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) { DebugDraw::get()->update(static_cast(_renderPassContext.getView()), _cmdList); + + //auto OutlineMaskTex = getRenderTarget(_renderPassContext.getFrameGraphID("OutlineMask")); + //auto outlineMask = OutlineMaskTex->getTextureHandle(); + + //EditorPassConstants * constants = (EditorPassConstants *)_cmdList->map(s_editorPassConstantsBuffer, sizeof(EditorPassConstants)).data; + //{ + // constants->setOutlineMask(outlineMask); + //} + //_cmdList->unmap(s_editorPassConstantsBuffer); } //-------------------------------------------------------------------------------------- @@ -84,17 +107,13 @@ namespace vg::renderer DrawGraphicInstances(renderContext, _cmdList, GraphicInstanceListType::All); } - bool boudingBoxSelection = true; - if (options->isAABBEnabled() || boudingBoxSelection) + if (options->isAABBEnabled()) { const GraphicInstanceList & allInstances = view->getCullingJobResult().get(GraphicInstanceListType::All); for (uint i = 0; i < allInstances.m_instances.size(); ++i) { auto * instance = (GraphicInstance*)allInstances.m_instances[i]; - if (boudingBoxSelection && !asBool(ObjectFlags::Selected & instance->getObjectFlags())) - continue; - AABB aabb; if (instance->TryGetAABB(aabb)) dbgDraw->drawAABB(_cmdList, aabb, instance->getGlobalMatrix()); @@ -109,7 +128,7 @@ namespace vg::renderer //-------------------------------------------------------------------------------------- void EditorPass::AfterRender(const RenderPassContext & _renderPassContext, CommandList * _cmdList) { - auto * view = (IView*)(_renderPassContext.getViewMutable()); + const auto * view = (IView*)(_renderPassContext.getView()); Buffer * toolmodeRWBuffer = getRWBuffer(_renderPassContext.getFrameGraphID("ToolmodeRWBuffer")); // allocate staging copy @@ -130,8 +149,15 @@ namespace vg::renderer { const ToolmodeRWBufferData * data = (ToolmodeRWBufferData *)result.data; const PickingData * pickingData = &data->m_picking; - view->SetPickingData(*pickingData); + m_pickingData = *pickingData; ; } m_toolmodeRWBufferStaging->getResource().unmap(); } + + //-------------------------------------------------------------------------------------- + void EditorPass::AfterAll(const gfx::RenderPassContext & _renderPassContext) + { + auto * view = (IView *)(_renderPassContext.getViewMutable()); + view->SetPickingData(m_pickingData); + } } \ No newline at end of file diff --git a/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.h b/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.h index c36075638..157b720af 100644 --- a/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.h +++ b/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.h @@ -19,6 +19,6 @@ namespace vg::renderer void Render (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) const final override; private: - static gfx::Buffer * s_TransparentPassConstantsBuffer; + static gfx::Buffer * s_transparentPassConstantsBuffer; }; } \ No newline at end of file diff --git a/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.hpp b/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.hpp index a2d772bfa..2756ee1e0 100644 --- a/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.hpp +++ b/src/renderer/RenderPass/RenderObjects/Forward/ForwardTransparentPass.hpp @@ -9,7 +9,7 @@ namespace vg::renderer { - gfx::Buffer * ForwardTransparentPass::s_TransparentPassConstantsBuffer = nullptr; + gfx::Buffer * ForwardTransparentPass::s_transparentPassConstantsBuffer = nullptr; //-------------------------------------------------------------------------------------- // Setup executed once, when pass is created @@ -19,22 +19,22 @@ namespace vg::renderer { auto * device = Device::get(); - if (nullptr == s_TransparentPassConstantsBuffer) + if (nullptr == s_transparentPassConstantsBuffer) { - BufferDesc viewConstantsBufferDesc = BufferDesc(Usage::Default, BindFlags::ShaderResource, CPUAccessFlags::Write, BufferFlags::None, sizeof(TransparentPassConstants)); - s_TransparentPassConstantsBuffer = device->createBuffer(viewConstantsBufferDesc, "TransparentPassConstants", nullptr, ReservedSlot::TransparentPassBufSrv); + BufferDesc editorPassConstantsBufferDesc = BufferDesc(Usage::Default, BindFlags::ShaderResource, CPUAccessFlags::Write, BufferFlags::None, sizeof(TransparentPassConstants)); + s_transparentPassConstantsBuffer = device->createBuffer(editorPassConstantsBufferDesc, "TransparentPassConstants", nullptr, ReservedSlot::TransparentPassBufSrv); } else { - VG_SAFE_INCREASE_REFCOUNT(s_TransparentPassConstantsBuffer); + VG_SAFE_INCREASE_REFCOUNT(s_transparentPassConstantsBuffer); } } //-------------------------------------------------------------------------------------- ForwardTransparentPass::~ForwardTransparentPass() { - if (s_TransparentPassConstantsBuffer && !s_TransparentPassConstantsBuffer->Release()) - s_TransparentPassConstantsBuffer = nullptr; + if (s_transparentPassConstantsBuffer && !s_transparentPassConstantsBuffer->Release()) + s_transparentPassConstantsBuffer = nullptr; } //-------------------------------------------------------------------------------------- @@ -67,11 +67,11 @@ namespace vg::renderer auto linearDepthTex = getRenderTarget(_renderPassContext.getFrameGraphID("LinearDepth")); auto linearDepth = linearDepthTex->getTextureHandle(); - TransparentPassConstants * constants = (TransparentPassConstants *)_cmdList->map(s_TransparentPassConstantsBuffer, sizeof(TransparentPassConstants)).data; + TransparentPassConstants * constants = (TransparentPassConstants *)_cmdList->map(s_transparentPassConstantsBuffer, sizeof(TransparentPassConstants)).data; { constants->setLinearDepth(linearDepth); } - _cmdList->unmap(s_TransparentPassConstantsBuffer); + _cmdList->unmap(s_transparentPassConstantsBuffer); } //-------------------------------------------------------------------------------------- diff --git a/src/renderer/RenderPass/RenderObjects/Misc/Outline/OutlineMaskPass.hpp b/src/renderer/RenderPass/RenderObjects/Misc/Outline/OutlineMaskPass.hpp index 05efc53c2..e0cc915b8 100644 --- a/src/renderer/RenderPass/RenderObjects/Misc/Outline/OutlineMaskPass.hpp +++ b/src/renderer/RenderPass/RenderObjects/Misc/Outline/OutlineMaskPass.hpp @@ -19,7 +19,7 @@ namespace vg::renderer core::u64 OutlineMaskPass::GetCostEstimate(const RenderPassContext & _renderPassContext) const { const View * view = static_cast(_renderPassContext.getView()); - return getListCostEstimate(view->getCullingJobResult(), GraphicInstanceListType::Selected); + return getListCostEstimate(view->getCullingJobResult(), GraphicInstanceListType::Outline); } //-------------------------------------------------------------------------------------- @@ -35,13 +35,21 @@ namespace vg::renderer FrameGraphTextureResourceDesc outlineMaskResourceDesc = *depthStencilResourceDesc; outlineMaskResourceDesc.type = TextureType::Texture2D; outlineMaskResourceDesc.msaa = MSAA::None; - outlineMaskResourceDesc.format = PixelFormat::R8G8B8A8_unorm; + outlineMaskResourceDesc.format = PixelFormat::R16G16B16A16_uint; // up to 4 outline masks, alpha channel used for editor selection outline outlineMaskResourceDesc.clearColor = (float4)0.0f; const auto outlineMaskID = _renderPassContext.getFrameGraphID("OutlineMask"); createRenderTarget(outlineMaskID, outlineMaskResourceDesc); writeRenderTarget(0, outlineMaskID); + FrameGraphTextureResourceDesc outlineMaskDepthStencilResourceDesc = *depthStencilResourceDesc; + outlineMaskDepthStencilResourceDesc.type = TextureType::Texture2D; + outlineMaskDepthStencilResourceDesc.msaa = MSAA::None; + + const auto outlineMaskDepthStencilID = _renderPassContext.getFrameGraphID("OutlineMaskDepthStencil"); + createRenderTarget(outlineMaskDepthStencilID, outlineMaskDepthStencilResourceDesc); + writeDepthStencil(outlineMaskDepthStencilID); + const auto linearDepthID = _renderPassContext.getFrameGraphID("LinearDepth"); readRenderTarget(linearDepthID); @@ -60,20 +68,19 @@ namespace vg::renderer renderContext.m_proj = view->getProjMatrix(); renderContext.m_toolmode = view->getViewID().target == gfx::ViewTarget::Editor || options->isToolModeEnabled(); renderContext.m_raytracing = view->IsUsingRayTracing(); - renderContext.m_shaderPass = ShaderPass::Transparent; + renderContext.m_shaderPass = ShaderPass::Outline; + renderContext.m_outline = true; RasterizerState rs(FillMode::Solid, CullMode::None); BlendState bs(BlendFactor::One, BlendFactor::Zero, BlendOp::Add); - const bool depthWrite = false; - - DepthStencilState ds(false, false, ComparisonFunc::LessEqual); + DepthStencilState ds(true, true, ComparisonFunc::LessEqual); _cmdList->setPrimitiveTopology(PrimitiveTopology::TriangleList); _cmdList->setRasterizerState(rs); _cmdList->setBlendState(bs); _cmdList->setDepthStencilState(ds); - DrawGraphicInstances(renderContext, _cmdList, GraphicInstanceListType::Selected); + DrawGraphicInstances(renderContext, _cmdList, GraphicInstanceListType::Outline); } } \ No newline at end of file diff --git a/src/renderer/RenderPass/RenderObjects/RenderObjectsPass.hpp b/src/renderer/RenderPass/RenderObjects/RenderObjectsPass.hpp index 7902b0ec5..2022d5a46 100644 --- a/src/renderer/RenderPass/RenderObjects/RenderObjectsPass.hpp +++ b/src/renderer/RenderPass/RenderObjects/RenderObjectsPass.hpp @@ -47,7 +47,7 @@ namespace vg::renderer break; case GraphicInstanceListType::All: - case GraphicInstanceListType::Selected: + case GraphicInstanceListType::Outline: case GraphicInstanceListType::Opaque: renderContext.m_surfaceType = gfx::SurfaceType::Opaque; break; diff --git a/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.h b/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.h index 57769807a..8ed59d63d 100644 --- a/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.h +++ b/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.h @@ -19,7 +19,7 @@ namespace vg::renderer ~InstanceDataUpdatePass(); core::u64 GetCostEstimate (const gfx::RenderPassContext & _renderContext) const final override; - void Prepare (const gfx::RenderPassContext & _renderContext) final override; + void BeforeAll (const gfx::RenderPassContext & _renderContext) final override; void BeforeRender (const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) final override; private: diff --git a/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.hpp b/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.hpp index a0521fc77..7d75bc6d0 100644 --- a/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.hpp +++ b/src/renderer/RenderPass/Update/InstanceData/InstanceDataUpdatePass.hpp @@ -34,7 +34,7 @@ namespace vg::renderer } //-------------------------------------------------------------------------------------- - void InstanceDataUpdatePass::Prepare(const gfx::RenderPassContext & _renderContext) + void InstanceDataUpdatePass::BeforeAll(const gfx::RenderPassContext & _renderContext) { VG_PROFILE_CPU("InstanceData"); diff --git a/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.h b/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.h index 92c5920e1..ae1e5e736 100644 --- a/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.h +++ b/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.h @@ -18,7 +18,7 @@ namespace vg::renderer MaterialDataUpdatePass(); ~MaterialDataUpdatePass(); - void Prepare(const gfx::RenderPassContext & _renderContext) final override; + void BeforeAll(const gfx::RenderPassContext & _renderContext) final override; void BeforeRender(const gfx::RenderPassContext & _renderPassContext, gfx::CommandList * _cmdList) final override; private: diff --git a/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.hpp b/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.hpp index dd5922454..ea0adba49 100644 --- a/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.hpp +++ b/src/renderer/RenderPass/Update/MaterialData/MaterialDataUpdatePass.hpp @@ -23,7 +23,7 @@ namespace vg::renderer } //-------------------------------------------------------------------------------------- - void MaterialDataUpdatePass::Prepare(const gfx::RenderPassContext & _renderContext) + void MaterialDataUpdatePass::BeforeAll(const gfx::RenderPassContext & _renderContext) { MaterialManager * materialManager = MaterialManager::get(); materialManager->getMaterialsSafeCopy(m_materials); diff --git a/src/renderer/View/Lit/LitView.hpp b/src/renderer/View/Lit/LitView.hpp index bac6f9d58..2f1e802ff 100644 --- a/src/renderer/View/Lit/LitView.hpp +++ b/src/renderer/View/Lit/LitView.hpp @@ -132,7 +132,7 @@ namespace vg::renderer break; } - const bool outline = toolmode && true; + const bool outline = view->IsOutlinePassNeeded(); // Resolve/copy linear depth just before transparent pass because even in case of forward rendering we might want to add other passes writing Z (e.g., Skin, Water ...) if (outline || options->isTransparencyEnabled() || view->IsComputePostProcessNeeded()) @@ -143,12 +143,11 @@ namespace vg::renderer // Render editor display to "Color" if (toolmode) - { - if (outline) - _frameGraph.addUserPass(_renderPassContext, m_outlineMaskPass, "OutlineMask"); - _frameGraph.addUserPass(_renderPassContext, m_editorPass, "Editor"); - } + + // Render outline mask buffer + if (outline) + _frameGraph.addUserPass(_renderPassContext, m_outlineMaskPass, "OutlineMask"); // Apply PostProcess from "Color" and "DepthStencil" to "PostProcessUAV" if (view->IsComputePostProcessNeeded()) diff --git a/src/renderer/View/View.cpp b/src/renderer/View/View.cpp index 4f14f918d..05f5bb03b 100644 --- a/src/renderer/View/View.cpp +++ b/src/renderer/View/View.cpp @@ -2,6 +2,7 @@ #include "View.h" #include "core/GameObject/GameObject.h" #include "core/IInput.h" +#include "core/Scheduler/Mutex.h" #include "gfx/ITexture.h" #include "gfx/Resource/Buffer.h" #include "gfx/Raytracing/TLAS.h" @@ -528,6 +529,13 @@ namespace vg::renderer return options->isPostProcessEnabled() || (isToolmode() && IsUsingRayTracing() && options->anyRayTracingDebugDisplay()); } + //-------------------------------------------------------------------------------------- + bool View::IsOutlinePassNeeded() const + { + const auto options = RendererOptions::get(); + return IsComputePostProcessNeeded() && isToolmode(); + } + //-------------------------------------------------------------------------------------- void View::setTLAS(TLAS * _tlas) { @@ -563,6 +571,8 @@ namespace vg::renderer // Copy last picking results m_rawPickingData = _pickingData; + lock_guard _(m_pickingHitsAssertMutex); + // Save hits const uint counter = m_rawPickingData.m_counter.x; m_pickingHits.clear(); @@ -599,6 +609,8 @@ namespace vg::renderer //-------------------------------------------------------------------------------------- void View::AddPickingHit(const PickingHit & _hit) { + lock_guard _(m_pickingHitsAssertMutex); + if (isToolmode()) m_pickingHits.insert(m_pickingHits.begin(), _hit); } @@ -606,6 +618,8 @@ namespace vg::renderer //-------------------------------------------------------------------------------------- const PickingHit & View::GetPickingClosestHit() const { + lock_guard _(m_pickingHitsAssertMutex); + VG_ASSERT(GetPickingHitCount() > 0); return m_pickingHits[0]; } @@ -613,12 +627,16 @@ namespace vg::renderer //-------------------------------------------------------------------------------------- const PickingHit & View::GetPickingHit(uint _index) const { + lock_guard _(m_pickingHitsAssertMutex); + return m_pickingHits[_index]; } //-------------------------------------------------------------------------------------- uint View::GetPickingHitCount() const { + lock_guard _(m_pickingHitsAssertMutex); + VG_ASSERT(m_pickingHits.size() <= PICKING_MAX_HITS); return (uint)m_pickingHits.size(); } @@ -644,7 +662,7 @@ namespace vg::renderer stats.alphatest = (uint)m_cullingJobResult.get(GraphicInstanceListType::AlphaTest).m_instances.size(); stats.transparent = (uint)m_cullingJobResult.get(GraphicInstanceListType::Transparent).m_instances.size(); stats.decal = (uint)m_cullingJobResult.get(GraphicInstanceListType::Decal).m_instances.size(); - stats.selected = (uint)m_cullingJobResult.get(GraphicInstanceListType::Selected).m_instances.size(); + stats.outline = (uint)m_cullingJobResult.get(GraphicInstanceListType::Outline).m_instances.size(); stats.directional = (uint)m_cullingJobResult.get(LightType::Directional).m_instances.size(); stats.omni = (uint)m_cullingJobResult.get(LightType::Omni).m_instances.size(); diff --git a/src/renderer/View/View.h b/src/renderer/View/View.h index 3e0023735..02a53142a 100644 --- a/src/renderer/View/View.h +++ b/src/renderer/View/View.h @@ -1,8 +1,9 @@ #pragma once -#include "renderer/IView.h" +#include "core/Scheduler/AssertMutex.h" #include "gfx/Resource/Texture.h" #include "gfx/FrameGraph/FrameGraph_consts.h" +#include "renderer/IView.h" #include "renderer/Job/Culling/ViewCullingJob.h" #include "shaders/system/picking.hlsli" #include "Frustum.h" @@ -96,6 +97,7 @@ namespace vg::renderer bool IsUsingRayTracing () const override; bool IsLit () const override; bool IsComputePostProcessNeeded () const override; + bool IsOutlinePassNeeded () const override; void setTLAS (gfx::TLAS * _tlas); gfx::TLAS * getTLAS () const; @@ -187,6 +189,7 @@ namespace vg::renderer core::uint2 m_mouseOffset; PickingData m_rawPickingData; core::vector m_pickingHits; + mutable core::AssertMutex m_pickingHitsAssertMutex = core::AssertMutex("PickingHits"); gfx::TLAS * m_tlas = nullptr; Frustum m_frustum; ViewCullingJobOutput m_cullingJobResult; diff --git a/src/version.h b/src/version.h index 12fd67b5c..5a0cc783f 100644 --- a/src/version.h +++ b/src/version.h @@ -2,4 +2,4 @@ #define VG_FRAMEWORK_VERSION_MAJOR 0 #define VG_FRAMEWORK_VERSION_MINOR 46 -#define VG_FRAMEWORK_VERSION_PATCH 1 \ No newline at end of file +#define VG_FRAMEWORK_VERSION_PATCH 2 \ No newline at end of file diff --git a/vgframework.sln b/vgframework.sln index cc23af6a4..72b049fc1 100644 --- a/vgframework.sln +++ b/vgframework.sln @@ -87,6 +87,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "system", "system", "{34ABDE data\Shaders\system\depthbias.hlsli = data\Shaders\system\depthbias.hlsli data\Shaders\system\depthstencil.hlsli = data\Shaders\system\depthstencil.hlsli data\Shaders\system\displaymodes.hlsli = data\Shaders\system\displaymodes.hlsli + data\Shaders\system\editorpass.hlsli = data\Shaders\system\editorpass.hlsli data\Shaders\system\environment.hlsli = data\Shaders\system\environment.hlsli data\Shaders\system\gamma.hlsli = data\Shaders\system\gamma.hlsli data\Shaders\system\instancedata.hlsli = data\Shaders\system\instancedata.hlsli @@ -96,6 +97,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "system", "system", "{34ABDE data\Shaders\system\material_consts.hlsli = data\Shaders\system\material_consts.hlsli data\Shaders\system\msaa.hlsli = data\Shaders\system\msaa.hlsli data\Shaders\system\packing.hlsli = data\Shaders\system\packing.hlsli + data\Shaders\system\outlinemask.hlsli = data\Shaders\system\outlinemask.hlsli data\Shaders\system\pbr.hlsli = data\Shaders\system\pbr.hlsli data\Shaders\system\picking.hlsl = data\Shaders\system\picking.hlsl data\Shaders\system\picking.hlsli = data\Shaders\system\picking.hlsli