managed to fix the disgusting icky input lag at specific frametimes (because the swapchain was rendering to the wrong frame for presentation), attempting to fix a regression with shadowmaps being icky
This commit is contained in:
parent
8aee000b05
commit
7034da71de
@ -2,7 +2,6 @@
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "StartMenu",
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"lights": { "enabled": true,
|
||||
"lightmaps": false,
|
||||
"max": 32,
|
||||
@ -10,7 +9,7 @@
|
||||
"enabled": true,
|
||||
"update": 4,
|
||||
"max": 16,
|
||||
"samples": 2
|
||||
"samples": 1
|
||||
},
|
||||
"bloom": {
|
||||
"scale": 1.0,
|
||||
@ -109,19 +108,19 @@
|
||||
"invariant": {
|
||||
"default stage buffers": true,
|
||||
"default defer buffer destroy": true,
|
||||
"default command buffer immediate": false,
|
||||
"n-buffered uniform": false,
|
||||
"multithreaded recording": true
|
||||
"default command buffer immediate": true,
|
||||
"n-buffered uniform": true,
|
||||
"multithreaded recording": false
|
||||
},
|
||||
"pipelines": {
|
||||
"deferred": true,
|
||||
"gui": true,
|
||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||
"vsync": false, // vsync on vulkan side rather than engine-side
|
||||
"hdr": true,
|
||||
"vxgi": true, // to-do: fix issues
|
||||
"vxgi": false, // to-do: fix issues
|
||||
"culling": false,
|
||||
"bloom": true,
|
||||
"dof": true,
|
||||
"bloom": false,
|
||||
"dof": false,
|
||||
"rt": false,
|
||||
"fsr": false,
|
||||
"postProcess": false // "postProcess.chromab" // false
|
||||
|
||||
@ -24,8 +24,8 @@
|
||||
"power": 100,
|
||||
"fov": 90,
|
||||
"bias": {
|
||||
"constant": 1.25,
|
||||
"slope": 1.75,
|
||||
"constant": -1.25,
|
||||
"slope": -1.75,
|
||||
"shader": 0.00001 // 0.000005 //0.000000005
|
||||
},
|
||||
"radius": [0.5, 0],
|
||||
|
||||
@ -113,7 +113,7 @@
|
||||
"settings": {
|
||||
"fixed": false,
|
||||
"fov" : 90.0,
|
||||
"clip" : [ 0.1, 64.0 ],
|
||||
"clip" : [ 0.1, 0 ],
|
||||
"size" : [ 0, 0 ]
|
||||
}
|
||||
},
|
||||
|
||||
@ -56,13 +56,10 @@ float omniShadowMap( const Light light, float def ) {
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z < -1 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
const float eyeDepthScale = 1.0;
|
||||
const float sampledDepthScale = light.view[1][1]; // light view matricies will incorporate scaling factors for some retarded reason, so we need to rescale it by grabbing from here, hopefully it remains coherent between all light matrices to ever exist in engine
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
const float bias = light.depthBias;
|
||||
const float eyeDepth = abs(positionClip.z / positionClip.w) * eyeDepthScale;
|
||||
const float eyeDepth = abs(positionClip.z / positionClip.w);
|
||||
|
||||
const vec3 sampleOffsetDirections[20] = {
|
||||
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||
@ -77,13 +74,13 @@ float omniShadowMap( const Light light, float def ) {
|
||||
// cubemap point light
|
||||
if ( light.typeMap == 1 ) {
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D).r * sampledDepthScale;
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D).r ;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
vec2 poisson = poissonDisk[idx] / 700.0;
|
||||
vec3 P = vec3( poisson.xy, (poisson.x + poisson.y) * 0.5 );
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D + P ).r * sampledDepthScale;
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D + P ).r ;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
@ -92,11 +89,11 @@ float omniShadowMap( const Light light, float def ) {
|
||||
} else if ( light.typeMap == 2 ) {
|
||||
const vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv).r * sampledDepthScale;
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv).r ;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv + poissonDisk[idx] / 700.0 ).r * sampledDepthScale;
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv + poissonDisk[idx] / 700.0 ).r ;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
|
||||
@ -188,6 +188,7 @@ struct Surface {
|
||||
|
||||
vec4 light;
|
||||
vec4 fragment;
|
||||
vec2 fragCoord;
|
||||
} surface;
|
||||
|
||||
// MSAA info
|
||||
|
||||
@ -63,7 +63,7 @@ layout( push_constant ) uniform PushBlock {
|
||||
#include "../../../common/structs.h"
|
||||
|
||||
layout (binding = 11, set = 0) uniform Camera {
|
||||
Viewport viewport[2];
|
||||
Viewport viewport[6];
|
||||
} camera;
|
||||
|
||||
layout (binding = 12, set = 0) uniform UBO {
|
||||
@ -165,7 +165,6 @@ void postProcess() {
|
||||
|
||||
if ( ubo.settings.mode.type > 0x0000 ) {
|
||||
uvec2 renderSize = imageSize(imageColor).xy;
|
||||
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
|
||||
if ( true ) {
|
||||
// if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.barycentric.rgb, 1);
|
||||
if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.material.albedo.rgb, 1);
|
||||
@ -189,6 +188,7 @@ void populateSurface() {
|
||||
const uvec2 renderSize = imageSize(imageColor).xy;
|
||||
if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y /*|| gl_GlobalInvocationID.z > PushConstant.pass*/ ) return;
|
||||
|
||||
surface.fragCoord = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
|
||||
surface.pass = gl_GlobalInvocationID.z;
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
@ -200,7 +200,6 @@ void populateSurface() {
|
||||
|
||||
float depth = 0.0;
|
||||
{
|
||||
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
|
||||
|
||||
#if USE_CAMERA_VIEWPORT
|
||||
const mat4 iProjection = inverse( camera.viewport[surface.pass].projection );
|
||||
@ -211,8 +210,8 @@ void populateSurface() {
|
||||
const mat4 iProjection = ubo.eyes[surface.pass].iProjection;
|
||||
const mat4 iProjectionView = /*iProjection * iView;*/ inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) );
|
||||
#endif
|
||||
const vec4 near4 = iProjectionView * (vec4(inUv, -1.0, 1.0));
|
||||
const vec4 far4 = iProjectionView * (vec4(inUv, 1.0, 1.0));
|
||||
const vec4 near4 = iProjectionView * (vec4(surface.fragCoord, -1.0, 1.0));
|
||||
const vec4 far4 = iProjectionView * (vec4(surface.fragCoord, 1.0, 1.0));
|
||||
const vec3 near3 = near4.xyz / near4.w;
|
||||
const vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
@ -221,7 +220,7 @@ void populateSurface() {
|
||||
|
||||
depth = IMAGE_LOAD(samplerDepth).r;
|
||||
|
||||
vec4 eye = iProjection * vec4(inUv, depth, 1.0);
|
||||
vec4 eye = iProjection * vec4(surface.fragCoord, depth, 1.0);
|
||||
eye /= eye.w;
|
||||
|
||||
surface.position.eye = eye.xyz;
|
||||
|
||||
@ -22,7 +22,7 @@ layout( push_constant ) uniform PushBlock {
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
Viewport viewport[6];
|
||||
} camera;
|
||||
|
||||
layout (std140, binding = 1) readonly buffer DrawCommands {
|
||||
|
||||
@ -17,6 +17,7 @@ namespace ext {
|
||||
0
|
||||
};
|
||||
VkDeviceSize alignment = 0;
|
||||
VkDeviceSize stride = 0;
|
||||
void* mapped = nullptr;
|
||||
mutable size_t address = {};
|
||||
mutable bool written = false; // could technically be deduced with the address being set
|
||||
|
||||
@ -8,6 +8,9 @@
|
||||
|
||||
#define UF_GRAPHIC_POINTERED_USERDATA 1
|
||||
|
||||
#define IS_DYNAMIC(name) true
|
||||
// name.ends_with("_d")
|
||||
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
#if UF_GRAPHIC_POINTERED_USERDATA
|
||||
|
||||
@ -21,8 +21,8 @@ namespace pod {
|
||||
pod::Matrix4f view;
|
||||
pod::Matrix4f projection;
|
||||
} matrices[uf::camera::maxViews];
|
||||
size_t views = 1;
|
||||
} viewport;
|
||||
size_t views = 1;
|
||||
bool stereoscopic = false;
|
||||
};
|
||||
}
|
||||
|
||||
@ -486,86 +486,27 @@ pod::Matrix4t<T> /*UF_API*/ uf::matrix::orthographic( T l, T r, T b, T t ) {
|
||||
}
|
||||
template<typename T>
|
||||
pod::Matrix4t<T> /*UF_API*/ uf::matrix::perspective( T fov, T raidou, T znear, T zfar ) {
|
||||
if (uf::matrix::reverseInfiniteProjection) {
|
||||
T f = static_cast<T>(1) / tan(static_cast<T>(0.5) * fov);
|
||||
#if UF_USE_OPENGL
|
||||
pod::Matrix4t<T> m = uf::matrix::identity<T>();
|
||||
m(0,0) = f / raidou;
|
||||
m(1,1) = f;
|
||||
m(2,2) = 0;
|
||||
m(2,3) = znear;
|
||||
m(3,2) = 1;
|
||||
m(3,3) = 0;
|
||||
return m;
|
||||
#elif UF_USE_VULKAN
|
||||
pod::Matrix4t<T> m = uf::matrix::identity<T>();
|
||||
m(0,0) = f / raidou;
|
||||
m(1,1) = -f; // Vulkan flips Y
|
||||
m(2,2) = 0;
|
||||
m(2,3) = znear;
|
||||
m(3,2) = 1;
|
||||
m(3,3) = 0;
|
||||
return m;
|
||||
#endif
|
||||
} else {
|
||||
T range = znear - zfar;
|
||||
T f = tan(static_cast<T>(0.5) * fov);
|
||||
pod::Matrix4t<T> m = uf::matrix::identity<T>();
|
||||
|
||||
T Sx = static_cast<T>(1) / (f * raidou);
|
||||
T Sy = static_cast<T>(1) / f;
|
||||
T Sz = (zfar + znear) / range;
|
||||
T Pz = (static_cast<T>(2) * zfar * znear) / range;
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
Sy = -Sy; // Vulkan NDC has inverted Y
|
||||
#endif
|
||||
|
||||
pod::Matrix4t<T> m = uf::matrix::identity<T>();
|
||||
m(0,0) = Sx;
|
||||
m(1,1) = Sy;
|
||||
m(2,2) = Sz;
|
||||
m(2,3) = Pz;
|
||||
m(3,2) = -1;
|
||||
m(3,3) = 0;
|
||||
return m;
|
||||
}
|
||||
#if 0
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
T f = static_cast<T>(1) / tan( static_cast<T>(0.5) * fov );
|
||||
#if UF_USE_OPENGL
|
||||
return pod::Matrix4t<T>({
|
||||
f / raidou, 0, 0, 0,
|
||||
0, f, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
0, 0, znear, 0
|
||||
});
|
||||
#elif UF_USE_VULKAN
|
||||
return pod::Matrix4t<T>({
|
||||
f / raidou, 0, 0, 0,
|
||||
0, -f, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
0, 0, znear, 0
|
||||
});
|
||||
#endif
|
||||
} else {
|
||||
T range = znear - zfar;
|
||||
T f = tan( static_cast<T>(0.5) * fov );
|
||||
|
||||
T Sx = static_cast<T>(1) / (f * raidou);
|
||||
T Sy = static_cast<T>(1) / f;
|
||||
T Sz = (-znear - zfar) / range;
|
||||
T Pz = static_cast<T>(2) * zfar * znear / range;
|
||||
#if UF_USE_VULKAN
|
||||
Sy = -Sy;
|
||||
#endif
|
||||
return pod::Matrix4t<T>({
|
||||
Sx, 0, 0, 0,
|
||||
0, Sy, 0, 0,
|
||||
0, 0, Sz, 1,
|
||||
0, 0, Pz, 0
|
||||
});
|
||||
}
|
||||
T f = static_cast<T>(1) / tan(static_cast<T>(0.5) * fov);
|
||||
m(0,0) = f / raidou;
|
||||
m(1,1) = f;
|
||||
#if UF_USE_VULKAN
|
||||
m(1,1) = -f;
|
||||
#endif
|
||||
m(3,2) = 1;
|
||||
m(3,3) = 0;
|
||||
|
||||
if ( zfar <= 0 ) {
|
||||
m(2,2) = 0;
|
||||
m(2,3) = znear;
|
||||
} else {
|
||||
T range = zfar - znear;
|
||||
m(2,2) = zfar / range;
|
||||
m(2,3) = -(zfar * znear) / range;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
template<typename T> T& uf::matrix::copy( T& destination, const T& source ) {
|
||||
FOR_EACH(T::rows * T::columns, {
|
||||
|
||||
@ -453,6 +453,8 @@ namespace ext {
|
||||
bool test = true;
|
||||
bool write = true;
|
||||
uf::renderer::enums::Compare::type_t operation = uf::renderer::enums::Compare::GREATER_OR_EQUAL;
|
||||
float min = 1.0f;
|
||||
float max = 0.0f;
|
||||
struct {
|
||||
bool enable = false;
|
||||
float constant = 0;
|
||||
|
||||
@ -93,7 +93,6 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
} else {
|
||||
size = pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height };
|
||||
}
|
||||
if ( radius.y < radius.x ) radius.y = 2048;
|
||||
camera.setProjection( uf::matrix::perspective( fov, (float) size.x / (float) size.y, radius.x, radius.y ) );
|
||||
camera.update();
|
||||
|
||||
@ -218,7 +217,7 @@ void ext::LightBehavior::tick( uf::Object& self ) {
|
||||
if ( /*renderMode.execute*/ renderMode.metadata.limiter.execute && !metadata.renderer.external ) {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& pod = camera.data();
|
||||
pod.viewport.views = 6;
|
||||
pod.views = 6;
|
||||
// omni light
|
||||
if ( metadata.shadows && std::abs(metadata.type) == 1 ) {
|
||||
auto transform = camera.getTransform();
|
||||
|
||||
@ -13,6 +13,7 @@ namespace ext {
|
||||
EXT_BEHAVIOR_DEFINE_FUNCTIONS();
|
||||
UF_BEHAVIOR_DEFINE_METADATA(
|
||||
pod::Vector3f color = {1,1,1};
|
||||
pod::Vector2f radius = { 0.001f, 32.0f };
|
||||
float power = 0.0f;
|
||||
float bias = 0.0f;
|
||||
bool shadows = false;
|
||||
|
||||
@ -560,7 +560,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
LightInfo& info = entities.emplace_back(LightInfo{
|
||||
.entity = entity,
|
||||
.position = flatten.position,
|
||||
.range = 0,
|
||||
.range = MAX(metadata.radius.x, metadata.radius.y),
|
||||
.color = metadata.color,
|
||||
.intensity = metadata.power,
|
||||
.distance = uf::vector::magnitude( uf::vector::subtract( flatten.position, controllerTransform.position ) ),
|
||||
@ -1265,9 +1265,11 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
|
||||
|
||||
// trigger an update when we have differing bound texture sizes
|
||||
bool shouldUpdate = metadata.shader.invalidated || graphic.material.textures.size() != previousTextures.size();
|
||||
/*
|
||||
for ( uint32_t i = 0; !shouldUpdate && i < previousTextures.size() && i < graphic.material.textures.size(); ++i ) {
|
||||
if ( previousTextures[i] != graphic.material.textures[i].image ) shouldUpdate = true;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ( shouldUpdate ) {
|
||||
// graphic.updatePipelines();
|
||||
|
||||
@ -208,7 +208,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
|
||||
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||
for ( auto& t : sceneTextures.voxels.outputMipmaps ) shader.textures.emplace_back().aliasTexture(t);
|
||||
|
||||
metadata.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE );
|
||||
metadata.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE | VK_BUFFER_USAGE_TRANSFER_DST_BIT );
|
||||
shader.aliasBuffer("atomicCounter", metadata.atomicCounter);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -723,11 +723,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
|
||||
if ( mode == "cw" ) graphic.descriptor.frontFace = uf::renderer::enums::Face::CW;
|
||||
else if ( mode == "ccw" ) graphic.descriptor.frontFace = uf::renderer::enums::Face::CCW;
|
||||
else if ( mode == "auto" ) {
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
graphic.descriptor.frontFace = graphMetadataJson["renderer"]["invert"].as<bool>(true) ? uf::renderer::enums::Face::CW : uf::renderer::enums::Face::CCW;
|
||||
} else {
|
||||
graphic.descriptor.frontFace = graphMetadataJson["renderer"]["invert"].as<bool>(true) ? uf::renderer::enums::Face::CW : uf::renderer::enums::Face::CCW;
|
||||
}
|
||||
graphic.descriptor.frontFace = graphMetadataJson["renderer"]["invert"].as<bool>(true) ? uf::renderer::enums::Face::CW : uf::renderer::enums::Face::CCW;
|
||||
}
|
||||
else UF_MSG_WARNING("Invalid Face enum string specified: {}", mode);
|
||||
}
|
||||
@ -1358,12 +1354,21 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
#else
|
||||
metadata.system.ignoreGraph = graphMetadataJson["debug"]["static"].as<bool>();
|
||||
#endif
|
||||
float powerScale = graphMetadataJson["lights"]["scale"].as<float>(1);
|
||||
const float LIGHT_POWER_CUTOFF = 0.005f;
|
||||
float power = l.intensity * graphMetadataJson["lights"]["scale"].as<float>(1);
|
||||
float range = l.range;
|
||||
if ( range <= 0.0f ) {
|
||||
if ( power > LIGHT_POWER_CUTOFF ) {
|
||||
range = std::sqrt( (power / LIGHT_POWER_CUTOFF) - 1.0f );
|
||||
} else {
|
||||
range = 0.001f;
|
||||
}
|
||||
}
|
||||
|
||||
uf::Serializer metadataLight;
|
||||
metadataLight["radius"][0] = 0.001;
|
||||
metadataLight["radius"][1] = l.range;
|
||||
metadataLight["power"] = l.intensity * powerScale;
|
||||
metadataLight["radius"][0] = range;
|
||||
metadataLight["radius"][1] = 0.001;
|
||||
metadataLight["power"] = power;
|
||||
|
||||
metadataLight["color"][0] = l.color.x;
|
||||
metadataLight["color"][1] = l.color.y;
|
||||
@ -1375,10 +1380,11 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
if ( uf::string::matched( node.name, R"(/\bspot\b/)" ) ) {
|
||||
metadataLight["type"] = "spot";
|
||||
}
|
||||
|
||||
/*
|
||||
if ( ext::json::isArray( graphMetadataJson["lights"]["radius"] ) ) {
|
||||
metadataLight["radius"] = graphMetadataJson["lights"]["radius"];
|
||||
}
|
||||
*/
|
||||
if ( graphMetadataJson["lights"]["bias"].is<float>() ) {
|
||||
metadataLight["bias"] = graphMetadataJson["lights"]["bias"].as<float>();
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ void ext::vulkan::Buffer::swap( ext::vulkan::Buffer& buffer ) {
|
||||
std::swap(this->memory, buffer.memory);
|
||||
std::swap(this->descriptor, buffer.descriptor);
|
||||
std::swap(this->alignment, buffer.alignment);
|
||||
std::swap(this->stride, buffer.stride);
|
||||
std::swap(this->address, buffer.address);
|
||||
std::swap(this->mapped, buffer.mapped);
|
||||
std::swap(this->usage, buffer.usage);
|
||||
@ -37,6 +38,7 @@ void ext::vulkan::Buffer::aliasBuffer( const ext::vulkan::Buffer& buffer ) {
|
||||
this->memory = buffer.memory;
|
||||
this->descriptor = buffer.descriptor;
|
||||
this->alignment = buffer.alignment;
|
||||
this->stride = buffer.alignment;
|
||||
this->address = buffer.address;
|
||||
this->mapped = buffer.mapped;
|
||||
this->usage = buffer.usage;
|
||||
@ -91,7 +93,7 @@ size_t ext::vulkan::Buffer::getLength( ) const {
|
||||
return allocationInfo.size;
|
||||
}
|
||||
size_t ext::vulkan::Buffer::getOffset( size_t i ) const {
|
||||
return this->getLength() / this->count * i;
|
||||
return this->stride * i;
|
||||
}
|
||||
|
||||
ext::vulkan::Buffer::~Buffer() {
|
||||
@ -117,6 +119,7 @@ void ext::vulkan::Buffer::destroy(bool defer) {
|
||||
this->memory = {};
|
||||
this->descriptor = {};
|
||||
// this->alignment = {};
|
||||
this->stride = {};
|
||||
this->address = {};
|
||||
this->mapped = {};
|
||||
// this->usage = {};
|
||||
@ -132,11 +135,12 @@ void ext::vulkan::Buffer::initialize( const void* data, VkDeviceSize length, VkB
|
||||
if ( this->staged ) usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; // implicitly set properties
|
||||
|
||||
// assume all UBOs are dynamic
|
||||
auto totalLength = length;
|
||||
auto totalLength = (this->stride = length);
|
||||
if ( VK_UBO_USE_N_BUFFERS && usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
|
||||
this->count = ext::vulkan::swapchain.buffers;
|
||||
this->alignment = device->properties.limits.minUniformBufferOffsetAlignment;
|
||||
totalLength = ALIGNED_SIZE( length, this->alignment ) * this->count;
|
||||
this->stride = ALIGNED_SIZE( length, this->alignment );
|
||||
totalLength = this->stride * this->count;
|
||||
}
|
||||
VK_CHECK_RESULT(device->createBuffer( nullptr, totalLength, usage, memoryProperties, *this ));
|
||||
|
||||
|
||||
@ -323,15 +323,8 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
descriptor.depth.write,
|
||||
descriptor.depth.operation
|
||||
);
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
depthStencilState.depthCompareOp = ext::vulkan::enums::Compare::GREATER_OR_EQUAL;
|
||||
depthStencilState.minDepthBounds = 1.0f;
|
||||
depthStencilState.maxDepthBounds = 0.0f;
|
||||
} else {
|
||||
depthStencilState.depthCompareOp = ext::vulkan::enums::Compare::LESS;
|
||||
depthStencilState.minDepthBounds = 0.0f;
|
||||
depthStencilState.maxDepthBounds = 1.0f;
|
||||
}
|
||||
depthStencilState.minDepthBounds = descriptor.depth.min;
|
||||
depthStencilState.maxDepthBounds = descriptor.depth.max;
|
||||
VkPipelineViewportStateCreateInfo viewportState = ext::vulkan::initializers::pipelineViewportStateCreateInfo(
|
||||
1, 1, 0
|
||||
);
|
||||
@ -532,6 +525,7 @@ void ext::vulkan::DescriptorSets::record( const Graphic& graphic, const GraphicD
|
||||
|
||||
// create dynamic offset ranges
|
||||
STATIC_THREAD_LOCAL(uf::stl::vector<uint32_t>, dynamicOffsets);
|
||||
static thread_local std::map<uint32_t, uint32_t> bindingStrides; bindingStrides.clear();
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
|
||||
|
||||
@ -556,14 +550,19 @@ void ext::vulkan::DescriptorSets::record( const Graphic& graphic, const GraphicD
|
||||
if ( descriptor.bind.point == VK_PIPELINE_BIND_POINT_GRAPHICS ) bound = true;
|
||||
else continue;
|
||||
}
|
||||
|
||||
if ( VK_UBO_USE_N_BUFFERS )
|
||||
dynamicOffsets.insert( dynamicOffsets.end(), shader->metadata.dynamicRanges.begin(), shader->metadata.dynamicRanges.end() );
|
||||
|
||||
if ( VK_UBO_USE_N_BUFFERS ) {
|
||||
for ( const auto& [name, uniform] : shader->metadata.definitions.uniforms ) {
|
||||
if ( IS_DYNAMIC(name) ) {
|
||||
bindingStrides[uniform.binding] = uniform.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto& dynamicOffset : dynamicOffsets ) {
|
||||
dynamicOffset *= offset;
|
||||
}
|
||||
for ( const auto& [binding, stride] : bindingStrides ) {
|
||||
dynamicOffsets.emplace_back( stride * offset );
|
||||
}
|
||||
|
||||
// no matching bind point for shaders, skip
|
||||
if ( !bound ) {
|
||||
@ -2152,7 +2151,7 @@ void ext::vulkan::GraphicDescriptor::parse( ext::json::Value& metadata ) {
|
||||
else if ( metadata["cull mode"].as<uf::stl::string>() == "none" ) cullMode = VK_CULL_MODE_NONE;
|
||||
else if ( metadata["cull mode"].as<uf::stl::string>() == "both" ) cullMode = VK_CULL_MODE_FRONT_AND_BACK;
|
||||
}
|
||||
|
||||
// to-do: probably parse depth op/min/max
|
||||
if ( ext::json::isObject(metadata["depth bias"]) ) {
|
||||
depth.bias.enable = VK_TRUE;
|
||||
depth.bias.constant = metadata["depth bias"]["constant"].as<float>();
|
||||
|
||||
@ -110,149 +110,97 @@ void ext::vulkan::BaseRenderMode::tick() {
|
||||
}
|
||||
}
|
||||
void ext::vulkan::BaseRenderMode::render() {
|
||||
// if ( ext::vulkan::states::frameSkip ) return;
|
||||
// if ( ext::vulkan::renderModes.size() > 1 ) return;
|
||||
// if ( ext::vulkan::renderModes.back() != this ) return;
|
||||
// if ( this->commands.container().empty() ) return;
|
||||
|
||||
if ( this->commands.container().empty() ) return;
|
||||
|
||||
//lockMutex( this->mostRecentCommandPoolId );
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
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(vkResetFences(*device, 1, &fences[states::currentBuffer]));
|
||||
|
||||
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;
|
||||
|
||||
{
|
||||
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]));
|
||||
#if 0
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
auto& commandBuffer = commands[states::currentBuffer];
|
||||
vkResetCommandBuffer(commandBuffer, 0);
|
||||
{
|
||||
VkQueue queue = device->getQueue( QueueEnum::PRESENT );
|
||||
VkResult res = vkQueueWaitIdle(device->getQueue( QueueEnum::PRESENT ));
|
||||
VK_CHECK_QUEUE_CHECKPOINT( queue, res );
|
||||
}
|
||||
#endif
|
||||
|
||||
states::currentBuffer = (states::currentBuffer + 1) % ext::vulkan::swapchain.buffers;
|
||||
this->executed = true;
|
||||
|
||||
//unlockMutex( this->mostRecentCommandPoolId );
|
||||
}
|
||||
|
||||
void ext::vulkan::BaseRenderMode::destroy() {
|
||||
|
||||
ext::vulkan::RenderMode::destroy();
|
||||
|
||||
for ( auto& presentCompleteSemaphore : swapchain.presentCompleteSemaphores ) {
|
||||
vkDestroySemaphore( *device, presentCompleteSemaphore, nullptr);
|
||||
VK_UNREGISTER_HANDLE( presentCompleteSemaphore );
|
||||
}
|
||||
swapchain.presentCompleteSemaphores.clear();
|
||||
}
|
||||
|
||||
ext::vulkan::GraphicDescriptor ext::vulkan::BaseRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) {
|
||||
ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, pass);
|
||||
|
||||
descriptor.depth.test = false;
|
||||
descriptor.depth.write = false;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
void ext::vulkan::BaseRenderMode::createCommandBuffers( const uf::stl::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
// if ( ext::vulkan::renderModes.size() > 1 ) return;
|
||||
|
||||
auto windowSize = device->window->getSize();
|
||||
float width = windowSize.x; //this->width > 0 ? this->width : windowSize.x;
|
||||
float height = windowSize.y; //this->height > 0 ? this->height : windowSize.y;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
||||
cmdBufInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
|
||||
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
|
||||
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
|
||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
|
||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
uf::stl::vector<RenderMode*> layers = ext::vulkan::getRenderModes(uf::stl::vector<uf::stl::string>{"Deferred", "Compute:RT", "RenderTarget"}, false);
|
||||
#if 0
|
||||
if ( settings::pipelines::rt ) {
|
||||
std::reverse( layers.begin(), layers.end() );
|
||||
}
|
||||
#endif
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
auto& commands = getCommands();
|
||||
|
||||
uf::stl::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
pod::Vector4f clearColor = uf::vector::decode( sceneMetadataJson["system"]["renderer"]["clear values"][(int) clearValues.size()], pod::Vector4f{0, 0, 0, 0} );
|
||||
auto& clearValue = clearValues.emplace_back();
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
clearValue.color.float32[0] = clearColor[0];
|
||||
clearValue.color.float32[1] = clearColor[1];
|
||||
clearValue.color.float32[2] = clearColor[2];
|
||||
clearValue.color.float32[3] = clearColor[3];
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
} else {
|
||||
clearValue.depthStencil = { 1.0f, 0 };
|
||||
STATIC_THREAD_LOCAL(uf::stl::vector<ext::vulkan::Graphic*>, graphics);
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
auto/*&*/ graph = scene.getGraph();
|
||||
for ( auto entity : graph ) {
|
||||
if ( entity->hasComponent<ext::vulkan::Graphics>() ) {
|
||||
auto& g = entity->getComponent<ext::vulkan::Graphics>();
|
||||
for ( auto& [ _, graphic ] : g ) {
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.emplace_back(&graphic);
|
||||
}
|
||||
}
|
||||
if ( entity->hasComponent<ext::vulkan::Graphic>() ) {
|
||||
auto& graphic = entity->getComponent<ext::vulkan::Graphic>();
|
||||
if ( !graphic.initialized || !graphic.process ) continue;
|
||||
graphics.emplace_back(&graphic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassBeginInfo = {};
|
||||
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassBeginInfo.pNext = nullptr;
|
||||
renderPassBeginInfo.renderPass = renderTarget.renderPass;
|
||||
renderPassBeginInfo.renderArea.offset.x = 0;
|
||||
renderPassBeginInfo.renderArea.offset.y = 0;
|
||||
renderPassBeginInfo.renderArea.extent.width = width;
|
||||
renderPassBeginInfo.renderArea.extent.height = height;
|
||||
renderPassBeginInfo.clearValueCount = clearValues.size();
|
||||
renderPassBeginInfo.pClearValues = &clearValues[0];
|
||||
size_t frame = states::currentBuffer;
|
||||
auto windowSize = device->window->getSize();
|
||||
float width = windowSize.x; //this->width > 0 ? this->width : windowSize.x;
|
||||
float height = windowSize.y; //this->height > 0 ? this->height : windowSize.y;
|
||||
|
||||
// Update dynamic viewport state
|
||||
VkViewport viewport = {};
|
||||
viewport.width = (float) width;
|
||||
viewport.height = (float) height;
|
||||
viewport.minDepth = (float) 0.0f;
|
||||
viewport.maxDepth = (float) 1.0f;
|
||||
|
||||
// Update dynamic scissor state
|
||||
VkRect2D scissor = {};
|
||||
scissor.extent.width = width;
|
||||
scissor.extent.height = height;
|
||||
scissor.offset.x = 0;
|
||||
scissor.offset.y = 0;
|
||||
|
||||
for (size_t frame = 0; frame < commands.size(); ++frame) {
|
||||
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
||||
cmdBufInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
|
||||
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
|
||||
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
|
||||
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
||||
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
|
||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
uf::stl::vector<RenderMode*> layers = ext::vulkan::getRenderModes(uf::stl::vector<uf::stl::string>{"Deferred", "Compute:RT", "RenderTarget"}, false);
|
||||
|
||||
float depthClear = uf::matrix::reverseInfiniteProjection ? 0.0f : 1.0f;
|
||||
uf::stl::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
pod::Vector4f clearColor = uf::vector::decode( sceneMetadataJson["system"]["renderer"]["clear values"][(int) clearValues.size()], pod::Vector4f{0, 0, 0, 0} );
|
||||
auto& clearValue = clearValues.emplace_back();
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
clearValue.color.float32[0] = clearColor[0];
|
||||
clearValue.color.float32[1] = clearColor[1];
|
||||
clearValue.color.float32[2] = clearColor[2];
|
||||
clearValue.color.float32[3] = clearColor[3];
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
clearValue.depthStencil = { depthClear, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassBeginInfo = {};
|
||||
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassBeginInfo.pNext = nullptr;
|
||||
renderPassBeginInfo.renderPass = renderTarget.renderPass;
|
||||
renderPassBeginInfo.renderArea.offset.x = 0;
|
||||
renderPassBeginInfo.renderArea.offset.y = 0;
|
||||
renderPassBeginInfo.renderArea.extent.width = width;
|
||||
renderPassBeginInfo.renderArea.extent.height = height;
|
||||
renderPassBeginInfo.clearValueCount = clearValues.size();
|
||||
renderPassBeginInfo.pClearValues = &clearValues[0];
|
||||
|
||||
// Update dynamic viewport state
|
||||
VkViewport viewport = {};
|
||||
viewport.width = (float) width;
|
||||
viewport.height = (float) height;
|
||||
viewport.minDepth = (float) 0.0f;
|
||||
viewport.maxDepth = (float) 1.0f;
|
||||
|
||||
auto& commandBuffer = commands[frame];
|
||||
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[frame];
|
||||
// Update dynamic scissor state
|
||||
VkRect2D scissor = {};
|
||||
scissor.extent.width = width;
|
||||
scissor.extent.height = height;
|
||||
scissor.offset.x = 0;
|
||||
scissor.offset.y = 0;
|
||||
|
||||
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[imageIndex];
|
||||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo));
|
||||
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::BEGIN, "begin" );
|
||||
@ -295,6 +243,52 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const uf::stl::vector<ex
|
||||
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" );
|
||||
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;
|
||||
|
||||
{
|
||||
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]));
|
||||
|
||||
states::currentBuffer = (states::currentBuffer + 1) % ext::vulkan::swapchain.buffers;
|
||||
this->executed = true;
|
||||
}
|
||||
|
||||
void ext::vulkan::BaseRenderMode::destroy() {
|
||||
|
||||
ext::vulkan::RenderMode::destroy();
|
||||
|
||||
for ( auto& presentCompleteSemaphore : swapchain.presentCompleteSemaphores ) {
|
||||
vkDestroySemaphore( *device, presentCompleteSemaphore, nullptr);
|
||||
VK_UNREGISTER_HANDLE( presentCompleteSemaphore );
|
||||
}
|
||||
swapchain.presentCompleteSemaphores.clear();
|
||||
}
|
||||
|
||||
ext::vulkan::GraphicDescriptor ext::vulkan::BaseRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) {
|
||||
ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, pass);
|
||||
|
||||
descriptor.depth.test = false;
|
||||
descriptor.depth.write = false;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
void ext::vulkan::BaseRenderMode::createCommandBuffers( const uf::stl::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -415,7 +415,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// atomic counter buffer
|
||||
::postprocesses::bloom.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE );
|
||||
::postprocesses::bloom.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE | VK_BUFFER_USAGE_TRANSFER_DST_BIT );
|
||||
shader.aliasBuffer("atomicCounterBloom", ::postprocesses::bloom.atomicCounter);
|
||||
}
|
||||
|
||||
@ -449,7 +449,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// atomic counter buffer
|
||||
::postprocesses::dof.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE );
|
||||
::postprocesses::dof.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE | VK_BUFFER_USAGE_TRANSFER_DST_BIT );
|
||||
shader.aliasBuffer("atomicCounterBloom", ::postprocesses::dof.atomicCounter);
|
||||
}
|
||||
|
||||
@ -482,7 +482,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
shader.aliasAttachment("depth_resolved", this);
|
||||
|
||||
// atomic counter buffer
|
||||
::postprocesses::depthPyramid.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE );
|
||||
::postprocesses::depthPyramid.atomicCounter.initialize( (const void*) nullptr, sizeof(::AtomicCounter) * 1, uf::renderer::enums::Buffer::STORAGE | VK_BUFFER_USAGE_TRANSFER_DST_BIT );
|
||||
shader.aliasBuffer("atomicCounterDepth", ::postprocesses::depthPyramid.atomicCounter);
|
||||
}
|
||||
}
|
||||
@ -759,6 +759,15 @@ void ext::vulkan::DeferredRenderMode::destroy() {
|
||||
ext::vulkan::GraphicDescriptor ext::vulkan::DeferredRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) {
|
||||
ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, pass);
|
||||
if ( descriptor.renderMode != "" ) descriptor.invalidated = true;
|
||||
if ( metadata.json["reverse depth"].as<bool>(uf::matrix::reverseInfiniteProjection) ) {
|
||||
descriptor.depth.operation = ext::vulkan::enums::Compare::GREATER_OR_EQUAL;
|
||||
descriptor.depth.min = 1.0f;
|
||||
descriptor.depth.max = 0.0f;
|
||||
} else {
|
||||
descriptor.depth.operation = ext::vulkan::enums::Compare::LESS;
|
||||
descriptor.depth.min = 0.0f;
|
||||
descriptor.depth.max = 1.0f;
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
@ -783,7 +792,13 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& commands = getCommands();
|
||||
// auto& swapchainRender = ext::vulkan::getRenderMode("Swapchain");
|
||||
|
||||
float depthClear = uf::matrix::reverseInfiniteProjection ? 0.0f : 1.0f;
|
||||
for ( auto graphic : graphics ) {
|
||||
auto descriptor = bindGraphicDescriptor(graphic->descriptor);
|
||||
depthClear = descriptor.depth.max;
|
||||
break;
|
||||
}
|
||||
uf::stl::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
pod::Vector4f clearColor = uf::vector::decode( sceneMetadataJson["system"]["renderer"]["clear values"][(int) clearValues.size()], pod::Vector4f{0, 0, 0, 0} );
|
||||
@ -794,11 +809,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
clearValue.color.float32[2] = clearColor[2];
|
||||
clearValue.color.float32[3] = clearColor[3];
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
} else {
|
||||
clearValue.depthStencil = { 1.0f, 0 };
|
||||
}
|
||||
clearValue.depthStencil = { depthClear, 0 };
|
||||
}
|
||||
}
|
||||
bool shouldRecord = true; // ( settings::pipelines::rt && !uf::config["engine"]["scenes"]["rt"]["full"].as<bool>() ) || !settings::pipelines::rt;
|
||||
@ -998,7 +1009,8 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
if ( graphic->descriptor.renderTarget != 1 /*"forward"*/ ) continue;
|
||||
//if ( graphic->descriptor.pipeline != "forward" ) continue;
|
||||
ext::vulkan::GraphicDescriptor descriptor = graphic->descriptor; // bindGraphicDescriptor(graphic->descriptor, currentSubpass);
|
||||
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass);
|
||||
//descriptor.renderTarget = 1;
|
||||
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, ::fmt::format("graphic[{}]", currentDraw) );
|
||||
graphic->record( commandBuffer, descriptor, 0, currentDraw++, frame );
|
||||
}
|
||||
|
||||
@ -25,8 +25,15 @@ ext::vulkan::GraphicDescriptor ext::vulkan::RenderTargetRenderMode::bindGraphicD
|
||||
descriptor.depth.write = false;
|
||||
} else if ( metadata.type == "depth" ) {
|
||||
descriptor.cullMode = VK_CULL_MODE_NONE;
|
||||
// descriptor.depth.test = false;
|
||||
// descriptor.depth.write = false;
|
||||
if ( metadata.json["reverse depth"].as<bool>(uf::matrix::reverseInfiniteProjection) ) {
|
||||
descriptor.depth.operation = ext::vulkan::enums::Compare::GREATER_OR_EQUAL;
|
||||
descriptor.depth.min = 1.0f;
|
||||
descriptor.depth.max = 0.0f;
|
||||
} else {
|
||||
descriptor.depth.operation = ext::vulkan::enums::Compare::LESS;
|
||||
descriptor.depth.min = 0.0f;
|
||||
descriptor.depth.max = 1.0f;
|
||||
}
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
@ -321,16 +328,18 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
uf::stl::vector<VkClearValue> clearValues;
|
||||
float depthClear = uf::matrix::reverseInfiniteProjection ? 0.0f : 1.0f;
|
||||
for ( auto graphic : graphics ) {
|
||||
auto descriptor = bindGraphicDescriptor(graphic->descriptor);
|
||||
depthClear = descriptor.depth.max;
|
||||
break;
|
||||
}
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
auto& clearValue = clearValues.emplace_back();
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } };
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
} else {
|
||||
clearValue.depthStencil = { 1.0f, 0 };
|
||||
}
|
||||
clearValue.depthStencil = { depthClear, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
#define VK_DEBUG_VALIDATION_MESSAGE(...)\
|
||||
//VK_VALIDATION_MESSAGE(__VA_ARGS__);
|
||||
|
||||
#define IS_DYNAMIC(name) true // name == "UBO"
|
||||
|
||||
#define UF_SHADER_PARSE_AS_JSON 0
|
||||
#if UF_SHADER_PARSE_AS_JSON
|
||||
ext::json::Value ext::vulkan::definitionToJson(/*const*/ ext::json::Value& definition ) {
|
||||
@ -519,11 +517,9 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
.size = bufferSize,
|
||||
};
|
||||
|
||||
if ( descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ) {
|
||||
if ( IS_DYNAMIC(name) ) {
|
||||
UF_MSG_DEBUG("Registered dynamic UBO: {}", name);
|
||||
}
|
||||
metadata.dynamicRanges.emplace_back( IS_DYNAMIC(name) ? bufferSize : 0 );
|
||||
if ( IS_DYNAMIC(name) ) {
|
||||
descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
||||
metadata.dynamicRanges.emplace_back( bufferSize );
|
||||
}
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
@ -580,7 +576,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
LOOP_RESOURCES( storage_images, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE );
|
||||
LOOP_RESOURCES( separate_samplers, VK_DESCRIPTOR_TYPE_SAMPLER );
|
||||
LOOP_RESOURCES( subpass_inputs, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT );
|
||||
LOOP_RESOURCES( uniform_buffers, VK_UBO_USE_N_BUFFERS ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER );
|
||||
LOOP_RESOURCES( uniform_buffers, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER );
|
||||
LOOP_RESOURCES( storage_buffers, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER );
|
||||
LOOP_RESOURCES( acceleration_structures, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR );
|
||||
#undef LOOP_RESOURCES
|
||||
|
||||
@ -20,7 +20,7 @@ pod::Vector3f uf::camera::eye( const pod::Camera& camera, int i ) {
|
||||
return position;
|
||||
}
|
||||
void uf::camera::view( pod::Camera& camera, const pod::Matrix4f& mat, int i ) {
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // camera.viewport.views;
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // camera.views;
|
||||
if ( i >= uf::camera::maxViews ) {
|
||||
for ( i = 0; i < uf::camera::maxViews; ++i ) {
|
||||
camera.viewport.matrices[i].view = mat;
|
||||
@ -30,7 +30,7 @@ void uf::camera::view( pod::Camera& camera, const pod::Matrix4f& mat, int i ) {
|
||||
camera.viewport.matrices[i].view = mat;
|
||||
}
|
||||
void uf::camera::projection( pod::Camera& camera, const pod::Matrix4f& mat, int i ) {
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // camera.viewport.views;
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // camera.views;
|
||||
if ( i >= uf::camera::maxViews ) {
|
||||
for ( i = 0; i < uf::camera::maxViews; ++i ) camera.viewport.matrices[i].projection = mat;
|
||||
return;
|
||||
@ -78,15 +78,15 @@ const pod::Matrix4& uf::Camera::getProjection( size_t i ) const { return this->v
|
||||
|
||||
void uf::Camera::setStereoscopic( bool b ) { this->stereoscopic = b; }
|
||||
pod::Vector3f uf::Camera::getEye( size_t i ) const {
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->viewport.views;
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->views;
|
||||
return uf::camera::eye( *this, i );
|
||||
}
|
||||
void uf::Camera::setView( const pod::Matrix4& mat, int i ) {
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->viewport.views;
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->views;
|
||||
uf::camera::view( *this, mat, i );
|
||||
}
|
||||
void uf::Camera::setProjection( const pod::Matrix4& mat, int i ) {
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->viewport.views;
|
||||
if ( i < 0 ) i = uf::camera::maxViews; // this->views;
|
||||
uf::camera::projection( *this, mat, i );
|
||||
}
|
||||
void uf::Camera::update() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user