From c3e337bb877a5b30a4e2423a4be885bc19cb14d7 Mon Sep 17 00:00:00 2001 From: ecker Date: Tue, 23 Jun 2026 21:51:01 -0500 Subject: [PATCH] finalized VR rendermode, rendertarget handles the camera for where it should render at (defaults to 3 units in front of camera), fixed flat GUI not clicking/hovering when in VR because of mismatched viewport sizes, fixed validation error regressions --- bin/data/config.json | 10 +- bin/data/shaders/base/line/vert.glsl | 1 + bin/data/shaders/base/textured/vert.glsl | 1 + bin/data/shaders/display/deferred/comp/comp.h | 1 + .../shaders/display/renderTarget/vert.glsl | 1 + bin/data/shaders/display/vr/flat.frag.glsl | 5 +- bin/data/shaders/display/vr/flat.vert.glsl | 25 ++- bin/data/shaders/display/vr/stereo.frag.glsl | 5 +- bin/data/shaders/display/vr/stereo.vert.glsl | 23 ++- bin/data/shaders/graph/cull/comp.glsl | 1 + bin/data/shaders/gui/gui/vert.h | 1 + bin/data/shaders/raytrace/shader.ray-gen.glsl | 1 + engine/inc/uf/engine/graph/pod.inl | 4 +- engine/inc/uf/ext/lua/component.h | 2 +- engine/inc/uf/ext/openvr/openvr.h | 8 +- engine/inc/uf/ext/vulkan/rendermode.h | 3 +- engine/inc/uf/ext/vulkan/rendermodes/base.h | 1 + .../uf/ext/vulkan/rendermodes/rendertarget.h | 1 - engine/inc/uf/ext/zlib/zlib.h | 10 +- engine/inc/uf/utils/camera/camera.h | 6 +- engine/inc/uf/utils/debug/checkpoint.h | 4 +- engine/inc/uf/utils/hook/function_traits.inl | 16 +- engine/inc/uf/utils/io/macros.inl | 6 +- engine/inc/uf/utils/io/vfs.h | 18 +-- .../uf/utils/math/physics/constraints/motor.h | 28 ++-- engine/inc/uf/utils/math/physics/structs.h | 4 +- .../inc/uf/utils/math/transform/transform.inl | 4 +- engine/inc/uf/utils/memory/deque.h | 12 +- engine/inc/uf/utils/memory/pool.h | 6 +- engine/inc/uf/utils/memory/queue.h | 4 +- engine/inc/uf/utils/memory/stack.h | 4 +- engine/inc/uf/utils/thread/perthread.h | 12 +- engine/inc/uf/utils/thread/perthread.inl | 43 +++-- engine/src/engine/ext/ext.cpp | 14 +- engine/src/engine/ext/gui/behavior.cpp | 16 +- .../src/engine/ext/player/camera/behavior.cpp | 9 +- engine/src/engine/scene/behavior.cpp | 2 - engine/src/ext/openvr/openvr.cpp | 40 ++++- engine/src/ext/vulkan/device.cpp | 4 +- engine/src/ext/vulkan/rendermode.cpp | 16 +- engine/src/ext/vulkan/rendermodes/base.cpp | 41 +++-- .../src/ext/vulkan/rendermodes/deferred.cpp | 152 +++++++----------- .../ext/vulkan/rendermodes/rendertarget.cpp | 58 +++++-- .../src/ext/vulkan/rendermodes/transition.inl | 14 ++ engine/src/ext/vulkan/rendermodes/vr.cpp | 51 +++--- engine/src/ext/vulkan/vulkan.cpp | 26 +-- 46 files changed, 418 insertions(+), 296 deletions(-) diff --git a/bin/data/config.json b/bin/data/config.json index 4ddcb0df..33693021 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -6,7 +6,7 @@ "lightmaps": true, "max": 32, "shadows": { - "enabled": true, + "enabled": false, "update": 4, "max": 16, "samples": 1 @@ -110,7 +110,7 @@ "default defer buffer destroy": true, "default command buffer immediate": true, "n-buffered uniform": true, - "multithreaded recording": false + "multithreaded recording": true }, "pipelines": { "deferred": true, @@ -324,11 +324,7 @@ "preset": "native" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x) }, "vr" : { - "enable" : true, - "manifest": "./data/openvr_manifest.json", - "swap eyes": false, - "dominant eye": 0, - "scale": 1.0 + "enable" : false }, "ultralight": { "enabled": true, "scale": 1.5 }, "discord": { "enabled": false }, diff --git a/bin/data/shaders/base/line/vert.glsl b/bin/data/shaders/base/line/vert.glsl index e5763af9..e38eb414 100644 --- a/bin/data/shaders/base/line/vert.glsl +++ b/bin/data/shaders/base/line/vert.glsl @@ -12,6 +12,7 @@ layout (location = 1) in vec4 inColor; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; layout (binding = 0) uniform Camera { diff --git a/bin/data/shaders/base/textured/vert.glsl b/bin/data/shaders/base/textured/vert.glsl index 838f20b9..c589ab70 100644 --- a/bin/data/shaders/base/textured/vert.glsl +++ b/bin/data/shaders/base/textured/vert.glsl @@ -14,6 +14,7 @@ layout (location = 3) in vec2 inOffset; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; layout (binding = 0) uniform Camera { diff --git a/bin/data/shaders/display/deferred/comp/comp.h b/bin/data/shaders/display/deferred/comp/comp.h index 7d8feb95..2499a0bb 100644 --- a/bin/data/shaders/display/deferred/comp/comp.h +++ b/bin/data/shaders/display/deferred/comp/comp.h @@ -58,6 +58,7 @@ layout(binding = 10, set = 0, r32f) uniform writeonly image2DArray imageDepthRes layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; #include "../../../common/structs.h" diff --git a/bin/data/shaders/display/renderTarget/vert.glsl b/bin/data/shaders/display/renderTarget/vert.glsl index 95fd44b3..77d49e89 100644 --- a/bin/data/shaders/display/renderTarget/vert.glsl +++ b/bin/data/shaders/display/renderTarget/vert.glsl @@ -7,6 +7,7 @@ layout (location = 1) out flat uint outPass; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; void main() { diff --git a/bin/data/shaders/display/vr/flat.frag.glsl b/bin/data/shaders/display/vr/flat.frag.glsl index 4fdd47c7..90b2cb23 100644 --- a/bin/data/shaders/display/vr/flat.frag.glsl +++ b/bin/data/shaders/display/vr/flat.frag.glsl @@ -8,7 +8,7 @@ layout (location = 1) flat in uint inPass; layout (location = 0) out vec4 outLeft; layout (location = 1) out vec4 outRight; -layout (binding = 0) uniform sampler2D samplerColor; +layout (binding = 1) uniform sampler2D samplerColor; layout(constant_id = 0) const int FORCE_OPAQUE = 0; @@ -19,6 +19,9 @@ layout(constant_id = 0) const int FORCE_OPAQUE = 0; #include "../../common/functions.h" void main() { + outLeft = vec4(0.0); + outRight = vec4(0.0); + vec4 outColor = texture( samplerColor, inUv ); if ( FORCE_OPAQUE == 1 ) outColor.a = 1; diff --git a/bin/data/shaders/display/vr/flat.vert.glsl b/bin/data/shaders/display/vr/flat.vert.glsl index da793524..6c885112 100644 --- a/bin/data/shaders/display/vr/flat.vert.glsl +++ b/bin/data/shaders/display/vr/flat.vert.glsl @@ -10,14 +10,33 @@ layout (location = 1) out flat uint outPass; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; -layout (binding = 0) uniform Camera { +layout (binding = 0) uniform UBO { Viewport viewport[6]; } camera; +const vec2 positions[6] = vec2[]( + vec2(-1.0, -1.0), + vec2( 1.0, -1.0), + vec2(-1.0, 1.0), + vec2(-1.0, 1.0), + vec2( 1.0, -1.0), + vec2( 1.0, 1.0) +); + +const vec2 uvs[6] = vec2[]( + vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(0.0, 1.0), + vec2(0.0, 1.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0) +); + void main() { - outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUv = uvs[gl_VertexIndex]; outPass = PushConstant.pass; - gl_Position = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(outUv * 2.0f + -1.0f, 0.0f, 1.0f); + gl_Position = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(positions[gl_VertexIndex], 0.0f, 1.0f); } \ No newline at end of file diff --git a/bin/data/shaders/display/vr/stereo.frag.glsl b/bin/data/shaders/display/vr/stereo.frag.glsl index 426a7c60..3b5d2cb0 100644 --- a/bin/data/shaders/display/vr/stereo.frag.glsl +++ b/bin/data/shaders/display/vr/stereo.frag.glsl @@ -8,7 +8,7 @@ layout (location = 1) flat in uint inPass; layout (location = 0) out vec4 outLeft; layout (location = 1) out vec4 outRight; -layout (binding = 0) uniform sampler2DArray samplerColor; +layout (binding = 1) uniform sampler2DArray samplerColor; layout(constant_id = 0) const int FORCE_OPAQUE = 0; @@ -19,6 +19,9 @@ layout(constant_id = 0) const int FORCE_OPAQUE = 0; #include "../../common/functions.h" void main() { + outLeft = vec4(0.0); + outRight = vec4(0.0); + vec4 outColor = texture( samplerColor, vec3(inUv, inPass) ); if ( FORCE_OPAQUE == 1 ) outColor.a = 1; diff --git a/bin/data/shaders/display/vr/stereo.vert.glsl b/bin/data/shaders/display/vr/stereo.vert.glsl index 95fd44b3..4f3569ca 100644 --- a/bin/data/shaders/display/vr/stereo.vert.glsl +++ b/bin/data/shaders/display/vr/stereo.vert.glsl @@ -7,10 +7,29 @@ layout (location = 1) out flat uint outPass; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; +const vec2 positions[6] = vec2[]( + vec2(-1.0, -1.0), + vec2( 1.0, -1.0), + vec2(-1.0, 1.0), + vec2(-1.0, 1.0), + vec2( 1.0, -1.0), + vec2( 1.0, 1.0) +); + +const vec2 uvs[6] = vec2[]( + vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(0.0, 1.0), + vec2(0.0, 1.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0) +); + void main() { - outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUv = uvs[gl_VertexIndex]; outPass = PushConstant.pass; - gl_Position = vec4(outUv * 2.0f + -1.0f, 0.0f, 1.0f); + gl_Position = vec4(positions[gl_VertexIndex], 0.0f, 1.0f); } \ No newline at end of file diff --git a/bin/data/shaders/graph/cull/comp.glsl b/bin/data/shaders/graph/cull/comp.glsl index fda95ebc..797424c8 100644 --- a/bin/data/shaders/graph/cull/comp.glsl +++ b/bin/data/shaders/graph/cull/comp.glsl @@ -57,6 +57,7 @@ bool projectSphere(vec3 C, float r, float znear, float P00, float P11, out vec4 layout( push_constant ) uniform PushBlock { uint pass; uint passes; + uint aux; } PushConstant; layout (binding = 0) uniform Camera { diff --git a/bin/data/shaders/gui/gui/vert.h b/bin/data/shaders/gui/gui/vert.h index cc52164b..7e389ba0 100644 --- a/bin/data/shaders/gui/gui/vert.h +++ b/bin/data/shaders/gui/gui/vert.h @@ -8,6 +8,7 @@ layout (location = 3) in vec2 inOffset; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; struct Matrices { diff --git a/bin/data/shaders/raytrace/shader.ray-gen.glsl b/bin/data/shaders/raytrace/shader.ray-gen.glsl index afb2acef..c706c598 100644 --- a/bin/data/shaders/raytrace/shader.ray-gen.glsl +++ b/bin/data/shaders/raytrace/shader.ray-gen.glsl @@ -28,6 +28,7 @@ layout (constant_id = 3) const uint CASCADES = 1; layout( push_constant ) uniform PushBlock { uint pass; uint draw; + uint aux; } PushConstant; layout (binding = 0) uniform accelerationStructureEXT tlas; diff --git a/engine/inc/uf/engine/graph/pod.inl b/engine/inc/uf/engine/graph/pod.inl index f5428c97..d509a32b 100644 --- a/engine/inc/uf/engine/graph/pod.inl +++ b/engine/inc/uf/engine/graph/pod.inl @@ -139,6 +139,6 @@ namespace pod { }; struct ImageStream { - StreamRegion buffer; - }; + StreamRegion buffer; + }; } \ No newline at end of file diff --git a/engine/inc/uf/ext/lua/component.h b/engine/inc/uf/ext/lua/component.h index 845a12c8..fd88c72f 100644 --- a/engine/inc/uf/ext/lua/component.h +++ b/engine/inc/uf/ext/lua/component.h @@ -15,7 +15,7 @@ namespace ext { template sol::object getComponent( uf::Object& self ) { - return sol::make_object(ext::lua::state, std::ref(self.getComponent())); + return sol::make_object(ext::lua::state, std::ref(self.getComponent())); } } } diff --git a/engine/inc/uf/ext/openvr/openvr.h b/engine/inc/uf/ext/openvr/openvr.h index de991a0d..1ebd14a4 100644 --- a/engine/inc/uf/ext/openvr/openvr.h +++ b/engine/inc/uf/ext/openvr/openvr.h @@ -45,7 +45,13 @@ namespace ext { pod::Vector3f UF_API hmdEyePosition( vr::Hmd_Eye eye ); pod::Quaternion<> UF_API hmdQuaternion(); pod::Matrix4t<> UF_API hmdViewMatrix( vr::Hmd_Eye eye, const pod::Matrix4f& = uf::matrix::identity() ); - pod::Matrix4t<> UF_API hmdProjectionMatrix( vr::Hmd_Eye, float = 0.1f, float = 1024.0f ); + pod::Matrix4t<> UF_API hmdProjectionMatrix( vr::Hmd_Eye, float = 0.001f, float = 0.0f ); + inline pod::Matrix4t<> UF_API hmdViewMatrix( int i, const pod::Matrix4f& m = uf::matrix::identity() ) { + return hmdViewMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right, m ); + } + inline pod::Matrix4t<> UF_API hmdProjectionMatrix( int i, float zNear = 0.001f, float zFar = 0.0f ) { + return hmdProjectionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right, zNear, zFar ); + } uf::Serializer UF_API controllerState( vr::Controller_Hand, const uf::stl::string& = "" ); pod::Vector3f UF_API controllerPosition( vr::Controller_Hand, bool = false ); diff --git a/engine/inc/uf/ext/vulkan/rendermode.h b/engine/inc/uf/ext/vulkan/rendermode.h index 1d452e59..fc0a8e88 100644 --- a/engine/inc/uf/ext/vulkan/rendermode.h +++ b/engine/inc/uf/ext/vulkan/rendermode.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -40,7 +41,6 @@ namespace ext { uf::stl::string target = ""; uf::stl::string pipeline = ""; uf::stl::vector pipelines; - // uf::stl::vector outputs; uf::stl::unordered_map attachments; uf::stl::unordered_map buffers; @@ -57,6 +57,7 @@ namespace ext { uint8_t views = 1; bool compute = false; + uf::Camera camera; } metadata; Device* device = VK_NULL_HANDLE; diff --git a/engine/inc/uf/ext/vulkan/rendermodes/base.h b/engine/inc/uf/ext/vulkan/rendermodes/base.h index fc798e37..9d05bd3d 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/base.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/base.h @@ -12,6 +12,7 @@ namespace ext { virtual GraphicDescriptor bindGraphicDescriptor( const GraphicDescriptor&, size_t = 0 ); virtual void build( bool = true ); virtual void tick(); + virtual VkSubmitInfo queue(); virtual void render(); virtual void destroy(); }; diff --git a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h index e7eabead..0defe068 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h @@ -15,7 +15,6 @@ namespace ext { virtual void tick(); virtual void destroy(); virtual void render(); - virtual void pipelineBarrier( VkCommandBuffer, uint8_t = -1 ); }; } } \ No newline at end of file diff --git a/engine/inc/uf/ext/zlib/zlib.h b/engine/inc/uf/ext/zlib/zlib.h index e931394a..18fe6c45 100644 --- a/engine/inc/uf/ext/zlib/zlib.h +++ b/engine/inc/uf/ext/zlib/zlib.h @@ -11,11 +11,11 @@ namespace pod { struct ZipEntry { - size_t offset; - size_t compressedSize; - size_t uncompressedSize; - uint16_t compressionMethod; - }; + size_t offset; + size_t compressedSize; + size_t uncompressedSize; + uint16_t compressionMethod; + }; } namespace ext { diff --git a/engine/inc/uf/utils/camera/camera.h b/engine/inc/uf/utils/camera/camera.h index 2d6a86a0..33202e52 100644 --- a/engine/inc/uf/utils/camera/camera.h +++ b/engine/inc/uf/utils/camera/camera.h @@ -15,11 +15,11 @@ namespace uf { namespace pod { struct UF_API Camera { - pod::Transform<> transform; + pod::Transform<> transform = {}; struct Viewports { struct Matrices{ - pod::Matrix4f view; - pod::Matrix4f projection; + pod::Matrix4f view = uf::matrix::identity(); + pod::Matrix4f projection = uf::matrix::identity(); } matrices[uf::camera::maxViews]; } viewport; size_t views = 1; diff --git a/engine/inc/uf/utils/debug/checkpoint.h b/engine/inc/uf/utils/debug/checkpoint.h index 985f712b..9d9e87e3 100644 --- a/engine/inc/uf/utils/debug/checkpoint.h +++ b/engine/inc/uf/utils/debug/checkpoint.h @@ -11,10 +11,10 @@ namespace pod { END, }; - pod::Checkpoint::Type type = Type::GENERIC; + pod::Checkpoint::Type type = Type::GENERIC; uf::stl::string name = ""; uf::stl::string info = ""; - pod::Checkpoint* previous = NULL; + pod::Checkpoint* previous = NULL; }; } diff --git a/engine/inc/uf/utils/hook/function_traits.inl b/engine/inc/uf/utils/hook/function_traits.inl index 1a332f42..71c5e5a7 100644 --- a/engine/inc/uf/utils/hook/function_traits.inl +++ b/engine/inc/uf/utils/hook/function_traits.inl @@ -6,7 +6,7 @@ template constexpr bool return_void(R(Args ...)) template struct count_args; template struct count_args> { - static constexpr size_t value = sizeof...(Args); + static constexpr size_t value = sizeof...(Args); }; // For generic types that are functors, delegate to its 'operator()' @@ -16,14 +16,14 @@ struct function_traits : public function_traits {}; // for pointers to member function template struct function_traits { - //enum { arity = sizeof...(Args) }; - static const size_t arguments = sizeof...(Args); - template + //enum { arity = sizeof...(Args) }; + static const size_t arguments = sizeof...(Args); + template struct Arg { typedef typename std::tuple_element>::type type; }; - typedef ReturnType return_type; - typedef std::function type; + typedef ReturnType return_type; + typedef std::function type; }; // for pointers to member function @@ -34,8 +34,8 @@ struct function_traits { struct Arg { typedef typename std::tuple_element>::type type; }; - typedef ReturnType return_type; - typedef std::function type; + typedef ReturnType return_type; + typedef std::function type; }; // for function pointers diff --git a/engine/inc/uf/utils/io/macros.inl b/engine/inc/uf/utils/io/macros.inl index 20425caa..6ff8def5 100644 --- a/engine/inc/uf/utils/io/macros.inl +++ b/engine/inc/uf/utils/io/macros.inl @@ -1,6 +1,6 @@ #define UF_VFS_MOUNT_CPP( LAMBDA, URI, PRIORITY ) \ namespace {\ - static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\ - uf::vfs::mount( LAMBDA( URI, PRIORITY ) );\ - });\ + static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\ + uf::vfs::mount( LAMBDA( URI, PRIORITY ) );\ + });\ } diff --git a/engine/inc/uf/utils/io/vfs.h b/engine/inc/uf/utils/io/vfs.h index 39755e21..f0f0aa76 100644 --- a/engine/inc/uf/utils/io/vfs.h +++ b/engine/inc/uf/utils/io/vfs.h @@ -32,18 +32,18 @@ namespace uf { namespace vfs { extern UF_API uf::stl::vector mounts; - size_t UF_API mount( const pod::Mount& mount ); - bool UF_API unmount( size_t ); - bool UF_API unmount( const uf::stl::string& prefix, const uf::stl::string& base ); + size_t UF_API mount( const pod::Mount& mount ); + bool UF_API unmount( size_t ); + bool UF_API unmount( const uf::stl::string& prefix, const uf::stl::string& base ); - bool UF_API exists( const uf::stl::string& path ); + bool UF_API exists( const uf::stl::string& path ); size_t UF_API size( const uf::stl::string& path ); size_t UF_API mtime( const uf::stl::string& path ); - bool UF_API read( const uf::stl::string& path, uf::stl::vector& buffer ); - - size_t UF_API write( const uf::stl::string& path, const void* data, size_t len ); - size_t UF_API write( const uf::stl::string& path, uf::stl::vector& buffer ); - bool UF_API mkdir( const uf::stl::string& path ); + bool UF_API read( const uf::stl::string& path, uf::stl::vector& buffer ); + + size_t UF_API write( const uf::stl::string& path, const void* data, size_t len ); + size_t UF_API write( const uf::stl::string& path, uf::stl::vector& buffer ); + bool UF_API mkdir( const uf::stl::string& path ); bool UF_API readRange( const uf::stl::string& path, size_t start, size_t len, uf::stl::vector& buffer ); bool UF_API readRanges( const uf::stl::string& path, const uf::stl::vector& ranges, uf::stl::vector& buffer ); diff --git a/engine/inc/uf/utils/math/physics/constraints/motor.h b/engine/inc/uf/utils/math/physics/constraints/motor.h index 3cbe8ed5..fc1947f4 100644 --- a/engine/inc/uf/utils/math/physics/constraints/motor.h +++ b/engine/inc/uf/utils/math/physics/constraints/motor.h @@ -3,22 +3,22 @@ #include "../structs.h" namespace impl { - void solve1DLinearMotor( - pod::PhysicsBody& a, pod::PhysicsBody& b, - const pod::Vector3f& rA, const pod::Vector3f& rB, const pod::Vector3f& axis, - float targetVelocity, float maxForce, float& accumulatedImpulse, float dt - ); - void solve1DAngularMotor( - pod::PhysicsBody& a, pod::PhysicsBody& b, - const pod::Vector3f& axis, - float targetVelocity, float maxTorque, - float& accumulatedImpulse, float dt - ); + void solve1DLinearMotor( + pod::PhysicsBody& a, pod::PhysicsBody& b, + const pod::Vector3f& rA, const pod::Vector3f& rB, const pod::Vector3f& axis, + float targetVelocity, float maxForce, float& accumulatedImpulse, float dt + ); + void solve1DAngularMotor( + pod::PhysicsBody& a, pod::PhysicsBody& b, + const pod::Vector3f& axis, + float targetVelocity, float maxTorque, + float& accumulatedImpulse, float dt + ); } namespace uf { - namespace physics { - pod::Constraint& UF_API constrainMotor( pod::Constraint& constraint, float targetVelocity, float maxForceOrTorque ); - } + namespace physics { + pod::Constraint& UF_API constrainMotor( pod::Constraint& constraint, float targetVelocity, float maxForceOrTorque ); + } } \ No newline at end of file diff --git a/engine/inc/uf/utils/math/physics/structs.h b/engine/inc/uf/utils/math/physics/structs.h index 6f4aad63..e1de76eb 100644 --- a/engine/inc/uf/utils/math/physics/structs.h +++ b/engine/inc/uf/utils/math/physics/structs.h @@ -330,8 +330,8 @@ namespace pod { MASK_NONE = 0, MASK_STATIC = CATEGORY_DYNAMIC | CATEGORY_PLAYER | CATEGORY_NPC | CATEGORY_PROJECTILE, MASK_DYNAMIC = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_PLAYER | CATEGORY_NPC | CATEGORY_TRIGGER, - MASK_PLAYER = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_NPC | CATEGORY_PROJECTILE | CATEGORY_TRIGGER, - MASK_NPC = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_PLAYER | CATEGORY_PROJECTILE | CATEGORY_TRIGGER, + MASK_PLAYER = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_NPC | CATEGORY_PROJECTILE | CATEGORY_TRIGGER, + MASK_NPC = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_PLAYER | CATEGORY_PROJECTILE | CATEGORY_TRIGGER, MASK_TRIGGER = CATEGORY_PLAYER | CATEGORY_NPC, MASK_PROJECTILE = CATEGORY_STATIC | CATEGORY_DYNAMIC | CATEGORY_PLAYER | CATEGORY_NPC, MASK_CHARACTER = MASK_PLAYER | MASK_NPC, diff --git a/engine/inc/uf/utils/math/transform/transform.inl b/engine/inc/uf/utils/math/transform/transform.inl index 5546f197..ed3c543d 100644 --- a/engine/inc/uf/utils/math/transform/transform.inl +++ b/engine/inc/uf/utils/math/transform/transform.inl @@ -122,8 +122,8 @@ template pod::Transform uf::transform::fromMatrix( const pod::Matrix4t& matrix ) { pod::Transform transform; transform.position = uf::matrix::extractTranslation( matrix ); - transform.orientation = uf::quaternion::fromMatrix( matrix ); - transform.scale = uf::matrix::extractScale( matrix ); + transform.orientation = uf::quaternion::fromMatrix( matrix ); + transform.scale = uf::matrix::extractScale( matrix ); return transform; } diff --git a/engine/inc/uf/utils/memory/deque.h b/engine/inc/uf/utils/memory/deque.h index c7dbddf1..804bd873 100644 --- a/engine/inc/uf/utils/memory/deque.h +++ b/engine/inc/uf/utils/memory/deque.h @@ -8,12 +8,12 @@ namespace uf { namespace stl { template< - class T, - #if UF_MEMORYPOOL_OVERRIDE_NEW_DELETE - class Allocator = std::allocator - #else - class Allocator = uf::Allocator - #endif + class T, + #if UF_MEMORYPOOL_OVERRIDE_NEW_DELETE + class Allocator = std::allocator + #else + class Allocator = uf::Allocator + #endif > using deque = std::deque; } diff --git a/engine/inc/uf/utils/memory/pool.h b/engine/inc/uf/utils/memory/pool.h index b44c1166..030e5e42 100644 --- a/engine/inc/uf/utils/memory/pool.h +++ b/engine/inc/uf/utils/memory/pool.h @@ -52,9 +52,9 @@ namespace pod { } segregated; struct { void* freeLists[32]; - uint8_t* splitBlockBitset; - size_t maxLevel; - size_t minBlockSize; + uint8_t* splitBlockBitset; + size_t maxLevel; + size_t minBlockSize; } buddy; } state; diff --git a/engine/inc/uf/utils/memory/queue.h b/engine/inc/uf/utils/memory/queue.h index 9a7837b7..c514ac9f 100644 --- a/engine/inc/uf/utils/memory/queue.h +++ b/engine/inc/uf/utils/memory/queue.h @@ -9,8 +9,8 @@ namespace uf { namespace stl { template< - class T, - class Container = uf::stl::deque + class T, + class Container = uf::stl::deque > using queue = std::queue; } diff --git a/engine/inc/uf/utils/memory/stack.h b/engine/inc/uf/utils/memory/stack.h index 1518a2a2..de6328e7 100644 --- a/engine/inc/uf/utils/memory/stack.h +++ b/engine/inc/uf/utils/memory/stack.h @@ -9,8 +9,8 @@ namespace uf { namespace stl { template< - class T, - class Container = uf::stl::deque + class T, + class Container = uf::stl::deque > using stack = std::stack; } diff --git a/engine/inc/uf/utils/thread/perthread.h b/engine/inc/uf/utils/thread/perthread.h index 9e408d94..5c687a72 100644 --- a/engine/inc/uf/utils/thread/perthread.h +++ b/engine/inc/uf/utils/thread/perthread.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "thread.h" namespace uf { @@ -8,20 +10,22 @@ namespace uf { class UF_API ThreadUnique { public: typedef T type_t; - typedef std::mutex* mutex_type_t; + typedef std::shared_ptr mutex_type_t; typedef std::thread::id id_t; - typedef uf::stl::unordered_map container_t; - typedef uf::stl::unordered_map mutex_container_t; + typedef uf::stl::map container_t; + typedef uf::stl::map mutex_container_t; protected: container_t m_container; mutex_container_t m_mutex_container; + mutex_type_t m_mutex; public: - ~ThreadUnique(); + ThreadUnique() : m_mutex(std::make_shared()) {} bool has( id_t id = std::this_thread::get_id() ) const; T& get( id_t id = std::this_thread::get_id() ); container_t& container(); + mutex_type_t getMutex( id_t id = std::this_thread::get_id() ); void lockMutex( id_t id = std::this_thread::get_id() ); bool tryMutex( id_t id = std::this_thread::get_id() ); void unlockMutex( id_t id = std::this_thread::get_id() ); diff --git a/engine/inc/uf/utils/thread/perthread.inl b/engine/inc/uf/utils/thread/perthread.inl index 15bc6f2a..e4561b06 100644 --- a/engine/inc/uf/utils/thread/perthread.inl +++ b/engine/inc/uf/utils/thread/perthread.inl @@ -1,52 +1,47 @@ -template -uf::ThreadUnique::~ThreadUnique() { - for ( auto& pair : m_mutex_container ) { - if ( !pair.second ) continue; - delete pair.second; - pair.second = NULL; - } -} - template bool uf::ThreadUnique::has( id_t id ) const { + std::lock_guard lock(*m_mutex); return m_container.count(id) > 0; } template T& uf::ThreadUnique::get( id_t id ) { + std::lock_guard lock(*m_mutex); return m_container[id]; } +template +uf::ThreadUnique::mutex_type_t uf::ThreadUnique::getMutex( id_t id ) { + std::lock_guard lock(*m_mutex); + if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = std::make_shared(); + return m_mutex_container[id]; + } + template void uf::ThreadUnique::lockMutex( id_t id ) { - if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = new std::mutex; - m_mutex_container[id]->lock(); + getMutex( id )->lock(); } template bool uf::ThreadUnique::tryMutex( id_t id ) { - if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = new std::mutex; - return m_mutex_container[id]->try_lock(); + return getMutex( id )->try_lock(); } template void uf::ThreadUnique::unlockMutex( id_t id ) { - if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = new std::mutex; - m_mutex_container[id]->unlock(); + getMutex( id )->unlock(); } template std::lock_guard uf::ThreadUnique::guardMutex( id_t id ) { - if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = new std::mutex; - return std::lock_guard(*m_mutex_container[id]); + return std::lock_guard(*getMutex( id )); } template void uf::ThreadUnique::cleanup( id_t id ) { + std::lock_guard lock(*m_mutex); + for ( auto it = m_container.begin(); it != m_container.end(); ) { - if ( it->first == id ) ++it; - else it = m_container.erase(it); + if ( it->first == id ) it = m_container.erase(it); + else ++it; } for ( auto it = m_mutex_container.begin(); it != m_mutex_container.end(); ) { - if ( it->first == id ) ++it; - else { - delete it->second; - it = m_mutex_container.erase(it); - } + if ( it->first == id ) it = m_mutex_container.erase(it); + else ++it; } } template diff --git a/engine/src/engine/ext/ext.cpp b/engine/src/engine/ext/ext.cpp index 8d9f8cb5..a33b213e 100644 --- a/engine/src/engine/ext/ext.cpp +++ b/engine/src/engine/ext/ext.cpp @@ -376,11 +376,6 @@ void UF_API uf::load( ext::json::Value& json ) { } #endif -#if 0 && UF_USE_OPENVR - static auto* vrRenderMode = new ext::vulkan::VrRenderMode; - uf::renderer::addRenderMode(vrRenderMode, "VR"); -#endif - // shouldn't ever fire because the deferred rendermode is owned by the scene now if ( uf::renderer::hasRenderMode("", true) ) { auto& renderMode = uf::renderer::getRenderMode("", true); @@ -677,6 +672,10 @@ void UF_API uf::initialize() { ext::openvr::recommendedResolution( uf::renderer::settings::width, uf::renderer::settings::height ); UF_MSG_DEBUG("VR Resolution: {}, {}", uf::renderer::settings::width, uf::renderer::settings::height); } + + // could probably live alongside gui/deferred in the scene + static auto* vrRenderMode = new ext::vulkan::VrRenderMode; + uf::renderer::addRenderMode(vrRenderMode, "VR"); } #endif @@ -987,11 +986,6 @@ void UF_API uf::render() { // uf::renderer::tick(); uf::renderer::render(); } -#if UF_USE_OPENVR - if ( !uf::renderer::hasRenderMode("VR") ) { - ext::openvr::submit(); - } -#endif } void UF_API uf::terminate() { /* Kill threads */ { diff --git a/engine/src/engine/ext/gui/behavior.cpp b/engine/src/engine/ext/gui/behavior.cpp index 677e8028..de4480b1 100644 --- a/engine/src/engine/ext/gui/behavior.cpp +++ b/engine/src/engine/ext/gui/behavior.cpp @@ -243,10 +243,6 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { auto anchor = ::parseAnchor( metadata.anchor, metadata.pivot ) * 2.0f - 1.0f; transform.position.x += anchor.x; transform.position.y += anchor.y; - /* - transform.position.x += anchor.x * ((float) metadata.size.x / uf::renderer::settings::width) * transform.scale.x; - transform.position.y += anchor.y * ((float) metadata.size.y / uf::renderer::settings::height) * transform.scale.y; - */ } @@ -280,7 +276,11 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { if ( metadata.space != "screen" ) return; if ((metadata.boxMin.x > metadata.boxMax.x)||(metadata.boxMin.y > metadata.boxMax.y)) return; + #if UF_USE_OPENVR + pod::Vector2ui guiSize = uf::renderer::device.window->getSize(); + #else pod::Vector2ui guiSize = pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height }; + #endif bool clicked = false; if ( payload.mouse.state == -1 ) { @@ -372,7 +372,11 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { if ( metadata.space != "screen" ) return; if ((metadata.boxMin.x > metadata.boxMax.x)||(metadata.boxMin.y > metadata.boxMax.y)) return; + #if UF_USE_OPENVR + pod::Vector2ui guiSize = uf::renderer::device.window->getSize(); + #else pod::Vector2ui guiSize = pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height }; + #endif bool hovered = false; pod::Vector2f click; @@ -469,7 +473,11 @@ void ext::GuiBehavior::tick( uf::Object& self ) { auto& camera = controller.getComponent(); if ( metadata.space == "screen" ) { + #if UF_USE_OPENVR + pod::Vector2ui guiSize = uf::renderer::device.window->getSize(); + #else pod::Vector2f guiSize = pod::Vector2f{ uf::renderer::settings::width, uf::renderer::settings::height }; + #endif pod::Vector2f scale = { 1, 1 }; if ( metadata.scaling == "fixed" || metadata.scaling == "fixed-x" ) scale.x = (float) metadata.size.x / guiSize.x; diff --git a/engine/src/engine/ext/player/camera/behavior.cpp b/engine/src/engine/ext/player/camera/behavior.cpp index 79f802fc..1ce7e288 100644 --- a/engine/src/engine/ext/player/camera/behavior.cpp +++ b/engine/src/engine/ext/player/camera/behavior.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "../../scene/behavior.h" @@ -60,7 +61,13 @@ void ext::PlayerCameraBehavior::initialize( uf::Object& self ) { size = uf::vector::decode(uf::config["window"]["size"], pod::Vector2ui{}); raidou = (float) size.x / (float) size.y; } - camera.setProjection( uf::matrix::perspective( fov, raidou, range.x, range.y ) ); + + if ( ext::openvr::enabled ) { + camera.setProjection( ext::openvr::hmdProjectionMatrix(0, range.x, range.y), 0 ); + camera.setProjection( ext::openvr::hmdProjectionMatrix(1, range.x, range.y), 1 ); + } else { + camera.setProjection( uf::matrix::perspective( fov, raidou, range.x, range.y ) ); + } } camera.update(); diff --git a/engine/src/engine/scene/behavior.cpp b/engine/src/engine/scene/behavior.cpp index ba65c611..fb26a62f 100644 --- a/engine/src/engine/scene/behavior.cpp +++ b/engine/src/engine/scene/behavior.cpp @@ -25,9 +25,7 @@ void uf::SceneBehavior::initialize( uf::Object& self ) { }); uf::physics::initialize( self ); - UF_MSG_DEBUG("Initializing graph..."); uf::graph::initialize( self ); - UF_MSG_DEBUG("Initialized graph."); auto& metadata = this->getComponent(); } diff --git a/engine/src/ext/openvr/openvr.cpp b/engine/src/ext/openvr/openvr.cpp index 4d66ea52..0246e07c 100644 --- a/engine/src/ext/openvr/openvr.cpp +++ b/engine/src/ext/openvr/openvr.cpp @@ -408,7 +408,9 @@ bool ext::openvr::requestRenderModel( const uf::stl::string& name ) { return false; } void ext::openvr::submit() { - if ( !g_vr.system ) return; + if ( !g_vr.system ) { + return; + } #if UF_USE_VULKAN bool invert = g_vr.swapEyes; @@ -421,12 +423,16 @@ void ext::openvr::submit() { } else { renderModePointer = &uf::renderer::getRenderMode("", true); } - if ( !renderModePointer ) return; + if ( !renderModePointer ) { + return; + } auto& renderMode = *renderModePointer; float width = renderMode.width > 0 ? renderMode.width : uf::renderer::settings::width; float height = renderMode.height > 0 ? renderMode.height : uf::renderer::settings::height; - if ( !renderMode.hasAttachment("left") || !renderMode.hasAttachment("right") ) return; + if ( !renderMode.hasAttachment("left") || !renderMode.hasAttachment("right") ) { + return; + } auto& leftEyeAttachment = renderMode.getAttachment("left"); auto& rightEyeAttachment = renderMode.getAttachment("right"); @@ -452,19 +458,19 @@ void ext::openvr::submit() { vr::EVRCompositorError err; vulkanData.m_nFormat = leftEyeAttachment.descriptor.format; vulkanData.m_nImage = (uint64_t) (VkImage) leftEyeAttachment.image; - VR_CHECK_COMPOSITOR_RESULT(vr::VRCompositor()->Submit( invert ? vr::Eye_Right : vr::Eye_Left, &texture, &bounds )); + VR_CHECK_COMPOSITOR_RESULT(g_vr.compositor->Submit( invert ? vr::Eye_Right : vr::Eye_Left, &texture, &bounds )); vulkanData.m_nFormat = rightEyeAttachment.descriptor.format; vulkanData.m_nImage = (uint64_t) (VkImage) rightEyeAttachment.image; - VR_CHECK_COMPOSITOR_RESULT(vr::VRCompositor()->Submit( invert ? vr::Eye_Left : vr::Eye_Right, &texture, &bounds )); + VR_CHECK_COMPOSITOR_RESULT(g_vr.compositor->Submit( invert ? vr::Eye_Left : vr::Eye_Right, &texture, &bounds )); - vr::VRCompositor()->PostPresentHandoff(); + g_vr.compositor->PostPresentHandoff(); #endif } void ext::openvr::synchronize() { if ( !g_vr.system ) return; - vr::VRCompositor()->WaitGetPoses(nullptr, 0, nullptr, 0); + g_vr.compositor->WaitGetPoses(nullptr, 0, nullptr, 0); updateTracking(1); } float ext::openvr::predictedTimeToDisplay( float additional ) { @@ -545,6 +551,25 @@ pod::Matrix4t<> ext::openvr::hmdProjectionMatrix( vr::Hmd_Eye eye, float zNear, float idx = 1.0f / (right - left); float idy = 1.0f / (bottom - top); + m(0,0) = 2.0f * idx; + m(1,1) = -2.0f * idy; + m(0,2) = (right + left) * idx; + m(1,2) = -(bottom + top) * idy; + m(3,2) = 1.0f; + m(3,3) = 0.0f; + + if ( zFar <= 0.0f) { + m(2,2) = 0.0f; + m(2,3) = zNear; + } else { + float range = zFar - zNear; + m(2,2) = zFar / range; + m(2,3) = -(zFar * zNear) / range; + } +/* + float idx = 1.0f / (right - left); + float idy = 1.0f / (bottom - top); + m(0,0) = 2.0f * idx; m(1,1) = 2.0f * idy; m(0,2) = (right + left) * idx; @@ -560,6 +585,7 @@ pod::Matrix4t<> ext::openvr::hmdProjectionMatrix( vr::Hmd_Eye eye, float zNear, m(2,2) = zFar / range; m(2,3) = -(zFar * zNear) / range; } +*/ return m; } diff --git a/engine/src/ext/vulkan/device.cpp b/engine/src/ext/vulkan/device.cpp index 8fea4559..58ed727f 100644 --- a/engine/src/ext/vulkan/device.cpp +++ b/engine/src/ext/vulkan/device.cpp @@ -824,7 +824,7 @@ VkCommandPool ext::vulkan::Device::getCommandPool( ext::vulkan::QueueEnum queueE break; } UF_ASSERT( commandPool ); - auto guard = commandPool->guardMutex(); + auto guard = commandPool->guardMutex(id); bool exists = commandPool->has(id); VkCommandPool& pool = commandPool->get(id); if ( !exists ) { @@ -873,7 +873,7 @@ VkQueue ext::vulkan::Device::getQueue( ext::vulkan::QueueEnum queueEnum, std::th break; } UF_ASSERT( commandPool ); - auto guard = commandPool->guardMutex(); + auto guard = commandPool->guardMutex(id); bool exists = commandPool->has(id); VkQueue& queue = commandPool->get(id); if ( !exists ) { diff --git a/engine/src/ext/vulkan/rendermode.cpp b/engine/src/ext/vulkan/rendermode.cpp index 520d8a19..78dc00b4 100644 --- a/engine/src/ext/vulkan/rendermode.cpp +++ b/engine/src/ext/vulkan/rendermode.cpp @@ -259,7 +259,7 @@ ext::vulkan::RenderMode::commands_container_t& ext::vulkan::RenderMode::getComma commands.resize( swapchain.buffers ); VkCommandBufferAllocateInfo cmdBufAllocateInfo = ext::vulkan::initializers::commandBufferAllocateInfo( - device->getCommandPool(this->queueEnum), + device->getCommandPool(this->queueEnum, id), VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast(commands.size()) ); @@ -286,8 +286,11 @@ void ext::vulkan::RenderMode::cleanupAllCommands() { if ( pair.second.empty() ) continue; VkQueue queue = device->getQueue( queueEnum, pair.first ); + vkQueueWaitIdle( queue ); + /* VkResult res = vkWaitForFences( *device, fences.size(), fences.data(), VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT ); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); + */ for ( auto& commandBuffer : pair.second ) { uf::checkpoint::deallocate(device->checkpoints[commandBuffer]); @@ -306,9 +309,13 @@ void ext::vulkan::RenderMode::cleanupCommands( std::thread::id id ) { if ( pair.first == id ) continue; if ( pair.second.empty() ) continue; + VkQueue queue = device->getQueue( queueEnum, pair.first ); + vkQueueWaitIdle( queue ); + /* VkResult res = vkWaitForFences( *device, fences.size(), fences.data(), VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT ); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); + */ for ( auto& commandBuffer : pair.second ) { uf::checkpoint::deallocate(device->checkpoints[commandBuffer]); @@ -425,10 +432,11 @@ void ext::vulkan::RenderMode::initialize( Device& device ) { if ( std::find( metadata.pipelines.begin(), metadata.pipelines.end(), metadata.pipeline ) == metadata.pipelines.end() ) { metadata.pipelines.emplace_back(metadata.pipeline); } - +/* if ( !this->hasBuffer("camera") ) { this->metadata.buffers["camera"] = this->initializeBuffer( (const void*) nullptr, sizeof(pod::Camera::Viewports), uf::renderer::enums::Buffer::UNIFORM ); } +*/ } void ext::vulkan::RenderMode::build( bool resized ) { @@ -436,12 +444,10 @@ void ext::vulkan::RenderMode::build( bool resized ) { } void ext::vulkan::RenderMode::tick() { if ( ext::vulkan::states::resized || uf::renderer::states::rebuild || rebuild ) { - //if ( device ) vkDeviceWaitIdle(*device); + synchronize(); cleanupAllCommands(); } - //this->synchronize(); - if ( metadata.limiter.frequency > 0 ) { if ( metadata.limiter.timer > metadata.limiter.frequency ) { metadata.limiter.timer = 0; diff --git a/engine/src/ext/vulkan/rendermodes/base.cpp b/engine/src/ext/vulkan/rendermodes/base.cpp index 731a1484..fda52d53 100644 --- a/engine/src/ext/vulkan/rendermodes/base.cpp +++ b/engine/src/ext/vulkan/rendermodes/base.cpp @@ -9,6 +9,10 @@ #include #include +namespace { + uint32_t imageIndex; +} + const uf::stl::string ext::vulkan::BaseRenderMode::getType() const { return "Swapchain"; } @@ -109,12 +113,28 @@ void ext::vulkan::BaseRenderMode::tick() { this->build( resized ); } } +VkSubmitInfo ext::vulkan::BaseRenderMode::queue() { + auto& commands = getCommands( this->mostRecentCommandPoolId ); + + static VkPipelineStageFlags waitStageMask[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pWaitDstStageMask = waitStageMask; + submitInfo.pWaitSemaphores = &swapchain.presentCompleteSemaphores[states::currentBuffer]; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &renderCompleteSemaphores[::imageIndex]; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pCommandBuffers = &commands[states::currentBuffer]; + submitInfo.commandBufferCount = 1; + + return submitInfo; +} void ext::vulkan::BaseRenderMode::render() { // if ( this->commands.container().empty() ) return; - uint32_t imageIndex; VK_CHECK_RESULT(vkWaitForFences(*device, 1, &fences[states::currentBuffer], VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT)); - VK_CHECK_RESULT(swapchain.acquireNextImage(&imageIndex, swapchain.presentCompleteSemaphores[states::currentBuffer])); + VK_CHECK_RESULT(swapchain.acquireNextImage(&::imageIndex, swapchain.presentCompleteSemaphores[states::currentBuffer])); VK_CHECK_RESULT(vkResetFences(*device, 1, &fences[states::currentBuffer])); auto& commands = getCommands( this->mostRecentCommandPoolId ); @@ -200,7 +220,7 @@ void ext::vulkan::BaseRenderMode::render() { scissor.offset.x = 0; scissor.offset.y = 0; - renderPassBeginInfo.framebuffer = renderTarget.framebuffers[imageIndex]; + renderPassBeginInfo.framebuffer = renderTarget.framebuffers[::imageIndex]; VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::BEGIN, "begin" ); @@ -244,25 +264,14 @@ void ext::vulkan::BaseRenderMode::render() { VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); } - VkPipelineStageFlags waitStageMask[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = waitStageMask; - submitInfo.pWaitSemaphores = &swapchain.presentCompleteSemaphores[states::currentBuffer]; - submitInfo.waitSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &renderCompleteSemaphores[imageIndex]; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; - submitInfo.commandBufferCount = 1; - { + VkSubmitInfo submitInfo = this->queue(); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, fences[states::currentBuffer]); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); } - VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( QueueEnum::PRESENT ), imageIndex, renderCompleteSemaphores[imageIndex])); + VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( QueueEnum::PRESENT ), ::imageIndex, renderCompleteSemaphores[::imageIndex])); states::currentBuffer = (states::currentBuffer + 1) % ext::vulkan::swapchain.buffers; this->executed = true; diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index e66cef3c..662b9525 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -367,7 +367,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { shader.aliasAttachment("uv", this); shader.aliasAttachment("normal", this); #endif - shader.aliasAttachment("depth", this); + shader.aliasAttachment("depth", this, VK_IMAGE_LAYOUT_GENERAL); shader.aliasAttachment("color", this, VK_IMAGE_LAYOUT_GENERAL); shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL); @@ -415,7 +415,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { auto& shader = blitter.material.getShader("compute", "dof-down"); shader.aliasAttachment("color", this, VK_IMAGE_LAYOUT_GENERAL); - shader.aliasAttachment("depth_resolved", this); + shader.aliasAttachment("depth_resolved", this, VK_IMAGE_LAYOUT_GENERAL); shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL); // atomic counter buffer @@ -432,7 +432,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { auto& shader = blitter.material.getShader("compute", "dof-up"); shader.aliasAttachment("color", this, VK_IMAGE_LAYOUT_GENERAL); - shader.aliasAttachment("depth_resolved", this); + shader.aliasAttachment("depth_resolved", this, VK_IMAGE_LAYOUT_GENERAL); shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL); { @@ -449,7 +449,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { auto& shader = blitter.material.getShader("compute", "depth-pyramid"); - shader.aliasAttachment("depth_resolved", this); + shader.aliasAttachment("depth_resolved", this, VK_IMAGE_LAYOUT_GENERAL); // atomic counter buffer ::postprocesses::depthPyramid.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE | VK_BUFFER_USAGE_TRANSFER_DST_BIT ); @@ -617,6 +617,10 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) { if ( ext::openvr::enabled ) { auto descriptor = blitter.descriptor; descriptor.pipeline = "vr"; + descriptor.renderMode = "VR"; + descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS; + descriptor.depth.test = false; + descriptor.cullMode = uf::renderer::enums::CullMode::NONE; blitter.update( descriptor ); } } @@ -657,56 +661,33 @@ void ext::vulkan::DeferredRenderMode::tick() { } } VkSubmitInfo ext::vulkan::DeferredRenderMode::queue() { - //lockMutex( this->mostRecentCommandPoolId ); auto& commands = getCommands( this->mostRecentCommandPoolId ); - // Pipeline stage at which the queue submission will wait (via pWaitSemaphores) - static VkPipelineStageFlags waitStageMask[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - // The submit info structure specifices a command buffer queue submission batch + VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = waitStageMask; // Pointer to the list of pipeline stages that the semaphore waits will occur at - submitInfo.pWaitSemaphores = &swapchain.presentCompleteSemaphores[states::currentBuffer]; // Semaphore(s) to wait upon before the submitted command buffer starts executing - submitInfo.waitSemaphoreCount = 1; // One wait semaphore - submitInfo.pSignalSemaphores = &renderCompleteSemaphores[states::currentBuffer]; // Semaphore(s) to be signaled when command buffers have completed - submitInfo.signalSemaphoreCount = 1; // One signal semaphore - submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission) + submitInfo.pWaitDstStageMask = NULL; + submitInfo.pWaitSemaphores = NULL; + submitInfo.waitSemaphoreCount = 0; + submitInfo.pSignalSemaphores = NULL; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pCommandBuffers = &commands[states::currentBuffer]; submitInfo.commandBufferCount = 1; return submitInfo; } void ext::vulkan::DeferredRenderMode::render() { -// if ( this->executed ) return; - //lockMutex( this->mostRecentCommandPoolId ); if ( this->commands.container().empty() ) return; - - auto& commands = getCommands( this->mostRecentCommandPoolId ); VK_COMMAND_BUFFER_CALLBACK( EXECUTE_BEGIN, VkCommandBuffer{}, 0, {} ); - // Submit commands - // Use a fence to ensure that command buffer has finished executing before using it again - /* - VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[states::currentBuffer], VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT )); - VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[states::currentBuffer] )); - */ - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = NULL; // Pointer to the list of pipeline stages that the semaphore waits will occur at - submitInfo.pWaitSemaphores = NULL; // Semaphore(s) to wait upon before the submitted command buffer starts executing - submitInfo.waitSemaphoreCount = 0; // One wait semaphore - submitInfo.pSignalSemaphores = NULL; // Semaphore(s) to be signaled when command buffers have completed - submitInfo.signalSemaphoreCount = 0; // One signal semaphore - submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission) - submitInfo.commandBufferCount = 1; - -// VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer])); + VkSubmitInfo submitInfo = this->queue(); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE/*fences[states::currentBuffer]*/); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); + VK_COMMAND_BUFFER_CALLBACK( EXECUTE_END, VkCommandBuffer{}, 0, {} ); this->executed = true; - //unlockMutex( this->mostRecentCommandPoolId ); } void ext::vulkan::DeferredRenderMode::destroy() { forwardRenderTarget.destroy(); @@ -899,7 +880,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto clearRect.rect.offset = { 0, 0 }; clearRect.rect.extent = { width, height }; clearRect.baseArrayLayer = 0; - clearRect.layerCount = metadata.eyes > 0 ? metadata.eyes : 1; + clearRect.layerCount = 1; vkCmdClearAttachments(commandBuffer, 1, &clearDepth, 1, &clearRect); } @@ -1204,70 +1185,57 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto #endif } - /* - #if UF_USE_FFX_FSR || UF_USE_FFX_SDK - { - device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "fsr:start" ); - ext::fsr::render( commandBuffer ); - device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "fsr:end" ); - } - #endif - */ #if UF_USE_OPENVR - // OpenVR does not respect layered images - if ( metadata.eyes == 2 && !ext::vulkan::hasRenderMode("VR") ) { - auto& outputAttachment = this->getAttachment("left"); - auto& scratchAttachment = this->getAttachment("right"); + if ( metadata.eyes == 2 ) { + if ( ext::vulkan::hasRenderMode("VR") ) { + /* + // transition outputs + auto& outputAttachment = this->getAttachment("output"); - VkImageSubresourceRange outRange = {}; - outRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - outRange.baseMipLevel = 0; - outRange.levelCount = 1; - outRange.baseArrayLayer = 0; - outRange.layerCount = metadata.eyes; + VkImageSubresourceRange range = {}; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = metadata.eyes; - VkImageSubresourceRange scratchRange = outRange; - scratchRange.layerCount = 1; + uf::renderer::Texture::setImageLayout( commandBuffer, outputAttachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, range ); + */ + } else { + // OpenVR does not respect layered images + auto& outputAttachment = this->getAttachment("left"); + auto& scratchAttachment = this->getAttachment("right"); - uf::renderer::Texture::setImageLayout( - commandBuffer, outputAttachment.image, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // Or SHADER_READ_ONLY - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - outRange - ); - uf::renderer::Texture::setImageLayout( - commandBuffer, scratchAttachment.image, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - scratchRange - ); + VkImageSubresourceRange outRange = {}; + outRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + outRange.baseMipLevel = 0; + outRange.levelCount = 1; + outRange.baseArrayLayer = 0; + outRange.layerCount = metadata.eyes; - VkImageCopy copy = {}; - copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy.srcSubresource.baseArrayLayer = 1; - copy.srcSubresource.layerCount = 1; - copy.srcSubresource.mipLevel = 0; + VkImageSubresourceRange scratchRange = outRange; + scratchRange.layerCount = 1; - copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy.dstSubresource.baseArrayLayer = 0; - copy.dstSubresource.layerCount = 1; - copy.dstSubresource.mipLevel = 0; + uf::renderer::Texture::setImageLayout( commandBuffer, outputAttachment.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, outRange ); + uf::renderer::Texture::setImageLayout( commandBuffer, scratchAttachment.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, scratchRange ); - copy.extent = { width, height, 1 }; + VkImageCopy copy = {}; + copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy.srcSubresource.baseArrayLayer = 1; + copy.srcSubresource.layerCount = 1; + copy.srcSubresource.mipLevel = 0; - vkCmdCopyImage( - commandBuffer, - outputAttachment.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - scratchAttachment.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, © - ); + copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy.dstSubresource.baseArrayLayer = 0; + copy.dstSubresource.layerCount = 1; + copy.dstSubresource.mipLevel = 0; - uf::renderer::Texture::setImageLayout( - commandBuffer, scratchAttachment.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - scratchRange - ); + copy.extent = { width, height, 1 }; + + vkCmdCopyImage( commandBuffer, outputAttachment.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, scratchAttachment.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, © ); + + uf::renderer::Texture::setImageLayout( commandBuffer, scratchAttachment.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, scratchRange ); + } } #endif diff --git a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp index ff48b6b8..cbbaf8ce 100644 --- a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp @@ -213,7 +213,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { } } } - + #if UF_USE_OPENVR if ( ext::openvr::enabled && metadata.json["vr"].as() ) { uf::stl::string vertexShaderFilename = uf::io::resolveURI(::fmt::format("{}/shaders/display/vr/{}.vert.spv", uf::io::root, metadata.json["stereo"].as(metadata.views == 2) ? "stereo" : "flat")); uf::stl::string fragmentShaderFilename = uf::io::resolveURI(::fmt::format("{}/shaders/display/vr/{}.frag.spv", uf::io::root, metadata.json["stereo"].as(metadata.views == 2) ? "stereo" : "flat")); @@ -225,7 +225,18 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { auto& shader = blitter.material.getShader("fragment", "vr"); shader.aliasAttachment("color", this); } + + { + pod::Transform<> transform = {}; + transform.position = {0, 0, -3}; + transform.scale = { 1, -1, 1 }; + transform.orientation = {0, 0, 0, 1}; + metadata.camera.setTransform(transform); + metadata.camera.setProjection( ext::openvr::hmdProjectionMatrix(0, 0.001f, 0.0f), 0 ); + metadata.camera.setProjection( ext::openvr::hmdProjectionMatrix(1, 0.001f, 0.0f), 1 ); + } } + #endif } this->build(true); @@ -284,6 +295,10 @@ void ext::vulkan::RenderTargetRenderMode::build( bool resized ) { if ( ext::openvr::enabled && metadata.json["vr"].as() ) { auto descriptor = blitter.descriptor; descriptor.pipeline = "vr"; + descriptor.renderMode = "VR"; + descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS; + descriptor.depth.test = false; + descriptor.cullMode = uf::renderer::enums::CullMode::NONE; blitter.update( descriptor ); } } @@ -304,6 +319,14 @@ void ext::vulkan::RenderTargetRenderMode::tick() { if ( rebuild && blitter.process ) { this->build( resized ); } + + if ( ext::openvr::enabled && metadata.json["vr"].as() ) { + auto& shader = blitter.material.getShader("vertex", "vr"); + metadata.camera.update(); + if ( shader.hasUniform("UBO") ) { + shader.updateBuffer( (const void*) &metadata.camera.data().viewport, sizeof(pod::Camera::Viewports), shader.getUniformBuffer("UBO") ); + } + } } void ext::vulkan::RenderTargetRenderMode::destroy() { ext::vulkan::RenderMode::destroy(); @@ -312,20 +335,9 @@ void ext::vulkan::RenderTargetRenderMode::destroy() { void ext::vulkan::RenderTargetRenderMode::render() { if ( this->commands.container().empty() ) return; - auto& commands = getCommands( this->mostRecentCommandPoolId ); - VK_COMMAND_BUFFER_CALLBACK( EXECUTE_BEGIN, VkCommandBuffer{}, 0, {} ); - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = NULL; - submitInfo.pWaitSemaphores = NULL; - submitInfo.waitSemaphoreCount = 0; - submitInfo.pSignalSemaphores = NULL; - submitInfo.signalSemaphoreCount = 0; - submitInfo.pCommandBuffers = &commands[states::currentBuffer]; - submitInfo.commandBufferCount = 1; - + VkSubmitInfo submitInfo = this->queue(); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, /*VK_NULL_HANDLE*/fences[states::currentBuffer]); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); @@ -333,9 +345,6 @@ void ext::vulkan::RenderTargetRenderMode::render() { this->executed = true; } -void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer commandBuffer, uint8_t state ) { - ext::vulkan::RenderMode::pipelineBarrier( commandBuffer, state ); -} void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::vector& graphics ) { // destroy if exists uint32_t width = this->width > 0 ? this->width : (ext::vulkan::settings::width * this->scale); @@ -461,12 +470,27 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "renderPass[end]" ); vkCmdEndRenderPass(commandBuffer); } - // post-renderpass commands VK_COMMAND_BUFFER_CALLBACK( CALLBACK_END, commandBuffer, frame, { device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[end]" ); } ); + + #if 0 && UF_USE_OPENVR + if ( ext::vulkan::hasRenderMode("VR") ) { + // transition outputs + auto& outputAttachment = this->getAttachment("color"); + + VkImageSubresourceRange range = {}; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + + uf::renderer::Texture::setImageLayout( commandBuffer, outputAttachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, range ); + } + #endif } device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" ); VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); diff --git a/engine/src/ext/vulkan/rendermodes/transition.inl b/engine/src/ext/vulkan/rendermodes/transition.inl index 042a3aa2..5d94962e 100644 --- a/engine/src/ext/vulkan/rendermodes/transition.inl +++ b/engine/src/ext/vulkan/rendermodes/transition.inl @@ -1,3 +1,5 @@ +#include + namespace { void transitionAttachmentsTo( ext::vulkan::RenderMode* self, @@ -5,6 +7,8 @@ namespace { VkCommandBuffer commandBuffer, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { + uf::stl::unordered_set transitioned; + VkImageSubresourceRange subresourceRange; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; @@ -35,6 +39,10 @@ namespace { } } if ( image == VK_NULL_HANDLE ) continue; + + if ( transitioned.count(image) > 0 ) continue; + transitioned.insert(image); + bool isDepth = descriptor.name.starts_with("depth"); subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; @@ -57,6 +65,8 @@ namespace { VkCommandBuffer commandBuffer, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { + uf::stl::unordered_set transitioned; + VkImageSubresourceRange subresourceRange; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; @@ -87,6 +97,10 @@ namespace { } } if ( image == VK_NULL_HANDLE ) continue; + + if ( transitioned.count(image) > 0 ) continue; + transitioned.insert(image); + bool isDepth = descriptor.name.starts_with("depth"); subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; diff --git a/engine/src/ext/vulkan/rendermodes/vr.cpp b/engine/src/ext/vulkan/rendermodes/vr.cpp index c45b7673..df61b9e1 100644 --- a/engine/src/ext/vulkan/rendermodes/vr.cpp +++ b/engine/src/ext/vulkan/rendermodes/vr.cpp @@ -13,10 +13,6 @@ #include #include -namespace { - uf::Camera camera; -} - const uf::stl::string ext::vulkan::VrRenderMode::getType() const { return "VR"; } @@ -25,7 +21,7 @@ void ext::vulkan::VrRenderMode::initialize(Device& device) { uint32_t width = this->width > 0 ? this->width : (ext::vulkan::settings::width * this->scale); uint32_t height = this->height > 0 ? this->height : (ext::vulkan::settings::height * this->scale); - metadata.pipeline = "vr"; + metadata.pipeline = "vr"; ext::vulkan::RenderMode::initialize( device ); renderTarget.device = &device; @@ -160,8 +156,20 @@ void ext::vulkan::VrRenderMode::createCommandBuffers(const uf::stl::vectorblitter; if ( !blitter.initialized || !blitter.process ) continue; - UF_MSG_DEBUG("currentPass={}, frame={}, renderMode name={}, type={}", currentPass, frame, layer->getName(), layer->getType()); - ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(blitter.descriptor); + ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor; + descriptor.pipeline = "vr"; + descriptor.renderMode = this->getName(); + descriptor.bind.width = width; + descriptor.bind.height = height; + descriptor.bind.depth = 1; + descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS; + descriptor.subpass = 0; + descriptor.depth.test = false; + descriptor.inputs.vertex.count = 6; + descriptor.cullMode = uf::renderer::enums::CullMode::NONE; + + // to-do: transition attachment here + device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, ::fmt::format("blitter[{}: {}]", layer->getName(), layer->getType()) ); blitter.record(commandBuffer, descriptor, currentPass, currentDraw++, frame); } @@ -175,6 +183,22 @@ void ext::vulkan::VrRenderMode::createCommandBuffers(const uf::stl::vectorUF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[end]" ); } ); + + // transition attachments + { + auto& leftEyeAttachment = this->getAttachment("left"); + auto& rightEyeAttachment = this->getAttachment("right"); + + VkImageSubresourceRange range = {}; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + + uf::renderer::Texture::setImageLayout( commandBuffer, leftEyeAttachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, range ); + uf::renderer::Texture::setImageLayout( commandBuffer, rightEyeAttachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, range ); + } } device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" ); VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); @@ -211,9 +235,6 @@ void ext::vulkan::VrRenderMode::tick() { if ( rebuild && blitter.process ) { this->build( resized ); } - - ::camera.update(); - this->updateBuffer( (const void*) &::camera.data().viewport, sizeof(pod::Camera::Viewports), metadata.buffers["camera"] ); } void ext::vulkan::VrRenderMode::destroy() { @@ -227,15 +248,7 @@ void ext::vulkan::VrRenderMode::render() { VK_COMMAND_BUFFER_CALLBACK( EXECUTE_BEGIN, VkCommandBuffer{}, 0, {} ); - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = NULL; - submitInfo.pWaitSemaphores = NULL; - submitInfo.waitSemaphoreCount = 0; - submitInfo.pSignalSemaphores = NULL; - submitInfo.signalSemaphoreCount = 0; - submitInfo.pCommandBuffers = &commands[states::currentBuffer]; - submitInfo.commandBufferCount = 1; + VkSubmitInfo submitInfo = this->queue(); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, /*VK_NULL_HANDLE*/fences[states::currentBuffer]); diff --git a/engine/src/ext/vulkan/vulkan.cpp b/engine/src/ext/vulkan/vulkan.cpp index e65b1508..4ac8327e 100644 --- a/engine/src/ext/vulkan/vulkan.cpp +++ b/engine/src/ext/vulkan/vulkan.cpp @@ -597,7 +597,6 @@ void ext::vulkan::render() { uf::stl::vector submitsCompute; submitsCompute.reserve( auxRenderModes.size() ); // stuff we can batch -// auto tasks = uf::thread::schedule( settings::invariant::multithreadedRecording ); for ( auto renderMode : auxRenderModes ) { auto submitInfo = renderMode->queue(); if ( submitInfo.sType != VK_STRUCTURE_TYPE_SUBMIT_INFO ) continue; @@ -605,17 +604,12 @@ void ext::vulkan::render() { else submitsGraphics.emplace_back(submitInfo); renderMode->executed = true; -// tasks.queue([renderMode]{ - ext::vulkan::setCurrentRenderMode(renderMode); - if ( renderMode->getType() != "Swapchain" ) { - uf::scene::render(); - } - ext::vulkan::setCurrentRenderMode(NULL); -// }); + ext::vulkan::setCurrentRenderMode(renderMode); + if ( renderMode->getType() != "Swapchain" ) { + uf::scene::render(); + } + ext::vulkan::setCurrentRenderMode(NULL); } -// uf::thread::execute( tasks ); - -// ext::vulkan::flushCommandBuffers(); VK_CHECK_RESULT(vkWaitForFences(device, fences.size(), fences.data(), VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT)); VK_CHECK_RESULT(vkResetFences(device, fences.size(), fences.data())); @@ -646,7 +640,9 @@ void ext::vulkan::render() { } } else { for ( auto& renderMode : renderModes ) { - if ( !renderMode || !renderMode->execute || !renderMode->metadata.limiter.execute ) continue; + if ( !renderMode || !renderMode->execute || !renderMode->metadata.limiter.execute ) { + continue; + } #if UF_USE_FFX_FSR || UF_USE_FFX_SDK if ( renderMode->getType() == "Swapchain" && settings::pipelines::fsr && ext::fsr::initialized ) { @@ -655,6 +651,7 @@ void ext::vulkan::render() { } #endif + ext::vulkan::setCurrentRenderMode(renderMode); if ( renderMode->getType() != "Swapchain" ) { uf::scene::render(); @@ -665,6 +662,11 @@ void ext::vulkan::render() { } } + #if UF_USE_OPENVR + if ( ext::openvr::enabled ) { + ext::openvr::submit(); + } + #endif if ( ext::vulkan::settings::invariant::waitOnRenderEnd ) synchronize(); // if ( ext::openvr::context ) ext::openvr::postSubmit();