Commit for 2020.10.25.7z
This commit is contained in:
parent
7027ce2db7
commit
360e921722
16
Makefile
16
Makefile
@ -15,18 +15,18 @@ UF_LIBS =
|
||||
# EXT_LIBS = -lpng16 -lz -lassimp -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics -llua52
|
||||
# EXT_LIBS = -lpng16 -lz -lassimp -ljsoncpp -lopenal32 -lalut -lvorbis -lvorbisfile -logg -lfreetype
|
||||
EXT_LIBS =
|
||||
#FLAGS = -std=c++0x -Wall -g -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENGL -DUF_USE_GLEW
|
||||
FLAGS = -Og -std=c++17 -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
|
||||
#FLAGS = -std=c++0x -Wall -g -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENGL -DUF_USE_GLEW -DUF_USE_DISCORD
|
||||
FLAGS = -fdiagnostics-color=always -Og -std=c++17 -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
|
||||
#-march=native
|
||||
LIB_NAME = uf
|
||||
EXT_LIB_NAME = ext
|
||||
|
||||
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.101.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.108.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.114.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
|
||||
VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.154.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.101.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.108.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.114.0/
|
||||
VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.154.0/
|
||||
WIN64_CC = /opt/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++
|
||||
WIN64_GLSL_VALIDATOR = $(VULKAN_WIN64_SDK_PATH)/Bin32/glslangValidator
|
||||
# Base Engine's DLL
|
||||
@ -35,7 +35,7 @@ WIN64_LB_FLAGS = $(ENGINE_LIB_DIR)/win64
|
||||
WIN64_DEPS = -lgdi32 -lvulkan -lspirv-cross -lpng -lz -ljsoncpp -lopenal -lalut -lvorbis -lvorbisfile -logg -lfreetype -lncursesw -lcurl -ldiscord_game_sdk -lopenvr_api
|
||||
#WIN64_DEPS = -lvulkan -lncursesw
|
||||
WIN64_LINKS = $(UF_LIBS) $(EXT_LIBS) $(WIN64_DEPS)
|
||||
WIN64_FLAGS = $(FLAGS) -g
|
||||
WIN64_FLAGS = $(FLAGS)
|
||||
#-Wl,-subsystem,windows
|
||||
|
||||
WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
||||
|
||||
@ -4,8 +4,7 @@ layout (constant_id = 0) const uint LIGHTS = 32;
|
||||
|
||||
layout (input_attachment_index = 0, binding = 1) uniform subpassInput samplerAlbedo;
|
||||
layout (input_attachment_index = 0, binding = 2) uniform subpassInput samplerNormal;
|
||||
layout (input_attachment_index = 0, binding = 3) uniform subpassInput samplerPosition;
|
||||
// layout (input_attachment_index = 0, binding = 4) uniform subpassInput samplerDepth;
|
||||
layout (input_attachment_index = 0, binding = 3) uniform subpassInput samplerDepth;
|
||||
layout (binding = 5) uniform sampler2D samplerShadows[LIGHTS];
|
||||
/*
|
||||
layout (std140, binding = 6) buffer Palette {
|
||||
@ -347,11 +346,34 @@ void main() {
|
||||
vec4 albedoSpecular = subpassLoad(samplerAlbedo);
|
||||
vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb;
|
||||
normal.eye = subpassLoad(samplerNormal).rgb;
|
||||
/*
|
||||
position.eye = subpassLoad(samplerPosition).rgb; {
|
||||
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
|
||||
vec4 positionWorld = iView * vec4(position.eye, 1);
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
*/
|
||||
{
|
||||
mat4 iProj = inverse( ubo.matrices.projection[inPushConstantPass] );
|
||||
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
|
||||
|
||||
float depth = subpassLoad(samplerDepth).r;
|
||||
|
||||
if ( false ) {
|
||||
depth /= 0.00526;
|
||||
outFragColor.rgb = vec3( 1 - depth );
|
||||
outFragColor.a = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 positionClip = vec4(inUv * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 positionEye = iProj * positionClip;
|
||||
positionEye /= positionEye.w;
|
||||
position.eye = positionEye.xyz;
|
||||
|
||||
vec4 positionWorld = iView * positionEye;
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
float litFactor = 1.0;
|
||||
for ( uint i = 0, shadowMap = 0; i < LIGHTS; ++i ) {
|
||||
Light light = ubo.lights[i];
|
||||
|
||||
380
bin/data/shaders/display.subpass.stereo.frag.glsl
Normal file
380
bin/data/shaders/display.subpass.stereo.frag.glsl
Normal file
@ -0,0 +1,380 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint LIGHTS = 32;
|
||||
|
||||
layout (input_attachment_index = 0, binding = 1) uniform subpassInput samplerAlbedo;
|
||||
layout (input_attachment_index = 0, binding = 2) uniform subpassInput samplerNormal;
|
||||
layout (input_attachment_index = 0, binding = 3) uniform subpassInput samplerPosition;
|
||||
layout (binding = 5) uniform sampler2D samplerShadows[LIGHTS];
|
||||
/*
|
||||
layout (std140, binding = 6) buffer Palette {
|
||||
vec4 palette[];
|
||||
};
|
||||
*/
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
/*
|
||||
const vec2 poissonDisk[4] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 )
|
||||
);
|
||||
*/
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
vec3 color;
|
||||
float power;
|
||||
int type;
|
||||
float depthBias;
|
||||
vec2 padding;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Matrices {
|
||||
mat4 view[2];
|
||||
mat4 projection[2];
|
||||
};
|
||||
|
||||
struct Space {
|
||||
vec3 eye;
|
||||
vec3 world;
|
||||
} position, normal, view;
|
||||
|
||||
struct Fog {
|
||||
vec4 color;
|
||||
vec2 range;
|
||||
vec2 padding;
|
||||
};
|
||||
|
||||
struct Mode {
|
||||
uint type;
|
||||
uint scalar;
|
||||
vec2 padding;
|
||||
vec4 parameters;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec3 ambient;
|
||||
float kexp;
|
||||
Mode mode;
|
||||
Fog fog;
|
||||
Light lights[LIGHTS];
|
||||
} ubo;
|
||||
|
||||
void fog( inout vec3 i, float scale ) {
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x;
|
||||
float outer = ubo.fog.range.y * scale;
|
||||
float distance = length(-position.eye);
|
||||
float factor = (distance - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
|
||||
i = mix(i.rgb, color, factor);
|
||||
}
|
||||
|
||||
void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
vec3 Ls = vec3(1.0, 1.0, 1.0); // light specular
|
||||
vec3 Ld = light.color; // light color
|
||||
vec3 La = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 Ks = vec3(albedoSpecular.a); // material specular
|
||||
vec3 Kd = albedoSpecular.rgb; // material diffuse
|
||||
vec3 Ka = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
float Kexp = ubo.kexp;
|
||||
|
||||
vec3 L = light.position.xyz - position.eye;
|
||||
float dist = length(L);
|
||||
|
||||
if ( light.radius > 0.001 && light.radius < dist ) return;
|
||||
|
||||
vec3 D = normalize(L);
|
||||
float d_dot = max(dot( D, normal.eye ), 0.0);
|
||||
|
||||
vec3 R = reflect( -D, normal.eye );
|
||||
vec3 S = normalize(-position.eye);
|
||||
float s_factor = pow( max(dot( R, S ), 0.0), Kexp );
|
||||
if ( Kexp < 0.0001 ) s_factor = 0;
|
||||
|
||||
float attenuation = 1;
|
||||
if ( light.radius > 0.0001 )
|
||||
attenuation = clamp( light.radius / (pow(dist, 2.0) + 1.0), 0.0, 1.0 );
|
||||
|
||||
vec3 Ia = La * Ka;
|
||||
vec3 Id = Ld * Kd * d_dot * attenuation;
|
||||
vec3 Is = Ls * Ks * s_factor * attenuation;
|
||||
|
||||
i += Id * light.power + Is;
|
||||
}
|
||||
|
||||
float random(vec3 seed, int i){
|
||||
vec4 seed4 = vec4(seed,i);
|
||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
||||
return fract(sin(dot_product) * 43758.5453);
|
||||
}
|
||||
|
||||
float shadowFactor( Light light, uint shadowMap ) {
|
||||
vec4 positionClip = light.projection * light.view * vec4(position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
float factor = 1.0;
|
||||
|
||||
// spot light
|
||||
if ( light.type == 2 || light.type == 3 ) {
|
||||
float dist = length( positionClip.xy );
|
||||
if ( dist > 0.5 ) return 0.0;
|
||||
|
||||
// spot light with attenuation
|
||||
if ( light.type == 3 ) {
|
||||
factor = 1.0 - (pow(dist * 2,2.0));
|
||||
}
|
||||
}
|
||||
|
||||
vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
float bias = light.depthBias;
|
||||
if ( false ) {
|
||||
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
|
||||
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
|
||||
}
|
||||
|
||||
float eyeDepth = positionClip.z;
|
||||
int samples = poissonDisk.length();
|
||||
if ( samples <= 1 ) {
|
||||
return eyeDepth < texture(samplerShadows[shadowMap], uv).r - bias ? 0.0 : factor;
|
||||
}
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
// int index = i;
|
||||
// int index = int( float(samples) * random(gl_FragCoord.xyy, i) ) % samples;
|
||||
int index = int( float(samples) * random(floor(position.world.xyz * 1000.0), i)) % samples;
|
||||
float lightDepth = texture(samplerShadows[shadowMap], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
vec3 hslToRgb(vec3 HSL) {
|
||||
vec3 RGB; {
|
||||
float H = HSL.x;
|
||||
float R = abs(H * 6 - 3) - 1;
|
||||
float G = 2 - abs(H * 6 - 2);
|
||||
float B = 2 - abs(H * 6 - 4);
|
||||
RGB = clamp(vec3(R,G,B), 0, 1);
|
||||
}
|
||||
float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
|
||||
return (RGB - 0.5) * C + HSL.z;
|
||||
}
|
||||
vec3 rgbToHsl(vec3 RGB) {
|
||||
float Epsilon = 1e-10;
|
||||
vec3 HCV; {
|
||||
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
|
||||
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
|
||||
float C = Q.x - min(Q.w, Q.y);
|
||||
float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
|
||||
HCV = vec3(H, C, Q.x);
|
||||
}
|
||||
float L = HCV.z - HCV.y * 0.5;
|
||||
float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
|
||||
return vec3(HCV.x, S, L);
|
||||
}
|
||||
|
||||
float hueDistance(float h1, float h2) {
|
||||
float diff = abs((h1 - h2));
|
||||
return min(abs((1.0 - diff)), diff);
|
||||
}
|
||||
const float lightnessSteps = 4.0;
|
||||
float lightnessStep(float l) {
|
||||
return floor((0.5 + l * lightnessSteps)) / lightnessSteps;
|
||||
}
|
||||
const int indexMatrix16x16[256] = int[](0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255,
|
||||
128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127,
|
||||
32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223,
|
||||
160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95,
|
||||
8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247,
|
||||
136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119,
|
||||
40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215,
|
||||
168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87,
|
||||
2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253,
|
||||
130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125,
|
||||
34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221,
|
||||
162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93,
|
||||
10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245,
|
||||
138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117,
|
||||
42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213,
|
||||
170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85);
|
||||
float indexValue16x16( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 16));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 16));
|
||||
return indexMatrix16x16[(x + y * 16)] / 256.0;
|
||||
}
|
||||
const int indexMatrix8x8[64] = int[](0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
12, 44, 4, 36, 14, 46, 6, 38,
|
||||
60, 28, 52, 20, 62, 30, 54, 22,
|
||||
3, 35, 11, 43, 1, 33, 9, 41,
|
||||
51, 19, 59, 27, 49, 17, 57, 25,
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21);
|
||||
float indexValue8x8( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 8));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 8));
|
||||
return indexMatrix8x8[(x + y * 8)] / 64.0;
|
||||
}
|
||||
const int indexMatrix4x4[16] = int[](0, 8, 2, 10,
|
||||
12, 4, 14, 6,
|
||||
3, 11, 1, 9,
|
||||
15, 7, 13, 5);
|
||||
float indexValue4x4( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 4));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 4));
|
||||
return indexMatrix4x4[(x + y * 4)] / 16.0;
|
||||
}
|
||||
vec3[2] closestColors(float hue) {
|
||||
vec3 ret[2];
|
||||
vec3 closest = vec3(-2, 0, 0);
|
||||
vec3 secondClosest = vec3(-2, 0, 0);
|
||||
vec3 temp;
|
||||
/*
|
||||
for (int i = 0; i < palette.length(); ++i) {
|
||||
temp = rgbToHsl(palette[i].rgb);
|
||||
float tempDistance = hueDistance(temp.x, hue);
|
||||
if (tempDistance < hueDistance(closest.x, hue)) {
|
||||
secondClosest = closest;
|
||||
closest = temp;
|
||||
} else {
|
||||
if (tempDistance < hueDistance(secondClosest.x, hue)) {
|
||||
secondClosest = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
ret[0] = closest;
|
||||
ret[1] = secondClosest;
|
||||
return ret;
|
||||
}
|
||||
float dither(float color) {
|
||||
float closestColor = (color < 0.5) ? 0 : 1;
|
||||
float secondClosestColor = 1 - closestColor;
|
||||
float d = 1; // -0.5 - fract(ubo.mode.parameters.w / 8.0);
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(1);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(1);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(1);
|
||||
}
|
||||
float distance = abs(closestColor - color);
|
||||
return (distance < d) ? closestColor : secondClosestColor;
|
||||
}
|
||||
void dither(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
hsl.x = dither(hsl.x);
|
||||
color = hslToRgb(hsl);
|
||||
}
|
||||
void dither1(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
|
||||
float d = 0;
|
||||
vec3 cs[2] = { hsl, hsl }; // closestColors(hsl.x);
|
||||
float scale = 1;
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(scale);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(scale);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(scale);
|
||||
}
|
||||
float hueDiff = hueDistance(hsl.x, cs[0].x) / hueDistance(cs[1].x, cs[0].x);
|
||||
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
|
||||
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
|
||||
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
|
||||
|
||||
vec3 resultColor = (hueDiff < d) ? cs[0] : cs[1];
|
||||
resultColor.z = (lightnessDiff < d) ? l1 : l2;
|
||||
color = hslToRgb(resultColor);
|
||||
}
|
||||
|
||||
float rand2(vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
|
||||
}
|
||||
float rand3(vec3 co){
|
||||
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453);
|
||||
}
|
||||
void whitenoise(inout vec3 color) {
|
||||
float flicker = ubo.mode.parameters.x;
|
||||
float pieces = ubo.mode.parameters.y;
|
||||
float blend = ubo.mode.parameters.z;
|
||||
float time = ubo.mode.parameters.w;
|
||||
if ( blend < 0.0001 ) return;
|
||||
float freq = sin(pow(mod(time, flicker) + flicker, 1.9));
|
||||
// float whiteNoise = rand3( floor(position.world / pieces) + floor(time * 2) );
|
||||
float whiteNoise = rand2( floor(gl_FragCoord.xy / pieces) + mod(time, freq) );
|
||||
color = mix( color, vec3(whiteNoise), blend );
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 albedoSpecular = subpassLoad(samplerAlbedo);
|
||||
vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb;
|
||||
normal.eye = subpassLoad(samplerNormal).rgb;
|
||||
position.eye = subpassLoad(samplerPosition).rgb; {
|
||||
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
|
||||
vec4 positionWorld = iView * vec4(position.eye, 1);
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
float litFactor = 1.0;
|
||||
for ( uint i = 0, shadowMap = 0; i < LIGHTS; ++i ) {
|
||||
Light light = ubo.lights[i];
|
||||
|
||||
if ( light.power <= 0.001 ) continue;
|
||||
|
||||
light.position.xyz = vec3(ubo.matrices.view[inPushConstantPass] * vec4(light.position.xyz, 1));
|
||||
if ( light.type > 0 ) {
|
||||
float shadowFactor = shadowFactor( light, shadowMap++ );
|
||||
if ( shadowFactor <= 0.0001 ) continue;
|
||||
light.power *= shadowFactor;
|
||||
litFactor += light.power;
|
||||
}
|
||||
phong( light, albedoSpecular, fragColor );
|
||||
}
|
||||
|
||||
fog(fragColor, litFactor);
|
||||
|
||||
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
|
||||
dither1(fragColor);
|
||||
}
|
||||
if ( (ubo.mode.type & (0x1 << 1)) == (0x1 << 1) ) {
|
||||
whitenoise(fragColor);
|
||||
}
|
||||
|
||||
outFragColor = vec4(fragColor,1);
|
||||
}
|
||||
@ -7,6 +7,7 @@
|
||||
#include <uf/spec/terminal/terminal.h>
|
||||
#include <uf/utils/hook/hook.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
|
||||
bool client::ready = false;
|
||||
@ -16,7 +17,7 @@ uf::Serializer client::config;
|
||||
|
||||
void client::initialize() {
|
||||
uf::IoStream::ncurses = true;
|
||||
ext::vulkan::device.window = &client::window;
|
||||
uf::renderer::device.window = &client::window;
|
||||
/* Initialize config */ {
|
||||
struct {
|
||||
uf::Serializer ext;
|
||||
@ -52,8 +53,8 @@ void client::initialize() {
|
||||
uf::IoStream::ncurses = client::config["window"]["terminal"]["ncurses"].asBool();
|
||||
|
||||
// Window's context settings
|
||||
ext::vulkan::width = size.x;
|
||||
ext::vulkan::height = size.y;
|
||||
uf::renderer::settings::width = size.x;
|
||||
uf::renderer::settings::height = size.y;
|
||||
client::window.create( size, title );
|
||||
|
||||
// Miscellaneous
|
||||
@ -130,10 +131,10 @@ void client::initialize() {
|
||||
client::window.setSize(size);
|
||||
}
|
||||
// Update viewport
|
||||
ext::vulkan::width = size.x;
|
||||
ext::vulkan::height = size.y;
|
||||
uf::renderer::settings::width = size.x;
|
||||
uf::renderer::settings::height = size.y;
|
||||
|
||||
ext::vulkan::resized = true;
|
||||
uf::renderer::states::resized = true;
|
||||
return "true";
|
||||
} );
|
||||
} else if ( client::config["engine"]["hook"]["mode"] == "Both" || client::config["engine"]["hook"]["mode"] == "Optimal" ) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <discord/discord.h>
|
||||
|
||||
namespace ext {
|
||||
namespace discord {
|
||||
|
||||
@ -9,7 +9,28 @@
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
struct Graphic;
|
||||
struct GraphicDescriptor {
|
||||
std::string renderMode = "";
|
||||
uint32_t renderTarget = 0;
|
||||
uint32_t subpass = 0;
|
||||
|
||||
uf::BaseGeometry geometry;
|
||||
size_t indices = 0;
|
||||
|
||||
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
VkPolygonMode fill = VK_POLYGON_MODE_FILL;
|
||||
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
float lineWidth = 1.0f;
|
||||
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
struct {
|
||||
VkBool32 test = true;
|
||||
VkBool32 write = true;
|
||||
VkCompareOp operation = VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
} depthTest;
|
||||
|
||||
std::string hash() const;
|
||||
bool operator==( const GraphicDescriptor& right ) const { return this->hash() == right.hash(); }
|
||||
};
|
||||
struct UF_API Shader : public Buffers {
|
||||
bool aliased = false;
|
||||
|
||||
@ -44,7 +65,9 @@ namespace ext {
|
||||
VkDescriptorSet descriptorSet;
|
||||
|
||||
void initialize( Graphic& graphic );
|
||||
void initialize( Graphic& graphic, GraphicDescriptor& descriptor );
|
||||
void update( Graphic& graphic );
|
||||
void update( Graphic& graphic, GraphicDescriptor& descriptor );
|
||||
void record( Graphic& graphic, VkCommandBuffer );
|
||||
void destroy();
|
||||
};
|
||||
@ -63,28 +86,7 @@ namespace ext {
|
||||
void initializeShaders( const std::vector<std::pair<std::string, VkShaderStageFlagBits>>& );
|
||||
};
|
||||
struct UF_API Graphic : public Buffers {
|
||||
struct Descriptor {
|
||||
std::string renderMode = "";
|
||||
uint32_t renderTarget = 0;
|
||||
uint32_t subpass = 0;
|
||||
|
||||
uf::BaseGeometry geometry;
|
||||
size_t indices = 0;
|
||||
|
||||
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
VkPolygonMode fill = VK_POLYGON_MODE_FILL;
|
||||
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
float lineWidth = 1.0f;
|
||||
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
struct {
|
||||
VkBool32 test = true;
|
||||
VkBool32 write = true;
|
||||
VkCompareOp operation = VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
} depthTest;
|
||||
|
||||
std::string hash() const;
|
||||
bool operator==( const Descriptor& right ) const { return this->hash() == right.hash(); }
|
||||
} descriptor;
|
||||
GraphicDescriptor descriptor;
|
||||
|
||||
bool initialized = false;
|
||||
bool process = true;
|
||||
@ -97,14 +99,15 @@ namespace ext {
|
||||
template<typename T, typename U>
|
||||
void initializeGeometry( uf::BaseMesh<T, U>& mesh, bool = false );
|
||||
|
||||
bool hasPipeline( Descriptor& descriptor );
|
||||
bool hasPipeline( GraphicDescriptor& descriptor );
|
||||
void initializePipeline();
|
||||
Pipeline& initializePipeline( Descriptor& descriptor, bool update = true );
|
||||
Pipeline& initializePipeline( GraphicDescriptor& descriptor, bool update = true );
|
||||
Pipeline& getPipeline();
|
||||
Pipeline& getPipeline( Descriptor& descriptor );
|
||||
Pipeline& getPipeline( GraphicDescriptor& descriptor );
|
||||
void updatePipelines();
|
||||
|
||||
void record( VkCommandBuffer commandBuffer );
|
||||
void record( VkCommandBuffer commandBuffer, Descriptor& descriptor );
|
||||
void record( VkCommandBuffer commandBuffer, GraphicDescriptor& descriptor );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ namespace ext {
|
||||
virtual void initialize( Device& device );
|
||||
virtual void createCommandBuffers();
|
||||
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||
virtual void bindPipelines();
|
||||
virtual void bindPipelines( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
|
||||
@ -6,10 +6,7 @@
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
struct UF_API RenderTargetRenderMode : public ext::vulkan::RenderMode {
|
||||
ext::vulkan::Graphic blitter;
|
||||
|
||||
VkFence fence;
|
||||
VkCommandBuffer commandBuffer;
|
||||
ext::vulkan::Graphic blitter;
|
||||
std::string target;
|
||||
|
||||
// RAII
|
||||
|
||||
@ -28,40 +28,44 @@ namespace ext {
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData
|
||||
);
|
||||
|
||||
VkShaderModule loadShader(const char *fileName, VkDevice device);
|
||||
VkPipelineShaderStageCreateInfo loadShader( std::string fileName, VkShaderStageFlagBits stage, VkDevice device, std::vector<VkShaderModule>& shaderModules );
|
||||
|
||||
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
|
||||
|
||||
struct VertexDescriptor {
|
||||
VkFormat format; // VK_FORMAT_R32G32B32_SFLOAT
|
||||
std::size_t offset; // offsetof(Vertex, position)
|
||||
};
|
||||
|
||||
extern UF_API uint32_t width;
|
||||
extern UF_API uint32_t height;
|
||||
extern UF_API uint8_t msaa;
|
||||
|
||||
extern UF_API bool validation;
|
||||
extern UF_API bool rebuildOnTickStart;
|
||||
extern UF_API bool waitOnRenderEnd;
|
||||
extern UF_API std::vector<std::string> validationFilters;
|
||||
extern UF_API std::vector<std::string> requestedDeviceFeatures;
|
||||
extern UF_API std::vector<std::string> requestedDeviceExtensions;
|
||||
extern UF_API std::vector<std::string> requestedInstanceExtensions;
|
||||
extern UF_API Device device;
|
||||
typedef VmaAllocator Allocator;
|
||||
|
||||
namespace settings {
|
||||
extern UF_API uint32_t width;
|
||||
extern UF_API uint32_t height;
|
||||
extern UF_API uint8_t msaa;
|
||||
extern UF_API bool validation;
|
||||
|
||||
extern UF_API std::vector<std::string> validationFilters;
|
||||
extern UF_API std::vector<std::string> requestedDeviceFeatures;
|
||||
extern UF_API std::vector<std::string> requestedDeviceExtensions;
|
||||
extern UF_API std::vector<std::string> requestedInstanceExtensions;
|
||||
|
||||
namespace experimental {
|
||||
extern UF_API bool rebuildOnTickBegin;
|
||||
extern UF_API bool waitOnRenderEnd;
|
||||
extern UF_API bool individualPipelines;
|
||||
extern UF_API bool multithreadedCommandRecording;
|
||||
}
|
||||
}
|
||||
namespace states {
|
||||
extern UF_API bool rebuild;
|
||||
extern UF_API bool resized;
|
||||
extern UF_API uint32_t currentBuffer;
|
||||
}
|
||||
|
||||
extern UF_API Device device;
|
||||
extern UF_API Allocator allocator;
|
||||
extern UF_API Swapchain swapchain;
|
||||
extern UF_API std::mutex mutex;
|
||||
|
||||
extern UF_API bool rebuild;
|
||||
extern UF_API bool resized;
|
||||
extern UF_API uint32_t currentBuffer;
|
||||
|
||||
extern UF_API RenderMode* currentRenderMode;
|
||||
extern UF_API std::vector<std::string> passes;
|
||||
extern UF_API std::vector<RenderMode*> renderModes;
|
||||
extern UF_API std::vector<uf::Scene*> scenes;
|
||||
|
||||
@ -76,6 +80,7 @@ namespace ext {
|
||||
void UF_API tick();
|
||||
void UF_API render();
|
||||
void UF_API destroy();
|
||||
void UF_API synchronize( uint8_t = 0b11 );
|
||||
std::string UF_API allocatorStats();
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,7 @@ void uf::ObjectBehavior::destroy( uf::Object& self ) {
|
||||
if ( this->hasComponent<uf::Graphic>() ) {
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
graphic.destroy();
|
||||
uf::renderer::rebuild = true;
|
||||
uf::renderer::states::rebuild = true;
|
||||
}
|
||||
}
|
||||
void uf::ObjectBehavior::tick( uf::Object& self ) {
|
||||
|
||||
@ -7,10 +7,10 @@ UF_BEHAVIOR_ENTITY_CPP_BEGIN(Scene)
|
||||
#define this ((uf::Scene*) &self)
|
||||
void uf::SceneBehavior::initialize( uf::Object& self ) {
|
||||
uf::renderer::scenes.push_back(this);
|
||||
uf::renderer::rebuild = true;
|
||||
uf::renderer::states::rebuild = true;
|
||||
|
||||
this->addHook( "system:Renderer.QueueRebuild", [&](const std::string& event)->std::string{
|
||||
uf::renderer::rebuild = true;
|
||||
uf::renderer::states::rebuild = true;
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "system:Destroy", [&](const std::string& event)->std::string{
|
||||
@ -34,7 +34,7 @@ void uf::SceneBehavior::render( uf::Object& self ) {
|
||||
void uf::SceneBehavior::destroy( uf::Object& self ) {
|
||||
auto it = std::find(uf::renderer::scenes.begin(), uf::renderer::scenes.end(), this);
|
||||
if ( it != uf::renderer::scenes.end() ) uf::renderer::scenes.erase(it);
|
||||
uf::renderer::rebuild = true;
|
||||
uf::renderer::states::rebuild = true;
|
||||
}
|
||||
#undef self
|
||||
UF_BEHAVIOR_ENTITY_CPP_END(Scene)
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -96,3 +97,4 @@ Result AchievementManager::GetUserAchievementAt(std::int32_t index,
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -175,3 +176,4 @@ void ActivityManager::AcceptInvite(UserId userId, std::function<void(Result)> ca
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -76,3 +77,4 @@ void ApplicationManager::GetTicket(std::function<void(Result, char const*)> call
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -180,3 +181,4 @@ discord::AchievementManager& Core::AchievementManager()
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,4 +1,5 @@
|
||||
#include <uf/ext/discord/discord.h>
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <array>
|
||||
@ -437,4 +438,10 @@ void UF_API ext::::discord::initialize() {
|
||||
void UF_API ext::::discord::tick() {
|
||||
DISCORD_REQUIRE(app.core->run_callbacks(app.core));
|
||||
}
|
||||
*/
|
||||
*/
|
||||
#else
|
||||
void UF_API ext::discord::initialize(){
|
||||
}
|
||||
void UF_API ext::discord::tick(){
|
||||
}
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -55,3 +56,4 @@ Result ImageManager::GetData(ImageHandle handle, std::uint8_t* data, std::uint32
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -545,3 +546,4 @@ Result LobbyManager::SendNetworkMessage(LobbyId lobbyId,
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -101,3 +102,4 @@ Result NetworkManager::SendMessage(NetworkPeerId peerId,
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -110,3 +111,4 @@ void OverlayManager::OpenVoiceSettings(std::function<void(Result)> callback)
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -88,3 +89,4 @@ Result RelationshipManager::GetAt(std::uint32_t index, Relationship* relationshi
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -156,3 +157,4 @@ Result StorageManager::GetPath(char path[4096])
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -158,3 +159,4 @@ void StoreManager::StartPurchase(Snowflake skuId, std::function<void(Result)> ca
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -767,3 +768,4 @@ Result LobbySearchQuery::Distance(LobbySearchDistance distance)
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -78,3 +79,4 @@ Result UserManager::CurrentUserHasFlag(UserFlag flag, bool* hasFlag)
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -1,3 +1,4 @@
|
||||
#if defined(UF_USE_DISCORD)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
@ -122,3 +123,4 @@ Result VoiceManager::SetLocalVolume(Snowflake userId, std::uint8_t volume)
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
#endif
|
||||
@ -2,7 +2,7 @@
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
#include <uf/utils/string/io.h>
|
||||
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
|
||||
#include <stdlib.h>
|
||||
@ -448,8 +448,8 @@ void ext::openvr::submit() { bool invert = swapEyes;
|
||||
|
||||
ext::vulkan::StereoscopicDeferredRenderMode* renderMode = (ext::vulkan::StereoscopicDeferredRenderMode*) &ext::vulkan::getRenderMode("");
|
||||
|
||||
float width = renderMode->width > 0 ? renderMode->width : ext::vulkan::width;
|
||||
float height = renderMode->height > 0 ? renderMode->height : ext::vulkan::height;
|
||||
float width = renderMode->width > 0 ? renderMode->width : uf::renderer::settings::width;
|
||||
float height = renderMode->height > 0 ? renderMode->height : uf::renderer::settings::height;
|
||||
auto& leftOutputAttachment = renderMode->renderTargets.left.attachments[renderMode->renderTargets.left.attachments.size()-1];
|
||||
auto& rightOutputAttachment = renderMode->renderTargets.right.attachments[renderMode->renderTargets.right.attachments.size()-1];
|
||||
|
||||
|
||||
@ -65,11 +65,11 @@ namespace {
|
||||
if ( feature == #NAME ) {\
|
||||
if ( device.features.NAME == VK_TRUE ) {\
|
||||
device.enabledFeatures.NAME = true;\
|
||||
if ( ext::vulkan::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
|
||||
} else if ( ext::vulkan::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
|
||||
if ( ext::vulkan::settings::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
|
||||
} else if ( ext::vulkan::settings::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
|
||||
}
|
||||
|
||||
for ( auto& feature : ext::vulkan::requestedDeviceFeatures ) {
|
||||
for ( auto& feature : ext::vulkan::settings::requestedDeviceFeatures ) {
|
||||
CHECK_FEATURE(robustBufferAccess);
|
||||
CHECK_FEATURE(fullDrawIndexUint32);
|
||||
CHECK_FEATURE(imageCubeArray);
|
||||
@ -132,8 +132,8 @@ namespace {
|
||||
if ( feature == #NAME ) {\
|
||||
if ( device.features2.NAME == VK_TRUE ) {\
|
||||
device.enabledFeatures2.NAME = true;\
|
||||
if ( ext::vulkan::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
|
||||
} else if ( ext::vulkan::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
|
||||
if ( ext::vulkan::settings::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
|
||||
} else if ( ext::vulkan::settings::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
|
||||
}
|
||||
#undef CHECK_FEATURE2
|
||||
}
|
||||
@ -510,7 +510,7 @@ void ext::vulkan::Device::initialize() {
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
};
|
||||
// Assert validation layers
|
||||
if ( ext::vulkan::validation ) {
|
||||
if ( ext::vulkan::settings::validation ) {
|
||||
uint32_t layerCount;
|
||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||
std::vector<VkLayerProperties> availableLayers(layerCount);
|
||||
@ -527,14 +527,14 @@ void ext::vulkan::Device::initialize() {
|
||||
}
|
||||
//
|
||||
// Get extensions
|
||||
std::vector<std::string> requestedExtensions = window->getExtensions( ext::vulkan::validation );
|
||||
std::vector<std::string> requestedExtensions = window->getExtensions( ext::vulkan::settings::validation );
|
||||
// Load any requested extensions
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::requestedInstanceExtensions.begin(), ext::vulkan::requestedInstanceExtensions.end() );
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::settings::requestedInstanceExtensions.begin(), ext::vulkan::settings::requestedInstanceExtensions.end() );
|
||||
// OpenVR Support
|
||||
if ( ext::openvr::enabled ) VRInstanceExtensions(requestedExtensions);
|
||||
|
||||
{
|
||||
if ( ext::vulkan::validation )
|
||||
if ( ext::vulkan::settings::validation )
|
||||
for ( auto ext : requestedExtensions )
|
||||
std::cout << "Requested instance extension: " << ext << std::endl;
|
||||
|
||||
@ -551,7 +551,7 @@ void ext::vulkan::Device::initialize() {
|
||||
{
|
||||
std::vector<const char*> instanceExtensions;
|
||||
for ( auto& s : supportedExtensions.instance ) {
|
||||
if ( ext::vulkan::validation )
|
||||
if ( ext::vulkan::settings::validation )
|
||||
std::cout << "Enabled instance extension: " << s << std::endl;
|
||||
instanceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
@ -571,7 +571,7 @@ void ext::vulkan::Device::initialize() {
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
|
||||
createInfo.ppEnabledExtensionNames = instanceExtensions.data();
|
||||
|
||||
if ( ext::vulkan::validation ) {
|
||||
if ( ext::vulkan::settings::validation ) {
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||
createInfo.ppEnabledLayerNames = validationLayers.data();
|
||||
} else {
|
||||
@ -581,7 +581,7 @@ void ext::vulkan::Device::initialize() {
|
||||
VK_CHECK_RESULT( vkCreateInstance( &createInfo, nullptr, &this->instance ));
|
||||
}
|
||||
// Setup debug
|
||||
if ( ext::vulkan::validation ) {
|
||||
if ( ext::vulkan::settings::validation ) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo = {};
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
@ -649,7 +649,7 @@ void ext::vulkan::Device::initialize() {
|
||||
else if (counts & VK_SAMPLE_COUNT_8_BIT) maxSamples = 8;
|
||||
else if (counts & VK_SAMPLE_COUNT_4_BIT) maxSamples = 4;
|
||||
else if (counts & VK_SAMPLE_COUNT_2_BIT) maxSamples = 2;
|
||||
ext::vulkan::msaa = std::min( maxSamples, ext::vulkan::msaa );
|
||||
ext::vulkan::settings::msaa = std::min( maxSamples, ext::vulkan::settings::msaa );
|
||||
}
|
||||
}
|
||||
// Create logical device
|
||||
@ -657,14 +657,14 @@ void ext::vulkan::Device::initialize() {
|
||||
bool useSwapChain = true;
|
||||
VkQueueFlags requestedQueueTypes = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
|
||||
std::vector<std::string> requestedExtensions;
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::requestedDeviceExtensions.begin(), ext::vulkan::requestedDeviceExtensions.end() );
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::settings::requestedDeviceExtensions.begin(), ext::vulkan::settings::requestedDeviceExtensions.end() );
|
||||
// OpenVR Support
|
||||
if ( ext::openvr::enabled ) {
|
||||
VRDeviceExtensions( this->physicalDevice, requestedExtensions);
|
||||
}
|
||||
{
|
||||
// Allocate enough ExtensionProperties to support all extensions being enabled
|
||||
if ( ext::vulkan::validation )
|
||||
if ( ext::vulkan::settings::validation )
|
||||
for ( auto ext : requestedExtensions ) std::cout << "Requested device extension: " << ext << std::endl;
|
||||
|
||||
uint32_t extensionsCount = 0;
|
||||
@ -680,7 +680,7 @@ void ext::vulkan::Device::initialize() {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
for ( auto& s : supportedExtensions.device ) {
|
||||
if ( ext::vulkan::validation ) std::cout << "Enabled device extension: " << s << std::endl;
|
||||
if ( ext::vulkan::settings::validation ) std::cout << "Enabled device extension: " << s << std::endl;
|
||||
deviceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
|
||||
@ -758,7 +758,7 @@ void ext::vulkan::Device::initialize() {
|
||||
if ( vkCreateDevice( this->physicalDevice, &deviceCreateInfo, nullptr, &this->logicalDevice) != VK_SUCCESS )
|
||||
throw std::runtime_error("failed to create logical device!");
|
||||
|
||||
if ( ext::vulkan::validation )
|
||||
if ( ext::vulkan::settings::validation )
|
||||
std::cout << retrieveDeviceFeatures( *this ) << std::endl;
|
||||
}
|
||||
// Create command pool
|
||||
|
||||
@ -214,14 +214,17 @@ void ext::vulkan::Shader::destroy() {
|
||||
}
|
||||
|
||||
void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
return this->initialize( graphic, graphic.descriptor );
|
||||
}
|
||||
void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& descriptor ) {
|
||||
this->device = graphic.device;
|
||||
Device& device = *graphic.device;
|
||||
|
||||
// std::cout << &graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size() << std::endl;
|
||||
assert( graphic.material.shaders.size() > 0 );
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget( graphic.descriptor.renderTarget );
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget( descriptor.renderTarget );
|
||||
{
|
||||
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||
std::vector<VkPushConstantRange> pushConstantRanges;
|
||||
@ -302,14 +305,14 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
// Graphic
|
||||
{
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = ext::vulkan::initializers::pipelineInputAssemblyStateCreateInfo(
|
||||
graphic.descriptor.topology,
|
||||
descriptor.topology,
|
||||
0,
|
||||
VK_FALSE
|
||||
);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo(
|
||||
graphic.descriptor.fill,
|
||||
graphic.descriptor.cullMode, // VK_CULL_MODE_NONE,
|
||||
graphic.descriptor.frontFace,
|
||||
descriptor.fill,
|
||||
descriptor.cullMode, // VK_CULL_MODE_NONE,
|
||||
descriptor.frontFace,
|
||||
0
|
||||
);
|
||||
rasterizationState.lineWidth = graphic.descriptor.lineWidth;
|
||||
@ -317,7 +320,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
std::vector<VkPipelineColorBlendAttachmentState> blendAttachmentStates;
|
||||
|
||||
if ( renderMode.getType() != "Swapchain" ) {
|
||||
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
|
||||
auto& subpass = renderTarget.passes[descriptor.subpass];
|
||||
for ( auto& color : subpass.colors ) {
|
||||
blendAttachmentStates.push_back(renderTarget.attachments[color.attachment].blendState);
|
||||
}
|
||||
@ -328,7 +331,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
graphic.descriptor.subpass = 0;
|
||||
descriptor.subpass = 0;
|
||||
|
||||
VkBool32 blendEnabled = VK_FALSE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
|
||||
@ -358,15 +361,15 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
blendAttachmentStates.data()
|
||||
);
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState = ext::vulkan::initializers::pipelineDepthStencilStateCreateInfo(
|
||||
graphic.descriptor.depthTest.test,
|
||||
graphic.descriptor.depthTest.write,
|
||||
graphic.descriptor.depthTest.operation //VK_COMPARE_OP_LESS_OR_EQUAL
|
||||
descriptor.depthTest.test,
|
||||
descriptor.depthTest.write,
|
||||
descriptor.depthTest.operation //VK_COMPARE_OP_LESS_OR_EQUAL
|
||||
);
|
||||
VkPipelineViewportStateCreateInfo viewportState = ext::vulkan::initializers::pipelineViewportStateCreateInfo(
|
||||
1, 1, 0
|
||||
);
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
switch ( ext::vulkan::msaa ) {
|
||||
switch ( ext::vulkan::settings::msaa ) {
|
||||
case 64: samples = VK_SAMPLE_COUNT_64_BIT; break;
|
||||
case 32: samples = VK_SAMPLE_COUNT_32_BIT; break;
|
||||
case 16: samples = VK_SAMPLE_COUNT_16_BIT; break;
|
||||
@ -393,14 +396,14 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
std::vector<VkVertexInputBindingDescription> vertexBindingDescriptions = {
|
||||
ext::vulkan::initializers::vertexInputBindingDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
graphic.descriptor.geometry.sizes.vertex,
|
||||
descriptor.geometry.sizes.vertex,
|
||||
VK_VERTEX_INPUT_RATE_VERTEX
|
||||
)
|
||||
};
|
||||
// Attribute descriptions
|
||||
// Describes memory layout and shader positions
|
||||
std::vector<VkVertexInputAttributeDescription> vertexAttributeDescriptions = {};
|
||||
for ( auto& attribute : graphic.descriptor.geometry.attributes ) {
|
||||
for ( auto& attribute : descriptor.geometry.attributes ) {
|
||||
auto d = ext::vulkan::initializers::vertexInputAttributeDescription(
|
||||
VERTEX_BUFFER_BIND_ID,
|
||||
vertexAttributeDescriptions.size(),
|
||||
@ -436,7 +439,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
pipelineCreateInfo.pDynamicState = &dynamicState;
|
||||
pipelineCreateInfo.stageCount = shaderDescriptors.size();
|
||||
pipelineCreateInfo.pStages = shaderDescriptors.data();
|
||||
pipelineCreateInfo.subpass = graphic.descriptor.subpass;
|
||||
pipelineCreateInfo.subpass = descriptor.subpass;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines( device, device.pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));
|
||||
}
|
||||
@ -476,11 +479,14 @@ void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuf
|
||||
vkCmdBindPipeline(commandBuffer, bindPoint, pipeline);
|
||||
}
|
||||
void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
return this->update( graphic, graphic.descriptor );
|
||||
}
|
||||
void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descriptor ) {
|
||||
// generate fallback empty texture
|
||||
auto& emptyTexture = Texture2D::empty;
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(graphic.descriptor.renderTarget );
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(descriptor.renderTarget );
|
||||
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||
@ -491,8 +497,8 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
descriptorSetLayoutBindings.insert( descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.end() );
|
||||
}
|
||||
|
||||
if ( graphic.descriptor.subpass < renderTarget.passes.size() ) {
|
||||
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
|
||||
if ( descriptor.subpass < renderTarget.passes.size() ) {
|
||||
auto& subpass = renderTarget.passes[descriptor.subpass];
|
||||
for ( auto& input : subpass.inputs ) {
|
||||
inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
|
||||
renderTarget.attachments[input.attachment].view,
|
||||
@ -525,14 +531,14 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {
|
||||
auto& descriptor = buffersStorageVector.emplace_back(buffer.descriptor);
|
||||
if ( descriptor.offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {
|
||||
std::cout << __LINE__ << ": Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
|
||||
std::cout << "[" << __LINE__ << "] Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
|
||||
descriptor.offset = 0;
|
||||
}
|
||||
}
|
||||
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
|
||||
auto& descriptor = buffersUniformsVector.emplace_back(buffer.descriptor);
|
||||
if ( descriptor.offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||
std::cout << __LINE__ << ": Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
|
||||
std::cout << "[" << __LINE__ << "] Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
|
||||
descriptor.offset = 0;
|
||||
}
|
||||
}
|
||||
@ -673,7 +679,7 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
||||
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo[i].offset << std::endl;
|
||||
std::cout << "Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " " << descriptor.pBufferInfo[i].offset << " " << descriptor.pBufferInfo[i].range << ", invalidating..." << std::endl;
|
||||
std::cout << "[" << __LINE__ << "] Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " " << descriptor.pBufferInfo[i].offset << " " << descriptor.pBufferInfo[i].range << ", invalidating..." << std::endl;
|
||||
auto pointer = const_cast<VkDescriptorBufferInfo*>(&descriptor.pBufferInfo[i]);
|
||||
pointer->offset = 0;
|
||||
pointer->range = 0;
|
||||
@ -774,33 +780,38 @@ void ext::vulkan::Graphic::initialize( const std::string& renderModeName ) {
|
||||
void ext::vulkan::Graphic::initializePipeline() {
|
||||
initializePipeline( this->descriptor, false );
|
||||
}
|
||||
ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( Descriptor& descriptor, bool update ) {
|
||||
ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( GraphicDescriptor& descriptor, bool update ) {
|
||||
auto& pipeline = pipelines[descriptor.hash()];
|
||||
|
||||
Descriptor previous = this->descriptor;
|
||||
this->descriptor = descriptor;
|
||||
pipeline.initialize(*this);
|
||||
pipeline.update(*this);
|
||||
if ( !update ) this->descriptor = previous;
|
||||
// auto previous = this->descriptor;
|
||||
// this->descriptor = descriptor;
|
||||
pipeline.initialize(*this, descriptor);
|
||||
pipeline.update(*this, descriptor);
|
||||
// if ( !update ) this->descriptor = previous;
|
||||
|
||||
initialized = true;
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
bool ext::vulkan::Graphic::hasPipeline( Descriptor& descriptor ) {
|
||||
bool ext::vulkan::Graphic::hasPipeline( GraphicDescriptor& descriptor ) {
|
||||
return pipelines.count( descriptor.hash() ) > 0;
|
||||
}
|
||||
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() {
|
||||
return getPipeline( descriptor );
|
||||
}
|
||||
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( Descriptor& descriptor ) {
|
||||
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( GraphicDescriptor& descriptor ) {
|
||||
if ( !hasPipeline(descriptor) ) return initializePipeline( descriptor );
|
||||
return pipelines[descriptor.hash()];
|
||||
}
|
||||
void ext::vulkan::Graphic::updatePipelines() {
|
||||
for ( auto pair : this->pipelines ) {
|
||||
pair.second.update( *this );
|
||||
}
|
||||
}
|
||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
|
||||
return this->record( commandBuffer, descriptor );
|
||||
}
|
||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, Descriptor& descriptor ) {
|
||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescriptor& descriptor ) {
|
||||
if ( !this->hasPipeline( descriptor ) ) {
|
||||
std::cout << this << ": has no valid pipeline" << std::endl;
|
||||
return;
|
||||
@ -838,14 +849,15 @@ void ext::vulkan::Graphic::destroy() {
|
||||
|
||||
ext::vulkan::Buffers::destroy();
|
||||
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
|
||||
#include <uf/utils/string/hash.h>
|
||||
std::string ext::vulkan::Graphic::Descriptor::hash() const {
|
||||
std::string ext::vulkan::GraphicDescriptor::hash() const {
|
||||
uf::Serializer serializer;
|
||||
|
||||
serializer["subpass"] = subpass;
|
||||
if ( settings::experimental::individualPipelines ) serializer["renderMode"] = renderMode;
|
||||
serializer["renderTarget"] = renderTarget;
|
||||
serializer["geometry"]["sizes"]["vertex"] = geometry.sizes.vertex;
|
||||
serializer["geometry"]["sizes"]["indices"] = geometry.sizes.indices;
|
||||
@ -867,6 +879,6 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const {
|
||||
serializer["depthTest"]["write"] = depthTest.write;
|
||||
serializer["depthTest"]["operation"] = depthTest.operation;
|
||||
|
||||
// std::cout << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << std::endl;
|
||||
// if ( renderMode != "Gui" ) std::cout << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << std::endl;
|
||||
return uf::string::sha256( serializer.serialize() );
|
||||
}
|
||||
@ -34,16 +34,7 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized ) return;
|
||||
if ( !graphic.process ) return;
|
||||
/*
|
||||
if ( !entity->hasComponent<uf::Mesh>() ) return;
|
||||
uf::MeshBase& mesh = entity->getComponent<uf::Mesh>();
|
||||
if ( !mesh.generated ) return;
|
||||
ext::vulkan::Graphic& graphic = mesh.graphic;
|
||||
if ( !graphic.initialized ) return;
|
||||
if ( !graphic.process ) return;
|
||||
*/
|
||||
if ( !graphic.initialized || !graphic.process ) return;
|
||||
graphics.push_back(&graphic);
|
||||
};
|
||||
for ( uf::Scene* scene : ext::vulkan::scenes ) {
|
||||
@ -52,7 +43,7 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
bindPipelines( graphics );
|
||||
// bindPipelines( graphics );
|
||||
createCommandBuffers( graphics );
|
||||
this->mostRecentCommandPoolId = std::this_thread::get_id();
|
||||
this->rebuild = false;
|
||||
@ -75,45 +66,35 @@ ext::vulkan::RenderMode::commands_container_t& ext::vulkan::RenderMode::getComma
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(*device, &cmdBufAllocateInfo, commands.data()));
|
||||
}
|
||||
return commands;
|
||||
/*
|
||||
VkCommandPool* pool = NULL;
|
||||
switch ( queueEnum ) {
|
||||
case QueueEnum::GRAPHICS:
|
||||
index = device.queueFamilyIndices.graphics;
|
||||
if ( commandPool.graphics.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.graphics[id];
|
||||
break;
|
||||
case QueueEnum::COMPUTE:
|
||||
index = device.queueFamilyIndices.compute;
|
||||
if ( commandPool.compute.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.compute[id];
|
||||
break;
|
||||
case QueueEnum::TRANSFER:
|
||||
index = device.queueFamilyIndices.transfer;
|
||||
if ( commandPool.transfer.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.transfer[id];
|
||||
break;
|
||||
}
|
||||
if ( !exists ) {
|
||||
VkCommandPoolCreateFlags createFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
VkCommandPoolCreateInfo cmdPoolInfo = {};
|
||||
cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
cmdPoolInfo.queueFamilyIndex = index;
|
||||
cmdPoolInfo.flags = createFlags;
|
||||
if ( vkCreateCommandPool( this->logicalDevice, &cmdPoolInfo, nullptr, pool ) != VK_SUCCESS )
|
||||
throw std::runtime_error("failed to create command pool for graphics!");
|
||||
}
|
||||
return *pool;
|
||||
*/
|
||||
}
|
||||
void ext::vulkan::RenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
|
||||
}
|
||||
void ext::vulkan::RenderMode::bindPipelines() {
|
||||
this->execute = true;
|
||||
|
||||
std::vector<ext::vulkan::Graphic*> graphics;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( !graphic.initialized ) return;
|
||||
if ( !graphic.process ) return;
|
||||
graphics.push_back(&graphic);
|
||||
};
|
||||
for ( uf::Scene* scene : ext::vulkan::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
this->bindPipelines( graphics );
|
||||
}
|
||||
void ext::vulkan::RenderMode::bindPipelines( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
for ( auto* pointer : graphics ) {
|
||||
auto& graphic = *pointer;
|
||||
// copy descriptor
|
||||
ext::vulkan::Graphic::Descriptor descriptor = graphic.descriptor;
|
||||
if ( graphic.descriptor.renderMode == this->getName() ) continue;
|
||||
ext::vulkan::GraphicDescriptor descriptor = graphic.descriptor;
|
||||
// bind to this render mode
|
||||
descriptor.renderMode = this->getName();
|
||||
// ignore if pipeline exists for this render mode
|
||||
@ -125,11 +106,11 @@ void ext::vulkan::RenderMode::bindPipelines( const std::vector<ext::vulkan::Grap
|
||||
void ext::vulkan::RenderMode::render() {
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Get next image in the swap chain (back/front buffer)
|
||||
VK_CHECK_RESULT(swapchain.acquireNextImage(¤tBuffer, swapchain.presentCompleteSemaphore));
|
||||
VK_CHECK_RESULT(swapchain.acquireNextImage(&states::currentBuffer, swapchain.presentCompleteSemaphore));
|
||||
|
||||
// Use a fence to wait until the command buffer has finished execution before using it again
|
||||
VK_CHECK_RESULT(vkWaitForFences(*device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX));
|
||||
VK_CHECK_RESULT(vkResetFences(*device, 1, &fences[currentBuffer]));
|
||||
VK_CHECK_RESULT(vkWaitForFences(*device, 1, &fences[states::currentBuffer], VK_TRUE, UINT64_MAX));
|
||||
VK_CHECK_RESULT(vkResetFences(*device, 1, &fences[states::currentBuffer]));
|
||||
|
||||
// Pipeline stage at which the queue submission will wait (via pWaitSemaphores)
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
@ -141,17 +122,17 @@ void ext::vulkan::RenderMode::render() {
|
||||
submitInfo.waitSemaphoreCount = 1; // One wait semaphore
|
||||
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
|
||||
submitInfo.signalSemaphoreCount = 1; // One signal semaphore
|
||||
submitInfo.pCommandBuffers = &commands[currentBuffer]; // Command buffers(s) to execute in this batch (submission)
|
||||
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission)
|
||||
submitInfo.commandBufferCount = 1;
|
||||
|
||||
// Submit to the graphics queue passing a wait fence
|
||||
VK_CHECK_RESULT(vkQueueSubmit( device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[currentBuffer]);
|
||||
VK_CHECK_RESULT(vkQueueSubmit( device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[states::currentBuffer]);
|
||||
|
||||
// Present the current buffer to the swap chain
|
||||
// Pass the semaphore signaled by the command buffer submission from the submit info as the wait semaphore for swap chain presentation
|
||||
// This ensures that the image is not presented to the windowing system until all commands have been submitted
|
||||
VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( Device::QueueEnum::PRESENT ), currentBuffer, renderCompleteSemaphore));
|
||||
VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( Device::QueueEnum::PRESENT ), states::currentBuffer, renderCompleteSemaphore));
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(device->getQueue( Device::QueueEnum::PRESENT )));
|
||||
}
|
||||
|
||||
|
||||
@ -21,8 +21,8 @@ std::string ext::vulkan::BaseRenderMode::getType() const {
|
||||
void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
if ( ext::vulkan::renderModes.size() > 1 ) return;
|
||||
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
VkCommandBufferBeginInfo commandBufferInfo = {};
|
||||
commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
@ -83,7 +83,7 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::v
|
||||
|
||||
void ext::vulkan::BaseRenderMode::tick() {
|
||||
ext::vulkan::RenderMode::tick();
|
||||
if ( ext::vulkan::resized ) {
|
||||
if ( ext::vulkan::states::resized ) {
|
||||
this->destroy();
|
||||
this->initialize( *this->device );
|
||||
}
|
||||
@ -110,8 +110,8 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
|
||||
renderTarget.attachments.clear();
|
||||
renderTarget.attachments.resize( ext::vulkan::swapchain.buffers + 1 );
|
||||
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
for ( size_t i = 0; i < images.size(); ++i ) {
|
||||
VkImageViewCreateInfo colorAttachmentView = {};
|
||||
|
||||
@ -24,8 +24,8 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
||||
// this->height = 2160;
|
||||
|
||||
{
|
||||
auto width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
auto height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
auto width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
auto height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
compute.device = &device;
|
||||
compute.material.device = &device;
|
||||
@ -61,8 +61,8 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
||||
|
||||
// update buffers
|
||||
if ( !compute.buffers.empty() ) {
|
||||
auto& pipeline = compute.getPipeline();
|
||||
pipeline.update( compute );
|
||||
// compute.getPipeline().update( compute );
|
||||
compute.updatePipelines();
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -102,24 +102,24 @@ void ext::vulkan::ComputeRenderMode::render() {
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Submit compute commands
|
||||
// Use a fence to ensure that compute command buffer has finished executing before using it again
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[currentBuffer] ));
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[states::currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[states::currentBuffer] ));
|
||||
|
||||
VkSubmitInfo submitInfo = ext::vulkan::initializers::submitInfo();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &commands[currentBuffer];
|
||||
submitInfo.pCommandBuffers = &commands[states::currentBuffer];
|
||||
|
||||
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::COMPUTE ), 1, &submitInfo, fences[currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.compute, 1, &submitInfo, fences[currentBuffer]);
|
||||
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::COMPUTE ), 1, &submitInfo, fences[states::currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.compute, 1, &submitInfo, fences[states::currentBuffer]);
|
||||
}
|
||||
void ext::vulkan::ComputeRenderMode::tick() {
|
||||
ext::vulkan::RenderMode::tick();
|
||||
|
||||
if ( ext::vulkan::resized ) {
|
||||
if ( ext::vulkan::states::resized ) {
|
||||
// auto-resize texture
|
||||
if ( this->width == 0 && this->height == 0 ) {
|
||||
auto width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
auto height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
auto width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
auto height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
for ( auto& texture : compute.material.textures ) {
|
||||
texture.destroy();
|
||||
}
|
||||
@ -138,9 +138,11 @@ void ext::vulkan::ComputeRenderMode::tick() {
|
||||
texture.device = NULL;
|
||||
}
|
||||
blitter.getPipeline().update( blitter );
|
||||
// blitter.updatePipelines();
|
||||
}
|
||||
if ( !compute.buffers.empty() ) {
|
||||
compute.getPipeline().update( compute );
|
||||
// compute.updatePipelines();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,8 +202,8 @@ void ext::vulkan::ComputeRenderMode::pipelineBarrier( VkCommandBuffer commandBuf
|
||||
void ext::vulkan::ComputeRenderMode::createCommandBuffers( ) {
|
||||
this->synchronize();
|
||||
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
||||
auto& pipeline = compute.getPipeline();
|
||||
|
||||
@ -72,7 +72,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.position/*, attachments.depth*/ },
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
@ -98,7 +98,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
blitter.initializeGeometry( mesh );
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
@ -156,11 +156,12 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
void ext::vulkan::DeferredRenderMode::tick() {
|
||||
ext::vulkan::RenderMode::tick();
|
||||
|
||||
if ( ext::vulkan::resized ) {
|
||||
if ( ext::vulkan::states::resized ) {
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
// update blitter descriptor set
|
||||
if ( blitter.initialized ) {
|
||||
blitter.getPipeline().update( blitter );
|
||||
// blitter.updatePipelines();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,24 +170,12 @@ void ext::vulkan::DeferredRenderMode::destroy() {
|
||||
blitter.destroy();
|
||||
}
|
||||
void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
// destroy if exists
|
||||
// ext::vulkan::RenderMode& swapchain =
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
cmdBufInfo.pNext = nullptr;
|
||||
/*
|
||||
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;
|
||||
*/
|
||||
|
||||
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
@ -246,21 +235,6 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
// transition layers for read
|
||||
for ( auto layer : layers ) {
|
||||
layer->pipelineBarrier( commands[i], 0 );
|
||||
/*
|
||||
if ( layer->getName() == "" ) continue;
|
||||
RenderTarget& renderTarget = layer->renderTarget;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.oldLayout = attachment.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
attachment.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
@ -269,15 +243,14 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
graphic->record(commands[i] );
|
||||
graphic->record( commands[i] );
|
||||
}
|
||||
// render gui layer
|
||||
// blit any RT's
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized ) continue;
|
||||
if ( blitter.descriptor.subpass != 0 ) continue;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 0 ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
@ -285,13 +258,12 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
{
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
// render gui layer
|
||||
// blit any RT's
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized ) continue;
|
||||
if ( blitter.descriptor.subpass != 1 ) continue;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 1 ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
@ -299,21 +271,6 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
|
||||
for ( auto layer : layers ) {
|
||||
layer->pipelineBarrier( commands[i], 1 );
|
||||
/*
|
||||
if ( layer->getName() == "" ) continue;
|
||||
RenderTarget& renderTarget = layer->renderTarget;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = attachment.layout;
|
||||
imageMemoryBarrier.newLayout = attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
attachment.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
);
|
||||
}
|
||||
// NOP
|
||||
{
|
||||
if ( !false ) {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
@ -78,7 +78,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
renderTarget.initialize( device );
|
||||
|
||||
{
|
||||
if ( blitter.process ) {
|
||||
uf::BaseMesh<pod::Vertex_2F2F, uint32_t> mesh;
|
||||
mesh.vertices = {
|
||||
{ {-1.0f, 1.0f}, {0.0f, 1.0f}, },
|
||||
@ -108,19 +108,18 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
void ext::vulkan::RenderTargetRenderMode::tick() {
|
||||
ext::vulkan::RenderMode::tick();
|
||||
if ( ext::vulkan::resized ) {
|
||||
if ( ext::vulkan::states::resized ) {
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
|
||||
blitter.material.textures.clear();
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
|
||||
Texture2D& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
}
|
||||
|
||||
auto& pipeline = blitter.getPipeline();
|
||||
pipeline.update( blitter );
|
||||
if ( blitter.process ) {
|
||||
blitter.getPipeline().update( blitter );
|
||||
// blitter.updatePipelines();
|
||||
}
|
||||
}
|
||||
}
|
||||
void ext::vulkan::RenderTargetRenderMode::destroy() {
|
||||
@ -131,8 +130,8 @@ void ext::vulkan::RenderTargetRenderMode::render() {
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Submit commands
|
||||
// Use a fence to ensure that command buffer has finished executing before using it again
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[currentBuffer] ));
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[states::currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[states::currentBuffer] ));
|
||||
|
||||
// Pipeline stage at which the queue submission will wait (via pWaitSemaphores)
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
@ -146,11 +145,11 @@ void ext::vulkan::RenderTargetRenderMode::render() {
|
||||
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
|
||||
submitInfo.signalSemaphoreCount = 1; // One signal semaphore
|
||||
*/
|
||||
submitInfo.pCommandBuffers = &commands[currentBuffer]; // Command buffers(s) to execute in this batch (submission)
|
||||
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission)
|
||||
submitInfo.commandBufferCount = 1;
|
||||
|
||||
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[currentBuffer]);
|
||||
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
|
||||
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[states::currentBuffer]);
|
||||
/*
|
||||
VkSemaphoreWaitInfo waitInfo = {};
|
||||
waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
|
||||
@ -217,8 +216,8 @@ void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer comma
|
||||
}
|
||||
void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
// destroy if exists
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
@ -269,11 +268,11 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto
|
||||
vkCmdSetScissor(commands[i], 0, 1, &scissor);
|
||||
for ( auto graphic : graphics ) {
|
||||
if ( graphic->descriptor.renderMode != this->target ) continue;
|
||||
ext::vulkan::Graphic::Descriptor descriptor = graphic->descriptor;
|
||||
descriptor.renderMode = this->name;
|
||||
ext::vulkan::GraphicDescriptor descriptor = graphic->descriptor;
|
||||
// descriptor.renderMode = this->name;
|
||||
graphic->record(commands[i], descriptor );
|
||||
}
|
||||
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
|
||||
if ( !false ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdEndRenderPass(commands[i]);
|
||||
}
|
||||
|
||||
|
||||
@ -85,14 +85,29 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
{
|
||||
/*
|
||||
if ( i == 0 ) {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.position/*, attachments.depth*/ },
|
||||
{ attachments.albedo, attachments.normals, attachments.depth },
|
||||
attachments.depth
|
||||
);
|
||||
} else {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
*/
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
attachments.depth
|
||||
);
|
||||
renderTarget.initialize( device );
|
||||
{
|
||||
uf::BaseMesh<pod::Vertex_2F2F, uint16_t> mesh;
|
||||
@ -112,10 +127,18 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
|
||||
blitter.initialize( this->getName() );
|
||||
blitter.initializeGeometry( mesh );
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
if ( i == 0 ) {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
// {"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
} else {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
}
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
@ -141,11 +164,12 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
blitter.initializePipeline();
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
|
||||
ext::vulkan::RenderMode::tick();
|
||||
if ( ext::vulkan::resized ) {
|
||||
if ( ext::vulkan::states::resized ) {
|
||||
struct EYES {
|
||||
RenderTarget* renderTarget;
|
||||
Graphic* blitter;
|
||||
@ -160,8 +184,8 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
|
||||
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
if ( blitter.initialized ) {
|
||||
auto& pipeline = blitter.getPipeline();
|
||||
pipeline.update( blitter );
|
||||
blitter.getPipeline().update( blitter );
|
||||
// blitter.updatePipelines();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,8 +200,8 @@ void ext::vulkan::StereoscopicDeferredRenderMode::destroy() {
|
||||
void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
// destroy if exists
|
||||
// ext::vulkan::RenderMode& swapchain =
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
@ -270,20 +294,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
// update push constants
|
||||
/*
|
||||
auto& shaders = graphic->material.shaders;
|
||||
for ( auto& shader : shaders ) {
|
||||
for ( auto& pushConstant : shader.pushConstants ) {
|
||||
struct Stereo {
|
||||
uint32_t pass;
|
||||
};
|
||||
auto& stereo = pushConstant.get<Stereo>();
|
||||
stereo.pass = ext::openvr::renderPass;
|
||||
std::cout << pushConstant.data().data << ": Expecting " << stereo.pass << std::endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
graphic->record(commands[i] );
|
||||
}
|
||||
// render gui layer
|
||||
@ -291,8 +301,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized ) continue;
|
||||
if ( blitter.descriptor.subpass != 0 ) continue;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 0 ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
@ -305,8 +314,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized ) continue;
|
||||
if ( blitter.descriptor.subpass != 1 ) continue;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 1 ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
@ -354,8 +362,8 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
imageBlitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
imageBlitRegion.dstSubresource.layerCount = 1;
|
||||
imageBlitRegion.dstOffsets[1] = {
|
||||
swapchainRender.width > 0 ? swapchainRender.width : ext::vulkan::width,
|
||||
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::height,
|
||||
swapchainRender.width > 0 ? swapchainRender.width : ext::vulkan::settings::width,
|
||||
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::settings::height,
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFla
|
||||
passes.push_back(pass);
|
||||
}
|
||||
size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usage, VkImageLayout layout, bool blend, Attachment* attachment ) {
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
if ( !attachment ) {
|
||||
attachments.resize(attachments.size()+1);
|
||||
@ -49,7 +49,7 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
switch ( ext::vulkan::msaa ) {
|
||||
switch ( ext::vulkan::settings::msaa ) {
|
||||
case 64: samples = VK_SAMPLE_COUNT_64_BIT; break;
|
||||
case 32: samples = VK_SAMPLE_COUNT_32_BIT; break;
|
||||
case 16: samples = VK_SAMPLE_COUNT_16_BIT; break;
|
||||
@ -142,8 +142,8 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
{
|
||||
this->device = &device;
|
||||
}
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
// resize attachments if necessary
|
||||
if ( initialized ) {
|
||||
|
||||
@ -28,8 +28,8 @@ void ext::vulkan::Swapchain::initialize( Device& device ) {
|
||||
// Bind
|
||||
{
|
||||
this->device = &device;
|
||||
if ( width == 0 ) width = ext::vulkan::width;
|
||||
if ( height == 0 ) height = ext::vulkan::height;
|
||||
// if ( width == 0 ) width = ext::vulkan::settings::width;
|
||||
// if ( height == 0 ) height = ext::vulkan::settings::height;
|
||||
}
|
||||
// Set present
|
||||
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
|
||||
@ -9,29 +9,32 @@
|
||||
#include <fstream>
|
||||
#include <atomic>
|
||||
|
||||
uint32_t ext::vulkan::width = 1280;
|
||||
uint32_t ext::vulkan::height = 720;
|
||||
uint8_t ext::vulkan::msaa = 1;
|
||||
uint32_t ext::vulkan::settings::width = 1280;
|
||||
uint32_t ext::vulkan::settings::height = 720;
|
||||
uint8_t ext::vulkan::settings::msaa = 1;
|
||||
bool ext::vulkan::settings::validation = true;
|
||||
|
||||
std::vector<std::string> ext::vulkan::settings::validationFilters;
|
||||
std::vector<std::string> ext::vulkan::settings::requestedDeviceFeatures;
|
||||
std::vector<std::string> ext::vulkan::settings::requestedDeviceExtensions;
|
||||
std::vector<std::string> ext::vulkan::settings::requestedInstanceExtensions;
|
||||
|
||||
bool ext::vulkan::settings::experimental::rebuildOnTickBegin = false;
|
||||
bool ext::vulkan::settings::experimental::waitOnRenderEnd = false;
|
||||
bool ext::vulkan::settings::experimental::individualPipelines = false;
|
||||
bool ext::vulkan::settings::experimental::multithreadedCommandRecording = false;
|
||||
|
||||
bool ext::vulkan::validation = true;
|
||||
bool ext::vulkan::rebuildOnTickStart = false;
|
||||
bool ext::vulkan::waitOnRenderEnd = false;
|
||||
std::vector<std::string> ext::vulkan::validationFilters;
|
||||
std::vector<std::string> ext::vulkan::requestedDeviceFeatures;
|
||||
std::vector<std::string> ext::vulkan::requestedDeviceExtensions;
|
||||
std::vector<std::string> ext::vulkan::requestedInstanceExtensions;
|
||||
ext::vulkan::Device ext::vulkan::device;
|
||||
ext::vulkan::Allocator ext::vulkan::allocator;
|
||||
ext::vulkan::Swapchain ext::vulkan::swapchain;
|
||||
std::mutex ext::vulkan::mutex;
|
||||
|
||||
bool ext::vulkan::resized = false;
|
||||
bool ext::vulkan::rebuild = false;
|
||||
uint32_t ext::vulkan::currentBuffer = 0;
|
||||
std::vector<std::string> ext::vulkan::passes = { "BASE" };
|
||||
bool ext::vulkan::states::resized = false;
|
||||
bool ext::vulkan::states::rebuild = false;
|
||||
uint32_t ext::vulkan::states::currentBuffer = 0;
|
||||
|
||||
std::vector<uf::Scene*> ext::vulkan::scenes;
|
||||
ext::vulkan::RenderMode* ext::vulkan::currentRenderMode = NULL;
|
||||
|
||||
std::vector<ext::vulkan::RenderMode*> ext::vulkan::renderModes = {
|
||||
new ext::vulkan::BaseRenderMode,
|
||||
};
|
||||
@ -55,51 +58,13 @@ VKAPI_ATTR VkBool32 VKAPI_CALL ext::vulkan::debugCallback(
|
||||
) {
|
||||
// if ( messageSeverity <= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT ) return VK_FALSE;
|
||||
std::string message = pCallbackData->pMessage;
|
||||
for ( auto& filter : ext::vulkan::validationFilters ) {
|
||||
for ( auto& filter : ext::vulkan::settings::validationFilters ) {
|
||||
if ( message.find(filter) != std::string::npos ) return VK_FALSE;
|
||||
}
|
||||
uf::iostream << "[Validation Layer] " << message << "\n";
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
VkShaderModule ext::vulkan::loadShader(const char *filename, VkDevice device) {
|
||||
std::ifstream is(filename, std::ios::binary | std::ios::in | std::ios::ate);
|
||||
|
||||
if ( !is.is_open() ) {
|
||||
uf::iostream << "Error: Could not open shader file \"" << filename << "\"" << "\n";
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
size_t size = is.tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
char* shaderCode = new char[size];
|
||||
is.read(shaderCode, size);
|
||||
is.close();
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
VkShaderModuleCreateInfo moduleCreateInfo{};
|
||||
moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
moduleCreateInfo.codeSize = size;
|
||||
moduleCreateInfo.pCode = (uint32_t*)shaderCode;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule));
|
||||
|
||||
delete[] shaderCode;
|
||||
return shaderModule;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo ext::vulkan::loadShader( std::string filename, VkShaderStageFlagBits stage, VkDevice device, std::vector<VkShaderModule>& shaderModules ) {
|
||||
VkPipelineShaderStageCreateInfo shaderStage = {};
|
||||
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStage.stage = stage;
|
||||
shaderStage.module = loadShader(filename.c_str(), device);
|
||||
shaderStage.pName = "main";
|
||||
assert(shaderStage.module != VK_NULL_HANDLE);
|
||||
shaderModules.push_back(shaderStage.module);
|
||||
return shaderStage;
|
||||
}
|
||||
|
||||
std::string ext::vulkan::errorString( VkResult result ) {
|
||||
switch ( result ) {
|
||||
#define STR(r) case VK_ ##r: return #r
|
||||
@ -181,7 +146,7 @@ ext::vulkan::RenderMode& ext::vulkan::addRenderMode( ext::vulkan::RenderMode* mo
|
||||
renderModes.push_back(mode);
|
||||
std::cout << "Adding RenderMode: " << name << ": " << mode->getType() << std::endl;
|
||||
// reorder
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
return *mode;
|
||||
}
|
||||
ext::vulkan::RenderMode& ext::vulkan::getRenderMode( const std::string& name, bool isName ) {
|
||||
@ -221,7 +186,7 @@ void ext::vulkan::removeRenderMode( ext::vulkan::RenderMode* mode, bool free ) {
|
||||
renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() );
|
||||
mode->destroy();
|
||||
if ( free ) delete mode;
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
|
||||
void ext::vulkan::initialize( uint8_t stage ) {
|
||||
@ -248,10 +213,28 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->initialize(device);
|
||||
}
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
/*
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
case 1: {
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
@ -260,7 +243,7 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
if ( graphic.initialized ) return;
|
||||
|
||||
graphic.initializePipeline();
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
};
|
||||
for ( uf::Scene* scene : ext::vulkan::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
@ -268,10 +251,28 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
}
|
||||
}
|
||||
case 2: {
|
||||
/*
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
*/
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
throw std::runtime_error("invalid stage id");
|
||||
@ -280,8 +281,8 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
}
|
||||
void ext::vulkan::tick() {
|
||||
ext::vulkan::mutex.lock();
|
||||
if ( ext::vulkan::resized || ext::vulkan::rebuildOnTickStart ) {
|
||||
ext::vulkan::rebuild = true;
|
||||
if ( ext::vulkan::states::resized || ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
@ -289,7 +290,7 @@ void ext::vulkan::tick() {
|
||||
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
|
||||
if ( graphic.initialized || !graphic.process || graphic.initialized ) return;
|
||||
graphic.initializePipeline();
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
};
|
||||
for ( uf::Scene* scene : ext::vulkan::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
@ -299,7 +300,7 @@ void ext::vulkan::tick() {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->device ) {
|
||||
renderMode->initialize(ext::vulkan::device);
|
||||
ext::vulkan::rebuild = true;
|
||||
ext::vulkan::states::rebuild = true;
|
||||
}
|
||||
renderMode->tick();
|
||||
}
|
||||
@ -307,21 +308,24 @@ void ext::vulkan::tick() {
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( ext::vulkan::rebuild || renderMode->rebuild ) {
|
||||
jobs.emplace_back([&]{
|
||||
if ( ext::vulkan::states::rebuild || renderMode->rebuild ) {
|
||||
if ( settings::experimental::individualPipelines ) renderMode->bindPipelines();
|
||||
if ( settings::experimental::multithreadedCommandRecording ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
// std::cout << "Batching " << jobs.size() << " command buffer jobs" << std::endl;
|
||||
uf::thread::batchWorkers( jobs );
|
||||
// std::cout << "Done" << std::endl;
|
||||
}
|
||||
|
||||
ext::vulkan::rebuild = false;
|
||||
ext::vulkan::resized = false;
|
||||
ext::vulkan::states::rebuild = false;
|
||||
ext::vulkan::states::resized = false;
|
||||
ext::vulkan::mutex.unlock();
|
||||
}
|
||||
void ext::vulkan::render() {
|
||||
@ -346,19 +350,14 @@ void ext::vulkan::render() {
|
||||
}
|
||||
|
||||
ext::vulkan::currentRenderMode = NULL;
|
||||
if ( ext::vulkan::waitOnRenderEnd ) {
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->execute ) continue;
|
||||
renderMode->synchronize();
|
||||
}
|
||||
vkDeviceWaitIdle( device );
|
||||
if ( ext::vulkan::settings::experimental::waitOnRenderEnd ) {
|
||||
synchronize();
|
||||
}
|
||||
ext::vulkan::mutex.unlock();
|
||||
}
|
||||
void ext::vulkan::destroy() {
|
||||
ext::vulkan::mutex.lock();
|
||||
vkDeviceWaitIdle( device );
|
||||
synchronize();
|
||||
|
||||
Texture2D::empty.destroy();
|
||||
|
||||
@ -385,6 +384,17 @@ void ext::vulkan::destroy() {
|
||||
device.destroy();
|
||||
ext::vulkan::mutex.unlock();
|
||||
}
|
||||
void ext::vulkan::synchronize( uint8_t flag ) {
|
||||
if ( flag & 0b01 ) {
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->execute ) continue;
|
||||
renderMode->synchronize();
|
||||
}
|
||||
}
|
||||
if ( flag & 0b10 )
|
||||
vkDeviceWaitIdle( device );
|
||||
}
|
||||
|
||||
std::string ext::vulkan::allocatorStats() {
|
||||
char* statsString = nullptr;
|
||||
|
||||
@ -76,6 +76,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
pod::Vector3 normal;
|
||||
float scale = metadata["system"]["physics"]["collision"].asFloat();
|
||||
float depth = json["depth"].asFloat() * scale;
|
||||
// if ( fabs(depth) < 0.005 ) return "false"; //std::cout << "Collision depth: " << depth << std::endl;
|
||||
|
||||
normal.x = json["normal"][0].asFloat();
|
||||
normal.y = json["normal"][1].asFloat();
|
||||
@ -84,6 +85,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
transform.position -= correction;
|
||||
|
||||
|
||||
if ( normal.x == 1 || normal.x == -1 ) physics.linear.velocity.x = 0;
|
||||
if ( normal.y == 1 || normal.y == -1 ) physics.linear.velocity.y = 0;
|
||||
if ( normal.z == 1 || normal.z == -1 ) physics.linear.velocity.z = 0;
|
||||
|
||||
@ -12,27 +12,26 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
|
||||
if ( metadata["light"]["shadows"]["enabled"].asBool() ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
std::string name = "RT:" + std::to_string((int) this->getUid());
|
||||
uf::renderer::addRenderMode( &renderMode, name );
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
|
||||
camera = controller.getComponent<uf::Camera>();
|
||||
camera.getTransform() = {};
|
||||
camera.setStereoscopic(false);
|
||||
if ( metadata["light"]["shadows"]["fov"].isNumeric() ) {
|
||||
camera.setFov( metadata["light"]["shadows"]["fov"].asFloat() );
|
||||
camera.updateProjection();
|
||||
}
|
||||
if ( metadata["light"]["radius"].isArray() ) {
|
||||
auto bounds = camera.getBounds();
|
||||
bounds.x = metadata["light"]["radius"][0].asFloat();
|
||||
bounds.y = metadata["light"]["radius"][1].asFloat();
|
||||
camera.setBounds(bounds);
|
||||
}
|
||||
renderMode.blitter.process = false;
|
||||
camera = controller.getComponent<uf::Camera>();
|
||||
camera.getTransform() = {};
|
||||
camera.setStereoscopic(false);
|
||||
if ( metadata["light"]["shadows"]["fov"].isNumeric() ) {
|
||||
camera.setFov( metadata["light"]["shadows"]["fov"].asFloat() );
|
||||
camera.updateProjection();
|
||||
}
|
||||
if ( metadata["light"]["radius"].isArray() ) {
|
||||
auto bounds = camera.getBounds();
|
||||
bounds.x = metadata["light"]["radius"][0].asFloat();
|
||||
bounds.y = metadata["light"]["radius"][1].asFloat();
|
||||
camera.setBounds(bounds);
|
||||
}
|
||||
if ( metadata["light"]["shadows"]["resolution"].isArray() ) {
|
||||
renderMode.width = metadata["light"]["shadows"]["resolution"][0].asUInt64();
|
||||
|
||||
@ -109,10 +109,10 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
return "true";
|
||||
});
|
||||
/* store viewport size */ {
|
||||
metadata["system"]["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["system"]["window"]["size"]["y"] = uf::renderer::height;
|
||||
ext::gui::size.current.x = uf::renderer::width;
|
||||
ext::gui::size.current.y = uf::renderer::height;
|
||||
metadata["system"]["window"]["size"]["x"] = uf::renderer::settings::width;
|
||||
metadata["system"]["window"]["size"]["y"] = uf::renderer::settings::height;
|
||||
ext::gui::size.current.x = uf::renderer::settings::width;
|
||||
ext::gui::size.current.y = uf::renderer::settings::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
@ -413,7 +413,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
// check if we actually do need to update our pipeline, to avoid the command buffer rebuild cost
|
||||
if ( shouldUpdate ) {
|
||||
blitter.getPipeline().update( blitter );
|
||||
// blitter.getPipeline().update( blitter );
|
||||
blitter.updatePipelines();
|
||||
}
|
||||
}
|
||||
shader->updateBuffer( (void*) buffer, len, 0, false );
|
||||
|
||||
@ -825,6 +825,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
// graphic.descriptor.indices = 0;
|
||||
graphic.initializeGeometry( mesh );
|
||||
graphic.getPipeline().update( graphic );
|
||||
// graphic.updatePipelines();
|
||||
// uf::renderer::rebuild = true;
|
||||
|
||||
/*
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
|
||||
ext::gui::Size ext::gui::size = {
|
||||
.current = {
|
||||
uf::renderer::width,
|
||||
uf::renderer::height,
|
||||
uf::renderer::settings::width,
|
||||
uf::renderer::settings::height,
|
||||
},
|
||||
.reference = {
|
||||
1920,
|
||||
@ -47,8 +47,8 @@ EXT_BEHAVIOR_REGISTER_AS_OBJECT(GuiManagerBehavior, GuiManager)
|
||||
#define this (&self)
|
||||
void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
|
||||
{
|
||||
ext::gui::size.current.x = uf::renderer::width;
|
||||
ext::gui::size.current.y = uf::renderer::height;
|
||||
ext::gui::size.current.x = uf::renderer::settings::width;
|
||||
ext::gui::size.current.y = uf::renderer::settings::height;
|
||||
}
|
||||
// add gui render mode
|
||||
if ( !uf::renderer::hasRenderMode( "Gui", true ) ) {
|
||||
|
||||
86
ext/main.cpp
86
ext/main.cpp
@ -59,6 +59,7 @@ namespace {
|
||||
double prevTime = 0;
|
||||
double curTime = 0;
|
||||
double deltaTime = 0;
|
||||
size_t frames = 0;
|
||||
} times;
|
||||
|
||||
uf::Serializer config;
|
||||
@ -69,6 +70,7 @@ std::vector<std::string> ext::arguments;
|
||||
void EXT_API ext::initialize() {
|
||||
::config = ext::getConfig();
|
||||
/* Arguments */ {
|
||||
bool modified = false;
|
||||
auto& arguments = ::config["arguments"];
|
||||
for ( auto& arg : ext::arguments ) {
|
||||
// store raw argument
|
||||
@ -88,11 +90,12 @@ void EXT_API ext::initialize() {
|
||||
traversal = &((*traversal)[key]);
|
||||
}
|
||||
*traversal = value;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
uf::iostream << "Arguments: " << uf::Serializer(arguments) << "\n";
|
||||
uf::iostream << "New config: " << ::config << "\n";
|
||||
if ( modified ) uf::iostream << "New config: " << ::config << "\n";
|
||||
}
|
||||
|
||||
/* Seed */ {
|
||||
@ -138,23 +141,23 @@ void EXT_API ext::initialize() {
|
||||
{
|
||||
size_t size = deduceSize( ::config["engine"]["memory pool"]["size"] );
|
||||
uf::MemoryPool::globalOverride = ::config["engine"]["memory pool"]["globalOverride"].asBool();
|
||||
std::cout << "Requesting " << (int) size << " bytes for global memory pool: " << &uf::MemoryPool::global << std::endl;
|
||||
uf::iostream << "Requesting " << (int) size << " bytes for global memory pool: " << &uf::MemoryPool::global << "\n";
|
||||
uf::MemoryPool::global.initialize( size );
|
||||
uf::MemoryPool::subPool = ::config["engine"]["memory pool"]["subPools"].asBool();
|
||||
if ( size <= 0 || uf::MemoryPool::subPool ) {
|
||||
{
|
||||
size_t size = deduceSize( ::config["engine"]["memory pools"]["component"] );
|
||||
std::cout << "Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool << std::endl;
|
||||
uf::iostream << "Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool << "\n";
|
||||
uf::component::memoryPool.initialize( size );
|
||||
}
|
||||
{
|
||||
size_t size = deduceSize( ::config["engine"]["memory pools"]["userdata"] );
|
||||
std::cout << "Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool << std::endl;
|
||||
uf::iostream << "Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool << "\n";
|
||||
uf::userdata::memoryPool.initialize( size );
|
||||
}
|
||||
{
|
||||
size_t size = deduceSize( ::config["engine"]["memory pools"]["entity"] );
|
||||
std::cout << "Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool << std::endl;
|
||||
uf::iostream << "Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool << "\n";
|
||||
uf::Entity::memoryPool.initialize( size );
|
||||
}
|
||||
}
|
||||
@ -178,27 +181,35 @@ void EXT_API ext::initialize() {
|
||||
uf::thread::limiter = 1.0 / ::config["engine"]["threads"]["frame limiter"].asDouble();
|
||||
}
|
||||
// Set worker threads
|
||||
if ( ::config["engine"]["threads"]["workers"].asString() == "auto" ) {
|
||||
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
|
||||
::config["engine"]["threads"]["workers"] = threads;
|
||||
uf::iostream << "Using " << threads << " worker threads" << "\n";
|
||||
}
|
||||
uf::thread::workers = ::config["engine"]["threads"]["workers"].asUInt64();
|
||||
// Enable valiation layer
|
||||
uf::renderer::validation = ::config["engine"]["ext"]["vulkan"]["validation"]["enabled"].asBool();
|
||||
if ( ::config["engine"]["ext"]["vulkan"]["validation"]["enabled"].isNumeric() )
|
||||
uf::renderer::msaa = ::config["engine"]["ext"]["vulkan"]["msaa"].asUInt64();
|
||||
uf::renderer::settings::validation = ::config["engine"]["ext"]["vulkan"]["validation"]["enabled"].asBool();
|
||||
|
||||
if ( ::config["engine"]["ext"]["vulkan"]["msaa"].isNumeric() )
|
||||
uf::renderer::settings::msaa = ::config["engine"]["ext"]["vulkan"]["msaa"].asUInt64();
|
||||
|
||||
uf::renderer::rebuildOnTickStart = ::config["engine"]["ext"]["vulkan"]["validation"]["rebuild on tick begin"].asBool();
|
||||
uf::renderer::waitOnRenderEnd = ::config["engine"]["ext"]["vulkan"]["validation"]["wait on render end"].asBool();
|
||||
|
||||
for ( int i = 0; i < ::config["engine"]["ext"]["vulkan"]["validation"]["filters"].size(); ++i ) {
|
||||
uf::renderer::validationFilters.push_back( ::config["engine"]["ext"]["vulkan"]["validation"]["filters"][i].asString() );
|
||||
uf::renderer::settings::validationFilters.push_back( ::config["engine"]["ext"]["vulkan"]["validation"]["filters"][i].asString() );
|
||||
}
|
||||
for ( int i = 0; i < ::config["engine"]["ext"]["vulkan"]["extensions"]["device"].size(); ++i ) {
|
||||
uf::renderer::requestedDeviceExtensions.push_back( ::config["engine"]["ext"]["vulkan"]["extensions"]["device"][i].asString() );
|
||||
uf::renderer::settings::requestedDeviceExtensions.push_back( ::config["engine"]["ext"]["vulkan"]["extensions"]["device"][i].asString() );
|
||||
}
|
||||
for ( int i = 0; i < ::config["engine"]["ext"]["vulkan"]["extensions"]["instance"].size(); ++i ) {
|
||||
uf::renderer::requestedInstanceExtensions.push_back( ::config["engine"]["ext"]["vulkan"]["extensions"]["instance"][i].asString() );
|
||||
uf::renderer::settings::requestedInstanceExtensions.push_back( ::config["engine"]["ext"]["vulkan"]["extensions"]["instance"][i].asString() );
|
||||
}
|
||||
for ( int i = 0; i < ::config["engine"]["ext"]["vulkan"]["features"].size(); ++i ) {
|
||||
uf::renderer::requestedDeviceFeatures.push_back( ::config["engine"]["ext"]["vulkan"]["features"][i].asString() );
|
||||
uf::renderer::settings::requestedDeviceFeatures.push_back( ::config["engine"]["ext"]["vulkan"]["features"][i].asString() );
|
||||
}
|
||||
uf::renderer::settings::experimental::rebuildOnTickBegin = ::config["engine"]["ext"]["vulkan"]["experimental"]["rebuild on tick begin"].asBool();
|
||||
uf::renderer::settings::experimental::waitOnRenderEnd = ::config["engine"]["ext"]["vulkan"]["experimental"]["wait on render end"].asBool();
|
||||
uf::renderer::settings::experimental::individualPipelines = ::config["engine"]["ext"]["vulkan"]["experimental"]["individual pipelines"].asBool();
|
||||
uf::renderer::settings::experimental::multithreadedCommandRecording = ::config["engine"]["ext"]["vulkan"]["experimental"]["multithreaded command recording"].asBool();
|
||||
|
||||
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].asBool();
|
||||
ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].asBool();
|
||||
if ( ::config["engine"]["ext"]["vr"]["dominatEye"].isNumeric() )
|
||||
@ -234,9 +245,6 @@ void EXT_API ext::initialize() {
|
||||
else if ( ::config["engine"]["render modes"]["deferred"].asBool() )
|
||||
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
|
||||
|
||||
// if ( ::config["engine"]["render modes"]["compute"].asBool() )
|
||||
// uf::renderer::addRenderMode( new uf::renderer::ComputeRenderMode, "C:RT:0" );
|
||||
|
||||
if ( ext::openvr::enabled ) {
|
||||
ext::openvr::initialize();
|
||||
|
||||
@ -247,7 +255,7 @@ void EXT_API ext::initialize() {
|
||||
renderMode.width = width;
|
||||
renderMode.height = height;
|
||||
|
||||
std::cout << "Recommended VR Resolution: " << width << ", " << height << std::endl;
|
||||
uf::iostream << "Recommended VR Resolution: " << width << ", " << height << "\n";
|
||||
}
|
||||
|
||||
uf::renderer::initialize();
|
||||
@ -271,9 +279,8 @@ void EXT_API ext::initialize() {
|
||||
/* Add hooks */ {
|
||||
uf::hooks.addHook( "game:LoadScene", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::cout << "SCENE CHANGE: " << event << std::endl;
|
||||
uf::renderer::mutex.lock();
|
||||
uf::renderer::mutex.unlock();
|
||||
uf::iostream << "SCENE CHANGE: " << event << "\n";
|
||||
uf::renderer::synchronize();
|
||||
uf::scene::unloadScene();
|
||||
auto& scene = uf::scene::loadScene( json["scene"].asString() );
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
@ -282,7 +289,7 @@ void EXT_API ext::initialize() {
|
||||
});
|
||||
|
||||
uf::hooks.addHook( "system:Quit", [&](const std::string& event)->std::string{
|
||||
std::cout << "system:Quit: " << event << std::endl;
|
||||
uf::iostream << "system:Quit: " << event << "\n";
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
@ -304,8 +311,6 @@ void EXT_API ext::tick() {
|
||||
times.curTime = times.sys.elapsed().asDouble();
|
||||
times.deltaTime = times.curTime - times.prevTime;
|
||||
}
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
|
||||
/* Print World Tree */ {
|
||||
static uf::Timer<long long> timer(false);
|
||||
@ -322,7 +327,7 @@ void EXT_API ext::tick() {
|
||||
};
|
||||
for ( uf::Scene* scene : uf::renderer::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
std::cout << "Scene: " << scene->getName() << ": " << scene << std::endl;
|
||||
uf::iostream << "Scene: " << scene->getName() << ": " << scene << "\n";
|
||||
scene->process(filter, 1);
|
||||
}
|
||||
}
|
||||
@ -335,13 +340,13 @@ void EXT_API ext::tick() {
|
||||
for ( int i = 0; i < indent; ++i ) uf::iostream << "\t";
|
||||
uf::iostream << entity->getName() << ": " << entity->getUid() << " [";
|
||||
for ( auto& behavior : entity->getBehaviors() ) {
|
||||
std::cout << uf::instantiator::behaviors->names[behavior.type] << ", ";
|
||||
uf::iostream << uf::instantiator::behaviors->names[behavior.type] << ", ";
|
||||
}
|
||||
uf::iostream << "]\n";
|
||||
};
|
||||
for ( uf::Scene* scene : uf::renderer::scenes ) {
|
||||
if ( !scene ) continue;
|
||||
std::cout << "Scene: " << scene->getName() << ": " << scene << std::endl;
|
||||
uf::iostream << "Scene: " << scene->getName() << ": " << scene << "\n";
|
||||
scene->process(filter, 1);
|
||||
}
|
||||
uf::Serializer instantiator;
|
||||
@ -357,7 +362,7 @@ void EXT_API ext::tick() {
|
||||
instantiator["behaviors"][i++] = pair.second;
|
||||
}
|
||||
}
|
||||
std::cout << instantiator << std::endl;
|
||||
uf::iostream << instantiator << "\n";
|
||||
}
|
||||
}
|
||||
/* Print Entity Information */ {
|
||||
@ -431,19 +436,26 @@ void EXT_API ext::tick() {
|
||||
/* FPS Print */ if ( ::config["engine"]["debug"]["framerate"]["print"].asBool() ) {
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
if ( timer.elapsed().asDouble() >= ::config["engine"]["debug"]["framerate"]["every"].asDouble() ) { timer.reset();
|
||||
std::cout << "Framerate: " << (1.0/times.deltaTime) << " FPS | Frametime: " << (times.deltaTime * 1000) << "ms" << std::endl;
|
||||
++::times.frames;
|
||||
double every = ::config["engine"]["debug"]["framerate"]["every"].asDouble();
|
||||
double time = 0;
|
||||
if ( (time = timer.elapsed().asDouble()) >= every ) { timer.reset();
|
||||
// uf::iostream << "Framerate: " << (1.0/times.deltaTime) << " FPS | Frametime: " << (times.deltaTime * 1000) << "ms" << "\n";
|
||||
uf::iostream << "System: " << (every * 1000.0/::times.frames) << " ms/frame | Time: " << time << " | Frames: " << ::times.frames << " | FPS: " << ::times.frames / time << "\n";
|
||||
::times.frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Frame limiter of sorts I guess */ if ( uf::thread::limiter > 0 ) {
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
auto elapsed = timer.elapsed().asMilliseconds();
|
||||
long long sleep = (uf::thread::limiter * 1000) - elapsed;
|
||||
if ( sleep > 0 ) {
|
||||
if ( ::config["engine"]["debug"]["framerate"]["print"].asBool() ) {
|
||||
std::cout << "Frame limiting: " << elapsed << "ms exceeds limit, sleeping for " << elapsed << "ms" << std::endl;
|
||||
// uf::iostream << "Frame limiting: " << elapsed << "ms exceeds limit, sleeping for " << elapsed << "ms" << "\n";
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
|
||||
}
|
||||
timer.reset();
|
||||
}
|
||||
@ -472,9 +484,9 @@ void EXT_API ext::terminate() {
|
||||
|
||||
|
||||
/* Flush input buffer */ {
|
||||
io.output << io.input << std::endl;
|
||||
for ( const auto& str : uf::iostream.getHistory() ) io.output << str << std::endl;
|
||||
io.output << "\nTerminated after " << times.sys.elapsed().asDouble() << " seconds" << std::endl;
|
||||
io.output << io.input << "\n";
|
||||
for ( const auto& str : uf::iostream.getHistory() ) io.output << str << "\n";
|
||||
io.output << "\nTerminated after " << times.sys.elapsed().asDouble() << " seconds" << "\n";
|
||||
io.output.close();
|
||||
}
|
||||
|
||||
@ -532,7 +544,7 @@ std::string EXT_API ext::getConfig() {
|
||||
config.fallback["engine"]["hook"]["mode"] = "Readable";
|
||||
config.fallback["engine"]["limiters"]["framerate"] = 60;
|
||||
config.fallback["engine"]["limiters"]["deltaTime"] = 120;
|
||||
config.fallback["engine"]["threads"]["workers"] = 1;
|
||||
config.fallback["engine"]["threads"]["workers"] = "auto";
|
||||
config.fallback["engine"]["threads"]["frame limiter"] = 144;
|
||||
config.fallback["engine"]["memory pool"]["size"] = "512 MiB";
|
||||
config.fallback["engine"]["memory pool"]["globalOverride"] = false;
|
||||
|
||||
@ -86,8 +86,9 @@ void ext::TerrainBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
graphic.initializeGeometry( mesh );
|
||||
graphic.getPipeline().update( graphic );
|
||||
// graphic.updatePipelines();
|
||||
graphic.process = true;
|
||||
uf::renderer::rebuild = true;
|
||||
uf::renderer::states::rebuild = true;
|
||||
|
||||
return "true";
|
||||
});
|
||||
@ -119,8 +120,7 @@ void ext::TerrainBehavior::initialize( uf::Object& self ) {
|
||||
{"./data/shaders/terrain.stereo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/terrain."+suffix+"frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
|
||||
uf::renderer::rebuildOnTickStart = false;
|
||||
// uf::renderer::rebuildOnTickStart = false;
|
||||
}
|
||||
|
||||
this->generate();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user