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
This commit is contained in:
parent
a98298b668
commit
c3e337bb87
@ -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 },
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -8,6 +8,7 @@ layout (location = 3) in vec2 inOffset;
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
uint aux;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -139,6 +139,6 @@ namespace pod {
|
||||
};
|
||||
|
||||
struct ImageStream {
|
||||
StreamRegion buffer;
|
||||
};
|
||||
StreamRegion buffer;
|
||||
};
|
||||
}
|
||||
@ -15,7 +15,7 @@ namespace ext {
|
||||
|
||||
template<typename T>
|
||||
sol::object getComponent( uf::Object& self ) {
|
||||
return sol::make_object(ext::lua::state, std::ref(self.getComponent<T>()));
|
||||
return sol::make_object(ext::lua::state, std::ref(self.getComponent<T>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <uf/utils/mesh/mesh.h>
|
||||
#include <uf/utils/image/image.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/ext/vulkan/device.h>
|
||||
#include <uf/ext/vulkan/buffer.h>
|
||||
#include <uf/ext/vulkan/texture.h>
|
||||
@ -40,7 +41,6 @@ namespace ext {
|
||||
uf::stl::string target = "";
|
||||
uf::stl::string pipeline = "";
|
||||
uf::stl::vector<uf::stl::string> pipelines;
|
||||
// uf::stl::vector<uint8_t> outputs;
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, uint8_t> attachments;
|
||||
uf::stl::unordered_map<uf::stl::string, uint8_t> buffers;
|
||||
@ -57,6 +57,7 @@ namespace ext {
|
||||
uint8_t views = 1;
|
||||
bool compute = false;
|
||||
|
||||
uf::Camera camera;
|
||||
} metadata;
|
||||
|
||||
Device* device = VK_NULL_HANDLE;
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
@ -15,7 +15,6 @@ namespace ext {
|
||||
virtual void tick();
|
||||
virtual void destroy();
|
||||
virtual void render();
|
||||
virtual void pipelineBarrier( VkCommandBuffer, uint8_t = -1 );
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ template <typename R, typename ... Args> constexpr bool return_void(R(Args ...))
|
||||
template <typename Signature> struct count_args;
|
||||
|
||||
template <typename Ret, typename... Args> struct count_args<std::function<Ret(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<decltype(&T::operator())> {};
|
||||
// for pointers to member function
|
||||
template <typename ClassType, typename ReturnType, typename... Args>
|
||||
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
|
||||
//enum { arity = sizeof...(Args) };
|
||||
static const size_t arguments = sizeof...(Args);
|
||||
template <size_t i>
|
||||
//enum { arity = sizeof...(Args) };
|
||||
static const size_t arguments = sizeof...(Args);
|
||||
template <size_t i>
|
||||
struct Arg {
|
||||
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
|
||||
};
|
||||
typedef ReturnType return_type;
|
||||
typedef std::function<ReturnType (Args...)> type;
|
||||
typedef ReturnType return_type;
|
||||
typedef std::function<ReturnType (Args...)> type;
|
||||
};
|
||||
|
||||
// for pointers to member function
|
||||
@ -34,8 +34,8 @@ struct function_traits<ReturnType(ClassType::*)(Args...) > {
|
||||
struct Arg {
|
||||
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
|
||||
};
|
||||
typedef ReturnType return_type;
|
||||
typedef std::function<ReturnType (Args...)> type;
|
||||
typedef ReturnType return_type;
|
||||
typedef std::function<ReturnType (Args...)> type;
|
||||
};
|
||||
|
||||
// for function pointers
|
||||
|
||||
@ -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 ) );\
|
||||
});\
|
||||
}
|
||||
|
||||
@ -32,18 +32,18 @@ namespace uf {
|
||||
namespace vfs {
|
||||
extern UF_API uf::stl::vector<pod::Mount> 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<uint8_t>& 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<uint8_t>& buffer );
|
||||
bool UF_API mkdir( const uf::stl::string& path );
|
||||
bool UF_API read( const uf::stl::string& path, uf::stl::vector<uint8_t>& 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<uint8_t>& 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<uint8_t>& buffer );
|
||||
bool UF_API readRanges( const uf::stl::string& path, const uf::stl::vector<pod::Range>& ranges, uf::stl::vector<uint8_t>& buffer );
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -122,8 +122,8 @@ template<typename T>
|
||||
pod::Transform<T> uf::transform::fromMatrix( const pod::Matrix4t<T>& matrix ) {
|
||||
pod::Transform<T> 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;
|
||||
}
|
||||
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
namespace uf {
|
||||
namespace stl {
|
||||
template<
|
||||
class T,
|
||||
#if UF_MEMORYPOOL_OVERRIDE_NEW_DELETE
|
||||
class Allocator = std::allocator<T>
|
||||
#else
|
||||
class Allocator = uf::Allocator<T>
|
||||
#endif
|
||||
class T,
|
||||
#if UF_MEMORYPOOL_OVERRIDE_NEW_DELETE
|
||||
class Allocator = std::allocator<T>
|
||||
#else
|
||||
class Allocator = uf::Allocator<T>
|
||||
#endif
|
||||
>
|
||||
using deque = std::deque<T, Allocator>;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
namespace uf {
|
||||
namespace stl {
|
||||
template<
|
||||
class T,
|
||||
class Container = uf::stl::deque<T>
|
||||
class T,
|
||||
class Container = uf::stl::deque<T>
|
||||
>
|
||||
using queue = std::queue<T, Container>;
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
namespace uf {
|
||||
namespace stl {
|
||||
template<
|
||||
class T,
|
||||
class Container = uf::stl::deque<T>
|
||||
class T,
|
||||
class Container = uf::stl::deque<T>
|
||||
>
|
||||
using stack = std::stack<T, Container>;
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/utils/memory/map.h>
|
||||
#include <memory>
|
||||
#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<std::mutex> mutex_type_t;
|
||||
typedef std::thread::id id_t;
|
||||
typedef uf::stl::unordered_map<id_t, type_t> container_t;
|
||||
typedef uf::stl::unordered_map<id_t, mutex_type_t> mutex_container_t;
|
||||
typedef uf::stl::map<id_t, type_t> container_t;
|
||||
typedef uf::stl::map<id_t, mutex_type_t> 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<std::mutex>()) {}
|
||||
|
||||
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() );
|
||||
|
||||
@ -1,52 +1,47 @@
|
||||
template<typename T>
|
||||
uf::ThreadUnique<T>::~ThreadUnique() {
|
||||
for ( auto& pair : m_mutex_container ) {
|
||||
if ( !pair.second ) continue;
|
||||
delete pair.second;
|
||||
pair.second = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool uf::ThreadUnique<T>::has( id_t id ) const {
|
||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
||||
return m_container.count(id) > 0;
|
||||
}
|
||||
template<typename T>
|
||||
T& uf::ThreadUnique<T>::get( id_t id ) {
|
||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
||||
return m_container[id];
|
||||
}
|
||||
template<typename T>
|
||||
uf::ThreadUnique<T>::mutex_type_t uf::ThreadUnique<T>::getMutex( id_t id ) {
|
||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
||||
if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = std::make_shared<std::mutex>();
|
||||
return m_mutex_container[id];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void uf::ThreadUnique<T>::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<typename T>
|
||||
bool uf::ThreadUnique<T>::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<typename T>
|
||||
void uf::ThreadUnique<T>::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<typename T>
|
||||
std::lock_guard<std::mutex> uf::ThreadUnique<T>::guardMutex( id_t id ) {
|
||||
if ( m_mutex_container.count(id) == 0 ) m_mutex_container[id] = new std::mutex;
|
||||
return std::lock_guard<std::mutex>(*m_mutex_container[id]);
|
||||
return std::lock_guard<std::mutex>(*getMutex( id ));
|
||||
}
|
||||
template<typename T>
|
||||
void uf::ThreadUnique<T>::cleanup( id_t id ) {
|
||||
std::lock_guard<std::mutex> 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<typename T>
|
||||
|
||||
@ -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 */ {
|
||||
|
||||
@ -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<uf::Camera>();
|
||||
|
||||
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;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <uf/utils/math/physics.h>
|
||||
#include <uf/spec/controller/controller.h>
|
||||
#include <uf/utils/io/inputs.h>
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
|
||||
#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();
|
||||
|
||||
|
||||
@ -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<uf::SceneBehavior::Metadata>();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
@ -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<uint32_t>(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;
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/utils/io/fmt.h>
|
||||
|
||||
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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -213,7 +213,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UF_USE_OPENVR
|
||||
if ( ext::openvr::enabled && metadata.json["vr"].as<bool>() ) {
|
||||
uf::stl::string vertexShaderFilename = uf::io::resolveURI(::fmt::format("{}/shaders/display/vr/{}.vert.spv", uf::io::root, metadata.json["stereo"].as<bool>(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<bool>(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<bool>() ) {
|
||||
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<bool>() ) {
|
||||
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<ext::vulkan::Graphic*>& 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));
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#include <uf/utils/memory/unordered_set.h>
|
||||
|
||||
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<VkImage> 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<VkImage> 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;
|
||||
|
||||
@ -13,10 +13,6 @@
|
||||
#include <uf/utils/io/fmt.h>
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
|
||||
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::vector<ext::
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
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::vector<ext::
|
||||
VK_COMMAND_BUFFER_CALLBACK( CALLBACK_END, commandBuffer, frame, {
|
||||
device->UF_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]);
|
||||
|
||||
@ -597,7 +597,6 @@ void ext::vulkan::render() {
|
||||
uf::stl::vector<VkSubmitInfo> 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();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user