Commit for 2022.08.14 23-37-12.7z

This commit is contained in:
mrq 2022-08-14 23:37:00 -05:00
parent cbde0b92d1
commit f556532dd4
43 changed files with 461 additions and 273 deletions

View File

@ -105,9 +105,11 @@ ifneq (,$(findstring fmt,$(REQ_DEPS)))
endif
endif
ifneq (,$(findstring ffx:fsr,$(REQ_DEPS)))
FLAGS += -DUF_USE_FFX_FSR
#INCS += -I./dep/include/ffx_fsr2/
DEPS += -lffx_fsr2_api_x64 -lffx_fsr2_api_vk_x64
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
FLAGS += -DUF_USE_FFX_FSR
#INCS += -I./dep/include/ffx_fsr2/
DEPS += -lffx_fsr2_api_x64 -lffx_fsr2_api_vk_x64
endif
endif
ifneq (,$(findstring imgui,$(REQ_DEPS)))
FLAGS += -DUF_USE_IMGUI

View File

@ -30,12 +30,14 @@
},
"vxgi": {
// "limiter": 0.5,
"limiter": 0.125,
// "limiter": 0.125,
// "limiter": 0.0125,
"limiter": 0.0,
"size": 256,
"dispatch": 8,
"cascades": 3,
"cascadePower": 1.5,
"granularity": 4,
"cascades": 2,
"cascadePower": 2,
"granularity": 6,
"voxelizeScale": 1,
"occlusionFalloff": 2,
"traceStartOffsetFactor": 1,
@ -57,11 +59,11 @@
}
},
"graph": {
"initial buffer elements": 131072
"initial buffer elements": 4096
},
"ext": {
"vulkan": {
"validation": { "enabled": true,
"validation": { "enabled": false,
"filters": [
"0x1feed437", // VUID-VkImageMemoryBarrier-synchronization2-03857 (screams because of FSR2 retardation)
// "0x141cb623", // UNASSIGNED-Threading-MultipleThreads (screams at me, a part of transient command buffer recording/submitting)
@ -97,6 +99,7 @@
"size": 1
// "size": 0.8
// "size": [ 640, 480, "NEAREST" ]
// "size": [ 1920, 1080 ]
// "size": [ 1280, 720 ]
// "size": [ 960, 540 ]
// "size": [ 640, 480 ]
@ -110,14 +113,14 @@
},
"pipelines": {
"deferred": true,
"vsync": false,
"vsync": true,
"hdr": false,
"vxgi": false,
"culling": false,
"bloom": false,
"rt": false,
"fsr": false,
"postProcess": false
"vxgi": true,
"culling": true,
"bloom": true,
"rt": true,
"fsr": true,
"postProcess": true
},
"formats": {
"depth": "D32_SFLOAT",
@ -224,8 +227,8 @@
"fsr": {
"enabled": true,
"sharpness": 1,
"jitter scale": 0.0625,
"preset": "ultra" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x)
"jitter scale": 0.03125,
"preset": "quality" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x)
},
"reactphysics": {
"timescale": 0.01666666666,
@ -258,7 +261,7 @@
"count": 4
},
"volumes": {
"sfx": 0.35,
"sfx": 0.5,
"bgm": 0.15,
"voice": 1.0
},
@ -323,8 +326,8 @@
"cursor" : {
"visible" : true,
"center" : false,
"sensitivity": [ 0.75, 0.75 ],
"smoothing": [ 2, 2 ]
"sensitivity": [ 1, 1 ],
"smoothing": [ 8, 8 ]
},
"mode" : "windowed", // fullscreen, borderless, windowed
"icon" : "./data/textures/icon.png",

View File

@ -17,8 +17,8 @@
},
*/
"assets": [
// { "filename": "./playerModel.json", "delay": 1 },
"./playerModel.json",
{ "filename": "./playerModel.json", "delay": 1 },
// "./playerModel.json",
"./playerLight.json",
"./playerHands.json",
"./scripts/player.lua"

View File

@ -1,7 +1,7 @@
{
"type": "Object",
"name": "Player: Model",
"ignore": true,
"ignore": false,
"import": "/model.json",
"assets": [
"/player/bear.glb"

View File

@ -6,12 +6,12 @@
"metadata": {
"holdable": true,
"physics": {
"gravity": [ 0, -9.81, 0 ],
"inertia": [10, 10, 10],
"mass": 10,
// "gravity": [ 0, -9.81, 0 ],
// "inertia": [10, 10, 10],
// "mass": 10,
"type": "bounding box",
"recenter": true
"recenter": false
}
}
}

View File

@ -5,7 +5,7 @@
// "GuiBehavior"
],
"assets": [
{ "filename": "./mcdonalds.json", "delay": 0 }
{ "filename": "./sm64.json", "delay": 0 }
],
"ignore": false,
"transform": {

View File

@ -6,13 +6,7 @@
],
"metadata": {
"graph": {
"baking": {
"enabled": true,
"resolution": 2048,
"settings": {
"useInputMeshUvs": false
}
},
"baking": { "enabled": true },
"renderer": {
"cull mode": "none",
"filter": "nearest"
@ -20,7 +14,7 @@
"tags": {
"/^worldspawn/": {
"physics": { "type": "mesh", "static": true },
// "grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true },
"grid": { "size": [9,1,9], "epsilon": 1.0, "cleanup": true, "print": true },
"optimize mesh": { "simplify": 0 },
"unwrap mesh": true
},

View File

@ -8,7 +8,12 @@
// exact matches
"worldspawn": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true },
"grid": { "size": [9,1,9], "epsilon": 1.0, "cleanup": true, "print": true },
"unwrap mesh": true,
"optimize mesh": { "simplify": 0 }
},
"worldspawn_skybox": {
"grid": { "size": [9,1,9], "epsilon": 1.0, "cleanup": true, "print": true },
"unwrap mesh": true,
"optimize mesh": { "simplify": 0 }
},

View File

@ -12,11 +12,6 @@
"tags": {
// exact matches
// "worldspawn_skybox": { "ignore": true },
"worldspawn_skybox": {
"grid": { "size": [5,1,5], "epsilon": 1.0, "cleanup": true, "print": true },
"unwrap mesh": true,
"optimize mesh": { "simplify": 0 }
},
"worldspawn_water": {},
// regex matches

View File

@ -6,8 +6,8 @@
],
"metadata": {
"light": {
// "ambient": [ 0, 0, 0 ],
"ambient": [ 0.05, 0.05, 0.05 ],
"ambient": [ 0, 0, 0 ],
// "ambient": [ 0.05, 0.05, 0.05 ],
// "ambient": [ 0.15, 0.15, 0.15 ],
// "ambient": [ 0.5, 0.5, 0.5 ],
// "ambient": [ 0.8, 0.8, 0.8 ],
@ -20,11 +20,11 @@
"threshold": 1.2,
"scale": 1.0,
"strength": 1,
"sigma": 1.0,
"sigma": 2.0,
"samples": 4
},
"fog": {
"fog-": {
// "color": [ 0.1, 0.1, 0.1 ],
// "color": [ 0.2, 0.2, 0.2 ],
"color": [ 0.3, 0.3, 0.3 ],

View File

@ -7,21 +7,23 @@
"metadata": {
"graph": {
"lights": {
"scale": 4.0
// "scale": 4.0
},
"assets": [
"./audio/soundscape/sh2_ambience.ogg"
],
"tags": {
// exact matches
/*
"worldspawn_sh2": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [5,1,5], "epsilon": 1.0, "cleanup": true, "print": true },
"grid": { "size": [9,1,9], "epsilon": 1.0, "cleanup": true, "print": true },
"unwrap mesh": true,
"optimize mesh": { "simplify": 0 }
},
"worldspawn_barrier": { "ignore": true },
"worldspawn_skybox": { "ignore": true },
*/
"/^worldspawn_barrier$/": { "ignore": true },
// "/^worldspawn_skybox/": { "ignore": true },
"func_door_rotating_5473": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } },
"func_door_rotating_5509": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } },

View File

@ -278,6 +278,8 @@ void populateSurfaceMaterial() {
{
surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
}
surface.light *= surface.material.albedo;
}
bool isValidAddress( uint64_t address ) {

View File

@ -14,6 +14,15 @@
#ifndef MAX_TEXTURES
#define MAX_TEXTURES TEXTURES
#endif
#ifndef MAX_LIGHTS
#define MAX_LIGHTS ubo.settings.lengths.lights
#endif
#ifndef MAX_SHADOWS
#define MAX_SHADOWS ubo.settings.lighting.maxShadows
#endif
#ifndef VIEW_MATRIX
#define VIEW_MATRIX ubo.eyes[surface.pass].view
#endif
// implicit shader settings
#ifndef CAN_DISCARD

View File

@ -1,12 +1,68 @@
// PBR
void pbr() {
// if ( surface.material.lightmapped ) return;
// per-surface, not per-light, compute once
const float Rs = 4.0; // specular lighting looks gross without this
// Freslen reflectance for a dieletric
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
// outcoming light from surface to eye
const vec3 Lo = normalize( -surface.position.eye );
// angle of outcoming light
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
#if BAKING
// skip if surface is a dynamic light, we aren't baking dynamic lights
if ( lights[i].type < 0 ) continue;
#else
// skip if surface is already baked, and this isn't a dynamic light
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
#endif
// skip if light power is too low
if ( lights[i].power <= LIGHT_POWER_CUTOFF ) continue;
// incoming light to surface (non-const to normalize it later)
// vec3 Li = lights[i].position - surface.position.world;
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
// magnitude of incoming light vector (for inverse-square attenuation)
const float Lmagnitude = dot(Li, Li);
// distance incoming light travels (reuse from above)
const float Ldistance = sqrt(Lmagnitude);
// "free" normalization, since we need to compute the above values anyways
Li = Li / Ldistance;
// attenuation factor
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
const float Lattenuation = 1.0 / (1 + Lmagnitude);
// skip if attenuation factor is too low
if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
// ray cast if our surface is occluded from the light
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
// skip if our shadow factor is too low
if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue;
// light radiance
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
// skip if our radiance is too low
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
// halfway vector
const vec3 Lh = normalize(Li + Lo);
// angle of incoming light
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
// angle of halfway light vector
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
// Fresnel term for direct lighting
const vec3 F = fresnelSchlick(F0, max(0.0, dot(Lh, Lo)));
// Distribution for specular lighting
const float D = ndfGGX( cosLh, surface.material.roughness );
// Geometric attenuation for specular lighting
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
// final lighting
const vec3 diffuse = mix(vec3(1.0) - F, vec3(0), surface.material.metallic) * surface.material.albedo.rgb;
const vec3 specular = ( shadows < MAX_SHADOWS ) ? ((F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo)) : vec3(0);
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += lights[i].power * Lattenuation * Lshadow;
}
#if 0
const float Rs = 4.0; // specular lighting looks gross without this
uint shadows = 0;
for ( uint i = 0; i < ubo.settings.lengths.lights; ++i ) {
const Light light = lights[i];
@ -14,11 +70,12 @@ void pbr() {
if ( surface.material.lightmapped && light.type >= 0 ) continue;
const vec3 Liu = vec3(ubo.eyes[surface.pass].view * vec4(light.position, 1)) - surface.position.eye;
const float Ld = length(Liu);
const float La = 1.0 / (1 + (PI * pow(Ld, 2.0)));
if ( La <= LIGHT_POWER_CUTOFF ) continue;
const vec3 Li = normalize(Liu);
const bool reverseZ = light.projection[2][2] < 0.00001;
const float Ls = ( shadows++ < ubo.settings.lighting.maxShadows ) ? shadowFactor( light, 0.0 ) : 1;
// const float La = 1.0 / (PI * pow(length(Liu), 2.0));
const float La = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
@ -41,4 +98,5 @@ void pbr() {
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += light.power * La * Ls;
}
#endif
}

View File

@ -134,9 +134,7 @@ void postProcess() {
#endif
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
bool bloom = brightness > ubo.settings.bloom.threshold;
if ( bloom ) {
toneMap( surface.fragment.rgb, brightness );
}
//if ( bloom ) toneMap( surface.fragment.rgb, brightness );
vec4 outFragColor = vec4(surface.fragment.rgb, 1.0);
vec4 outFragBright = bloom ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
vec2 outFragMotion = surface.motion;
@ -162,7 +160,7 @@ void populateSurface() {
const vec3 far3 = far4.xyz / far4.w;
surface.ray.direction = normalize( far3 - near3 );
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
surface.ray.origin = near3.xyz; // ubo.eyes[surface.pass].eyePos.xyz;
const float depth = IMAGE_LOAD(samplerDepth).r;

View File

@ -16,7 +16,6 @@ layout (binding = 1) uniform UBO {
uint padding;
} ubo;
#define TONE_MAP 1
#define GAMMA_CORRECT 1
#define TEXTURES 1
@ -25,6 +24,102 @@ layout (binding = 1) uniform UBO {
#include "../../common/structs.h"
#include "../../common/functions.h"
#define M_PI 3.1415926535897932384626433832795
const float u_imgx = 0;
const float u_imgy = 0;
const float u_imgw = 1;
const float u_imgh = 1;
const float u_img_gain = 2;
const float u_img_bias = 0;
const float u_beam_bias = 0.185;
const float u_beam_gain = 0.25;
const float u_corner = 0.05;
const float u_zoom = 1.0;
const float u_shape = 2;
const float u_round = -0.02;
const float u_grain = 0.4;
const float u_vpitch = 936.1;
const float u_hpitch = 1024.6;
const float u_top = 1;
const float u_bot = 1;
void main() {
const vec2 screenResolution = textureSize( samplerColor, 0 );
const float u_lines = screenResolution.y * 0.5;
vec2 uv_orig = (inUv.xy * 2.0 - 1.0);
vec2 uv_mod = uv_orig * pow(1.0-abs(uv_orig),vec2(u_round)) * (u_zoom + u_corner * pow( abs(uv_orig.yx), vec2(u_shape)) );
vec2 uv = uv_mod / 2.0 + 0.5;
if ( abs(uv_mod).x > 1.0 || abs(uv_mod.y) > 1.0 ) {
outColor = vec4(0.0, 0.0, 0.0, 1.0);
return;
}
float spacing = 1.0/u_lines;
uv+=spacing*0.5;
float line_top = ( ceil(uv.y*u_lines)) / u_lines;
float line_bot = line_top - spacing;
vec2 scale = vec2(u_imgw, u_imgh);
vec2 offset = vec2(u_imgx, u_imgy);
vec2 uv_top = (vec2(uv.x, line_top)+offset) * scale - (scale-1.0)*0.5 ;
vec2 uv_bot = (vec2(uv.x, line_bot)+offset) * scale - (scale-1.0)*0.5 ;
uv_top -= spacing * 0.5;
uv_bot -= spacing * 0.5;
vec4 sampled_top = texture(samplerColor, uv_top);
vec4 sampled_bot = texture(samplerColor, uv_bot);
vec3 color_top = sampled_top.xyz * u_img_gain + u_img_bias;
vec3 color_bot = sampled_bot.xyz * u_img_gain + u_img_bias;
float dist_top = pow(abs(uv.y - line_top), 1.0);
float dist_bot = pow(abs(uv.y - line_bot), 1.0);
vec3 beam_top = 1.0 - (dist_top / (spacing * (color_top * u_beam_gain + u_beam_bias)));
vec3 beam_bot = 1.0 - (dist_bot / (spacing * (color_bot * u_beam_gain + u_beam_bias)));
beam_top = clamp(beam_top, 0.0, 1.0) ;
beam_bot = clamp(beam_bot, 0.0, 1.0) ;
vec3 color = (color_top*beam_top)*u_top + (color_bot*beam_bot)*u_bot;
vec2 dot;
dot.y = floor(uv.y * u_vpitch) ;
dot.x = uv.x;
if (mod(dot.y, 2.0) > 0.5)
dot.x += (4.5/3.0) / u_hpitch;
dot.x = (floor(dot.x*u_hpitch)) ;
int fil = int(mod(dot.x, 3.0));
vec3 out_color = color * (1.0-u_grain);
vec3 passthru = vec3(
float(fil == 0),
float(fil == 1),
float(fil == 2)
) * (u_grain);
out_color += color * passthru;
outColor = vec4(out_color, (sampled_top.a + sampled_bot.a) * 0.5 );
#if TONE_MAP
toneMap(outColor, ubo.exposure);
#endif
#if GAMMA_CORRECT
gammaCorrect(outColor, ubo.gamma);
#endif
}
#if 0
float iTime = 0;
float noise(vec2 p) {
@ -89,7 +184,7 @@ void main() {
#endif
}
#endif
#if 1
#if 0
vec2 curveRemapUV(vec2 uv, vec2 curvature) {
uv = uv * 2.0 - 1.0;
vec2 offset = abs(uv.yx) / vec2(curvature.x, curvature.y);

View File

@ -11,6 +11,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
#define VXGI 1
#define MAX_CUBEMAPS CUBEMAPS
#define GAMMA_CORRECT 1
#define PBR 1
layout (constant_id = 0) const uint TEXTURES = 512;
layout (constant_id = 1) const uint CUBEMAPS = 128;
@ -20,7 +21,7 @@ layout (constant_id = 2) const uint CASCADES = 16;
#include "../../common/structs.h"
layout (binding = 0) uniform UBO {
EyeMatrices matrices[2];
EyeMatrices eyes[2];
Settings settings;
} ubo;
@ -57,9 +58,8 @@ layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCA
#include "../../common/functions.h"
#include "../../common/light.h"
#undef VXGI
#undef VXGI //
#include "../../common/shadows.h"
#define PBR 1
void main() {
const vec3 tUvw = gl_GlobalInvocationID.xzy;
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
@ -93,6 +93,10 @@ void main() {
} else {
surface.fragment.rgb += surface.material.albedo.rgb * ambient;
// corrections
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4( surface.position.world, 1 ) );
surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0) );
pbr();
/*
surface.material.roughness *= 4.0;
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
const vec3 Lo = normalize( surface.position.world );
@ -127,6 +131,7 @@ void main() {
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += light.power * La * Ls;
}
*/
}
surface.fragment.rgb += surface.light.rgb;

View File

@ -14,6 +14,10 @@ layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
#define SHADOW_SAMPLES 16
#define FRAGMENT 1
#define BAKING 1
#define PBR 1
#define MAX_LIGHTS min(ubo.lights, lights.length())
#define MAX_SHADOWS MAX_LIGHTS
#define VIEW_MATRIX camera.viewport[0].view
#include "../../common/macros.h"
#include "../../common/structs.h"
@ -80,7 +84,7 @@ float shadowFactor( const Light light, float def ) {
#include "../../common/shadows.h"
#endif
#define PBR 1
#include "../../common/light.h"
layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0;
@ -135,6 +139,10 @@ void main() {
surface.light = material.colorEmissive;
surface.material.albedo = vec4(1);
{
surface.normal.eye = surface.normal.eye;
surface.position.eye = surface.position.eye;
pbr();
/*
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
for ( uint i = 0; i < min(ubo.lights, lights.length()); ++i ) {
const Light light = lights[i];
@ -179,6 +187,7 @@ void main() {
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += light.power * La * Ls;
}
*/
}
#define EXPOSURE 0
#define GAMMA 0

View File

@ -279,7 +279,7 @@ void main() {
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
bool visible = frustumCull( gID );
if ( visible ) visible = occlusionCull( gID );
// if ( visible ) visible = occlusionCull( gID );
// bool visible = occlusionCull( gID );
drawCommands[gID].instances = visible ? 1 : 0;
}

View File

@ -45,6 +45,14 @@ namespace {
}
}
bool hasDispatchedThread = false;
void renderProc() {
while ( !client::ready || !ext::ready ) {
ext::render();
client::render();
}
}
int main(int argc, char** argv){
for ( size_t i = 0; i < argc; ++i ) {
char* c_str = argv[i];
@ -72,13 +80,32 @@ int main(int argc, char** argv){
}
}
auto& renderer = uf::thread::fetchWorker();
// auto& renderer = uf::thread::get("Render");
// auto& renderer = uf::thread::fetchWorker();
auto& renderer = uf::thread::get("Render");
/*
UF_MSG_DEBUG("?");
std::thread dispatchedThread;
UF_MSG_DEBUG("!");
*/
while ( client::ready && ext::ready ) {
#if UF_EXCEPTIONS
try {
#endif
/*
client::tick();
ext::tick();
if ( !hasDispatchedThread ) {
if ( uf::renderer::settings::experimental::dedicatedThread ) {
hasDispatchedThread = true;
dispatchedThread = std::thread(renderProc);
} else {
ext::render();
client::render();
}
}
*/
#if 1
if ( uf::renderer::settings::experimental::dedicatedThread ) {
uf::thread::queue(renderer, [&]{
@ -117,6 +144,13 @@ int main(int argc, char** argv){
}
#endif
}
/*
if ( hasDispatchedThread ) {
dispatchedThread.join();
}
*/
if ( !client::terminated ) {
client::terminated = true;
UF_MSG_INFO("Natural termination!");

View File

@ -2,18 +2,23 @@
#include <uf/ext/opengl/device.h>
#include <uf/ext/opengl/commands.h>
#include <uf/ext/opengl/graphic.h>
#include <uf/utils/mesh/mesh.h>
namespace ext {
namespace opengl {
struct Graphic;
namespace opengl {
struct UF_API RenderMode {
bool execute = false;
bool executed = false;
bool rebuild = false;
bool resized = false;
uint32_t width = 0;
uint32_t height = 0;
float scale = 0;
ext::opengl::Graphic blitter;
struct {
uf::Serializer json;
@ -22,12 +27,23 @@ namespace ext {
uf::stl::string target = "";
uf::stl::string pipeline = "";
uf::stl::vector<uf::stl::string> pipelines;
// uf::stl::vector<uint8_t> outputs;
uf::stl::vector<uint8_t> outputs;
uf::stl::unordered_map<uf::stl::string, uint8_t> attachments;
uf::stl::unordered_map<uf::stl::string, uint8_t> buffers;
struct {
float frequency = 0.0f;
float timer = 0.0f;
bool execute = true;
} limiter;
uint8_t subpasses = 1;
uint8_t samples = 1;
uint8_t eyes = 1;
uint8_t views = 1;
bool compute = false;
} metadata;
Device* device = GL_NULL_HANDLE;
@ -40,15 +56,23 @@ namespace ext {
uf::ThreadUnique<CommandBuffer> commands;
virtual ~RenderMode();
// RAII
ext::opengl::Graphic& getBlitter();
RenderTarget& getRenderTarget();
bool hasAttachment( const uf::stl::string& ) const;
const RenderTarget::Attachment& getAttachment( const uf::stl::string& ) const;
size_t getAttachmentIndex( const uf::stl::string& ) const;
bool hasBuffer( const uf::stl::string& ) const;
const Buffer& getBuffer( const uf::stl::string& ) const;
size_t getBufferIndex( const uf::stl::string& ) const;
const uf::stl::string getTarget() const;
void setTarget( const uf::stl::string& );
virtual const uf::stl::string getName() const;
virtual const uf::stl::string getType() const;
virtual RenderTarget& getRenderTarget(size_t = 0);
virtual const RenderTarget& getRenderTarget(size_t = 0) const;
virtual const size_t blitters() const;
virtual ext::opengl::Graphic* getBlitter(size_t = 0);
virtual uf::stl::vector<ext::opengl::Graphic*> getBlitters();
virtual CommandBuffer& getCommands( std::thread::id = std::this_thread::get_id() );

View File

@ -5,8 +5,6 @@
namespace ext {
namespace opengl {
struct UF_API BaseRenderMode : public RenderMode {
// virtual ~RenderMode();
// RAII
virtual const uf::stl::string getType() const;
virtual void initialize( Device& device );

View File

@ -6,14 +6,9 @@
namespace ext {
namespace opengl {
struct UF_API DeferredRenderMode : public RenderMode {
ext::opengl::Graphic blitter;
// RAII
virtual const uf::stl::string getType() const;
virtual const size_t blitters() const;
virtual ext::opengl::Graphic* getBlitter(size_t = 0);
virtual uf::stl::vector<ext::opengl::Graphic*> getBlitters();
virtual void createCommandBuffers( const uf::stl::vector<ext::opengl::Graphic*>& graphics );
virtual void initialize( Device& device );
virtual void tick();

View File

@ -6,16 +6,7 @@
namespace ext {
namespace opengl {
struct UF_API RenderTargetRenderMode : public RenderMode {
ext::opengl::Graphic blitter;
//
const uf::stl::string getTarget() const;
void setTarget( const uf::stl::string& );
// RAII
virtual const uf::stl::string getType() const;
virtual const size_t blitters() const;
virtual ext::opengl::Graphic* getBlitter(size_t = 0);
virtual uf::stl::vector<ext::opengl::Graphic*> getBlitters();
virtual GraphicDescriptor bindGraphicDescriptor( const GraphicDescriptor&, size_t = 0 );

View File

@ -19,6 +19,7 @@ namespace ext {
struct Graphic;
struct CommandBuffer;
struct RenderMode;
ext::json::Value definitionToJson(/*const*/ ext::json::Value& definition );
ext::opengl::userdata_t jsonToUserdata( const ext::json::Value& payload, const ext::json::Value& definition );
@ -79,6 +80,24 @@ namespace ext {
uf::stl::unordered_map<uf::stl::string, Storage> storage;
uf::stl::unordered_map<uf::stl::string, PushConstant> pushConstants;
} definitions;
// to automatically grab attachments from the target renderMode
struct AttachmentDescriptor {
uf::stl::string name{};
const ext::opengl::RenderMode* renderMode{};
GLenum layout = 0;
GLenum filter = GL_LINEAR;
};
struct BufferDescriptor {
uf::stl::string name{};
ext::opengl::Buffer fallback;
const ext::opengl::RenderMode* renderMode{};
GLenum flags{};
};
struct {
uf::stl::vector<AttachmentDescriptor> attachments;
uf::stl::vector<BufferDescriptor> buffers;
} aliases;
} metadata;
ext::opengl::userdata_t specializationConstants;

View File

@ -18,6 +18,7 @@ namespace ext {
bool immediate{true};
QueueEnum queueType{QueueEnum::TRANSFER};
VkCommandBuffer handle{VK_NULL_HANDLE};
std::thread::id threadId{std::this_thread::get_id()};
operator VkCommandBuffer() { return handle; }
};
@ -66,7 +67,7 @@ namespace ext {
struct {
uf::stl::vector<Buffer> buffers;
uf::stl::unordered_map<QueueEnum, uf::stl::vector<VkCommandBuffer>> commandBuffers;
uf::stl::unordered_map<QueueEnum, uf::stl::unordered_map<std::thread::id, std::vector<VkCommandBuffer>>> commandBuffers;
} transient;
/*

View File

@ -135,6 +135,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
for ( auto& key : uf::graph::storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( uf::graph::storage.texture2Ds.map[key] );
// bind scene's voxel texture
#if UF_USE_VULKAN
if ( uf::renderer::settings::pipelines::vxgi ) {
auto& scene = uf::scene::getCurrentScene();
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
@ -144,6 +145,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
for ( auto& t : sceneTextures.voxels.radiance ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) graphic.material.textures.emplace_back().aliasTexture(t);
}
#endif
}
uf::stl::string root = uf::io::directory( graph.name );
@ -193,9 +195,11 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
*/
{
auto& shader = graphic.material.getShader("vertex");
// shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
#if UF_USE_VULKAN
shader.aliasBuffer( "camera", uf::graph::storage.buffers.camera );
#else
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
#endif
// // shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
#if UF_USE_VULKAN
shader.buffers.emplace_back( indirect->alias() );

View File

@ -151,8 +151,10 @@ uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::stl::str
const uf::stl::string filename = _filename != "" ? _filename : (uf::stl::string("/") + uf::string::lowercase(name) + "/scene.json");
#endif
scene->load(filename);
#if UF_USE_VULKAN
if ( uf::renderer::settings::pipelines::rt ) uf::instantiator::bind( "RayTraceSceneBehavior", *scene );
if ( uf::renderer::settings::pipelines::vxgi ) uf::instantiator::bind( "VoxelizerSceneBehavior", *scene );
#endif
scene->initialize();
return *scene;
}
@ -160,8 +162,10 @@ uf::Scene& uf::scene::loadScene( const uf::stl::string& name, const uf::Serializ
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
uf::scene::scenes.emplace_back( scene );
if ( data != "" ) scene->load(data);
#if UF_USE_VULKAN
if ( uf::renderer::settings::pipelines::rt ) uf::instantiator::bind( "RayTraceSceneBehavior", *scene );
if ( uf::renderer::settings::pipelines::vxgi ) uf::instantiator::bind( "VoxelizerSceneBehavior", *scene );
#endif
scene->initialize();
return *scene;
}

View File

@ -45,6 +45,7 @@ bool ext::opengl::settings::experimental::dedicatedThread = false;
bool ext::opengl::settings::experimental::dedicatedThread = true;
#endif
bool ext::opengl::settings::experimental::rebuildOnTickBegin = false;
bool ext::opengl::settings::experimental::batchQueueSubmissions = false;
// not so experimental
bool ext::opengl::settings::invariant::waitOnRenderEnd = false;
@ -56,29 +57,15 @@ uf::stl::string ext::opengl::settings::invariant::deferredMode = "";
bool ext::opengl::settings::invariant::multiview = false;
// pipelines
bool ext::opengl::settings::pipelines::deferred = false;
bool ext::opengl::settings::pipelines::vsync = true;
bool ext::opengl::settings::pipelines::hdr = false;
bool ext::opengl::settings::pipelines::vxgi = false;
bool ext::opengl::settings::pipelines::culling = false;
bool ext::opengl::settings::pipelines::occlusion = false;
bool ext::opengl::settings::pipelines::bloom = false;
bool ext::opengl::settings::pipelines::rt = false;
uf::stl::string ext::opengl::settings::pipelines::names::deferred = "deferred";
uf::stl::string ext::opengl::settings::pipelines::names::vsync = "vsync";
uf::stl::string ext::opengl::settings::pipelines::names::hdr = "hdr";
uf::stl::string ext::opengl::settings::pipelines::names::vxgi = "vxgi";
uf::stl::string ext::opengl::settings::pipelines::names::culling = "culling";
uf::stl::string ext::opengl::settings::pipelines::names::occlusion = "occlusion";
uf::stl::string ext::opengl::settings::pipelines::names::bloom = "bloom";
uf::stl::string ext::opengl::settings::pipelines::names::rt = "rt";
GLhandle(VkColorSpaceKHR) ext::opengl::settings::formats::colorSpace;
ext::opengl::enums::Format::type_t ext::opengl::settings::formats::color = ext::opengl::enums::Format::R8G8B8A8_UNORM;
ext::opengl::enums::Format::type_t ext::opengl::settings::formats::depth = ext::opengl::enums::Format::D32_SFLOAT;
ext::opengl::enums::Format::type_t ext::opengl::settings::formats::normal = ext::opengl::enums::Format::R16G16B16A16_SFLOAT;
ext::opengl::enums::Format::type_t ext::opengl::settings::formats::position = ext::opengl::enums::Format::R16G16B16A16_SFLOAT;
ext::opengl::Device ext::opengl::device;
std::mutex ext::opengl::mutex;

View File

@ -27,21 +27,20 @@ const uf::stl::string ext::opengl::RenderMode::getName() const {
// return metadata["name"].as<uf::stl::string>();
return metadata.name;
}
ext::opengl::RenderTarget& ext::opengl::RenderMode::getRenderTarget( size_t i ) {
ext::opengl::Graphic& ext::opengl::RenderMode::getBlitter() {
return blitter;
}
ext::opengl::RenderTarget& ext::opengl::RenderMode::getRenderTarget() {
return renderTarget;
}
const ext::opengl::RenderTarget& ext::opengl::RenderMode::getRenderTarget( size_t i ) const {
return renderTarget;
const uf::stl::string ext::opengl::RenderMode::getTarget() const {
// auto& metadata = *const_cast<uf::Serializer*>(&this->metadata);
// return metadata["target"].as<uf::stl::string>();
return metadata.target;
}
const size_t ext::opengl::RenderMode::blitters() const {
return 0;
}
ext::opengl::Graphic* ext::opengl::RenderMode::getBlitter( size_t i ) {
return NULL;
}
uf::stl::vector<ext::opengl::Graphic*> ext::opengl::RenderMode::getBlitters() {
return {};
void ext::opengl::RenderMode::setTarget( const uf::stl::string& target ) {
// this->metadata["target"] = target;
metadata.target = target;
}
ext::opengl::GraphicDescriptor ext::opengl::RenderMode::bindGraphicDescriptor( const ext::opengl::GraphicDescriptor& reference, size_t pass ) {

View File

@ -18,15 +18,6 @@
const uf::stl::string ext::opengl::DeferredRenderMode::getType() const {
return "Deferred";
}
const size_t ext::opengl::DeferredRenderMode::blitters() const {
return 1;
}
ext::opengl::Graphic* ext::opengl::DeferredRenderMode::getBlitter( size_t i ) {
return &this->blitter;
}
uf::stl::vector<ext::opengl::Graphic*> ext::opengl::DeferredRenderMode::getBlitters() {
return { &this->blitter };
}
void ext::opengl::DeferredRenderMode::initialize( Device& device ) {
ext::opengl::RenderMode::initialize( device );

View File

@ -8,39 +8,14 @@
#include <uf/ext/opengl/graphic.h>
#include <uf/utils/camera/camera.h>
const uf::stl::string ext::opengl::RenderTargetRenderMode::getTarget() const {
// auto& metadata = *const_cast<uf::Serializer*>(&this->metadata);
// return metadata["target"].as<uf::stl::string>();
return metadata.target;
}
void ext::opengl::RenderTargetRenderMode::setTarget( const uf::stl::string& target ) {
// this->metadata["target"] = target;
metadata.target = target;
}
const uf::stl::string ext::opengl::RenderTargetRenderMode::getType() const {
return "RenderTarget";
}
const size_t ext::opengl::RenderTargetRenderMode::blitters() const {
return 1;
}
ext::opengl::Graphic* ext::opengl::RenderTargetRenderMode::getBlitter( size_t i ) {
return &this->blitter;
}
uf::stl::vector<ext::opengl::Graphic*> ext::opengl::RenderTargetRenderMode::getBlitters() {
return { &this->blitter };
}
ext::opengl::GraphicDescriptor ext::opengl::RenderTargetRenderMode::bindGraphicDescriptor( const ext::opengl::GraphicDescriptor& reference, size_t pass ) {
ext::opengl::GraphicDescriptor descriptor = ext::opengl::RenderMode::bindGraphicDescriptor(reference, pass);
descriptor.parse(metadata.json["descriptor"]);
if ( 0 <= pass && pass < metadata.subpasses && metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
// descriptor.cullMode = GL_CULL_MODE_NONE;
descriptor.depth.test = false;
descriptor.depth.write = false;
descriptor.pipeline = uf::renderer::settings::pipelines::names::vxgi;
} else if ( metadata.type == "depth" ) {
if ( metadata.type == "depth" ) {
// descriptor.cullMode = GL_CULL_MODE_NONE;
}
// invalidate

View File

@ -220,7 +220,7 @@ void ext::opengl::Texture::fromBuffers(
if ( this->mips == 0 ) {
this->mips = 1;
} else if ( this->depth == 1 ) {
this->mips = uf::vector::mips( pod::Vector2ui{ texWidth, texHeight, texDepth } );
this->mips = uf::vector::mips( pod::Vector3ui{ texWidth, texHeight, texDepth } );
}
if ( this->mips > 1 ) {

View File

@ -175,7 +175,7 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool st
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
auto commandBuffer = device->fetchCommandBuffer(QueueEnum::TRANSFER, true); // waits on finish
auto commandBuffer = device->fetchCommandBuffer(QueueEnum::TRANSFER, false); // waits on finish
VkBufferCopy region = {};
region.size = length;
vkCmdCopyBuffer(commandBuffer, staging.buffer, buffer, 1, &region);

View File

@ -596,7 +596,7 @@ void ext::vulkan::Device::flushCommandBuffer( VkCommandBuffer commandBuffer, Que
#endif
else {
ext::vulkan::mutex.lock();
this->transient.commandBuffers[queueType].emplace_back(commandBuffer);
this->transient.commandBuffers[queueType][std::this_thread::get_id()].emplace_back(commandBuffer);
ext::vulkan::mutex.unlock();
}
}
@ -610,6 +610,7 @@ ext::vulkan::CommandBuffer ext::vulkan::Device::fetchCommandBuffer( ext::vulkan:
.immediate = immediate,
.queueType = queueType,
.handle = this->createCommandBuffer( VK_COMMAND_BUFFER_LEVEL_PRIMARY, queueType, true ),
.threadId = std::this_thread::get_id(),
};
#if 0
if ( transient ) {
@ -637,7 +638,40 @@ ext::vulkan::CommandBuffer ext::vulkan::Device::fetchCommandBuffer( ext::vulkan:
#endif
}
void ext::vulkan::Device::flushCommandBuffer( ext::vulkan::CommandBuffer commandBuffer ) {
return this->flushCommandBuffer( commandBuffer.handle, commandBuffer.queueType, commandBuffer.immediate );
// return this->flushCommandBuffer( commandBuffer.handle, commandBuffer.queueType, commandBuffer.immediate );
if ( commandBuffer.handle == VK_NULL_HANDLE ) return;
VK_CHECK_RESULT( vkEndCommandBuffer( commandBuffer.handle ) );
#if 0
if ( commandBuffer.immediate ) {
VkSubmitInfo submitInfo = ext::vulkan::initializers::submitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer.handle;
auto queue = getQueue( commandBuffer.queueType );
VK_CHECK_RESULT(vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE));
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkFreeCommandBuffers(logicalDevice, getCommandPool( commandBuffer.queueType ), 1, &commandBuffer.handle);
}
#else
VkSubmitInfo submitInfo = ext::vulkan::initializers::submitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer.handle;
auto queue = getQueue( commandBuffer.queueType, commandBuffer.threadId );
VK_CHECK_RESULT(vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE));
if ( commandBuffer.immediate ) {
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkFreeCommandBuffers(logicalDevice, getCommandPool( commandBuffer.queueType, commandBuffer.threadId ), 1, &commandBuffer.handle);
}
#endif
else {
ext::vulkan::mutex.lock();
this->transient.commandBuffers[commandBuffer.queueType][commandBuffer.threadId].emplace_back(commandBuffer.handle);
ext::vulkan::mutex.unlock();
}
}
ext::vulkan::Buffer ext::vulkan::Device::createBuffer(
const void* data,
@ -668,7 +702,6 @@ VkResult ext::vulkan::Device::createBuffer(
void* map = buffer.map();
memcpy(map, data, size);
buffer.unmap();
// if ((memoryProperties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) buffer.flush();
}
// Initialize a default descriptor that covers the whole buffer size
@ -762,7 +795,7 @@ VkQueue ext::vulkan::Device::getQueue( ext::vulkan::QueueEnum queueEnum, std::th
void ext::vulkan::Device::initialize() {
uf::stl::vector<uf::stl::string> instanceLayers = {
"VK_LAYER_KHRONOS_synchronization2",
// "VK_LAYER_KHRONOS_synchronization2",
};
// Assert validation layers
if ( ext::vulkan::settings::validation ) instanceLayers.emplace_back("VK_LAYER_KHRONOS_validation");

View File

@ -1095,16 +1095,6 @@ void ext::vulkan::Graphic::initializeMesh( uf::Mesh& mesh, bool buffer ) {
descriptor.inputs.bufferOffset = buffers.size(); // buffers.empty() ? 0 : buffers.size() - 1;
VkBufferUsageFlags baseUsage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
/*
#define PARSE_ATTRIBUTE(i, usage) {\
auto& buffer = mesh.buffers[i];\
if ( !buffer.empty() ) queue.emplace_back(Queue{ (void*) buffer.data(), buffer.size(), usage | baseUsage });\
}
#define PARSE_INPUT(name, usage){\
if ( mesh.isInterleaved( mesh.name.interleaved ) ) PARSE_ATTRIBUTE(descriptor.inputs.name.interleaved, usage | baseUsage)\
else for ( auto& attribute : descriptor.inputs.name.attributes ) PARSE_ATTRIBUTE(attribute.buffer, usage | baseUsage)\
}
*/
#define PARSE_INPUT(name, usage){\
if ( mesh.isInterleaved( mesh.name.interleaved ) ) {\
auto& buffer = mesh.buffers[mesh.name.interleaved];\
@ -1128,7 +1118,6 @@ void ext::vulkan::Graphic::initializeMesh( uf::Mesh& mesh, bool buffer ) {
PARSE_INPUT(index, uf::renderer::enums::Buffer::INDEX)
PARSE_INPUT(instance, uf::renderer::enums::Buffer::VERTEX)
PARSE_INPUT(indirect, uf::renderer::enums::Buffer::INDIRECT | uf::renderer::enums::Buffer::STORAGE)
// for ( auto& q : queue ) initializeBuffer( q.data, q.size, q.usage );
this->requestedAlignment = previousRequestedAlignment;
}
@ -1144,27 +1133,6 @@ bool ext::vulkan::Graphic::updateMesh( uf::Mesh& mesh ) {
// ensure our descriptors are proper
mesh.updateDescriptor();
/*
// copy descriptors
#define UPDATE_DESCRIPTOR(N) {\
for ( size_t i = 0; i < mesh.N.attributes.size(); ++i ) {\
descriptor.inputs.N.attributes[i].descriptor = mesh.N.attributes[i].descriptor;\
descriptor.inputs.N.attributes[i].offset = mesh.N.attributes[i].offset;\
descriptor.inputs.N.attributes[i].stride = mesh.N.attributes[i].stride;\
descriptor.inputs.N.attributes[i].length = mesh.N.attributes[i].length;\
descriptor.inputs.N.attributes[i].pointer = mesh.N.attributes[i].pointer;\
}\
descriptor.inputs.N.count = mesh.N.count;\
descriptor.inputs.N.first = mesh.N.first;\
descriptor.inputs.N.size = mesh.N.size;\
descriptor.inputs.N.offset = mesh.N.offset;\
}
UPDATE_DESCRIPTOR(vertex);
UPDATE_DESCRIPTOR(index);
UPDATE_DESCRIPTOR(instance);
UPDATE_DESCRIPTOR(indirect);
*/
descriptor.inputs.vertex = mesh.vertex;
descriptor.inputs.index = mesh.index;
descriptor.inputs.instance = mesh.instance;
@ -1179,27 +1147,6 @@ bool ext::vulkan::Graphic::updateMesh( uf::Mesh& mesh ) {
};
uf::stl::vector<Queue> queue;
/*
#define PARSE_ATTRIBUTE(i, usage) {\
auto& buffer = mesh.buffers[i];\
if ( !buffer.empty() ) queue.emplace_back(Queue{ (void*) buffer.data(), buffer.size(), usage });\
}
#define PARSE_INPUT(name, usage){\
if ( mesh.isInterleaved( mesh.name.interleaved ) ) PARSE_ATTRIBUTE(descriptor.inputs.name.interleaved, usage)\
else for ( auto& attribute : descriptor.inputs.name.attributes ) PARSE_ATTRIBUTE(attribute.buffer, usage)\
}
*/
/*
#define PARSE_INPUT(name, usage){\
if ( mesh.isInterleaved( mesh.name.interleaved ) ) {\
auto& buffer = mesh.buffers[mesh.name.interleaved];\
if ( !buffer.empty() ) rebuild = rebuild || updateBuffer( (const void*) buffer.data(), buffer.size(), descriptor.inputs.name.interleaved );\
} else for ( size_t i = 0; i < descriptor.inputs.name.attributes.size(); ++i ) {\
auto& buffer = mesh.buffers[mesh.name.attributes[i].buffer];\
if ( !buffer.empty() ) rebuild = rebuild || updateBuffer( (const void*) buffer.data(), buffer.size(), descriptor.inputs.name.attributes[i].buffer );\
}\
}
*/
#define PARSE_INPUT(name, usage){\
if ( mesh.isInterleaved( mesh.name.interleaved ) ) {\
auto& buffer = mesh.buffers[mesh.name.interleaved];\
@ -1230,14 +1177,7 @@ bool ext::vulkan::Graphic::updateMesh( uf::Mesh& mesh ) {
PARSE_INPUT(instance, uf::renderer::enums::Buffer::VERTEX)
PARSE_INPUT(indirect, uf::renderer::enums::Buffer::INDIRECT)
this->requestedAlignment = previousRequestedAlignment;
/*
// allocate buffers
bool rebuild = false;
for ( auto i = 0; i < queue.size(); ++i ) {
auto& q = queue[i];
rebuild = rebuild || updateBuffer( q.data, q.size, descriptor.inputs.bufferOffset + i );
}
*/
if ( mesh.instance.count == 0 && mesh.instance.attributes.empty() ) {
descriptor.inputs.instance.count = 1;
}

View File

@ -281,7 +281,9 @@ void ext::vulkan::initialize() {
swapchain.initialize( device );
ext::vulkan::scratchBuffer.alignment = ext::vulkan::settings::scratchBufferAlignment;
ext::vulkan::scratchBuffer.initialize( NULL, ext::vulkan::settings::scratchBufferInitialSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS | uf::renderer::enums::Buffer::STORAGE );
ext::vulkan::scratchBuffer.initialize( NULL, ext::vulkan::settings::scratchBufferInitialSize,
uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS | uf::renderer::enums::Buffer::STORAGE
);
if ( uf::io::exists(uf::io::root + "/textures/missing.png") ) {
uf::Image image;
@ -427,19 +429,24 @@ void ext::vulkan::render() {
auto queueType = pair.first;
auto& commandBuffers = pair.second;
#if 0
VkSubmitInfo submitInfo = ext::vulkan::initializers::submitInfo();
submitInfo.commandBufferCount = commandBuffers.size();
submitInfo.pCommandBuffers = commandBuffers.data();
for ( auto& pair : commandBuffers ) {
auto threadId = pair.first;
auto commandBuffers = pair.second;
#if 0
VkSubmitInfo submitInfo = ext::vulkan::initializers::submitInfo();
submitInfo.commandBufferCount = commandBuffers.size();
submitInfo.pCommandBuffers = commandBuffers.data();
auto queue = device.getQueue( queueType );
VK_CHECK_RESULT(vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE));
#else
auto queue = device.getQueue( queueType );
#endif
auto commandPool = device.getCommandPool( queueType );
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
auto queue = device.getQueue( queueType, threadId );
VK_CHECK_RESULT(vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE));
#else
auto queue = device.getQueue( queueType, threadId );
#endif
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
auto commandPool = device.getCommandPool( queueType, threadId );
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
}
commandBuffers.clear();
}

View File

@ -153,9 +153,11 @@ bool uf::Image::open( const uf::stl::string& filename, bool flip ) {
#endif
{
stbi_set_flip_vertically_on_load(flip);
uint8_t* buffer = stbi_load( filename.c_str(), &width, &height, &channelsDud, STBI_rgb_alpha );
uint8_t* buffer = stbi_load( filename.c_str(), &width, &height, &channels, STBI_rgb_alpha );
size_t len = width * height * channels;
this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
this->m_pixels.resize( len );
memcpy( &this->m_pixels[0], buffer, len );
// this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
stbi_image_free(buffer);
}

View File

@ -226,6 +226,20 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
metadata.shader.frameAccumulateReset = false;
}
static bool lagged = false;
/* funi sound */ if ( lagged || uf::time::current - uf::time::previous > 5 ) {
lagged = true;
auto& controller = this->getController().as<uf::Object>();
if ( controller.getUid() != this->getUid() ) {
lagged = false;
ext::json::Value payload;
payload["filename"] = "/ui/pl_drown1.ogg";
payload["volume"] = "sfx";
payload["spatial"] = true;
controller.queueHook("sound:Emit.%UID%", payload);
}
}
// uf::renderer::states::frameAccumulate = metadata.shader.frameAccumulate;
// uf::renderer::states::frameAccumulateReset = metadata.shader.frameAccumulateReset;
@ -259,6 +273,12 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
UF_MSG_DEBUG("Screenshot saved to {}", filename);
}
}
/* Screenshot */ {
TIMER(1, uf::inputs::kbm::states::R ) {
uf::renderer::states::rebuild = true;
UF_MSG_DEBUG("Rebuild requested");
}
}
#endif
#if 0
/* Mark as ready for multithreading */ {
@ -595,6 +615,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
uf::graph::storage.buffers.light.update( (const void*) uf::graph::storage.lights.data(), uf::graph::storage.lights.size() * sizeof(pod::Light) );
}
#endif
#if UF_USE_VULKAN
/* Update lights */ if ( uf::renderer::settings::pipelines::deferred && !uf::renderer::settings::pipelines::vxgi ) {
auto& deferredRenderMode = uf::renderer::getRenderMode("", true);
auto& deferredBlitter = deferredRenderMode.getBlitter();
@ -604,6 +625,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
ext::ExtSceneBehavior::bindBuffers( *this, "", "fragment", "deferred" );
}
}
#endif
/* Update post processing */ {
auto& renderMode = uf::renderer::getRenderMode("", true);
@ -777,7 +799,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
GL_ERROR_CHECK(glDisable(GL_LIGHTING));
}
#endif
#if UF_USE_VULKAN
if ( uf::renderer::settings::pipelines::bloom ) {
auto& renderMode = uf::renderer::getRenderMode("", true);
auto& blitter = renderMode.getBlitter();
@ -808,6 +830,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") );
}
#endif
}
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {

View File

@ -22,7 +22,7 @@ namespace ext {
bool enabled = true;
uint32_t max = 256;
pod::Vector4f ambient = {0,0,0,1};
pod::Vector4f _placeholder = {1,1,1,1};
pod::Vector4f specular = {1,1,1,1};
float exposure = 1.0f;
float gamma = 1.0f;
bool useLightmaps = true;

View File

@ -495,7 +495,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
if ( !assetLoader.has<uf::Image>(payload.filename) ) return;
auto image = assetLoader.get<uf::Image>(payload.filename);
auto& image = assetLoader.get<uf::Image>(payload.filename);
this->as<ext::Gui>().load( image );
});

View File

@ -396,25 +396,18 @@ void EXT_API ext::initialize() {
for ( int i = 0; i < configRenderJson["features"].size(); ++i ) {
uf::renderer::settings::requestedDeviceFeatures.emplace_back( configRenderJson["features"][i].as<uf::stl::string>() );
}
/*
"rebuild on tick begin": false,
"wait on render end": false,
"multithreaded recording": true,
"individual pipelines": true,
"deferred mode": "",
"deferred reconstruct position": true,
"deferred alias output to swapchain": false,
*/
#endif
#if UF_USE_VULKAN
#if 1
uf::renderer::settings::experimental::dedicatedThread = false;
::requestDedicatedRenderThread = configRenderExperimentalJson["dedicated thread"].as( uf::renderer::settings::experimental::dedicatedThread );
#else
uf::renderer::settings::experimental::dedicatedThread = configRenderExperimentalJson["dedicated thread"].as( uf::renderer::settings::experimental::dedicatedThread );
#endif
uf::renderer::settings::experimental::rebuildOnTickBegin = configRenderExperimentalJson["rebuild on tick begin"].as( uf::renderer::settings::experimental::rebuildOnTickBegin );
uf::renderer::settings::experimental::batchQueueSubmissions = configRenderExperimentalJson["batch queue submissions"].as( uf::renderer::settings::experimental::batchQueueSubmissions );
#endif
uf::renderer::settings::experimental::rebuildOnTickBegin = configRenderExperimentalJson["rebuild on tick begin"].as( uf::renderer::settings::experimental::rebuildOnTickBegin );
uf::renderer::settings::invariant::multithreadedRecording = configRenderInvariantJson["multithreaded recording"].as( uf::renderer::settings::invariant::multithreadedRecording );
uf::renderer::settings::invariant::waitOnRenderEnd = configRenderInvariantJson["wait on render end"].as( uf::renderer::settings::invariant::waitOnRenderEnd );
@ -424,7 +417,7 @@ void EXT_API ext::initialize() {
uf::renderer::settings::pipelines::vsync = configRenderPipelinesJson["vsync"].as( uf::renderer::settings::pipelines::vsync );
uf::renderer::settings::pipelines::culling = configRenderPipelinesJson["culling"].as( uf::renderer::settings::pipelines::culling );
#if UF_USE_VULKAN
#if UF_USE_VULKAN
uf::renderer::settings::pipelines::deferred = configRenderPipelinesJson["deferred"].as( uf::renderer::settings::pipelines::deferred );
uf::renderer::settings::pipelines::hdr = configRenderPipelinesJson["hdr"].as( uf::renderer::settings::pipelines::hdr );
uf::renderer::settings::pipelines::vxgi = configRenderPipelinesJson["vxgi"].as( uf::renderer::settings::pipelines::vxgi );
@ -455,7 +448,6 @@ void EXT_API ext::initialize() {
JSON_TO_FORMAT(depth);
#endif
}
#endif
/* Init controllers */ {
spec::controller::initialize();
@ -499,15 +491,6 @@ void EXT_API ext::initialize() {
/* Initialize Vulkan */ {
// setup render mode
/*
if ( ::json["engine"]["render modes"]["gui"].as<bool>(true) ) {
auto* renderMode = new uf::renderer::RenderTargetRenderMode;
renderMode->blitter.descriptor.renderMode = "Swapchain";
renderMode->blitter.descriptor.subpass = 0;
renderMode->metadata.type = "single";
uf::renderer::addRenderMode( renderMode, "Gui" );
}
*/
if ( ::json["engine"]["render modes"]["deferred"].as<bool>(true) ) {
auto* renderMode = new uf::renderer::DeferredRenderMode;
@ -534,13 +517,14 @@ void EXT_API ext::initialize() {
if ( ::json["engine"]["render modes"]["stereo deferred"].as<bool>() ) {
renderMode->metadata.eyes = 2;
}
#if UF_USE_VULKAN
if ( uf::renderer::settings::pipelines::deferred ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::deferred);
}
if ( uf::renderer::settings::pipelines::culling ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::culling);
}
#endif
uf::renderer::addRenderMode( renderMode, "" );
}
@ -784,7 +768,7 @@ void EXT_API ext::tick() {
}
#endif
/* Update vulkan */ {
// uf::renderer::tick();
uf::renderer::tick();
}
//UF_TIMER_TRACE("ticking renderer");
#if UF_USE_DISCORD
@ -852,7 +836,7 @@ void EXT_API ext::render() {
}
#endif
/* Render scene */ {
uf::renderer::tick();
// uf::renderer::tick();
uf::renderer::render();
}
#if UF_USE_OPENVR

View File

@ -1 +1 @@
clang
gcc