Commit for 2022.07.29 00-31-45.7z

This commit is contained in:
mrq 2022-07-29 00:31:00 -05:00
parent 5a12332ad8
commit ae28b31d02
35 changed files with 605 additions and 874 deletions

View File

@ -6,12 +6,12 @@
"meshes": { "interleaved": false },
"lights": { "enabled": true,
"useLightmaps": false,
"max": 48,
"max": 8,
"shadows": {
"enabled": true,
"update": 4,
"max": 24,
"samples": 16
"update": 2,
"max": 4,
"samples": 1
},
"bloom": {
"scale": 1.0,
@ -90,7 +90,7 @@
// "size": 0.25
// "size": 0.50
// "size": 0.75
"size": 1
"size": 0.5
// "size": [ 640, 480, "NEAREST" ]
// "size": [ 1280, 720 ]
// "size": [ 960, 540 ]
@ -107,13 +107,12 @@
"deferred": true,
"vsync": false,
"hdr": false,
"vxgi": true,
"culling": false,
"occlusion": false,
"vxgi": false,
"culling": true,
"bloom": false,
"rt": false,
"postProcess": false,
"fsr": false
"fsr": true
},
"formats": {
"depth": "D32_SFLOAT",

View File

@ -17,7 +17,7 @@
"gamma": 2.2,
"brightnessThreshold": 1.2,
"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

@ -1,6 +1,6 @@
{
// "import": "./rp_downtown_v2.json"
// "import": "./ss2_medsci1.json"
"import": "./sh2_mcdonalds.json"
// "import": "./gm_construct.json"
// "import": "./sh2_mcdonalds.json"
"import": "./gm_construct.json"
}

View File

@ -8,6 +8,7 @@ uint tea(uint val0, uint val1) {
uint v1 = val1;
uint s0 = 0;
#pragma unroll 16
for(uint n = 0; n < 16; n++) {
s0 += 0x9e3779b9;
v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s0) ^ ((v1 >> 5) + 0xc8013ea4);
@ -210,98 +211,7 @@ vec3 decodeBarycentrics( vec2 attributes ) {
);
}
#if DEFERRED_SAMPLING
void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
Triangle triangle;
Vertex points[3];
if ( 0 < instanceAddresses.vertex ) {
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
} else {
if ( 0 < instanceAddresses.position ) {
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.uv ) {
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.st ) {
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.normal ) {
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
}
}
#if FETCH_BARYCENTRIC
{
const vec3 p = vec3(inverse( surface.instance.model ) * vec4(surface.position.world, 1));
const vec3 a = points[0].position;
const vec3 b = points[1].position;
const vec3 c = points[2].position;
const vec3 v0 = b - a;
const vec3 v1 = c - a;
const vec3 v2 = p - a;
const float d00 = dot(v0, v0);
const float d01 = dot(v0, v1);
const float d11 = dot(v1, v1);
const float d20 = dot(v2, v0);
const float d21 = dot(v2, v1);
const float denom = d00 * d11 - d01 * d01;
const float v = (d11 * d20 - d01 * d21) / denom;
const float w = (d00 * d21 - d01 * d20) / denom;
const float u = 1.0f - v - w;
surface.barycentric = vec3( u, v, w );
}
#endif
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
triangle.point.position = /*triangle.*/points[0].position * surface.barycentric[0] + /*triangle.*/points[1].position * surface.barycentric[1] + /*triangle.*/points[2].position * surface.barycentric[2];
triangle.point.uv = /*triangle.*/points[0].uv * surface.barycentric[0] + /*triangle.*/points[1].uv * surface.barycentric[1] + /*triangle.*/points[2].uv * surface.barycentric[2];
triangle.point.st = /*triangle.*/points[0].st * surface.barycentric[0] + /*triangle.*/points[1].st * surface.barycentric[1] + /*triangle.*/points[2].st * surface.barycentric[2];
triangle.point.tangent = /*triangle.*/points[0].tangent * surface.barycentric[0] + /*triangle.*/points[1].tangent * surface.barycentric[1] + /*triangle.*/points[2].tangent * surface.barycentric[2];
if ( triangle.point.tangent != vec3(0) ) {
vec3 tangent = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) ));
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
surface.tbn = mat3(tangent, bitangent, triangle.point.normal);
}
// bind position
#if !FETCH_BARYCENTRIC
{
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) );
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
}
#endif
// bind normals
{
surface.normal.world = normalize(vec3( surface.instance.model * vec4(triangle.point.normal, 0.0 ) ));
// surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) );
}
// bind UVs
{
surface.uv.xy = triangle.point.uv;
surface.uv.z = 0;
surface.st.xy = triangle.point.st;
surface.st.z = 0;
}
void populateSurfaceMaterial() {
const Material material = materials[surface.instance.materialID];
surface.material.albedo = material.colorBase;
surface.material.metallic = material.factorMetallic;
@ -345,13 +255,113 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
surface.material.roughness = samp.g;
}
// Normals
if ( validTextureIndex( material.indexNormal ) && surface.tangent != vec3(0) ) {
if ( validTextureIndex( material.indexNormal ) && surface.tangent.world != vec3(0) ) {
surface.normal.world = surface.tbn * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
}
{
surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
}
}
void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
Triangle triangle;
Vertex points[3];
if ( 0 < instanceAddresses.vertex ) {
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
} else {
if ( 0 < instanceAddresses.position ) {
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.uv ) {
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.st ) {
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.normal ) {
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
}
}
#if FETCH_BARYCENTRIC
{
const vec3 p = vec3(inverse( surface.instance.model ) * vec4(surface.position.world, 1));
const vec3 a = points[0].position;
const vec3 b = points[1].position;
const vec3 c = points[2].position;
const vec3 v0 = b - a;
const vec3 v1 = c - a;
const vec3 v2 = p - a;
const float d00 = dot(v0, v0);
const float d01 = dot(v0, v1);
const float d11 = dot(v1, v1);
const float d20 = dot(v2, v0);
const float d21 = dot(v2, v1);
const float denom = d00 * d11 - d01 * d01;
const float v = (d11 * d20 - d01 * d21) / denom;
const float w = (d00 * d21 - d01 * d20) / denom;
const float u = 1.0f - v - w;
surface.barycentric = vec3( u, v, w );
}
#endif
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
triangle.point.position = /*triangle.*/points[0].position * surface.barycentric[0] + /*triangle.*/points[1].position * surface.barycentric[1] + /*triangle.*/points[2].position * surface.barycentric[2];
triangle.point.uv = /*triangle.*/points[0].uv * surface.barycentric[0] + /*triangle.*/points[1].uv * surface.barycentric[1] + /*triangle.*/points[2].uv * surface.barycentric[2];
triangle.point.st = /*triangle.*/points[0].st * surface.barycentric[0] + /*triangle.*/points[1].st * surface.barycentric[1] + /*triangle.*/points[2].st * surface.barycentric[2];
triangle.point.tangent = /*triangle.*/points[0].tangent * surface.barycentric[0] + /*triangle.*/points[1].tangent * surface.barycentric[1] + /*triangle.*/points[2].tangent * surface.barycentric[2];
if ( triangle.point.tangent != vec3(0) ) {
surface.tangent.world = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) ));
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal);
}
// bind position
#if !FETCH_BARYCENTRIC
{
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) );
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
}
#endif
// bind normals
{
surface.normal.world = normalize(vec3( surface.instance.model * vec4(triangle.point.normal, 0.0 ) ));
// surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) );
}
// bind UVs
{
surface.uv.xy = triangle.point.uv;
surface.uv.z = 0;
surface.st.xy = triangle.point.st;
surface.st.z = 0;
}
populateSurfaceMaterial();
}
void populateSurface( uint instanceID, uint primitiveID ) {
surface.fragment = vec4(0);
surface.light = vec4(0);
@ -362,6 +372,7 @@ void populateSurface( uint instanceID, uint primitiveID ) {
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
const uint triangleID = primitiveID + (drawCommand.indexID / 3);
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
populateSurface( instanceAddresses, indices );

View File

@ -187,7 +187,7 @@ struct Surface {
vec3 st;
Space position;
Space normal;
vec3 tangent;
Space tangent;
mat3 tbn;
vec3 barycentric;
vec2 motion;

View File

@ -5,7 +5,7 @@
#extension GL_EXT_ray_query : require
#endif
layout (local_size_x = 8, local_size_y = 8, local_size_z = 2) in;
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define COMPUTE 1
#define TONE_MAP 0
@ -16,7 +16,8 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 2) in;
#define PBR 1
#define BUFFER_REFERENCE 1
#define DEFERRED_SAMPLING 1
#define FETCH_BARYCENTRIC 1
#define FETCH_BARYCENTRIC 0
#define EXTENDED_ATTRIBUTES 0
//#define TEXTURE_WORKAROUND 0
#include "../../common/macros.h"
@ -29,15 +30,28 @@ layout (constant_id = 1) const uint CUBEMAPS = 128;
#if !MULTISAMPLING
layout(binding = 0) uniform utexture2D samplerId;
layout(binding = 1) uniform texture2D samplerDepth;
#if EXTENDED_ATTRIBUTES
layout(binding = 1) uniform texture2D samplerUv;
layout(binding = 2) uniform texture2D samplerNormal;
#else
layout(binding = 1) uniform texture2D samplerBary;
#endif
layout(binding = 3) uniform texture2D samplerDepth;
#else
layout(binding = 0) uniform utexture2DMS samplerId;
layout(binding = 1) uniform texture2DMS samplerDepth;
#if EXTENDED_ATTRIBUTES
layout(binding = 1) uniform texture2DMS samplerUv;
layout(binding = 2) uniform texture2DMS samplerNormal;
#else
layout(binding = 1) uniform texture2DMS samplerBary;
#endif
layout(binding = 3) uniform texture2DMS samplerDepth;
#endif
layout(binding = 2, rgba16f) uniform volatile coherent image2D imageColor;
layout(binding = 3, rgba16f) uniform volatile coherent image2D imageBright;
layout(binding = 4, rg16f) uniform volatile coherent image2D imageMotion;
layout(binding = 7, rgba16f) uniform volatile coherent image2D imageColor;
layout(binding = 8, rgba16f) uniform volatile coherent image2D imageBright;
layout(binding = 9, rg16f) uniform volatile coherent image2D imageMotion;
layout( push_constant ) uniform PushBlock {
uint pass;
@ -46,42 +60,42 @@ layout( push_constant ) uniform PushBlock {
#include "../../common/structs.h"
layout (binding = 5) uniform UBO {
layout (binding = 10) uniform UBO {
EyeMatrices eyes[2];
Settings settings;
} ubo;
/*
*/
layout (std140, binding = 6) readonly buffer DrawCommands {
layout (std140, binding = 11) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 7) readonly buffer Instances {
layout (std140, binding = 12) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 8) readonly buffer InstanceAddresseses {
layout (std140, binding = 13) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (std140, binding = 9) readonly buffer Materials {
layout (std140, binding = 14) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 10) readonly buffer Textures {
layout (std140, binding = 15) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 11) readonly buffer Lights {
layout (std140, binding = 16) readonly buffer Lights {
Light lights[];
};
layout (binding = 12) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 13) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 14) uniform sampler3D samplerNoise;
layout (binding = 17) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 18) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 19) uniform sampler3D samplerNoise;
#if VXGI
layout (binding = 15) uniform usampler3D voxelId[CASCADES];
layout (binding = 16) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 17) uniform sampler3D voxelRadiance[CASCADES];
layout (binding = 20) uniform usampler3D voxelId[CASCADES];
layout (binding = 21) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 22) uniform sampler3D voxelRadiance[CASCADES];
#endif
#if RT
layout (binding = 18) uniform accelerationStructureEXT tlas;
layout (binding = 23) uniform accelerationStructureEXT tlas;
#endif
layout(buffer_reference, scalar) buffer Vertices { Vertex v[]; };
@ -137,27 +151,24 @@ void postProcess() {
}
void populateSurface() {
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / imageSize(imageColor)); // * 2.0f - 1.0f;
if ( inUv.x >= 1.0 || inUv.y >= 1.0 ) return;
if ( gl_GlobalInvocationID.x >= imageSize(imageColor).x|| gl_GlobalInvocationID.y >= imageSize(imageColor).y ) return;
surface.fragment = vec4(0);
surface.pass = PushConstant.pass;
{
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / imageSize(imageColor)) * 2.0f - 1.0f;
const mat4 iProjectionView = inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) );
const vec4 near4 = iProjectionView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
const vec4 far4 = iProjectionView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
const vec4 near4 = iProjectionView * (vec4(inUv, -1.0, 1.0));
const vec4 far4 = iProjectionView * (vec4(inUv, 1.0, 1.0));
const vec3 near3 = near4.xyz / near4.w;
const vec3 far3 = far4.xyz / far4.w;
surface.ray.direction = normalize( far3 - near3 );
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
}
{
const float depth = IMAGE_LOAD(samplerDepth).r;
vec2 eUv = inUv * 2.0 - 1.0;
vec4 positionEye = ubo.eyes[surface.pass].iProjection * vec4(eUv, depth, 1.0);
vec4 positionEye = ubo.eyes[surface.pass].iProjection * vec4(inUv, depth, 1.0);
positionEye /= positionEye.w;
surface.position.eye = positionEye.xyz;
surface.position.world = vec3( ubo.eyes[surface.pass].iView * positionEye );
@ -181,7 +192,28 @@ void populateSurface() {
const uint triangleID = ID.x - 1;
const uint instanceID = ID.y - 1;
surface.subID = 1;
#if EXTENDED_ATTRIBUTES
vec4 uvst = IMAGE_LOAD(samplerUv);
vec4 normaltangent = IMAGE_LOAD(samplerNormal);
surface.uv.xy = uvst.xy;
surface.uv.z = 0;
surface.st.xy = uvst.zw;
surface.st.z = 0;
surface.normal.world = decodeNormals(normaltangent.xy);
// surface.tangent.world = decodeNormals(normaltangent.zw);
surface.fragment = vec4(0);
surface.light = vec4(0);
surface.instance = instances[instanceID];
populateSurfaceMaterial();
#else
surface.barycentric = decodeBarycentrics(IMAGE_LOAD(samplerBary).xy).xyz;
populateSurface( instanceID, triangleID );
#endif
}
{

View File

@ -47,12 +47,14 @@ layout (binding = 13, rgba8) uniform volatile coherent image3D outAlbedos;
#endif
layout (location = 0) flat in uvec4 inId;
layout (location = 1) in vec3 inPosition;
layout (location = 2) in vec2 inUv;
layout (location = 3) in vec4 inColor;
layout (location = 4) in vec2 inSt;
layout (location = 5) in vec3 inNormal;
layout (location = 6) in vec3 inTangent;
layout (location = 1) flat in vec4 inPOS0;
layout (location = 2) in vec4 inPOS1;
layout (location = 3) in vec3 inPosition;
layout (location = 4) in vec2 inUv;
layout (location = 5) in vec4 inColor;
layout (location = 6) in vec2 inSt;
layout (location = 7) in vec3 inNormal;
layout (location = 8) in vec3 inTangent;
layout (location = 0) out vec4 outAlbedo;

View File

@ -3,15 +3,25 @@
//#extension GL_EXT_nonuniform_qualifier : enable
#define STABILIZE_BARY 1
#define QUERY_MIPMAP 0
#define EXTRA_ATTRIBUTES 1
#define CUBEMAPS 1
#define FRAGMENT 1
#define CAN_DISCARD 1
#define BARYCENTRIC 0
#define EXTENDED_ATTRIBUTES 0
#if !EXTENDED_ATTRIBUTES
#define STABILIZE_BARY 1
#define BARYCENTRIC 1
#endif
// #define MAX_TEXTURES TEXTURES
#define MAX_TEXTURES textures.length()
#if BARYCENTRIC
#extension GL_EXT_fragment_shader_barycentric : enable
#extension GL_AMD_shader_explicit_vertex_parameter : enable
#endif
layout (constant_id = 0) const uint TEXTURES = 1;
#include "../../common/macros.h"
@ -40,29 +50,42 @@ layout (std140, binding = 11) readonly buffer Lights {
#include "../../common/functions.h"
layout (location = 0) flat in uvec4 inId;
#if EXTRA_ATTRIBUTES
layout (location = 1) in vec3 inPosition;
layout (location = 2) in vec2 inUv;
layout (location = 3) in vec4 inColor;
layout (location = 4) in vec2 inSt;
layout (location = 5) in vec3 inNormal;
layout (location = 6) in vec3 inTangent;
layout (location = 1) flat in vec4 inPOS0;
#if STABILIZE_BARY
layout (location = 2) __explicitInterpAMD in vec4 inPOS1;
#else
layout (location = 2) in vec4 inPOS1;
#endif
layout (location = 3) in vec3 inPosition;
layout (location = 4) in vec2 inUv;
layout (location = 5) in vec4 inColor;
layout (location = 6) in vec2 inSt;
layout (location = 7) in vec3 inNormal;
layout (location = 8) in vec3 inTangent;
layout (location = 0) out uvec2 outId;
#if EXTENDED_ATTRIBUTES
layout (location = 1) out vec4 outUv;
layout (location = 2) out vec4 outNormal;
#else
layout (location = 1) out vec2 outBary;
#endif
void main() {
const uint triangleID = gl_PrimitiveID; // uint(inId.x);
const uint drawID = uint(inId.y);
const uint instanceID = uint(inId.z);
#if EXTRA_ATTRIBUTES && CAN_DISCARD
#if CAN_DISCARD
const DrawCommand drawCommand = drawCommands[drawID];
const Instance instance = instances[instanceID];
const Material material = materials[instance.materialID];
surface.uv.xy = wrap(inUv.xy);
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
surface.st.xy = wrap(inSt.xy);
surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt));
vec4 A = inColor * material.colorBase;
// sample albedo
@ -81,8 +104,27 @@ void main() {
A.a = 1;
}
if ( A.a < 0.0001 ) discard;
#if EXTENDED_ATTRIBUTES
outUv = vec4(surface.uv, surface.st);
outNormal = vec4( encodeNormals(inNormal), encodeNormals(inTangent) );
#endif
#endif
// outId = uvec2(triangleID + 1, instanceID + 1);
outId = uvec2(triangleID + 1, instanceID + 1);
#if BARYCENTRIC
#if STABILIZE_BARY
vec4 v0 = interpolateAtVertexAMD(inPOS1, 0);
vec4 v1 = interpolateAtVertexAMD(inPOS1, 1);
vec4 v2 = interpolateAtVertexAMD(inPOS1, 2);
if (v0 == inPOS0) outBary = encodeBarycentrics(gl_BaryCoordEXT.yzx);
else if (v1 == inPOS0) outBary = encodeBarycentrics(gl_BaryCoordEXT.zxy);
else if (v2 == inPOS0) outBary = encodeBarycentrics(gl_BaryCoordEXT.xyz);
#else
outBary = encodeBarycentrics(gl_BaryCoordEXT.xyz);
#endif
#endif
}

View File

@ -45,13 +45,15 @@ layout (std140, binding = 2) readonly buffer Instances {
#endif
layout (location = 0) out uvec4 outId;
layout (location = 1) flat out vec4 outPOS0;
layout (location = 2) out vec4 outPOS1;
#if EXTRA_ATTRIBUTES
layout (location = 1) out vec3 outPosition;
layout (location = 2) out vec2 outUv;
layout (location = 3) out vec4 outColor;
layout (location = 4) out vec2 outSt;
layout (location = 5) out vec3 outNormal;
layout (location = 6) out vec3 outTangent;
layout (location = 3) out vec3 outPosition;
layout (location = 4) out vec2 outUv;
layout (location = 5) out vec4 outColor;
layout (location = 6) out vec2 outSt;
layout (location = 7) out vec3 outNormal;
layout (location = 8) out vec3 outTangent;
#endif
vec4 snap(vec4 vertex, vec2 resolution) {
@ -91,6 +93,9 @@ void main() {
#else
gl_Position = projection * view * model * vec4(inPos.xyz, 1.0);
#endif
outPOS0 = gl_Position;
outPOS1 = gl_Position;
outId = uvec4(triangleID, drawID, instanceID, PushConstant.pass);
#if EXTRA_ATTRIBUTES

View File

@ -140,7 +140,9 @@ bool frustumCull( uint id ) {
vec4( instance.bounds.min.x, instance.bounds.max.y, instance.bounds.max.z, 1.0 ),
};
vec4 planes[6]; {
#pragma unroll 3
for (int i = 0; i < 3; ++i)
#pragma unroll 2
for (int j = 0; j < 2; ++j) {
planes[i*2+j].x = mat[0][3] + (j == 0 ? mat[0][i] : -mat[0][i]);
planes[i*2+j].y = mat[1][3] + (j == 0 ? mat[1][i] : -mat[1][i]);
@ -149,8 +151,11 @@ bool frustumCull( uint id ) {
planes[i*2+j] = normalizePlane( planes[i*2+j] );
}
}
#pragma unroll 8
for ( uint p = 0; p < 8; ++p ) corners[p] = mat * corners[p];
#pragma unroll 6
for ( uint p = 0; p < 6; ++p ) {
#pragma unroll 8
for ( uint q = 0; q < 8; ++q ) {
if ( dot( corners[q], planes[p] ) > 0 ) return true;
}

View File

@ -34,13 +34,15 @@ layout (std140, binding = 11) readonly buffer Lights {
#include "../../common/functions.h"
layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0;
layout (location = 2) in vec4 inPOS1;
#if EXTRA_ATTRIBUTES
layout (location = 1) in vec3 inPosition;
layout (location = 2) in vec2 inUv;
layout (location = 3) in vec4 inColor;
layout (location = 4) in vec2 inSt;
layout (location = 5) in vec3 inNormal;
layout (location = 6) in vec3 inTangent;
layout (location = 3) in vec3 inPosition;
layout (location = 4) in vec2 inUv;
layout (location = 5) in vec4 inColor;
layout (location = 6) in vec2 inSt;
layout (location = 7) in vec3 inNormal;
layout (location = 8) in vec3 inTangent;
#endif
void main() {

View File

@ -48,12 +48,16 @@ layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCA
#endif
layout (location = 0) flat in uvec4 inId;
layout (location = 1) in vec3 inPosition;
layout (location = 2) in vec2 inUv;
layout (location = 3) in vec4 inColor;
layout (location = 4) in vec2 inSt;
layout (location = 5) in vec3 inNormal;
layout (location = 6) in vec3 inTangent;
layout (location = 1) flat in vec4 inPOS0;
layout (location = 2) in vec4 inPOS1;
#if 1 || EXTRA_ATTRIBUTES
layout (location = 3) in vec3 inPosition;
layout (location = 4) in vec2 inUv;
layout (location = 5) in vec4 inColor;
layout (location = 6) in vec2 inSt;
layout (location = 7) in vec3 inNormal;
layout (location = 8) in vec3 inTangent;
#endif
#include "../../common/functions.h"

View File

@ -5,20 +5,24 @@ layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
layout (location = 0) flat in uvec4 inId[];
layout (location = 1) in vec3 inPosition[];
layout (location = 2) in vec2 inUv[];
layout (location = 3) in vec4 inColor[];
layout (location = 4) in vec2 inSt[];
layout (location = 5) in vec3 inNormal[];
layout (location = 6) in vec3 inTangent[];
layout (location = 1) flat in vec4 inPOS0[];
layout (location = 2) in vec4 inPOS1[];
layout (location = 3) in vec3 inPosition[];
layout (location = 4) in vec2 inUv[];
layout (location = 5) in vec4 inColor[];
layout (location = 6) in vec2 inSt[];
layout (location = 7) in vec3 inNormal[];
layout (location = 8) in vec3 inTangent[];
layout (location = 0) flat out uvec4 outId;
layout (location = 1) out vec3 outPosition;
layout (location = 2) out vec2 outUv;
layout (location = 3) out vec4 outColor;
layout (location = 4) out vec2 outSt;
layout (location = 5) out vec3 outNormal;
layout (location = 6) out vec3 outTangent;
layout (location = 1) flat out vec4 outPOS0;
layout (location = 2) out vec4 outPOS1;
layout (location = 3) out vec3 outPosition;
layout (location = 4) out vec2 outUv;
layout (location = 5) out vec4 outColor;
layout (location = 6) out vec2 outSt;
layout (location = 7) out vec3 outNormal;
layout (location = 8) out vec3 outTangent;
layout (binding = 4) uniform UBO {
mat4 voxel;
@ -59,10 +63,13 @@ void main(){
vec3( ubo.voxel * vec4( inPosition[2], 1 ) ) / cascadePower(CASCADE),
};
#pragma unroll 3
for( uint i = 0; i < 3; ++i ){
const vec3 D = normalize( inPosition[i] - C ) * HALF_PIXEL;
outPosition = P[i] + D;
outPOS0 = inPOS0[i];
outPOS1 = inPOS1[i];
outUv = inUv[i];
outSt = inSt[i];
outColor = inColor[i];

View File

@ -46,72 +46,4 @@ void main() {
payload.primitiveID = gl_PrimitiveID;
payload.attributes = attribs;
#if 0
const vec3 bary = vec3(
1.0 - attribs.x - attribs.y,
attribs.x,
attribs.y
);
const uint instanceID = gl_InstanceCustomIndexEXT;
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
if ( !(0 < instanceAddresses.index) ) return;
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
const uint triangleID = gl_PrimitiveID + (drawCommand.indexID / 3);
Triangle triangle;
Vertex points[3];
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
if ( 0 < instanceAddresses.vertex ) {
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
} else {
if ( 0 < instanceAddresses.position ) {
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.uv ) {
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.st ) {
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.normal ) {
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
}
}
triangle.point.position = /*triangle.*/points[0].position * bary[0] + /*triangle.*/points[1].position * bary[1] + /*triangle.*/points[2].position * bary[2];
triangle.point.uv = /*triangle.*/points[0].uv * bary[0] + /*triangle.*/points[1].uv * bary[1] + /*triangle.*/points[2].uv * bary[2];
triangle.point.st = /*triangle.*/points[0].st * bary[0] + /*triangle.*/points[1].st * bary[1] + /*triangle.*/points[2].st * bary[2];
triangle.point.normal = /*triangle.*/points[0].normal * bary[0] + /*triangle.*/points[1].normal * bary[1] + /*triangle.*/points[2].normal * bary[2];
triangle.point.tangent = /*triangle.*/points[0].tangent * bary[0] + /*triangle.*/points[1].tangent * bary[1] + /*triangle.*/points[2].tangent * bary[2];
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.instanceID = instanceID;
/*
{
vec3 edge1 = points[1].position - points[0].position;
vec3 edge2 = points[2].position - points[1].position;
vec3 deltaUv1 = points[1].uv - points[0].uv;
vec3 deltaUv2 = points[2].uv - points[1].uv;
float f = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv2.x * deltaUv1.y);
vec3 tangent;
tangent1.x = f * ();
}
*/
payload.hit = true;
payload.triangle = triangle;
#endif
}

View File

@ -42,74 +42,4 @@ void main() {
payload.instanceID = gl_InstanceCustomIndexEXT;
payload.primitiveID = gl_PrimitiveID;
payload.attributes = attribs;
#if 0
const vec3 bary = vec3(
1.0 - attribs.x - attribs.y,
attribs.x,
attribs.y
);
const uint instanceID = gl_InstanceCustomIndexEXT;
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
if ( !(0 < instanceAddresses.index) ) return;
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
const uint triangleID = gl_PrimitiveID + (drawCommand.indexID / 3);
Triangle triangle;
Vertex points[3];
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
if ( 0 < instanceAddresses.vertex ) {
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
} else {
if ( 0 < instanceAddresses.position ) {
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.uv ) {
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.st ) {
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.normal ) {
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
}
}
triangle.point.position = /*triangle.*/points[0].position * bary[0] + /*triangle.*/points[1].position * bary[1] + /*triangle.*/points[2].position * bary[2];
triangle.point.uv = /*triangle.*/points[0].uv * bary[0] + /*triangle.*/points[1].uv * bary[1] + /*triangle.*/points[2].uv * bary[2];
triangle.point.st = /*triangle.*/points[0].st * bary[0] + /*triangle.*/points[1].st * bary[1] + /*triangle.*/points[2].st * bary[2];
triangle.point.normal = /*triangle.*/points[0].normal * bary[0] + /*triangle.*/points[1].normal * bary[1] + /*triangle.*/points[2].normal * bary[2];
triangle.point.tangent = /*triangle.*/points[0].tangent * bary[0] + /*triangle.*/points[1].tangent * bary[1] + /*triangle.*/points[2].tangent * bary[2];
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.instanceID = instanceID;
/*
{
vec3 edge1 = points[1].position - points[0].position;
vec3 edge2 = points[2].position - points[1].position;
vec3 deltaUv1 = points[1].uv - points[0].uv;
vec3 deltaUv2 = points[2].uv - points[1].uv;
float f = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv2.x * deltaUv1.y);
vec3 tangent;
tangent1.x = f * ();
}
*/
payload.hit = true;
payload.triangle = triangle;
#endif
}

View File

@ -41,13 +41,12 @@ namespace ext {
uint8_t eyes = 1;
uint8_t views = 1;
bool compute = false;
} metadata;
Device* device = VK_NULL_HANDLE;
RenderTarget renderTarget;
uf::stl::vector<Texture2D> textures;
VkSemaphore renderCompleteSemaphore;
uf::stl::vector<VkFence> fences;

View File

@ -12,7 +12,7 @@ namespace ext {
VkImageUsageFlags usage;
bool blend = false;
uint8_t samples = 1;
uint8_t layers = 1;
uint8_t mips = 0;
bool screenshottable = true;
bool aliased = false;
} descriptor;

View File

@ -5,6 +5,7 @@
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/texture.h>
#include <uf/utils/mesh/mesh.h>
#include <uf/ext/vulkan/rendermode.h>
#define UF_GRAPHIC_POINTERED_USERDATA 1
@ -102,6 +103,15 @@ namespace ext {
uf::stl::unordered_map<uf::stl::string, PushConstant> pushConstants;
uf::stl::unordered_map<uf::stl::string, SpecializationConstants> specializationConstants;
} definitions;
// to automatically grab attachments from the target renderMode
struct AttachmentDescriptor {
uf::stl::string name{};
const ext::vulkan::RenderMode* renderMode{};
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkFilter filter = VK_FILTER_NEAREST;
};
uf::stl::vector<AttachmentDescriptor> attachments;
} metadata;
ext::vulkan::userdata_t specializationConstants;
@ -116,6 +126,9 @@ namespace ext {
void destroy();
bool validate();
void aliasAttachment( const Metadata::AttachmentDescriptor& descriptor );
void aliasAttachment( const uf::stl::string& name, const ext::vulkan::RenderMode* renderMode = NULL, VkImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, VkFilter filter = VK_FILTER_NEAREST );
bool hasUniform( const uf::stl::string& name ) const;
Buffer& getUniformBuffer( const uf::stl::string& name );

View File

@ -47,6 +47,7 @@ namespace ext {
static VkFormat DefaultFormat;
Device* device = nullptr;
bool aliased = false;
VkImage image = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE;

View File

@ -90,7 +90,6 @@ namespace ext {
extern UF_API bool hdr;
extern UF_API bool vxgi;
extern UF_API bool culling;
extern UF_API bool occlusion;
extern UF_API bool bloom;
extern UF_API bool rt;
extern UF_API bool postProcess;
@ -102,7 +101,6 @@ namespace ext {
extern UF_API uf::stl::string hdr;
extern UF_API uf::stl::string vxgi;
extern UF_API uf::stl::string culling;
extern UF_API uf::stl::string occlusion;
extern UF_API uf::stl::string bloom;
extern UF_API uf::stl::string rt;
extern UF_API uf::stl::string postProcess;

View File

@ -22,6 +22,7 @@ namespace uf {
uf::stl::vector<uf::stl::string> UF_API split( const uf::stl::string&, const uf::stl::string& );
uf::stl::string UF_API si( double value, const uf::stl::string& unit, size_t precision = 3 );
bool UF_API contains( const uf::stl::string&, const uf::stl::string& );
uf::stl::vector<const char*> cStrings( const uf::stl::vector<uf::stl::string>& );
template<typename T>
uf::stl::string /*UF_API*/ join( const T&, const uf::stl::string& = "\n", bool = false );

View File

@ -250,32 +250,8 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
shader.buffers.emplace_back( indirect->alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
}
}
if ( uf::renderer::settings::pipelines::occlusion ) {
uf::renderer::Buffer* indirect = NULL;
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
UF_ASSERT( indirect );
if ( indirect ) {
uf::stl::string compShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::occlusion]["compute"].as<uf::stl::string>("/graph/occlusion/comp.spv");
{
graphic.material.metadata.autoInitializeUniformBuffers = false;
compShaderFilename = entity.resolveURI( compShaderFilename, root );
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, uf::renderer::settings::pipelines::names::occlusion);
graphic.material.metadata.autoInitializeUniformBuffers = true;
}
graphic.descriptor.inputs.dispatch = { graphic.descriptor.inputs.indirect.count, 1, 1 };
auto& shader = graphic.material.getShader("compute", uf::renderer::settings::pipelines::names::occlusion);
auto& renderMode = uf::renderer::getRenderMode( graphic.descriptor.renderMode, true );
auto& renderTarget = renderMode.getRenderTarget( graphic.descriptor.renderTarget );
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
shader.buffers.emplace_back( indirect->alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[0] ); // alias ID buffer
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[5] ); // alias depth buffer
shader.aliasAttachment("depth");
}
}
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {

View File

@ -1,156 +0,0 @@
#include <uf/ext/ncurses/ncurses.h>
ext::Ncurses ext::ncurses;
#if UF_USE_NCURSES
#include <ncursesw/ncurses.h>
#include <uf/spec/terminal/terminal.h>
#include <locale.h>
UF_API_CALL ext::Ncurses::Ncurses() :
m_initialized(false),
m_window(NULL),
m_timeout(0)
{
if ( this->m_initializeOnCtor ) this->initialize();
}
ext::Ncurses::~Ncurses() {
this->terminate();
}
void UF_API_CALL ext::Ncurses::initialize() {
// setlocale(LC_ALL, "");
spec::terminal.setLocale();
this->m_initialized = true;
this->m_window = (void*) initscr();
keypad((WINDOW*) this->m_window, true);
scrollok((WINDOW*) this->m_window, true);
mousemask(ALL_MOUSE_EVENTS, NULL);
mouseinterval(0);
timeout(this->m_timeout);
nonl();
noecho();
cbreak();
}
bool UF_API_CALL ext::Ncurses::initialized() {
return this->m_initialized;
}
void UF_API_CALL ext::Ncurses::terminate() {
if ( !this->m_initialized ) return;
if ( (WINDOW*) this->m_window != stdscr ) delwin((WINDOW*) this->m_window);
endwin();
}
void UF_API_CALL ext::Ncurses::move(int row, int column) {
if ( !this->m_initialized ) this->initialize();
wmove((WINDOW*) this->m_window, row, column);
}
void UF_API_CALL ext::Ncurses::move(int toRow, int toColumn, int& row, int& column) {
if ( !this->m_initialized ) this->initialize();
this->move(-1 ? row : toRow, -1 ? column : toColumn);
this->getYX(row, column);
}
void UF_API_CALL ext::Ncurses::getYX(int& row, int& column) {
if ( !this->m_initialized ) this->initialize();
getyx((WINDOW*) this->m_window, row, column);
}
void UF_API_CALL ext::Ncurses::getMaxYX(int& row, int& column) {
if ( !this->m_initialized ) this->initialize();
getmaxyx((WINDOW*) this->m_window, row, column);
}
void UF_API_CALL ext::Ncurses::refresh() {
if ( !this->m_initialized ) this->initialize();
wrefresh((WINDOW*) this->m_window);
}
void UF_API_CALL ext::Ncurses::clrToEol() {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
wclrtoeol((WINDOW*) this->m_window);
}
void UF_API_CALL ext::Ncurses::clrToBot() {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
wclrtobot((WINDOW*) this->m_window);
}
int UF_API_CALL ext::Ncurses::getCh() {
if ( !this->m_initialized ) this->initialize();
return wgetch((WINDOW*) this->m_window);
}
void UF_API_CALL ext::Ncurses::delCh() {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
wdelch((WINDOW*) this->m_window);
}
void UF_API_CALL ext::Ncurses::addCh( char c ) {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
waddch((WINDOW*) this->m_window, c);
}
void UF_API_CALL ext::Ncurses::addStr(const char* c_str) {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
waddstr((WINDOW*) this->m_window, c_str);
}
void UF_API_CALL ext::Ncurses::addStr(const uf::stl::string str) {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
waddstr((WINDOW*) this->m_window, str.c_str());
}
void UF_API_CALL ext::Ncurses::attrOn(int att) {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
wattron((WINDOW*) this->m_window, att);
}
void UF_API_CALL ext::Ncurses::attrOff(int att) {
if ( !this->m_initialized ) this->initialize();
// if ( !this->m_initialized ) return;
wattroff((WINDOW*) this->m_window, att);
}
bool UF_API_CALL ext::Ncurses::hasColors() {
if ( !this->m_initialized ) this->initialize();
return has_colors();
}
bool UF_API_CALL ext::Ncurses::startColor() {
if ( !this->m_initialized ) this->initialize();
return start_color();
}
void UF_API_CALL ext::Ncurses::initPair( short id, short fore, short back ) {
if ( !this->m_initialized ) this->initialize();
init_pair(id, fore, back);
}
// Define dummy implementation
#else
UF_API_CALL ext::Ncurses::Ncurses() {}
ext::Ncurses::~Ncurses() {}
void UF_API_CALL ext::Ncurses::initialize() {}
bool UF_API_CALL ext::Ncurses::initialized() { return false; }
void UF_API_CALL ext::Ncurses::terminate() {}
void UF_API_CALL ext::Ncurses::move(int row, int column) {}
void UF_API_CALL ext::Ncurses::move(int toRow, int toColumn, int& row, int& column) {}
void UF_API_CALL ext::Ncurses::getYX(int& row, int& column) {
}
void UF_API_CALL ext::Ncurses::getMaxYX(int& row, int& column) {}
void UF_API_CALL ext::Ncurses::refresh() {}
void UF_API_CALL ext::Ncurses::clrToEol() {}
void UF_API_CALL ext::Ncurses::clrToBot() {}
int UF_API_CALL ext::Ncurses::getCh() { return 0; }
void UF_API_CALL ext::Ncurses::delCh() {}
void UF_API_CALL ext::Ncurses::addCh( char c ) {}
void UF_API_CALL ext::Ncurses::addStr(const char* c_str) {}
void UF_API_CALL ext::Ncurses::addStr(const uf::stl::string str) {}
void UF_API_CALL ext::Ncurses::attrOn(int att) {}
void UF_API_CALL ext::Ncurses::attrOff(int att) {}
bool UF_API_CALL ext::Ncurses::hasColors() { return false; }
bool UF_API_CALL ext::Ncurses::startColor() { return false; }
void UF_API_CALL ext::Ncurses::initPair( short id, short fore, short back ) {}
#endif

View File

@ -141,7 +141,7 @@ namespace {
if ( !deviceFeatures.geometryShader ) return deviceInfo;
//
{
const uf::stl::vector<const char*> deviceExtensions = {
const uf::stl::vector<uf::stl::string> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
uint32_t extensionCount;
@ -748,23 +748,29 @@ VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::QueueEnum queueEnum, std::t
}
void ext::vulkan::Device::initialize() {
const uf::stl::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
uf::stl::vector<uf::stl::string> instanceLayers = {
"VK_LAYER_KHRONOS_synchronization2",
};
// Assert validation layers
if ( ext::vulkan::settings::validation ) {
if ( ext::vulkan::settings::validation ) instanceLayers.emplace_back("VK_LAYER_KHRONOS_validation");
{
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
uf::stl::vector<VkLayerProperties> availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
for ( const char* layerName : validationLayers ) {
for ( auto& layerName : instanceLayers ) {
bool layerFound = false;
for ( const auto& layerProperties : availableLayers ) {
if ( strcmp(layerName, layerProperties.layerName) == 0 ) {
layerFound = true; break;
for ( auto& layerProperties : availableLayers ) {
if ( layerName == layerProperties.layerName ) {
layerFound = true;
break;
}
}
if ( !layerFound ) UF_EXCEPTION("Vulkan error: validation layers requested, but not available!");
if ( layerFound ) {
UF_MSG_VALIDATION("Vulkan layer enabled: {}", layerName);
} else UF_EXCEPTION("Vulkan error: layer requested, but not available: {}", layerName);
}
}
//
@ -772,6 +778,7 @@ void ext::vulkan::Device::initialize() {
uf::stl::vector<uf::stl::string> requestedExtensions = window->getExtensions( ext::vulkan::settings::validation );
// Load any requested extensions
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::settings::requestedInstanceExtensions.begin(), ext::vulkan::settings::requestedInstanceExtensions.end() );
#if UF_USE_OPENVR
// OpenVR Support
if ( ext::openvr::enabled ) VRInstanceExtensions(requestedExtensions);
@ -792,12 +799,15 @@ void ext::vulkan::Device::initialize() {
}
// Create instance
{
uf::stl::vector<const char*> instanceExtensions;
uf::stl::vector<uf::stl::string> instanceExtensions;
for ( auto& s : supportedExtensions.instance ) {
UF_MSG_VALIDATION("Enabled instance extension: {}", s);
instanceExtensions.push_back( s.c_str() );
instanceExtensions.emplace_back( s );
}
auto cInstanceExtensions = uf::string::cStrings( instanceExtensions );
auto cInstanceLayers = uf::string::cStrings( instanceLayers );
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Program";
@ -810,22 +820,18 @@ void ext::vulkan::Device::initialize() {
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
createInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
createInfo.ppEnabledExtensionNames = instanceExtensions.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(cInstanceExtensions.size());
createInfo.ppEnabledExtensionNames = cInstanceExtensions.data();
if ( ext::vulkan::settings::validation ) {
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
} else {
createInfo.enabledLayerCount = 0;
}
createInfo.enabledLayerCount = static_cast<uint32_t>(cInstanceLayers.size());
createInfo.ppEnabledLayerNames = cInstanceLayers.data();
VK_CHECK_RESULT( vkCreateInstance( &createInfo, nullptr, &this->instance ));
{
ext::json::Value payload = ext::json::array();
for ( auto* c_str : instanceExtensions ) {
payload.emplace_back( uf::stl::string(c_str) );
for ( auto& s : instanceExtensions ) {
payload.emplace_back( s );
}
uf::hooks.call("vulkan:Instance.ExtensionsEnabled", payload);
}
@ -956,12 +962,12 @@ void ext::vulkan::Device::initialize() {
validateRequestedExtensions( extensionProperties.device, requestedExtensions, supportedExtensions.device );
}
uf::stl::vector<const char*> deviceExtensions = {
uf::stl::vector<uf::stl::string> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
for ( auto& s : supportedExtensions.device ) {
UF_MSG_VALIDATION("Enabled device extension: {}", s);
deviceExtensions.push_back( s.c_str() );
deviceExtensions.emplace_back( s );
}
// Desired queues need to be requested upon logical device creation
@ -1009,7 +1015,7 @@ void ext::vulkan::Device::initialize() {
queueInfo.queueFamilyIndex = queueFamilyIndices.transfer;
queueInfo.queueCount = 1;
queueInfo.pQueuePriorities = &defaultQueuePriority;
queueCreateInfos.push_back(queueInfo);
queueCreateInfos.emplace_back(queueInfo);
}
} else {
// Else we use the same queue
@ -1019,12 +1025,12 @@ void ext::vulkan::Device::initialize() {
// Create the logical device representation
if ( useSwapChain ) {
// If the device will be used for presenting to a display via a swapchain we need to request the swapchain extension
deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
deviceExtensions.emplace_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
enableRequestedDeviceFeatures( *this );
auto cDeviceExtensions = uf::string::cStrings( deviceExtensions );
VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@ -1039,8 +1045,8 @@ void ext::vulkan::Device::initialize() {
groupDeviceCreateInfo.pPhysicalDevices = physicalDevices.data();
if ( deviceExtensions.size() > 0 ) {
deviceCreateInfo.enabledExtensionCount = (uint32_t) deviceExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
deviceCreateInfo.enabledExtensionCount = (uint32_t) cDeviceExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = cDeviceExtensions.data();
}
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
@ -1139,7 +1145,9 @@ void ext::vulkan::Device::initialize() {
{
ext::json::Value payload = ext::json::array();
for ( auto* c_str : deviceExtensions ) payload.emplace_back( uf::stl::string(c_str) );
for ( auto& s : deviceExtensions ) {
payload.emplace_back( s );
}
uf::hooks.call("vulkan:Device.ExtensionsEnabled", payload);
}
{

View File

@ -514,52 +514,67 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
}
}
for ( auto& texture : renderMode.textures ) {
infos.image.emplace_back(texture.descriptor);
switch ( texture.viewType ) {
case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: infos.image2DA.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_CUBE: infos.imageCube.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_3D: infos.image3D.emplace_back(texture.descriptor); break;
default: infos.imageUnknown.emplace_back(texture.descriptor); break;
}
#define INSERT_IMAGE(texture) {\
infos.image.emplace_back(texture.descriptor);\
switch ( texture.viewType ) {\
case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break;\
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: infos.image2DA.emplace_back(texture.descriptor); break;\
case VK_IMAGE_VIEW_TYPE_CUBE: infos.imageCube.emplace_back(texture.descriptor); break;\
case VK_IMAGE_VIEW_TYPE_3D: infos.image3D.emplace_back(texture.descriptor); break;\
default: infos.imageUnknown.emplace_back(texture.descriptor); break;\
}\
}
for ( auto& texture : shader->textures ) {
infos.image.emplace_back(texture.descriptor);
switch ( texture.viewType ) {
case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: infos.image2DA.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_CUBE: infos.imageCube.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_3D: infos.image3D.emplace_back(texture.descriptor); break;
default: infos.imageUnknown.emplace_back(texture.descriptor); break;
for ( auto& descriptor : shader->metadata.attachments ) {
auto texture = Texture2D::empty.alias();
texture.sampler.descriptor.filter.min = descriptor.filter;
texture.sampler.descriptor.filter.mag = descriptor.filter;
auto matches = uf::string::match(descriptor.name, R"(/^(.+?)\[(\d+)\]$/)");
auto name = matches.size() == 2 ? matches[0] : descriptor.name;
auto view = matches.size() == 2 ? stoi(matches[1]) : -1;
const ext::vulkan::RenderTarget::Attachment* attachment = NULL;
if ( descriptor.renderMode ) {
if ( descriptor.renderMode->hasAttachment(name) )
attachment = &descriptor.renderMode->getAttachment(name);
} else if ( renderMode.hasAttachment(name) ) {
attachment = &renderMode.getAttachment(name);
}
if ( attachment ) {
// subscript on name will grab the view # from attachment->views
if ( 0 <= view ) {
texture.aliasAttachment( *attachment, (size_t) view );
} else {
texture.aliasAttachment( *attachment );
}
}
if ( descriptor.layout != VK_IMAGE_LAYOUT_UNDEFINED ) {
texture.imageLayout = descriptor.layout;
texture.descriptor.imageLayout = descriptor.layout;
}
INSERT_IMAGE(texture);
}
#if 0
for ( auto& texture : renderMode.textures ) {
INSERT_IMAGE(texture);
}
#endif
for ( auto& texture : shader->textures ) {
INSERT_IMAGE(texture);
}
for ( auto& texture : graphic.material.textures ) {
infos.image.emplace_back(texture.descriptor);
switch ( texture.viewType ) {
case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: infos.image2DA.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_CUBE: infos.imageCube.emplace_back(texture.descriptor); break;
case VK_IMAGE_VIEW_TYPE_3D: infos.image3D.emplace_back(texture.descriptor); break;
default: infos.imageUnknown.emplace_back(texture.descriptor); break;
}
INSERT_IMAGE(texture);
}
for ( auto& sampler : graphic.material.samplers ) {
infos.sampler.emplace_back(sampler.descriptor.info);
}
//
/*
uf::stl::vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationStructureInfos;
{
auto& descriptorAccelerationStructureInfo = accelerationStructureInfos.emplace_back();
descriptorAccelerationStructureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptorAccelerationStructureInfo.accelerationStructureCount = 1;
descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.tops[0].handle;
}
*/
// check if we can even consume that many infos
size_t consumes = 0;
for ( auto& layout : shader->descriptorSetLayoutBindings ) {

View File

@ -14,6 +14,8 @@
#include <uf/ext/vulkan/graphic.h>
#include <uf/engine/graph/graph.h>
#define EXTENDED_ATTRIBUTES 0
const uf::stl::string ext::vulkan::DeferredRenderMode::getType() const {
return "Deferred";
}
@ -37,7 +39,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
size_t msaa = ext::vulkan::settings::msaa;
struct {
size_t id, depth, color, bright, scratch, motion, output;
size_t id, bary, depth, uv, normal, color, bright, motion, scratch, output;
} attachments = {};
bool blend = true; // !ext::vulkan::settings::invariant::deferredSampling;
@ -50,14 +52,38 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.blend = */false,
/*.samples = */msaa,
});
attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */ext::vulkan::settings::formats::depth,
/*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
#if EXTENDED_ATTRIBUTES
attachments.uv = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,
/*.samples = */msaa,
});
attachments.normal = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,
/*.samples = */msaa,
});
#else
attachments.bary = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,
/*.samples = */msaa,
});
#endif
attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */ext::vulkan::settings::formats::depth,
/*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
/*.blend = */false,
/*.samples = */msaa,
});
// output buffers
attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format =*/ ext::vulkan::settings::pipelines::hdr ? HDR_FORMAT : SDR_FORMAT,
@ -86,12 +112,19 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
/*.blend = */false,
/*.samples = */msaa,
/*.samples = */1,
});
metadata.attachments["id"] = attachments.id;
metadata.attachments["depth"] = attachments.depth;
#if EXTENDED_ATTRIBUTES
metadata.attachments["uv"] = attachments.uv;
metadata.attachments["normal"] = attachments.normal;
#else
metadata.attachments["bary"] = attachments.bary;
#endif
metadata.attachments["depth"] = attachments.depth;
metadata.attachments["color"] = attachments.color;
metadata.attachments["bright"] = attachments.bright;
metadata.attachments["scratch"] = attachments.scratch;
@ -103,7 +136,11 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
renderTarget.addPass(
/*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
/*.colors =*/ { attachments.id },
#if EXTENDED_ATTRIBUTES
/*.colors =*/ { attachments.id, attachments.uv, attachments.normal },
#else
/*.colors =*/ { attachments.id, attachments.bary },
#endif
/*.inputs =*/ {},
/*.resolve =*/{},
/*.depth = */ attachments.depth,
@ -146,11 +183,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
});
}
{
size_t index = metadata.attachments["output"];
if ( blitter.material.hasShader("fragment") ) {
auto& shader = blitter.material.getShader("fragment");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[index] ); // attachments.color
shader.aliasAttachment("output", this);
}
if ( settings::pipelines::deferred ) {
uf::stl::string computeShaderFilename = "comp.spv"; {
@ -172,9 +207,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.getShader("compute", "bloom");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["color"]/*attachments.color*/], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]/*attachments.bright*/], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["scratch"]/*attachments.scratch*/], (size_t) 0 );
shader.aliasAttachment("color", this);
shader.aliasAttachment("bright", this);
shader.aliasAttachment("scratch", this);
for ( auto& texture : shader.textures ) {
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
@ -236,35 +271,21 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
}
}
}
if ( settings::pipelines::deferred && blitter.material.hasShader("compute", "deferred-compute") ) {
this->textures.clear();
this->textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["id"]] );
this->textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["depth"]] );
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["color"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["motion"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
auto& shader = blitter.material.getShader("compute", "deferred-compute");
shader.aliasAttachment("id", this);
#if EXTENDED_ATTRIBUTES
shader.aliasAttachment("uv", this);
shader.aliasAttachment("normal", this);
#else
shader.aliasAttachment("bary", this);
#endif
shader.aliasAttachment("depth", this);
shader.aliasAttachment("color", this, VK_IMAGE_LAYOUT_GENERAL);
shader.aliasAttachment("bright", this, VK_IMAGE_LAYOUT_GENERAL);
shader.aliasAttachment("motion", this, VK_IMAGE_LAYOUT_GENERAL);
}
if ( !blitter.hasPipeline( blitter.descriptor ) ){
@ -277,6 +298,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
if ( settings::pipelines::deferred && blitter.material.hasShader("compute", "deferred-compute") ) {
descriptor.pipeline = "deferred-compute";
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.subpass = 0;
if ( !blitter.hasPipeline( descriptor ) ) {
blitter.initializePipeline( descriptor );
@ -284,8 +306,8 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
}
if ( settings::pipelines::bloom ) {
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.pipeline = "bloom";
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.subpass = 0;
if ( !blitter.hasPipeline( descriptor ) ) {
blitter.initializePipeline( descriptor );
@ -316,58 +338,9 @@ void ext::vulkan::DeferredRenderMode::tick() {
if ( resized ) {
this->resized = false;
renderTarget.initialize( *renderTarget.device );
if ( settings::pipelines::bloom ) {
auto& shader = blitter.material.getShader("compute", "bloom");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["color"]], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["scratch"]], (size_t) 0 );
for ( auto& texture : shader.textures ) {
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
}
if ( settings::pipelines::deferred && blitter.material.hasShader("compute", "deferred-compute") ) {
this->textures.clear();
this->textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["id"]] );
this->textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["depth"]] );
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["color"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
{
auto& texture = this->textures.emplace_back();
texture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
texture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
texture.aliasAttachment( renderTarget.attachments[metadata.attachments["motion"]] );
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
}
}
// update blitter descriptor set
if ( rebuild && blitter.initialized ) {
{
size_t index = metadata.attachments["output"];
auto& shader = blitter.material.getShader("fragment");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[index], (size_t) 0 ); // attachments.color
}
if ( blitter.hasPipeline( blitter.descriptor ) ){
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
}
@ -376,6 +349,7 @@ void ext::vulkan::DeferredRenderMode::tick() {
descriptor.renderMode = "";
if ( settings::pipelines::deferred && blitter.material.hasShader("compute", "deferred-compute") ) {
descriptor.pipeline = "deferred-compute";
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.subpass = 0;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
@ -383,8 +357,8 @@ void ext::vulkan::DeferredRenderMode::tick() {
}
if ( settings::pipelines::bloom ) {
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.pipeline = "bloom";
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.subpass = 0;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
@ -558,56 +532,77 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
vkCmdEndRenderPass(commands[i]);
if ( !settings::pipelines::rt && settings::pipelines::deferred && blitter.material.hasShader("compute", "deferred-compute") ) {
auto& shader = blitter.material.getShader("compute", "deferred-compute");
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
descriptor.renderMode = "";
descriptor.pipeline = "deferred-compute";
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
descriptor.subpass = 0;
#if 1
imageMemoryBarrier.subresourceRange.layerCount = metadata.eyes;
for ( auto& attachment : this->textures ) {
switch ( attachment.imageLayout ) {
case VK_IMAGE_LAYOUT_GENERAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL", "VK_IMAGE_LAYOUT_GENERAL");
uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, imageMemoryBarrier.subresourceRange );
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL", "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL");
// uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageMemoryBarrier.subresourceRange );
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL", "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
// uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, imageMemoryBarrier.subresourceRange );
break;
for ( auto& descriptor : shader.metadata.attachments ) {
if ( descriptor.layout == VK_IMAGE_LAYOUT_UNDEFINED ) continue;
VkImage image = VK_NULL_HANDLE;
if ( descriptor.renderMode ) {
if ( descriptor.renderMode->hasAttachment(descriptor.name) )
image = descriptor.renderMode->getAttachment(descriptor.name).image;
} else if ( this->hasAttachment(descriptor.name) ) {
if ( this->hasAttachment(descriptor.name) )
image = this->getAttachment(descriptor.name).image;
}
if ( image == VK_NULL_HANDLE ) continue;
uf::renderer::Texture::setImageLayout( commands[i], image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, descriptor.layout, imageMemoryBarrier.subresourceRange );
}
#endif
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
blitter.record(commands[i], descriptor, eye, 0);
}
for ( auto& descriptor : shader.metadata.attachments ) {
if ( descriptor.layout == VK_IMAGE_LAYOUT_UNDEFINED ) continue;
VkImage image = VK_NULL_HANDLE;
if ( descriptor.renderMode ) {
if ( descriptor.renderMode->hasAttachment(descriptor.name) )
image = descriptor.renderMode->getAttachment(descriptor.name).image;
} else if ( this->hasAttachment(descriptor.name) ) {
image = this->getAttachment(descriptor.name).image;
}
if ( image == VK_NULL_HANDLE ) continue;
uf::renderer::Texture::setImageLayout( commands[i], image, descriptor.layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageMemoryBarrier.subresourceRange );
}
imageMemoryBarrier.subresourceRange.layerCount = 1;
}
// VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
// VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
#if 0
if ( this->hasAttachment("depth") ) {
auto& attachment = this->getAttachment("depth");
ext::vulkan::Texture texture; texture.aliasAttachment( attachment );
texture.width = width;
texture.height = height;
texture.depth = 1;
texture.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
#if 1
imageMemoryBarrier.subresourceRange.layerCount = metadata.eyes;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageMemoryBarrier.subresourceRange );
#endif
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
texture.generateMipmaps(commands[i], eye);
}
#if 1
for ( auto& attachment : this->textures ) {
switch ( attachment.imageLayout ) {
case VK_IMAGE_LAYOUT_GENERAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_GENERAL", "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL");
uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageMemoryBarrier.subresourceRange );
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL", "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL");
// uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, imageMemoryBarrier.subresourceRange );
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
// UF_MSG_DEBUG("Converting {} to {}", "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL", "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL");
// uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, imageMemoryBarrier.subresourceRange );
break;
}
}
uf::renderer::Texture::setImageLayout( commands[i], attachment.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, imageMemoryBarrier.subresourceRange );
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageMemoryBarrier.subresourceRange.layerCount = 1;
#endif
}
#endif
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i], i );

View File

@ -241,15 +241,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
}
}
} else if ( metadata.type != uf::renderer::settings::pipelines::names::rt ) {
/*
auto previousTextures = std::move(blitter.material.textures);
blitter.material.textures.clear();
auto& shader = blitter.material.getShader("fragment");
for ( auto& prevTex : previousTextures ) {
shader.textures.emplace_back(prevTex);
}
*/
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
@ -261,18 +252,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
texture.aliasAttachment(attachment);
}
}
/*
if ( blitter.process ) {
auto& mainRenderMode = ext::vulkan::getRenderMode("");
size_t eyes = mainRenderMode.metadata["eyes"].as<size_t>();
for ( size_t eye = 0; eye < eyes; ++eye ) {
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
descriptor.subpass = 2 * eye + 1;
if ( blitter.hasPipeline( descriptor ) ) continue;
blitter.initializePipeline( descriptor );
}
}
*/
}
}

View File

@ -29,13 +29,7 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
if ( attachment ) {
if ( attachment->view ) {
if ( attachment->view != attachment->views.front() ) {
vkDestroyImageView(*device, attachment->view, nullptr);
attachment->view = VK_NULL_HANDLE;
}
}
for ( size_t i = 0; i < this->views; ++i ) vkDestroyImageView(*device, attachment->views[i], nullptr);
for ( auto& view : attachment->views ) vkDestroyImageView(*device, view, nullptr);
attachment->views.clear();
if ( attachment->image ) {
vmaDestroyImage( allocator, attachment->image, attachment->allocation );
@ -47,7 +41,6 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
} else {
attachment = &attachments.emplace_back();
attachment->descriptor = descriptor;
attachment->views.resize(this->views);
}
// un-request transient attachments if not supported yet requested
if ( attachment->descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ) {
@ -68,12 +61,19 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
attachment->descriptor.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
if ( attachment->descriptor.mips == 0 ) {
attachment->descriptor.mips = 1;
} else {
attachment->descriptor.mips = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
}
attachment->views.resize(this->views * attachment->descriptor.mips);
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = attachment->descriptor.format;
imageCreateInfo.extent = { width, height, 1 };
imageCreateInfo.mipLevels = 1;
imageCreateInfo.mipLevels = attachment->descriptor.mips;
imageCreateInfo.arrayLayers = this->views;
imageCreateInfo.samples = ext::vulkan::sampleCount( attachment->descriptor.samples );
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
@ -108,14 +108,31 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
imageView.subresourceRange = {};
imageView.subresourceRange.aspectMask = aspectMask;
imageView.subresourceRange.baseMipLevel = 0;
imageView.subresourceRange.levelCount = 1;
imageView.subresourceRange.baseArrayLayer = 0;
imageView.subresourceRange.levelCount = attachment->descriptor.mips;
imageView.subresourceRange.layerCount = this->views;
imageView.image = attachment->image;
VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->view));
#if 1
size_t viewIndex = 0;
for ( size_t layer = 0; layer < this->views; ++layer ) {
imageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageView.subresourceRange.levelCount = 1;
imageView.subresourceRange.layerCount = 1;
for ( size_t mip = 0; mip < attachment->descriptor.mips; ++mip ) {
imageView.subresourceRange.baseMipLevel = mip;
imageView.subresourceRange.baseArrayLayer = layer;
VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->views[viewIndex++]));
}
}
#endif
#if 0
if ( this->views == 1 ) {
attachment->views[0] = attachment->view;
for ( ) {
}
} else {
imageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageView.subresourceRange.layerCount = 1;
@ -124,6 +141,7 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->views[i]));
}
}
#endif
{
VkBool32 blendEnabled = attachment->descriptor.blend ? VK_TRUE : VK_FALSE;
@ -299,6 +317,17 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
framebuffers.resize(ext::vulkan::swapchain.buffers);
for ( size_t i = 0; i < framebuffers.size(); ++i ) {
uf::stl::vector<VkImageView> attachmentViews;
for ( size_t view = 0; view < this->views; ++view ) {
for ( auto& attachment : this->attachments ) {
if ( attachment.descriptor.aliased && attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
attachmentViews.emplace_back(base.renderTarget.attachments[i].view);
continue;
}
attachmentViews.emplace_back(attachment.views[view * attachment.descriptor.mips]);
}
}
#if 0
for ( size_t j = 0; j < this->views; ++j ) {
for ( auto& attachment : this->attachments ) {
if ( attachment.descriptor.aliased && attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
@ -306,6 +335,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
} else attachmentViews.emplace_back(attachment.views[j]);
}
}
#endif
VkFramebufferCreateInfo frameBufferCreateInfo = {};
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;

View File

@ -851,6 +851,14 @@ bool ext::vulkan::Shader::validate() {
}
return valid;
}
void ext::vulkan::Shader::aliasAttachment( const ext::vulkan::Shader::Metadata::AttachmentDescriptor& descriptor ) {
metadata.attachments.emplace_back(descriptor);
}
void ext::vulkan::Shader::aliasAttachment( const uf::stl::string& name, const ext::vulkan::RenderMode* renderMode, VkImageLayout layout, VkFilter filter ) {
return aliasAttachment({ name, renderMode, layout, filter });
}
bool ext::vulkan::Shader::hasUniform( const uf::stl::string& name ) const {
return metadata.definitions.uniforms.count(name) > 0;
}

View File

@ -191,7 +191,7 @@ bool ext::vulkan::Texture::generated() const {
return view != VK_NULL_HANDLE;
}
void ext::vulkan::Texture::destroy() {
if ( !device || !device->logicalDevice ) return; // device->logicalDevice should never be null, but it happens, somehow
if ( !device || !device->logicalDevice || aliased ) return; // device->logicalDevice should never be null, but it happens, somehow
if ( view != VK_NULL_HANDLE ) {
vkDestroyImageView(device->logicalDevice, view, nullptr);
@ -664,7 +664,9 @@ ext::vulkan::Texture ext::vulkan::Texture::alias() const {
}
void ext::vulkan::Texture::aliasTexture( const Texture& texture ) {
*this = {
.device = nullptr,
.device = texture.device,
.aliased = true,
.image = texture.image,
.view = texture.view,
.type = texture.type,
@ -698,6 +700,8 @@ VkImageLayout ext::vulkan::Texture::remapRenderpassLayout( VkImageLayout layout
return layout;
}
void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& attachment, bool createSampler ) {
device = &ext::vulkan::device;
aliased = true;
image = attachment.image;
type = ext::vulkan::enums::Image::TYPE_2D;
viewType = attachment.views.size() == 6 ? ext::vulkan::enums::Image::VIEW_TYPE_CUBE : ext::vulkan::enums::Image::VIEW_TYPE_2D;
@ -705,10 +709,13 @@ void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& atta
imageLayout = ext::vulkan::Texture::remapRenderpassLayout( attachment.descriptor.layout );
deviceMemory = attachment.mem;
format = attachment.descriptor.format;
mips = attachment.descriptor.mips;
// Create sampler
if ( createSampler ) {
// sampler.initialize( ext::vulkan::device );
sampler.descriptor.mip.min = 0;
sampler.descriptor.mip.max = static_cast<float>(this->mips);
::enforceFilterFromFormat( sampler.descriptor, format );
sampler = ext::vulkan::Sampler::retrieve( sampler.descriptor );
}
@ -716,6 +723,8 @@ void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& atta
this->updateDescriptors();
}
void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& attachment, size_t layer, bool createSampler ) {
device = &ext::vulkan::device;
aliased = true;
image = attachment.image;
type = ext::vulkan::enums::Image::TYPE_2D;
viewType = ext::vulkan::enums::Image::VIEW_TYPE_2D;
@ -723,10 +732,13 @@ void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& atta
imageLayout = ext::vulkan::Texture::remapRenderpassLayout( attachment.descriptor.layout );
deviceMemory = attachment.mem;
format = attachment.descriptor.format;
mips = attachment.descriptor.mips;
// Create sampler
if ( createSampler ) {
// sampler.initialize( ext::vulkan::device );
sampler.descriptor.mip.min = 0;
sampler.descriptor.mip.max = static_cast<float>(this->mips);
::enforceFilterFromFormat( sampler.descriptor, format );
sampler = ext::vulkan::Sampler::retrieve( sampler.descriptor );
}
@ -821,13 +833,17 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
blitting = false;
}
bool isDepth = formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
auto aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
auto filter = isDepth ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
// base layer barrier
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.image = image;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.aspectMask = aspectMask;
barrier.subresourceRange.baseArrayLayer = layer;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.levelCount = 1;
@ -854,13 +870,13 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
VkImageBlit blit{};
blit.srcOffsets[0] = { 0, 0, 0 };
blit.srcOffsets[1] = { mipWidth, mipHeight, mipDepth };
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.srcSubresource.aspectMask = aspectMask;
blit.srcSubresource.mipLevel = i - 1;
blit.srcSubresource.baseArrayLayer = layer;
blit.srcSubresource.layerCount = 1;
blit.dstOffsets[0] = { 0, 0, 0 };
blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, mipDepth > 1 ? mipDepth / 2 : 1 };
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.dstSubresource.aspectMask = aspectMask;
blit.dstSubresource.mipLevel = i;
blit.dstSubresource.baseArrayLayer = layer;
blit.dstSubresource.layerCount = 1;
@ -870,10 +886,10 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &blit,
VK_FILTER_LINEAR
filter
);
} else {
UF_MSG_ERROR("mipmapping not supported without blitting");
}
// transition previous layer back

View File

@ -60,7 +60,6 @@ bool ext::vulkan::settings::pipelines::vsync = true;
bool ext::vulkan::settings::pipelines::hdr = true;
bool ext::vulkan::settings::pipelines::vxgi = true;
bool ext::vulkan::settings::pipelines::culling = false;
bool ext::vulkan::settings::pipelines::occlusion = false;
bool ext::vulkan::settings::pipelines::bloom = false;
bool ext::vulkan::settings::pipelines::rt = false;
bool ext::vulkan::settings::pipelines::postProcess = false;
@ -71,7 +70,6 @@ uf::stl::string ext::vulkan::settings::pipelines::names::vsync = "vsync";
uf::stl::string ext::vulkan::settings::pipelines::names::hdr = "hdr";
uf::stl::string ext::vulkan::settings::pipelines::names::vxgi = "vxgi";
uf::stl::string ext::vulkan::settings::pipelines::names::culling = "culling";
uf::stl::string ext::vulkan::settings::pipelines::names::occlusion = "occlusion";
uf::stl::string ext::vulkan::settings::pipelines::names::bloom = "bloom";
uf::stl::string ext::vulkan::settings::pipelines::names::rt = "rt";
uf::stl::string ext::vulkan::settings::pipelines::names::postProcess = "postprocess";

View File

@ -80,6 +80,17 @@ uf::stl::string UF_API uf::string::join( const uf::stl::vector<uf::stl::string>&
return ss.str();
}
*/
uf::stl::vector<const char*> UF_API uf::string::cStrings( const uf::stl::vector<uf::stl::string>& strings ) {
uf::stl::vector<const char*> v;
v.reserve( strings.size() );
for ( auto& s : strings ) {
v.emplace_back(s.c_str());
}
return v;
}
uf::stl::string UF_API uf::string::replace( const uf::stl::string& string, const uf::stl::string& search, const uf::stl::string& replace ) {
uf::stl::string result = string;

View File

@ -527,6 +527,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
int32_t index = -1;
// separated texture2Ds
if ( metadata.shadow.typeMap == MODE_SEPARATE_2DS ) {
UF_MSG_WARNING("deprecated feature used: separate Texture2Ds for shadow maps");
index = uf::graph::storage.shadow2Ds.size();
for ( auto& attachment : renderMode.renderTarget.attachments ) {
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;

View File

@ -161,6 +161,8 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.depth ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
});
//
renderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer, size_t _ ){
// parse voxel lighting
if ( renderMode.blitter.initialized ) {
@ -193,136 +195,6 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
);
}
});
#if 0
renderMode.bindCallback( renderMode.EXECUTE_BEGIN, [&]( VkCommandBuffer _, size_t __ ) {
auto& controller = scene.getController();
auto controllerTransform = uf::transform::flatten( controller.getComponent<uf::Camera>().getTransform() );
pod::Vector3f controllerPosition = controllerTransform.position - metadata.extents.min;
controllerPosition.x = floor(controllerPosition.x);
controllerPosition.y = floor(controllerPosition.y);
controllerPosition.z = floor(controllerPosition.z);
controllerPosition += metadata.extents.min;
controllerPosition.x = floor(controllerPosition.x);
controllerPosition.y = floor(controllerPosition.y);
controllerPosition.z = -floor(controllerPosition.z);
pod::Vector3f min = metadata.extents.min + controllerPosition;
pod::Vector3f max = metadata.extents.max + controllerPosition;
metadata.extents.matrix = uf::matrix::orthographic( min.x, max.x, min.y, max.y, min.z, max.z );
auto& graph = scene.getGraph();
for ( auto entity : graph ) {
if ( !entity->hasComponent<uf::Graphic>() ) continue;
auto& graphic = entity->getComponent<uf::Graphic>();
if ( graphic.material.hasShader("geometry", "vxgi") ) {
auto& shader = graphic.material.getShader("geometry", "vxgi");
struct UniformDescriptor {
/*alignas(16)*/ pod::Matrix4f matrix;
/*alignas(4)*/ float cascadePower;
/*alignas(4)*/ float padding1;
/*alignas(4)*/ float padding2;
/*alignas(4)*/ float padding3;
};
#if UF_UNIFORMS_REUSE
auto& uniform = shader.getUniform("UBO");
auto& uniforms = uniform.get<UniformDescriptor>();
uniforms = UniformDescriptor{
.matrix = metadata.extents.matrix,
.cascadePower = metadata.cascadePower,
};
shader.updateUniform( "UBO", uniform );
#else
UniformDescriptor uniforms = {
.matrix = metadata.extents.matrix,
.cascadePower = metadata.cascadePower,
};
shader.updateBuffer( uniforms, shader.getUniformBuffer("UBO") );
#endif
}
}
} );
#endif
#if 0
auto& deferredRenderMode = uf::renderer::getRenderMode("", true);
deferredRenderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
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.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
for ( auto& t : sceneTextures.voxels.radiance ) {
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
/*
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
*/
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
}
});
deferredRenderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer, size_t _ ){
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.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
for ( auto& t : sceneTextures.voxels.radiance ) {
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
/*
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
*/
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
}
});
#endif
}
#endif
}

View File

@ -427,7 +427,6 @@ void EXT_API ext::initialize() {
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 );
uf::renderer::settings::pipelines::occlusion = configRenderPipelinesJson["occlusion"].as( uf::renderer::settings::pipelines::occlusion );
uf::renderer::settings::pipelines::bloom = configRenderPipelinesJson["bloom"].as( uf::renderer::settings::pipelines::bloom );
uf::renderer::settings::pipelines::rt = configRenderPipelinesJson["rt"].as( uf::renderer::settings::pipelines::rt );
uf::renderer::settings::pipelines::postProcess = configRenderPipelinesJson["postProcess"].as( uf::renderer::settings::pipelines::postProcess );
@ -436,7 +435,6 @@ void EXT_API ext::initialize() {
if ( uf::renderer::settings::pipelines::rt ) {
uf::renderer::settings::pipelines::vxgi = false;
uf::renderer::settings::pipelines::culling = false;
uf::renderer::settings::pipelines::occlusion = false;
::json["engine"]["scenes"]["lights"]["shadows"]["enabled"] = false;
}
#define JSON_TO_FORMAT( key ) if ( configRenderJson["formats"][#key].is<uf::stl::string>() ) {\
@ -516,9 +514,6 @@ void EXT_API ext::initialize() {
if ( uf::renderer::settings::pipelines::culling ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::culling);
}
if ( uf::renderer::settings::pipelines::occlusion ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::occlusion);
}
uf::renderer::addRenderMode( renderMode, "" );
}