Commit for 2022.07.29 00-31-45.7z
This commit is contained in:
parent
5a12332ad8
commit
ae28b31d02
@ -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",
|
||||
|
@ -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 ],
|
||||
|
@ -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"
|
||||
}
|
@ -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 );
|
||||
|
@ -187,7 +187,7 @@ struct Surface {
|
||||
vec3 st;
|
||||
Space position;
|
||||
Space normal;
|
||||
vec3 tangent;
|
||||
Space tangent;
|
||||
mat3 tbn;
|
||||
vec3 barycentric;
|
||||
vec2 motion;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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 ) {
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
{
|
||||
|
@ -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 ) {
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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, "" );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user