Commit for 2021.02.07.7z
This commit is contained in:
parent
910039a877
commit
160c7ff198
@ -1,116 +1,19 @@
|
||||
#version 450
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
#define SAMPLES 16
|
||||
#define POISSON_DISK 4
|
||||
#define RAY_MARCH_FOG 0
|
||||
#define UF_DEFERRED_SAMPLING 1
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 256;
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
int mapIndex;
|
||||
float depthBias;
|
||||
float padding;
|
||||
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
|
||||
int padding1;
|
||||
int padding2;
|
||||
int padding3;
|
||||
};
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
struct DrawCall {
|
||||
int materialIndex;
|
||||
uint materials;
|
||||
int textureIndex;
|
||||
uint textures;
|
||||
};
|
||||
|
||||
layout (input_attachment_index = 0, binding = 1) uniform usubpassInput samplerId;
|
||||
layout (input_attachment_index = 1, binding = 2) uniform subpassInput samplerNormal;
|
||||
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (input_attachment_index = 2, binding = 3) uniform subpassInput samplerUv;
|
||||
#else
|
||||
layout (input_attachment_index = 2, binding = 3) uniform subpassInput samplerAlbedo;
|
||||
#endif
|
||||
|
||||
layout (input_attachment_index = 3, binding = 4) uniform subpassInput samplerDepth;
|
||||
|
||||
layout (binding = 5) uniform sampler3D samplerNoise;
|
||||
layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (std140, binding = 7) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
layout (std140, binding = 8) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 9) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 10) readonly buffer DrawCalls {
|
||||
DrawCall drawCalls[];
|
||||
};
|
||||
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
struct Matrices {
|
||||
mat4 view[2];
|
||||
mat4 projection[2];
|
||||
mat4 iView[2];
|
||||
mat4 iProjection[2];
|
||||
mat4 iProjectionView[2];
|
||||
};
|
||||
|
||||
struct Space {
|
||||
@ -142,7 +45,72 @@ struct Mode {
|
||||
vec4 parameters;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
int mapIndex;
|
||||
float depthBias;
|
||||
float padding;
|
||||
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
int modeAlpha;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
struct DrawCall {
|
||||
int materialIndex;
|
||||
uint materials;
|
||||
int textureIndex;
|
||||
uint textures;
|
||||
};
|
||||
|
||||
layout (input_attachment_index = 0, binding = 0) uniform usubpassInputMS samplerId;
|
||||
layout (input_attachment_index = 1, binding = 1) uniform subpassInputMS samplerNormal;
|
||||
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerUv;
|
||||
#else
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerAlbedo;
|
||||
#endif
|
||||
|
||||
layout (input_attachment_index = 3, binding = 3) uniform subpassInputMS samplerDepth;
|
||||
|
||||
layout (binding = 4) uniform sampler3D samplerNoise;
|
||||
layout (binding = 5) uniform samplerCube samplerSkybox;
|
||||
layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
|
||||
|
||||
layout (binding = 7) uniform UBO {
|
||||
Matrices matrices;
|
||||
|
||||
Mode mode;
|
||||
@ -157,6 +125,44 @@ layout (binding = 0) uniform UBO {
|
||||
float kexp;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 8) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
layout (std140, binding = 9) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 10) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 11) readonly buffer DrawCalls {
|
||||
DrawCall drawCalls[];
|
||||
};
|
||||
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
vec3 Ls = vec3(1.0, 1.0, 1.0); // light specular
|
||||
vec3 Ld = light.color; // light color
|
||||
@ -476,9 +482,9 @@ void pbr( Light light, vec3 albedo, float metallic, float roughness, vec3 lightP
|
||||
i += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, vec3 rayOrigin, vec3 rayDir ) {
|
||||
vec3 t0 = (boundsMin - rayOrigin) / rayDir;
|
||||
vec3 t1 = (boundsMax - rayOrigin) / rayDir;
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, vec3 rayO, vec3 rayD ) {
|
||||
vec3 t0 = (boundsMin - rayO) / rayD;
|
||||
vec3 t1 = (boundsMax - rayO) / rayD;
|
||||
vec3 tmin = min(t0, t1);
|
||||
vec3 tmax = max(t0, t1);
|
||||
float dstA = max( max(tmin.x, tmin.y), tmin.z );
|
||||
@ -493,26 +499,17 @@ float sampleDensity( vec3 position ) {
|
||||
return max(0, texture(samplerNoise, uvw).r - ubo.fog.densityThreshold) * ubo.fog.densityMultiplier;
|
||||
}
|
||||
|
||||
void fog( inout vec3 i, float scale ) {
|
||||
void fog( vec3 rayO, vec3 rayD, inout vec3 i, float scale ) {
|
||||
if ( ubo.fog.stepScale <= 0 ) return;
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
#if RAY_MARCH_FOG
|
||||
mat4 iProjView = inverse( ubo.matrices.projection[inPushConstantPass] * ubo.matrices.view[inPushConstantPass] );
|
||||
vec4 near4 = iProjView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = iProjView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
vec3 rayOrigin = near3;
|
||||
vec3 rayDir = normalize( far3 - near3 );
|
||||
|
||||
float range = ubo.fog.range.y;
|
||||
vec3 boundsMin = vec3(-range,-range,-range) + rayOrigin;
|
||||
vec3 boundsMax = vec3(range,range,range) + rayOrigin;
|
||||
vec3 boundsMin = vec3(-range,-range,-range) + rayO;
|
||||
vec3 boundsMax = vec3(range,range,range) + rayO;
|
||||
int numSteps = int(length(boundsMax - boundsMin) * ubo.fog.stepScale );
|
||||
|
||||
vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, rayOrigin, rayDir );
|
||||
vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, rayO, rayD );
|
||||
float dstToBox = rayBoxInfo.x;
|
||||
float dstInsideBox = rayBoxInfo.y;
|
||||
float depth = position.eye.z;
|
||||
@ -526,7 +523,7 @@ void fog( inout vec3 i, float scale ) {
|
||||
float totalDensity = 0;
|
||||
float transmittance = 1;
|
||||
while ( dstTravelled < dstLimit ) {
|
||||
vec3 rayPos = rayOrigin + rayDir * (dstToBox + dstTravelled);
|
||||
vec3 rayPos = rayO + rayD * (dstToBox + dstTravelled);
|
||||
float density = sampleDensity(rayPos);
|
||||
if ( density > 0 ) {
|
||||
transmittance *= exp(-density * stepSize * ubo.fog.absorbtion);
|
||||
@ -557,49 +554,93 @@ vec3 decodeNormals( vec2 enc ) {
|
||||
n.z = 1-f/2;
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
float wrap( float i ) {
|
||||
return fract(i);
|
||||
}
|
||||
vec2 wrap( vec2 uv ) {
|
||||
return vec2( wrap( uv.x ), wrap( uv.y ) );
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < ubo.textures;
|
||||
}
|
||||
vec4 sampleTexture( uint drawId, int textureIndex, vec2 uv, vec4 base ) {
|
||||
if ( !validTextureIndex( textureIndex ) ) return base;
|
||||
vec4 sampleTexture( uint drawId, int textureIndex, in vec2 uv, vec4 base ) {
|
||||
if ( !validTextureIndex( textureIndex ) ) return base;
|
||||
Texture t = textures[textureIndex+1];
|
||||
// if ( t.remap != textureIndex && validTextureIndex(t.remap) ) t = textures[t.remap+1];
|
||||
return texture( samplerTextures[drawId], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
float mip = mipLevel( uv );
|
||||
return texture( samplerTextures[drawId], mix( t.lerp.xy, t.lerp.zw, wrap( uv ) ), mip );
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 rayO = vec3(0);
|
||||
vec3 rayD = vec3(0);
|
||||
vec3 fragColor = vec3(0);
|
||||
|
||||
{
|
||||
mat4 iProj = inverse( ubo.matrices.projection[inPushConstantPass] );
|
||||
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
|
||||
float depth = subpassLoad(samplerDepth).r;
|
||||
float depth = subpassLoad(samplerDepth, SAMPLES).r;
|
||||
|
||||
vec4 positionClip = vec4(inUv * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 positionEye = iProj * positionClip;
|
||||
vec4 positionEye = ubo.matrices.iProjection[inPushConstantPass] * positionClip;
|
||||
positionEye /= positionEye.w;
|
||||
position.eye = positionEye.xyz;
|
||||
|
||||
vec4 positionWorld = iView * positionEye;
|
||||
vec4 positionWorld = ubo.matrices.iView[inPushConstantPass] * positionEye;
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
|
||||
normal.eye = decodeNormals( subpassLoad(samplerNormal).xy );
|
||||
{
|
||||
vec4 near4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
uvec2 ID = subpassLoad(samplerId).xy;
|
||||
rayO = near3;
|
||||
}
|
||||
{
|
||||
mat4 iProjectionView = inverse( ubo.matrices.projection[inPushConstantPass] * mat4(mat3(ubo.matrices.view[inPushConstantPass])) );
|
||||
vec4 near4 = iProjectionView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = iProjectionView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
rayD = normalize( far3 - near3 );
|
||||
}
|
||||
|
||||
normal.eye = decodeNormals( subpassLoad(samplerNormal, SAMPLES).xy );
|
||||
|
||||
uvec2 ID = subpassLoad(samplerId, SAMPLES).xy;
|
||||
uint drawId = ID.x;
|
||||
uint materialId = ID.y;
|
||||
if ( drawId == 0 || materialId == 0 ) {
|
||||
fragColor.rgb = texture( samplerSkybox, rayD ).rgb;
|
||||
fog(rayO, rayD, fragColor, 0.0);
|
||||
outFragColor = vec4(fragColor,1);
|
||||
return;
|
||||
}
|
||||
--drawId;
|
||||
--materialId;
|
||||
|
||||
DrawCall drawCall = drawCalls[drawId];
|
||||
uint materialId = ID.y;
|
||||
materialId += drawCall.materialIndex;
|
||||
|
||||
Material material = materials[materialId];
|
||||
vec4 C = material.colorBase;
|
||||
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
vec2 uv = subpassLoad(samplerUv).xy;
|
||||
vec2 uv = subpassLoad(samplerUv, SAMPLES).xy;
|
||||
C = sampleTexture( drawId, drawCall.textureIndex + material.indexAlbedo, uv, C );
|
||||
// OPAQUE
|
||||
if ( material.modeAlpha == 0 ) C.a = 1;
|
||||
// BLEND
|
||||
else if ( material.modeAlpha == 1 ) {
|
||||
// MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
}
|
||||
#else
|
||||
C = subpassLoad(samplerAlbedo);
|
||||
C = subpassLoad(samplerAlbedo, SAMPLES);
|
||||
#endif
|
||||
|
||||
float M = material.factorMetallic;
|
||||
@ -609,7 +650,7 @@ void main() {
|
||||
bool usePbr = true;
|
||||
bool gammaCorrect = false;
|
||||
float litFactor = 1.0;
|
||||
vec3 fragColor = C.rgb * ubo.ambient.rgb * AO;
|
||||
fragColor = C.rgb * ubo.ambient.rgb * AO;
|
||||
for ( uint i = 0; i < ubo.lights; ++i ) {
|
||||
Light light = lights[i];
|
||||
|
||||
@ -636,7 +677,7 @@ void main() {
|
||||
fragColor = pow(fragColor, vec3(1.0/2.2));
|
||||
}
|
||||
|
||||
fog(fragColor, litFactor);
|
||||
fog(rayO, rayD, fragColor, litFactor);
|
||||
|
||||
/*
|
||||
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#version 450
|
||||
|
||||
#define UF_DEFERRED_SAMPLING 1
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 1;
|
||||
@ -21,10 +21,9 @@ struct Material {
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
|
||||
int modeAlpha;
|
||||
int padding1;
|
||||
int padding2;
|
||||
int padding3;
|
||||
};
|
||||
struct Texture {
|
||||
int index;
|
||||
@ -62,43 +61,46 @@ vec2 encodeNormals( vec3 n ) {
|
||||
return n.xy/p + 0.5;
|
||||
}
|
||||
|
||||
float wrap( float i ) {
|
||||
return fract(i);
|
||||
}
|
||||
vec2 wrap( vec2 uv ) {
|
||||
return vec2( wrap( uv.x ), wrap( uv.y ) );
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < TEXTURES;
|
||||
}
|
||||
vec4 sampleTexture( int textureIndex, vec2 uv, vec4 base ) {
|
||||
if ( !validTextureIndex( textureIndex ) ) return base;
|
||||
Texture t = textures[textureIndex+1];
|
||||
// if ( 0 <= t.remap && t.remap <= TEXTURES && t.remap != textureIndex ) t = textures[t.remap+1];
|
||||
return texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
}
|
||||
|
||||
void main() {
|
||||
float mip = mipLevel(inUv.xy);
|
||||
vec2 uv = wrap(inUv.xy);
|
||||
vec4 C = vec4(0, 0, 0, 0);
|
||||
vec3 P = inPosition;
|
||||
vec3 N = inNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
outUvs = fract(inUv);
|
||||
outUvs = wrap(inUv.xy);
|
||||
vec4 outAlbedo = vec4(0,0,0,0);
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
|
||||
int materialId = int(inId.y);
|
||||
Material material = materials[materialId];
|
||||
|
||||
vec2 uv = fract(inUv.xy);
|
||||
|
||||
float M = material.factorMetallic;
|
||||
float R = material.factorRoughness;
|
||||
float AO = material.factorOcclusion;
|
||||
|
||||
// sample albedo
|
||||
// C = sampleTexture( material.indexAlbedo, uv, material.colorBase );
|
||||
if ( !validTextureIndex( material.indexAlbedo ) ) {
|
||||
discard;
|
||||
}
|
||||
{
|
||||
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
|
||||
Texture t = textures[material.indexAlbedo + 1];
|
||||
C = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
if ( C.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
C = textureLod( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
// alpha mode MASK
|
||||
if ( material.modeAlpha == 0 ) C.a = 1;
|
||||
else if ( material.modeAlpha == 2 && C.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
// alpha mode OPAQUE
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -106,14 +108,14 @@ void main() {
|
||||
// sample normal
|
||||
if ( validTextureIndex( material.indexNormal ) ) {
|
||||
Texture t = textures[material.indexNormal + 1];
|
||||
N = inTBN * normalize( texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) ).xyz * 2.0 - vec3(1.0));
|
||||
N = inTBN * normalize( textureLod( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip ).xyz * 2.0 - vec3(1.0));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// sample metallic/roughness
|
||||
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
|
||||
Texture t = textures[material.indexMetallicRoughness + 1];
|
||||
vec4 sampled = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
vec4 sampled = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
M = sampled.b;
|
||||
R = sampled.g;
|
||||
}
|
||||
@ -124,84 +126,9 @@ void main() {
|
||||
AO = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) ).r;
|
||||
}
|
||||
#endif
|
||||
|
||||
C.rgb *= inColor.rgb * C.a;
|
||||
outAlbedo = vec4(C.rgb,1);
|
||||
outAlbedo = C * inColor;
|
||||
#endif
|
||||
|
||||
outNormals = encodeNormals( N );
|
||||
outId = ivec2(inId.w, inId.y);
|
||||
}
|
||||
|
||||
/*
|
||||
layout (location = 0) out vec4 outAlbedoMetallic;
|
||||
layout (location = 1) out vec4 outNormalRoughness;
|
||||
layout (location = 2) out vec4 outPositionAO;
|
||||
|
||||
bool validIndex( int index ) {
|
||||
return 0 <= index && index < TEXTURES;
|
||||
}
|
||||
vec4 sampleTexture( int index ) {
|
||||
return texture(samplerTextures[index], inUv.xy);
|
||||
}
|
||||
|
||||
void main() {
|
||||
int materialId = int(inId.y);
|
||||
|
||||
vec4 C = vec4(1, 0, 1, 1);
|
||||
vec3 N = inNormal;
|
||||
vec3 P = inPosition;
|
||||
float M = 1;
|
||||
float R = 1;
|
||||
float AO = 1;
|
||||
if ( 0 <= materialId && materialId < materials.length() ) {
|
||||
Material material = materials[materialId];
|
||||
|
||||
// sample albedo
|
||||
C = material.colorBase;
|
||||
if ( validIndex( material.indexAlbedo ) ) {
|
||||
C = sampleTexture( material.indexAlbedo );
|
||||
if ( material.indexAlbedo != material.indexMappedTarget && validIndex( material.indexMappedTarget ) ) {
|
||||
C = mix( C, sampleTexture( material.indexMappedTarget ), material.factorMappedBlend );
|
||||
}
|
||||
} else if ( validIndex( material.indexMappedTarget ) ) {
|
||||
C = sampleTexture( material.indexMappedTarget );
|
||||
}
|
||||
// debug
|
||||
if ( material.factorAlphaCutoff < 0 ) {
|
||||
float percent = float(material.indexAlbedo) / float(TEXTURES);
|
||||
if ( percent < 0.33 ) {
|
||||
C.rgb = vec3( percent * 3, 0, 0 );
|
||||
} else if ( percent < 0.66 ) {
|
||||
C.rgb = vec3( 0, percent * 3, 0 );
|
||||
} else {
|
||||
C.rgb = vec3( 0, 0, percent * 3 );
|
||||
}
|
||||
}
|
||||
if ( C.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
|
||||
// sample normal
|
||||
if ( validIndex( material.indexNormal ) ) {
|
||||
N = inTBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
|
||||
}
|
||||
// sample metallic/roughness
|
||||
M = material.factorMetallic;
|
||||
R = material.factorRoughness;
|
||||
if ( validIndex( material.indexMetallicRoughness ) ) {
|
||||
vec4 sampled = sampleTexture( material.indexMetallicRoughness );
|
||||
M = sampled.b;
|
||||
R = sampled.g;
|
||||
}
|
||||
AO = material.factorOcclusion;
|
||||
if ( validIndex( material.indexOcclusion ) ) {
|
||||
AO = sampleTexture( material.indexOcclusion ).r;
|
||||
}
|
||||
}
|
||||
|
||||
C.rgb *= inColor.rgb * C.a;
|
||||
|
||||
outAlbedoMetallic = vec4(C.rgb,M);
|
||||
outNormalRoughness = vec4(N,R);
|
||||
outPositionAO = vec4(P,AO);
|
||||
}
|
||||
*/
|
||||
outId = ivec2(inId.w+1, inId.y+1);
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#include <uf/utils/mempool/mempool.h>
|
||||
|
||||
#define HANDLE_EXCEPTIONS 0
|
||||
#define HANDLE_EXCEPTIONS 1
|
||||
|
||||
int main(int argc, char** argv){
|
||||
for ( size_t i = 0; i < argc; ++i ) {
|
||||
|
||||
@ -48,6 +48,7 @@ namespace uf {
|
||||
uf::Entity* UF_API alloc( size_t );
|
||||
template<typename T> T* alloc();
|
||||
void UF_API free( uf::Entity* );
|
||||
bool UF_API valid( uf::Entity* );
|
||||
|
||||
uf::Entity* UF_API reuse( size_t );
|
||||
size_t UF_API collect( uint8_t = 0 );
|
||||
|
||||
@ -14,10 +14,17 @@
|
||||
|
||||
namespace pod {
|
||||
struct UF_API DrawCall {
|
||||
alignas(4) int32_t materialIndex = -1;
|
||||
alignas(4) uint32_t materials = 0;
|
||||
alignas(4) int32_t textureIndex = -1;
|
||||
alignas(4) uint32_t textures = 0;
|
||||
std::string name = "";
|
||||
struct Storage {
|
||||
alignas(4) int32_t materialIndex = -1;
|
||||
alignas(4) uint32_t materials = 0;
|
||||
alignas(4) int32_t textureIndex = -1;
|
||||
alignas(4) uint32_t textures = 0;
|
||||
} storage;
|
||||
size_t verticesIndex = 0;
|
||||
size_t vertices = 0;
|
||||
size_t indicesIndex = 0;
|
||||
size_t indices = 0;
|
||||
};
|
||||
struct UF_API Texture {
|
||||
std::string name = "";
|
||||
@ -58,6 +65,7 @@ namespace pod {
|
||||
*/
|
||||
struct UF_API Material {
|
||||
std::string name = "";
|
||||
std::string alphaMode = "";
|
||||
//
|
||||
struct Storage {
|
||||
alignas(16) pod::Vector4f colorBase = { 0, 0, 0, 0 };
|
||||
@ -68,15 +76,15 @@ namespace pod {
|
||||
alignas(4) float factorOcclusion = 0.0f;
|
||||
alignas(4) float factorAlphaCutoff = 1.0f;
|
||||
|
||||
alignas(4) int indexAlbedo = -1;
|
||||
alignas(4) int indexNormal = -1;
|
||||
alignas(4) int indexEmissive = -1;
|
||||
alignas(4) int indexOcclusion = -1;
|
||||
alignas(4) int32_t indexAlbedo = -1;
|
||||
alignas(4) int32_t indexNormal = -1;
|
||||
alignas(4) int32_t indexEmissive = -1;
|
||||
alignas(4) int32_t indexOcclusion = -1;
|
||||
|
||||
alignas(4) int indexMetallicRoughness = -1;
|
||||
alignas(4) int padding1 = -1;
|
||||
alignas(4) int padding2 = -1;
|
||||
alignas(4) int padding3 = -1;
|
||||
alignas(4) int32_t indexMetallicRoughness = -1;
|
||||
alignas(4) int32_t modeAlpha = -1;
|
||||
alignas(4) int32_t padding1 = -1;
|
||||
alignas(4) int32_t padding2 = -1;
|
||||
} storage;
|
||||
};
|
||||
struct UF_API Node {
|
||||
@ -84,22 +92,21 @@ namespace pod {
|
||||
|
||||
std::string name = "";
|
||||
int32_t index = -1;
|
||||
|
||||
// Node* parent = NULL;
|
||||
// std::vector<Node*> children;
|
||||
int32_t parent = -1;
|
||||
std::vector<int32_t> children;
|
||||
|
||||
uf::Object* entity = NULL;
|
||||
size_t jointBufferIndex = -1;
|
||||
size_t materialBufferIndex = -1;
|
||||
size_t textureBufferIndex = -1;
|
||||
int32_t jointBufferIndex = -1;
|
||||
int32_t materialBufferIndex = -1;
|
||||
int32_t textureBufferIndex = -1;
|
||||
|
||||
int32_t skin = -1;
|
||||
Mesh mesh;
|
||||
uf::Collider collider;
|
||||
|
||||
pod::Transform<> transform;
|
||||
|
||||
std::vector<pod::DrawCall> primitives;
|
||||
pod::DrawCall drawCall;
|
||||
};
|
||||
|
||||
struct UF_API Skin {
|
||||
@ -146,6 +153,7 @@ namespace pod {
|
||||
std::vector<pod::Texture> textures;
|
||||
std::vector<pod::Material> materials;
|
||||
std::vector<pod::Light> lights;
|
||||
pod::DrawCall drawCall;
|
||||
|
||||
std::vector<Skin> skins;
|
||||
std::unordered_map<std::string, Animation> animations;
|
||||
|
||||
@ -37,13 +37,6 @@
|
||||
|
||||
#define VK_FLAGS_NONE 0
|
||||
#define DEFAULT_FENCE_TIMEOUT 100000000000
|
||||
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
std::string errorString( VkResult result );
|
||||
void* alignedAlloc( size_t size, size_t alignment );
|
||||
void alignedFree(void* data);
|
||||
}
|
||||
}
|
||||
#define VK_DEFAULT_STAGE_BUFFERS 1
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
@ -3,8 +3,6 @@
|
||||
#include <uf/ext/vulkan.h>
|
||||
#include <vector>
|
||||
|
||||
#define VK_DEFAULT_STAGE_BUFFERS 1
|
||||
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
struct Device;
|
||||
@ -68,9 +66,9 @@ namespace ext {
|
||||
void initialize( Device& device );
|
||||
void destroy();
|
||||
//
|
||||
size_t initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS );
|
||||
template<typename T> inline size_t initializeBuffer( T data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, length, usageFlags, memoryPropertyFlags, stage ); }
|
||||
template<typename T> inline size_t initializeBuffer( T data, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), usageFlags, memoryPropertyFlags, stage ); }
|
||||
size_t initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool stage = VK_DEFAULT_STAGE_BUFFERS );
|
||||
template<typename T> inline size_t initializeBuffer( T data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, length, usageFlags, memoryPropertyFlags, stage ); }
|
||||
template<typename T> inline size_t initializeBuffer( T data, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), usageFlags, memoryPropertyFlags, stage ); }
|
||||
|
||||
void updateBuffer( void* data, VkDeviceSize length, size_t index = 0, bool stage = VK_DEFAULT_STAGE_BUFFERS );
|
||||
void updateBuffer( void* data, VkDeviceSize length, Buffer& buffer, bool stage = VK_DEFAULT_STAGE_BUFFERS );
|
||||
|
||||
@ -73,6 +73,7 @@ namespace ext {
|
||||
VkDescriptorSetLayout descriptorSetLayout;
|
||||
VkDescriptorPool descriptorPool;
|
||||
VkDescriptorSet descriptorSet;
|
||||
GraphicDescriptor descriptor;
|
||||
|
||||
void initialize( Graphic& graphic );
|
||||
void initialize( Graphic& graphic, GraphicDescriptor& descriptor );
|
||||
@ -114,7 +115,7 @@ namespace ext {
|
||||
void destroy();
|
||||
|
||||
template<typename T, typename U>
|
||||
void initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t = SIZE_MAX, bool stage = VK_DEFAULT_STAGE_BUFFERS );
|
||||
void initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t = SIZE_MAX );
|
||||
|
||||
bool hasPipeline( GraphicDescriptor& descriptor );
|
||||
void initializePipeline();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
template<typename T, typename U>
|
||||
void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t o, bool stage ) {
|
||||
void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t o ) {
|
||||
if ( mesh.indices.empty() ) mesh.initialize( o );
|
||||
mesh.updateDescriptor();
|
||||
|
||||
@ -9,19 +9,26 @@ void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t
|
||||
// too lazy to check if this equals, only matters in pipeline creation anyways
|
||||
descriptor.geometry = mesh;
|
||||
|
||||
updateBuffer(
|
||||
(void*) mesh.vertices.data(),
|
||||
mesh.vertices.size() * mesh.sizes.vertex,
|
||||
0,
|
||||
stage
|
||||
);
|
||||
updateBuffer(
|
||||
(void*) mesh.indices.data(),
|
||||
mesh.indices.size() * mesh.sizes.indices,
|
||||
1,
|
||||
stage
|
||||
);
|
||||
return;
|
||||
int32_t vertexBuffer = -1;
|
||||
int32_t indexBuffer = -1;
|
||||
for ( size_t i = 0; i < buffers.size(); ++i ) {
|
||||
if ( buffers[i].usageFlags & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ) vertexBuffer = i;
|
||||
if ( buffers[i].usageFlags & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ) indexBuffer = i;
|
||||
}
|
||||
|
||||
if ( vertexBuffer > 0 && indexBuffer > 0 ) {
|
||||
updateBuffer(
|
||||
(void*) mesh.vertices.data(),
|
||||
mesh.vertices.size() * mesh.sizes.vertex,
|
||||
vertexBuffer
|
||||
);
|
||||
updateBuffer(
|
||||
(void*) mesh.indices.data(),
|
||||
mesh.indices.size() * mesh.sizes.indices,
|
||||
indexBuffer
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// can't reuse buffers, re-create buffers
|
||||
{
|
||||
@ -36,15 +43,11 @@ void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh<T, U>& mesh, size_t
|
||||
initializeBuffer(
|
||||
(void*) mesh.vertices.data(),
|
||||
mesh.vertices.size() * mesh.sizes.vertex,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, //VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
stage
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
||||
);
|
||||
initializeBuffer(
|
||||
(void*) mesh.indices.data(),
|
||||
mesh.indices.size() * mesh.sizes.indices,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, //VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
stage
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
@ -5,12 +5,15 @@
|
||||
namespace ext {
|
||||
namespace vulkan {
|
||||
struct UF_API RenderTarget {
|
||||
typedef struct {
|
||||
VkFormat format;
|
||||
VkImageLayout layout;
|
||||
VkImageUsageFlags usage;
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
bool aliased = false;
|
||||
struct Attachment {
|
||||
struct Descriptor {
|
||||
VkFormat format;
|
||||
VkImageLayout layout;
|
||||
VkImageUsageFlags usage;
|
||||
bool blend = false;
|
||||
uint8_t samples = 1;
|
||||
bool aliased = false;
|
||||
} descriptor;
|
||||
|
||||
VkImage image;
|
||||
VkDeviceMemory mem;
|
||||
@ -18,17 +21,18 @@ namespace ext {
|
||||
VmaAllocation allocation;
|
||||
VmaAllocationInfo allocationInfo;
|
||||
VkPipelineColorBlendAttachmentState blendState;
|
||||
} Attachment;
|
||||
};
|
||||
std::vector<Attachment> attachments;
|
||||
|
||||
typedef struct {
|
||||
struct Subpass {
|
||||
VkPipelineStageFlags stage;
|
||||
VkAccessFlags access;
|
||||
|
||||
std::vector<VkAttachmentReference> colors;
|
||||
std::vector<VkAttachmentReference> inputs;
|
||||
std::vector<VkAttachmentReference> resolves;
|
||||
VkAttachmentReference depth;
|
||||
} Subpass;
|
||||
};
|
||||
std::vector<Subpass> passes;
|
||||
|
||||
bool initialized = false;
|
||||
@ -37,13 +41,12 @@ namespace ext {
|
||||
std::vector<VkFramebuffer> framebuffers;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint8_t multiviews = 1;
|
||||
uint8_t samples = 1;
|
||||
uint8_t views = 1;
|
||||
// RAII
|
||||
void initialize( Device& device );
|
||||
void destroy();
|
||||
void addPass( VkPipelineStageFlags, VkAccessFlags, const std::vector<size_t>&, const std::vector<size_t>&, size_t );
|
||||
size_t attach( VkFormat format, VkImageUsageFlags usage, VkImageLayout layout, bool blend = false, Attachment* attachment = NULL );
|
||||
void addPass( VkPipelineStageFlags, VkAccessFlags, const std::vector<size_t>&, const std::vector<size_t>&, const std::vector<size_t>&, size_t );
|
||||
size_t attach( const Attachment::Descriptor& descriptor, Attachment* attachment = NULL );
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,8 @@ namespace ext {
|
||||
|
||||
VkImage image;
|
||||
VkImageView view;
|
||||
VkImageType type;
|
||||
VkImageViewType viewType;
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkDeviceMemory deviceMemory;
|
||||
VkDescriptorImageInfo descriptor;
|
||||
@ -55,9 +57,10 @@ namespace ext {
|
||||
VmaAllocationInfo allocationInfo;
|
||||
|
||||
uint32_t width, height, depth, layers;
|
||||
uint32_t mips;
|
||||
uint32_t mips = 1;
|
||||
// RAII
|
||||
void initialize( Device& device, size_t width, size_t height, size_t depth = 1, size_t layers = 1 );
|
||||
void initialize( Device& device, VkImageViewType, size_t width, size_t height, size_t depth = 1, size_t layers = 1 );
|
||||
void updateDescriptors();
|
||||
void destroy();
|
||||
bool generated() const;
|
||||
@ -76,9 +79,6 @@ namespace ext {
|
||||
VkImageLayout newImageLayout,
|
||||
uint32_t mipLevels
|
||||
);
|
||||
};
|
||||
struct UF_API Texture2D : public Texture {
|
||||
static Texture2D empty;
|
||||
void loadFromFile(
|
||||
std::string filename,
|
||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
@ -118,10 +118,12 @@ namespace ext {
|
||||
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM );
|
||||
void aliasTexture( const Texture2D& );
|
||||
void aliasTexture( const Texture& );
|
||||
void aliasAttachment( const RenderTarget::Attachment& attachment, bool = true );
|
||||
|
||||
void update( uf::Image& image, VkImageLayout, uint32_t layer = 1 );
|
||||
void update( void*, VkDeviceSize, VkImageLayout, uint32_t layer = 1 );
|
||||
|
||||
inline void fromBuffers(
|
||||
void* buffer,
|
||||
VkDeviceSize bufferSize,
|
||||
@ -137,5 +139,18 @@ namespace ext {
|
||||
|
||||
void generateMipmaps(VkCommandBuffer commandBuffer, uint32_t layer = 1);
|
||||
};
|
||||
class UF_API Texture2D : public Texture {
|
||||
public:
|
||||
Texture2D();
|
||||
static Texture2D empty;
|
||||
};
|
||||
class UF_API Texture3D : public Texture {
|
||||
public:
|
||||
Texture3D();
|
||||
};
|
||||
class UF_API TextureCube : public Texture {
|
||||
public:
|
||||
TextureCube();
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,11 @@ namespace ext {
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData
|
||||
);
|
||||
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
|
||||
|
||||
std::string errorString( VkResult result );
|
||||
VkSampleCountFlagBits sampleCount( uint8_t );
|
||||
void* alignedAlloc( size_t size, size_t alignment );
|
||||
void alignedFree(void* data);
|
||||
|
||||
typedef VmaAllocator Allocator;
|
||||
|
||||
|
||||
@ -14,3 +14,6 @@
|
||||
};\
|
||||
double time = 0;\
|
||||
if ( __VA_ARGS__ (time = TOKEN_PASTE(TIMER, __LINE__)(x)) >= x )
|
||||
|
||||
#define UF_DEBUG 1
|
||||
#define UF_DEBUG_PRINT() if ( UF_DEBUG ) uf::iostream << __FILE__ << ":" << __FUNCTION__ << "@" << __LINE__ << "\n";
|
||||
@ -37,11 +37,17 @@ namespace ext {
|
||||
uf::BaseGeometry geometry;
|
||||
size_t indices = 0;
|
||||
|
||||
struct {
|
||||
size_t vertex = 0;
|
||||
size_t index = 0;
|
||||
} offsets;
|
||||
|
||||
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
VkPolygonMode fill = VK_POLYGON_MODE_FILL;
|
||||
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
float lineWidth = 1.0f;
|
||||
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
struct {
|
||||
VkBool32 test = true;
|
||||
VkBool32 write = true;
|
||||
|
||||
@ -27,7 +27,7 @@ namespace uf {
|
||||
Image( Image::container_t&& move, const Image::vec2_t& size ); // Move from vector of pixels
|
||||
Image( const Image::container_t& copy, const Image::vec2_t& size ); // Copy from vector of pixels
|
||||
|
||||
bool open( const std::string& filename ); // from file
|
||||
bool open( const std::string& filename, bool = true ); // from file
|
||||
void open( const std::istream& stream ); // from stream
|
||||
void move( Image::container_t&& move, const Image::vec2_t& size ); // move from vector of pixels
|
||||
void copy( const Image::container_t& copy, const Image::vec2_t& size ); // copy from vector of pixels
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,20 @@
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/instantiator/instantiator.h>
|
||||
|
||||
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Entity)
|
||||
uf::Entity::Entity() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Entity)
|
||||
#define this ((uf::Entity*) &self)
|
||||
void uf::EntityBehavior::initialize( uf::Object& self ) {
|
||||
if ( !this->isValid() )
|
||||
this->m_uid = ++uf::Entity::uids;
|
||||
if ( !this->isValid() ) this->m_uid = ++uf::Entity::uids;
|
||||
// sanitize children
|
||||
/*
|
||||
for ( auto& kv : this->m_children ) {
|
||||
if ( !uf::instantiator::valid(kv) ) {
|
||||
std::cout << "FOUND INVALID CHILD IN " << this->getName() << ": " << this->getUid() << ": " << kv << std::endl;
|
||||
kv = NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
void uf::EntityBehavior::tick( uf::Object& self ) {
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
|
||||
@ -79,6 +79,19 @@ void uf::instantiator::free( uf::Entity* pointer ) {
|
||||
else ::free( pointer );
|
||||
#endif
|
||||
}
|
||||
bool uf::instantiator::valid( uf::Entity* pointer ) {
|
||||
#if UF_MEMORYPOOL_INVALID_FREE
|
||||
uf::MemoryPool& memoryPool = uf::Entity::memoryPool.size() > 0 ? uf::Entity::memoryPool : uf::MemoryPool::global;
|
||||
return memoryPool.exists( pointer );
|
||||
#else
|
||||
uf::MemoryPool* memoryPool = NULL;
|
||||
if ( uf::Entity::memoryPool.size() > 0 )
|
||||
memoryPool = &uf::Entity::memoryPool;
|
||||
else if ( uf::MemoryPool::global.size() > 0 )
|
||||
memoryPool = &uf::MemoryPool::global;
|
||||
return memoryPool ? memoryPool->exists( pointer ) : pointer && pointer->isValid();
|
||||
#endif
|
||||
}
|
||||
|
||||
void uf::instantiator::registerBinding( const std::string& object, const std::string& behavior ) {
|
||||
if ( !objects ) objects = new pod::NamedTypes<pod::Instantiator>;
|
||||
|
||||
@ -71,7 +71,7 @@ void uf::scene::unloadScene() {
|
||||
uf::Scene* current = uf::scene::scenes.back();
|
||||
current->destroy();
|
||||
uf::scene::scenes.pop_back();
|
||||
delete current;
|
||||
//delete current;
|
||||
}
|
||||
uf::Scene& uf::scene::getCurrentScene() {
|
||||
return *uf::scene::scenes.back();
|
||||
|
||||
@ -105,11 +105,17 @@ namespace {
|
||||
auto& mesh = graph.nodes[nodeIndex].mesh;
|
||||
auto& collider = graph.nodes[nodeIndex].collider;
|
||||
if ( node.mesh > -1 ) {
|
||||
auto& drawCall = graph.nodes[nodeIndex].drawCall;
|
||||
drawCall.name = node.name;
|
||||
drawCall.verticesIndex = mesh.vertices.size();
|
||||
drawCall.indicesIndex = mesh.indices.size();
|
||||
drawCall.vertices = 0;
|
||||
drawCall.indices = 0;
|
||||
for ( auto& primitive : model.meshes[node.mesh].primitives ) {
|
||||
size_t verticesStart = mesh.vertices.size();
|
||||
size_t indicesStart = mesh.indices.size();
|
||||
auto& dc = graph.nodes[nodeIndex].primitives.emplace_back();
|
||||
dc.verticesIndex = mesh.vertices.size();
|
||||
dc.indicesIndex = mesh.indices.size();
|
||||
|
||||
size_t vertices = 0;
|
||||
struct Attribute {
|
||||
std::string name = "";
|
||||
size_t components = 1;
|
||||
@ -135,7 +141,7 @@ namespace {
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
|
||||
if ( attribute.name == "POSITION" ) {
|
||||
vertices = accessor.count;
|
||||
dc.vertices = accessor.count;
|
||||
pod::Vector3f minCorner = { accessor.minValues[0], accessor.minValues[1], accessor.minValues[2] };
|
||||
pod::Vector3f maxCorner = { accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2] };
|
||||
|
||||
@ -158,8 +164,8 @@ namespace {
|
||||
}
|
||||
|
||||
auto modelMatrix = uf::transform::model( transform );
|
||||
mesh.vertices.reserve( vertices + verticesStart );
|
||||
for ( size_t i = 0; i < vertices; ++i ) {
|
||||
mesh.vertices.reserve( dc.vertices + dc.verticesIndex );
|
||||
for ( size_t i = 0; i < dc.vertices; ++i ) {
|
||||
#define ITERATE_ATTRIBUTE( name, member )\
|
||||
if ( !attributes[name].indices.empty() ) { \
|
||||
for ( size_t j = 0; j < attributes[name].components; ++j )\
|
||||
@ -205,13 +211,13 @@ namespace {
|
||||
auto& view = model.bufferViews[accessor.bufferView];
|
||||
auto& buffer = model.buffers[view.buffer];
|
||||
|
||||
auto indices = static_cast<uint32_t>(accessor.count);
|
||||
mesh.indices.reserve( indices + indicesStart );
|
||||
dc.indices = static_cast<uint32_t>(accessor.count);
|
||||
mesh.indices.reserve( dc.indices + dc.indicesIndex );
|
||||
const void* pointer = &(buffer.data[accessor.byteOffset + view.byteOffset]);
|
||||
|
||||
#define COPY_INDICES()\
|
||||
for (size_t index = 0; index < indices; index++)\
|
||||
mesh.indices.emplace_back(buf[index] + verticesStart);
|
||||
for (size_t index = 0; index < dc.indices; index++)\
|
||||
mesh.indices.emplace_back(buf[index] + dc.verticesIndex);
|
||||
|
||||
switch (accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: {
|
||||
@ -232,6 +238,12 @@ namespace {
|
||||
}
|
||||
#undef COPY_INDICES
|
||||
}
|
||||
|
||||
drawCall.vertices += dc.vertices;
|
||||
drawCall.indices += dc.indices;
|
||||
|
||||
graph.drawCall.vertices += dc.vertices;
|
||||
graph.drawCall.indices += dc.indices;
|
||||
/*
|
||||
if ( graph.mode & ext::gltf::LoadMode::TRANSFORM ) {
|
||||
auto model = uf::transform::model( transform );
|
||||
@ -344,29 +356,18 @@ pod::Graph ext::gltf::load( const std::string& filename, ext::gltf::load_mode_t
|
||||
material.storage.factorMetallic = m.pbrMetallicRoughness.metallicFactor;
|
||||
material.storage.factorRoughness = m.pbrMetallicRoughness.roughnessFactor;
|
||||
material.storage.factorOcclusion = m.occlusionTexture.strength;
|
||||
|
||||
/*
|
||||
if ( 0 <= material.storage.indexAlbedo && material.storage.indexAlbedo < graph.textures.size() ) {
|
||||
auto& texture = graph.textures[material.storage.indexAlbedo];
|
||||
material.storage.indexAlbedo = texture.storage.index;
|
||||
material.storage.factorAlphaCutoff = m.alphaCutoff;
|
||||
|
||||
material.alphaMode = m.alphaMode;
|
||||
if ( material.alphaMode == "OPAQUE" ) {
|
||||
material.storage.modeAlpha = 0;
|
||||
} else if ( material.alphaMode == "BLEND" ) {
|
||||
material.storage.modeAlpha = 1;
|
||||
} else if ( material.alphaMode == "MASK" ) {
|
||||
material.storage.modeAlpha = 2;
|
||||
} else {
|
||||
std::cout << "Unhandled alpha mode: " << material.alphaMode << std::endl;
|
||||
}
|
||||
if ( 0 <= material.storage.indexNormal && material.storage.indexNormal < graph.textures.size() ) {
|
||||
auto& texture = graph.textures[material.storage.indexNormal];
|
||||
material.storage.indexNormal = texture.storage.index;
|
||||
}
|
||||
if ( 0 <= material.storage.indexEmissive && material.storage.indexEmissive < graph.textures.size() ) {
|
||||
auto& texture = graph.textures[material.storage.indexEmissive];
|
||||
material.storage.indexEmissive = texture.storage.index;
|
||||
}
|
||||
if ( 0 <= material.storage.indexOcclusion && material.storage.indexOcclusion < graph.textures.size() ) {
|
||||
auto& texture = graph.textures[material.storage.indexOcclusion];
|
||||
material.storage.indexOcclusion = texture.storage.index;
|
||||
}
|
||||
if ( 0 <= material.storage.indexMetallicRoughness && material.storage.indexMetallicRoughness < graph.textures.size() ) {
|
||||
auto& texture = graph.textures[material.storage.indexMetallicRoughness];
|
||||
material.storage.indexMetallicRoughness = texture.storage.index;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
// load node information/meshes
|
||||
|
||||
@ -178,8 +178,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
graph.instanceBufferIndex = graphic.initializeBuffer(
|
||||
(void*) instances.data(),
|
||||
instances.size() * sizeof(pod::Matrix4f),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
// Joints storage buffer
|
||||
if ( graph.mode & ext::gltf::LoadMode::SKINNED ) {
|
||||
@ -188,9 +187,8 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
auto& skin = graph.skins[node.skin];
|
||||
node.jointBufferIndex = graphic.initializeBuffer(
|
||||
(void*) skin.inverseBindMatrices.data(),
|
||||
skin.inverseBindMatrices.size() * sizeof(pod::Matrix4f),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
(1 + skin.inverseBindMatrices.size()) * sizeof(pod::Matrix4f),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -205,8 +203,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
graph.root.materialBufferIndex = graphic.initializeBuffer(
|
||||
(void*) materials.data(),
|
||||
materials.size() * sizeof(pod::Material::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
// Texture storage buffer
|
||||
std::vector<pod::Texture::Storage> textures( graph.textures.size() );
|
||||
@ -217,8 +214,7 @@ void uf::graph::process( pod::Graph& graph ) {
|
||||
graph.root.textureBufferIndex = graphic.initializeBuffer(
|
||||
(void*) textures.data(),
|
||||
textures.size() * sizeof(pod::Texture::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
|
||||
@ -328,7 +324,8 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
for ( auto& l : graph.lights ) {
|
||||
if ( l.name != node.name ) continue;
|
||||
entity.load("/light.json");
|
||||
auto& metadata = entity.getComponent<uf::Serializer>();
|
||||
auto& metadata = entity.getComponent<uf::Serializer>();
|
||||
|
||||
metadata["light"]["radius"][0] = 0.001;
|
||||
metadata["light"]["radius"][1] = l.range; // l.range <= 0.001f ? graph.metadata["lights"]["range cap"].as<float>() : l.range;
|
||||
metadata["light"]["power"] = l.intensity; // * graph.metadata["lights"]["power scale"].as<float>();
|
||||
@ -350,6 +347,26 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
if ( key == "transform" ) return;
|
||||
metadata["light"][key] = value;
|
||||
});
|
||||
|
||||
if ( metadata["light"]["shadows"].as<bool>() ) {
|
||||
ext::json::Value m;
|
||||
if ( ext::json::isObject( graph.metadata["tags"][node.name]["renderMode"] ) ) {
|
||||
m = graph.metadata["tags"][node.name]["renderMode"];
|
||||
} else if ( ext::json::isObject( graph.metadata["lights"]["renderMode"] ) ) {
|
||||
m = graph.metadata["lights"]["renderMode"];
|
||||
}
|
||||
if ( m["target"].is<std::string>() ) {
|
||||
std::string targetNode = m["target"].as<std::string>();
|
||||
auto* node = uf::graph::find( graph, targetNode );
|
||||
if ( node ) {
|
||||
auto& drawCall = node->drawCall;
|
||||
size_t targetIndices = graph.drawCall.indices;
|
||||
metadata["renderMode"]["target"][std::to_string(targetIndices)]["size"] = drawCall.indices;
|
||||
metadata["renderMode"]["target"][std::to_string(targetIndices)]["offset"] = drawCall.indicesIndex;
|
||||
// std::cout << "Found " << targetNode << ", Replacing " << targetNode << " with " << drawCall.indicesIndex << " + " << drawCall.indices << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// auto& transform = entity.getComponent<pod::Transform<>>();
|
||||
// transform.orientation = uf::quaternion::inverse( transform.orientation );
|
||||
break;
|
||||
@ -423,9 +440,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
node.jointBufferIndex = graphic.initializeBuffer(
|
||||
(void*) skin.inverseBindMatrices.data(),
|
||||
skin.inverseBindMatrices.size() * sizeof(pod::Matrix4f),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
true
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
// Materials storage buffer
|
||||
@ -433,18 +448,18 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
for ( size_t i = 0; i < graph.materials.size(); ++i ) {
|
||||
materials[i] = graph.materials[i].storage;
|
||||
}
|
||||
/*
|
||||
if ( !ext::json::isNull( graph.metadata["tags"][node.name] ) ) {
|
||||
auto& info = graph.metadata["tags"][node.name];
|
||||
for ( size_t i = 0; i < graph.materials.size(); ++i ) {
|
||||
materials[i].factorAlphaCutoff = info["alpha cutoff"].as<float>();
|
||||
}
|
||||
}
|
||||
*/
|
||||
node.materialBufferIndex = graphic.initializeBuffer(
|
||||
(void*) materials.data(),
|
||||
materials.size() * sizeof(pod::Material::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
true
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
// Texture storage buffer
|
||||
std::vector<pod::Texture::Storage> textures( graph.textures.size() );
|
||||
@ -455,8 +470,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
graph.root.textureBufferIndex = graphic.initializeBuffer(
|
||||
(void*) textures.data(),
|
||||
textures.size() * sizeof(pod::Texture::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -598,5 +612,8 @@ void uf::graph::update( pod::Graph& graph, pod::Node& node ) {
|
||||
}
|
||||
}
|
||||
void uf::graph::destroy( pod::Graph& graph ) {
|
||||
for ( auto& t : graph.textures ) {
|
||||
t.texture.destroy();
|
||||
}
|
||||
delete graph.atlas;
|
||||
}
|
||||
@ -426,12 +426,12 @@ bool ext::openvr::requestRenderModel( const std::string& name ) {
|
||||
return false;
|
||||
}
|
||||
void ext::openvr::submit() { bool invert = swapEyes;
|
||||
ext::vulkan::StereoscopicDeferredRenderMode* renderMode = (ext::vulkan::StereoscopicDeferredRenderMode*) &ext::vulkan::getRenderMode("");
|
||||
auto& renderMode = ext::vulkan::getRenderMode("");
|
||||
|
||||
float width = renderMode->width > 0 ? renderMode->width : uf::renderer::settings::width;
|
||||
float height = renderMode->height > 0 ? renderMode->height : uf::renderer::settings::height;
|
||||
auto& leftOutputAttachment = renderMode->renderTargets.left.attachments[renderMode->renderTargets.left.attachments.size()-1];
|
||||
auto& rightOutputAttachment = renderMode->renderTargets.right.attachments[renderMode->renderTargets.right.attachments.size()-1];
|
||||
float width = renderMode.width > 0 ? renderMode.width : uf::renderer::settings::width;
|
||||
float height = renderMode.height > 0 ? renderMode.height : uf::renderer::settings::height;
|
||||
auto& leftOutputAttachment = renderMode.renderTarget.attachments[renderMode.metadata["outputs"][0].as<size_t>()];
|
||||
auto& rightOutputAttachment = renderMode.renderTarget.attachments[renderMode.metadata["outputs"][1].as<size_t>()];
|
||||
|
||||
// Submit to SteamVR
|
||||
vr::VRTextureBounds_t bounds;
|
||||
@ -453,12 +453,12 @@ void ext::openvr::submit() { bool invert = swapEyes;
|
||||
|
||||
vr::Texture_t texture = { &vulkanData, vr::TextureType_Vulkan, vr::ColorSpace_Auto };
|
||||
|
||||
vulkanData.m_nFormat = leftOutputAttachment.format;
|
||||
vulkanData.m_nFormat = leftOutputAttachment.descriptor.format;
|
||||
vulkanData.m_nImage = (uint64_t) (VkImage) leftOutputAttachment.image;
|
||||
// if ( DEBUG_MARKER ) std::cout << leftOutputAttachment.image << std::endl;
|
||||
vr::VRCompositor()->Submit( invert ? vr::Eye_Right : vr::Eye_Left, &texture, &bounds );
|
||||
|
||||
vulkanData.m_nFormat = rightOutputAttachment.format;
|
||||
vulkanData.m_nFormat = rightOutputAttachment.descriptor.format;
|
||||
vulkanData.m_nImage = (uint64_t) (VkImage) rightOutputAttachment.image;
|
||||
// if ( DEBUG_MARKER ) std::cout << rightOutputAttachment.image << std::endl;
|
||||
vr::VRCompositor()->Submit( invert ? vr::Eye_Left : vr::Eye_Right, &texture, &bounds );
|
||||
|
||||
@ -171,12 +171,12 @@ size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length,
|
||||
length
|
||||
));
|
||||
this->updateBuffer( data, length, buffer, stage );
|
||||
// size_t index = buffers.size();
|
||||
// buffers.push_back( std::move(buffer) );
|
||||
return index;
|
||||
}
|
||||
|
||||
// VkQueue queue = device->queues.transfer;
|
||||
// implicitly set properties
|
||||
usageFlags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
Buffer staging;
|
||||
VkDeviceSize storageBufferSize = length;
|
||||
device->createBuffer(
|
||||
|
||||
@ -250,7 +250,7 @@ uint32_t ext::vulkan::Device::getMemoryType( uint32_t typeBits, VkMemoryProperty
|
||||
*memTypeFound = false;
|
||||
return 0;
|
||||
}
|
||||
throw std::runtime_error("Could not find a matching memory type");
|
||||
// throw std::runtime_error("Could not find a matching memory type");
|
||||
}
|
||||
|
||||
int ext::vulkan::Device::rate( VkPhysicalDevice device ) {
|
||||
@ -381,7 +381,6 @@ VkResult ext::vulkan::Device::createBuffer( VkBufferUsageFlags usageFlags, VkMem
|
||||
|
||||
// Attach the memory to the buffer object
|
||||
VK_CHECK_RESULT(vkBindBufferMemory(logicalDevice, *buffer, *memory, 0));
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
@ -573,10 +572,10 @@ void ext::vulkan::Device::initialize() {
|
||||
VkApplicationInfo appInfo = {};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pApplicationName = "Program";
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 2, 0);
|
||||
appInfo.pEngineName = "Engine";
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_2;
|
||||
|
||||
VkInstanceCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
@ -908,6 +907,15 @@ void ext::vulkan::Device::initialize() {
|
||||
pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
VK_CHECK_RESULT(vkCreatePipelineCache( device, &pipelineCacheCreateInfo, nullptr, &this->pipelineCache));
|
||||
}
|
||||
// setup allocator
|
||||
{
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.device = logicalDevice;
|
||||
vmaCreateAllocator(&allocatorInfo, &allocator);
|
||||
}
|
||||
}
|
||||
|
||||
void ext::vulkan::Device::destroy() {
|
||||
@ -943,4 +951,5 @@ void ext::vulkan::Device::destroy() {
|
||||
vkDestroyInstance( this->instance, nullptr );
|
||||
this->instance = nullptr;
|
||||
}
|
||||
vmaDestroyAllocator( allocator );
|
||||
}
|
||||
@ -644,9 +644,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
|
||||
initializeBuffer(
|
||||
(void*) userdata.data,
|
||||
userdata.len,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
false
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -778,6 +776,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
|
||||
}
|
||||
void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& descriptor ) {
|
||||
this->device = graphic.device;
|
||||
//this->descriptor = descriptor;
|
||||
Device& device = *graphic.device;
|
||||
|
||||
// VK_VALIDATION_MESSAGE(&graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size());
|
||||
@ -884,10 +883,13 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
|
||||
|
||||
std::vector<VkPipelineColorBlendAttachmentState> blendAttachmentStates;
|
||||
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
if ( renderMode.getType() != "Swapchain" ) {
|
||||
auto& subpass = renderTarget.passes[descriptor.subpass];
|
||||
for ( auto& color : subpass.colors ) {
|
||||
blendAttachmentStates.push_back(renderTarget.attachments[color.attachment].blendState);
|
||||
auto& attachment = renderTarget.attachments[color.attachment];
|
||||
blendAttachmentStates.push_back(attachment.blendState);
|
||||
samples = std::max(samples, ext::vulkan::sampleCount( attachment.descriptor.samples ));
|
||||
}
|
||||
// require blending if independentBlend is not an enabled feature
|
||||
if ( device.enabledFeatures.independentBlend == VK_FALSE ) {
|
||||
@ -933,21 +935,16 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
|
||||
VkPipelineViewportStateCreateInfo viewportState = ext::vulkan::initializers::pipelineViewportStateCreateInfo(
|
||||
1, 1, 0
|
||||
);
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
// switch ( ext::vulkan::settings::msaa ) {
|
||||
switch ( renderTarget.samples ) {
|
||||
case 64: samples = VK_SAMPLE_COUNT_64_BIT; break;
|
||||
case 32: samples = VK_SAMPLE_COUNT_32_BIT; break;
|
||||
case 16: samples = VK_SAMPLE_COUNT_16_BIT; break;
|
||||
case 8: samples = VK_SAMPLE_COUNT_8_BIT; break;
|
||||
case 4: samples = VK_SAMPLE_COUNT_4_BIT; break;
|
||||
case 2: samples = VK_SAMPLE_COUNT_2_BIT; break;
|
||||
default: samples = VK_SAMPLE_COUNT_1_BIT; break;
|
||||
}
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState = ext::vulkan::initializers::pipelineMultisampleStateCreateInfo(
|
||||
samples,
|
||||
0
|
||||
);
|
||||
if ( device.features.sampleRateShading ) {
|
||||
multisampleState.sampleShadingEnable = VK_TRUE;
|
||||
multisampleState.minSampleShading = 0.25f;
|
||||
}
|
||||
|
||||
|
||||
std::vector<VkDynamicState> dynamicStateEnables = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
@ -1101,6 +1098,7 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descriptor ) {
|
||||
//
|
||||
if ( descriptorSet == VK_NULL_HANDLE ) return;
|
||||
//descriptor = d;
|
||||
// generate fallback empty texture
|
||||
auto& emptyTexture = Texture2D::empty;
|
||||
|
||||
@ -1463,7 +1461,7 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescrip
|
||||
|
||||
pipeline.record(*this, commandBuffer, pass, draw);
|
||||
// Bind triangle vertex buffer (contains position and colors)
|
||||
VkDeviceSize offsets[1] = { 0 };
|
||||
VkDeviceSize offsets[1] = { descriptor.offsets.vertex };
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer->buffer, offsets);
|
||||
// Bind triangle index buffer
|
||||
VkIndexType indicesType = VK_INDEX_TYPE_UINT32;
|
||||
@ -1475,9 +1473,10 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescrip
|
||||
throw std::runtime_error("invalid indices size of " + std::to_string((int) descriptor.geometry.sizes.indices));
|
||||
break;
|
||||
}
|
||||
vkCmdBindIndexBuffer(commandBuffer, indexBuffer->buffer, 0, indicesType);
|
||||
vkCmdBindIndexBuffer(commandBuffer, indexBuffer->buffer, descriptor.offsets.index, indicesType);
|
||||
// Draw indexed triangle
|
||||
vkCmdDrawIndexed(commandBuffer, descriptor.indices, 1, 0, 0, 1);
|
||||
//std::cout << (int) descriptor.indices << "\t" << (int) descriptor.offsets.index << std::endl;
|
||||
}
|
||||
void ext::vulkan::Graphic::destroy() {
|
||||
for ( auto& pair : pipelines ) pair.second.destroy();
|
||||
@ -1545,6 +1544,13 @@ void ext::vulkan::GraphicDescriptor::parse( ext::json::Value& metadata ) {
|
||||
cullMode = VK_CULL_MODE_FRONT_AND_BACK;
|
||||
}
|
||||
}
|
||||
if ( metadata["indices"].is<size_t>() ) {
|
||||
indices = metadata["indices"].as<size_t>();
|
||||
}
|
||||
if ( ext::json::isObject( metadata["offsets"] ) ) {
|
||||
offsets.vertex = metadata["offsets"]["vertex"].as<size_t>();
|
||||
offsets.index = metadata["offsets"]["index"].as<size_t>();
|
||||
}
|
||||
if ( ext::json::isObject(metadata["depth bias"]) ) {
|
||||
depth.bias.enable = VK_TRUE;
|
||||
depth.bias.constant = metadata["depth bias"]["constant"].as<float>();
|
||||
@ -1557,9 +1563,13 @@ std::string ext::vulkan::GraphicDescriptor::hash() const {
|
||||
|
||||
serializer["subpass"] = subpass;
|
||||
if ( settings::experimental::individualPipelines ) serializer["renderMode"] = renderMode;
|
||||
|
||||
serializer["renderTarget"] = renderTarget;
|
||||
serializer["geometry"]["sizes"]["vertex"] = geometry.sizes.vertex;
|
||||
serializer["geometry"]["sizes"]["indices"] = geometry.sizes.indices;
|
||||
serializer["indices"] = indices;
|
||||
serializer["offsets"]["vertex"] = offsets.vertex;
|
||||
serializer["offsets"]["index"] = offsets.index;
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@ -140,11 +140,11 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImageView( device, &colorAttachmentView, nullptr, &renderTarget.attachments[i].view));
|
||||
|
||||
renderTarget.attachments[i].descriptor.format = ext::vulkan::settings::formats::color;
|
||||
renderTarget.attachments[i].descriptor.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
renderTarget.attachments[i].descriptor.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
renderTarget.attachments[i].descriptor.aliased = true;
|
||||
renderTarget.attachments[i].image = images[i];
|
||||
renderTarget.attachments[i].format = ext::vulkan::settings::formats::color;
|
||||
renderTarget.attachments[i].layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
renderTarget.attachments[i].usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
renderTarget.attachments[i].aliased = true;
|
||||
renderTarget.attachments[i].mem = VK_NULL_HANDLE;
|
||||
}
|
||||
// Create depth
|
||||
@ -366,7 +366,7 @@ void ext::vulkan::BaseRenderMode::destroy() {
|
||||
vkDestroyImageView( *device, attachment.view, nullptr);
|
||||
attachment.view = VK_NULL_HANDLE;
|
||||
}
|
||||
if ( attachment.aliased ) continue;
|
||||
if ( attachment.descriptor.aliased ) continue;
|
||||
if ( attachment.image != VK_NULL_HANDLE ) {
|
||||
// vkDestroyImage( *device, attachment.image, nullptr );
|
||||
vmaDestroyImage( allocator, attachment.image, attachment.allocation );
|
||||
|
||||
@ -36,31 +36,62 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
|
||||
ext::vulkan::RenderMode::initialize( device );
|
||||
{
|
||||
renderTarget.device = &device;
|
||||
renderTarget.samples = ext::vulkan::settings::msaa;
|
||||
renderTarget.device = &device;
|
||||
if ( !metadata["eyes"].is<size_t>() ) metadata["eyes"] = 1;
|
||||
size_t eyes = metadata["eyes"].as<size_t>();
|
||||
for ( size_t eye = 0; eye < eyes; ++eye ) {
|
||||
struct {
|
||||
size_t id, normals, uvs, albedo, depth, output;
|
||||
} attachments;
|
||||
size_t msaa = ext::vulkan::settings::msaa;
|
||||
|
||||
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UINT,
|
||||
/*.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.normals = 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,
|
||||
});
|
||||
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
|
||||
attachments.id = renderTarget.attach( VK_FORMAT_R16G16_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
|
||||
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
attachments.uvs = renderTarget.attach( VK_FORMAT_R16G16_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // uvs
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UNORM,
|
||||
/*.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.id = renderTarget.attach( VK_FORMAT_R16G16_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
|
||||
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.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.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,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
|
||||
// Attach swapchain's image as output
|
||||
if ( settings::experimental::deferredAliasOutputToSwapchain ) {
|
||||
attachments.output = renderTarget.attachments.size();
|
||||
RenderTarget::Attachment swapchainAttachment;
|
||||
swapchainAttachment.format = ext::vulkan::settings::formats::color; //device.formats.color;
|
||||
swapchainAttachment.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainAttachment.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
swapchainAttachment.aliased = true;
|
||||
auto& swapchainAttachment = renderTarget.attachments.emplace_back();
|
||||
swapchainAttachment.descriptor.format = ext::vulkan::settings::formats::color; //device.formats.color;
|
||||
swapchainAttachment.descriptor.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainAttachment.descriptor.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
swapchainAttachment.descriptor.aliased = true;
|
||||
{
|
||||
VkBool32 blendEnabled = VK_TRUE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
@ -78,10 +109,17 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
swapchainAttachment.blendState = blendAttachmentState;
|
||||
}
|
||||
renderTarget.attachments.push_back(swapchainAttachment);
|
||||
} else {
|
||||
attachments.output = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
|
||||
attachments.output = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
}
|
||||
metadata["outputs"][eye] = attachments.output;
|
||||
|
||||
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
@ -89,6 +127,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.id, attachments.normals, attachments.uvs },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
@ -98,6 +137,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.id, attachments.normals, attachments.uvs, attachments.depth },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
@ -108,6 +148,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.id, attachments.normals, attachments.albedo },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
@ -117,142 +158,11 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.id, attachments.normals, attachments.albedo, attachments.depth },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
}
|
||||
/*
|
||||
#if UF_VK_TESTING
|
||||
struct {
|
||||
size_t normals, uvs, id, depth, output;
|
||||
} attachments;
|
||||
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
attachments.uvs = renderTarget.attach( VK_FORMAT_R16G16_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // uvs
|
||||
attachments.id = renderTarget.attach( VK_FORMAT_R16G16_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
#else
|
||||
// attach targets
|
||||
struct {
|
||||
size_t normals, albedo, depth, output;
|
||||
} attachments;
|
||||
//VK_FORMAT_R16G16B16A16_SFLOAT
|
||||
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
#endif
|
||||
// Attach swapchain's image as output
|
||||
if ( settings::experimental::deferredAliasOutputToSwapchain ) {
|
||||
attachments.output = renderTarget.attachments.size();
|
||||
RenderTarget::Attachment swapchainAttachment;
|
||||
swapchainAttachment.format = ext::vulkan::settings::formats::color; //device.formats.color;
|
||||
swapchainAttachment.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainAttachment.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
swapchainAttachment.aliased = true;
|
||||
{
|
||||
VkBool32 blendEnabled = VK_TRUE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
|
||||
writeMask,
|
||||
blendEnabled
|
||||
);
|
||||
if ( blendEnabled == VK_TRUE ) {
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
}
|
||||
swapchainAttachment.blendState = blendAttachmentState;
|
||||
}
|
||||
renderTarget.attachments.push_back(swapchainAttachment);
|
||||
} else {
|
||||
attachments.output = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
|
||||
}
|
||||
#if UF_VK_TESTING
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.normals, attachments.uvs, attachments.id },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.normals, attachments.uvs, attachments.id, attachments.depth },
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
#else
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.normals, attachments.albedo },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.normals, attachments.albedo, attachments.depth },
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
/*
|
||||
struct {
|
||||
size_t albedo, normals, position, depth, output, ping, pong;
|
||||
} attachments;
|
||||
attachments.albedo = renderTarget.attach( ext::vulkan::settings::formats::color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // albedo
|
||||
attachments.normals = renderTarget.attach( ext::vulkan::settings::formats::normal, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
if ( !settings::experimental::deferredReconstructPosition )
|
||||
attachments.position = renderTarget.attach( ext::vulkan::settings::formats::position, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
|
||||
// attachments.ping = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
|
||||
// attachments.pong = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
|
||||
if ( settings::experimental::deferredReconstructPosition ) {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.albedo, attachments.normals },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
} else {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
if ( settings::experimental::deferredReconstructPosition ) {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.depth },
|
||||
attachments.depth
|
||||
);
|
||||
} else {
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
renderTarget.initialize( device );
|
||||
|
||||
@ -298,38 +208,40 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
std::vector<pod::Light::Storage> lights(maxLights);
|
||||
std::vector<pod::Material::Storage> materials(specializationConstants.maxTextures);
|
||||
std::vector<pod::Texture::Storage> textures(specializationConstants.maxTextures);
|
||||
std::vector<pod::DrawCall> drawCalls(specializationConstants.maxTextures);
|
||||
std::vector<pod::DrawCall::Storage> drawCalls(specializationConstants.maxTextures);
|
||||
|
||||
for ( auto& material : materials ) material.colorBase = {0,0,0,0};
|
||||
|
||||
this->metadata["lightBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) lights.data(),
|
||||
lights.size() * sizeof(pod::Light::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
this->metadata["materialBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) materials.data(),
|
||||
materials.size() * sizeof(pod::Material::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
this->metadata["textureBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) textures.data(),
|
||||
textures.size() * sizeof(pod::Texture::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
this->metadata["drawCallBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) drawCalls.data(),
|
||||
drawCalls.size() * sizeof(pod::DrawCall),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
drawCalls.size() * sizeof(pod::DrawCall::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
blitter.initializePipeline();
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
void ext::vulkan::DeferredRenderMode::tick() {
|
||||
@ -351,6 +263,8 @@ void ext::vulkan::DeferredRenderMode::destroy() {
|
||||
void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
if ( !metadata["eyes"].is<size_t>() ) metadata["eyes"] = 1;
|
||||
size_t eyes = metadata["eyes"].as<size_t>();
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
@ -377,7 +291,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
std::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
VkClearValue clearValue;
|
||||
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
|
||||
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
|
||||
clearValue.color = { {
|
||||
@ -389,7 +303,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
} else {
|
||||
clearValue.color = { { 0, 0, 0, 0 } };
|
||||
}
|
||||
} else if ( attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
}
|
||||
clearValues.push_back(clearValue);
|
||||
@ -426,40 +340,43 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
layer->pipelineBarrier( commands[i], 0 );
|
||||
}
|
||||
|
||||
size_t currentPass = 0;
|
||||
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdSetViewport(commands[i], 0, 1, &viewport);
|
||||
vkCmdSetScissor(commands[i], 0, 1, &scissor);
|
||||
// render to geometry buffers
|
||||
size_t currentDraw = 0;
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor);
|
||||
graphic->record( commands[i], descriptor, currentPass, currentDraw++ );
|
||||
}
|
||||
// blit any RT's that request this subpass
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
|
||||
for ( size_t eye = 0; eye < eyes; ++eye ) {
|
||||
size_t currentPass = 0;
|
||||
size_t currentDraw = 0;
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor);
|
||||
graphic->record( commands[i], descriptor, eye, currentDraw++ );
|
||||
}
|
||||
// blit any RT's that request this subpass
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentPass;
|
||||
// deferred post-processing lighting pass
|
||||
{
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentPass;
|
||||
// deferred post-processing lighting pass
|
||||
{
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
// blit any RT's that request this subpass
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
|
||||
blitter.record(commands[i]);
|
||||
// blit any RT's that request this subpass
|
||||
{
|
||||
for ( auto _ : layers ) {
|
||||
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
|
||||
auto& blitter = layer->blitter;
|
||||
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
|
||||
blitter.record(commands[i]);
|
||||
}
|
||||
}
|
||||
if ( eye + 1 < eyes ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
vkCmdEndRenderPass(commands[i]);
|
||||
|
||||
@ -512,19 +429,19 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
|
||||
vkCmdBlitImage(
|
||||
@ -542,19 +459,19 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,12 +30,12 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::initialize( Device& d
|
||||
renderTarget.device = &device;
|
||||
renderTarget.width = this->width;
|
||||
renderTarget.height = this->height;
|
||||
renderTarget.multiviews = 2;
|
||||
renderTarget.views = 2;
|
||||
// attach targets
|
||||
struct {
|
||||
size_t albedo, normals, position, depth, output;
|
||||
} attachments;
|
||||
|
||||
#if 0
|
||||
attachments.albedo = renderTarget.attach( ext::vulkan::settings::formats::color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // albedo
|
||||
attachments.normals = renderTarget.attach( ext::vulkan::settings::formats::normal, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
if ( !settings::experimental::deferredReconstructPosition )
|
||||
@ -88,6 +88,7 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::initialize( Device& d
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
#endif
|
||||
renderTarget.initialize( device );
|
||||
{
|
||||
uf::BaseMesh<pod::Vertex_2F2F> mesh;
|
||||
@ -187,7 +188,7 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers(
|
||||
std::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
VkClearValue clearValue;
|
||||
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
|
||||
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
|
||||
clearValue.color = { {
|
||||
@ -199,7 +200,7 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers(
|
||||
} else {
|
||||
clearValue.color = { { 0, 0, 0, 0 } };
|
||||
}
|
||||
} else if ( attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
}
|
||||
clearValues.push_back(clearValue);
|
||||
@ -322,19 +323,19 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers(
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
|
||||
vkCmdBlitImage(
|
||||
@ -352,19 +353,19 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers(
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,10 +28,19 @@ std::vector<ext::vulkan::Graphic*> ext::vulkan::RenderTargetRenderMode::getBlitt
|
||||
|
||||
ext::vulkan::GraphicDescriptor ext::vulkan::RenderTargetRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) {
|
||||
ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, pass);
|
||||
descriptor.parse(metadata["descriptor"]);
|
||||
std::string type = metadata["type"].as<std::string>();
|
||||
if ( type == "depth" ) {
|
||||
descriptor.cullMode = VK_CULL_MODE_NONE;
|
||||
}
|
||||
// allows for "easy" remapping for indices ranges
|
||||
if ( ext::json::isObject( metadata["renderMode"]["target"][std::to_string(descriptor.indices)] ) ) {
|
||||
auto& map = metadata["renderMode"]["target"][std::to_string(descriptor.indices)];
|
||||
std::cout << "Replacing " << descriptor.indices;
|
||||
descriptor.indices = map["size"].as<size_t>();
|
||||
descriptor.offsets.index = map["offset"].as<size_t>();
|
||||
std::cout << " with " << descriptor.offsets.index << " + " << descriptor.indices << std::endl;
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@ -49,11 +58,18 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
size_t depth;
|
||||
} attachments;
|
||||
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
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,
|
||||
/*.blend = */ false,
|
||||
/*.samples = */ 1,
|
||||
});
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
} else {
|
||||
@ -62,11 +78,37 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
size_t albedo, normals, position, depth;
|
||||
} attachments;
|
||||
|
||||
attachments.albedo = renderTarget.attach( ext::vulkan::settings::formats::color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
|
||||
attachments.normals = renderTarget.attach( ext::vulkan::settings::formats::normal, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ ext::vulkan::settings::formats::color,
|
||||
/*.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,
|
||||
/*.blend = */ true,
|
||||
/*.samples = */ 1,
|
||||
});
|
||||
attachments.normals = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ ext::vulkan::settings::formats::normal,
|
||||
/*.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,
|
||||
/*.blend = */ false,
|
||||
/*.samples = */ 1,
|
||||
});
|
||||
|
||||
if ( !settings::experimental::deferredReconstructPosition )
|
||||
attachments.position = renderTarget.attach( ext::vulkan::settings::formats::position, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
|
||||
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
|
||||
attachments.position = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ ext::vulkan::settings::formats::position,
|
||||
/*.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,
|
||||
/*.blend = */ false,
|
||||
/*.samples = */ 1,
|
||||
});
|
||||
|
||||
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,
|
||||
/*.blend = */ false,
|
||||
/*.samples = */ 1,
|
||||
});
|
||||
|
||||
// First pass: write to target
|
||||
if ( settings::experimental::deferredReconstructPosition ) {
|
||||
@ -74,6 +116,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.albedo, attachments.normals },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
} else {
|
||||
@ -81,6 +124,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.albedo, attachments.normals, attachments.position },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
@ -138,7 +182,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
});
|
||||
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
|
||||
Texture2D& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
@ -152,7 +196,7 @@ void ext::vulkan::RenderTargetRenderMode::tick() {
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
blitter.material.textures.clear();
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
Texture2D& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
}
|
||||
@ -210,13 +254,13 @@ void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer comma
|
||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
|
||||
VkPipelineStageFlags srcStageMask, dstStageMask;
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
imageMemoryBarrier.oldLayout = attachment.layout;
|
||||
imageMemoryBarrier.newLayout = attachment.layout;
|
||||
imageMemoryBarrier.oldLayout = attachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = attachment.descriptor.layout;
|
||||
|
||||
switch ( state ) {
|
||||
case 0: {
|
||||
@ -229,7 +273,7 @@ void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer comma
|
||||
case 1: {
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.newLayout = attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.newLayout = attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
} break;
|
||||
@ -250,7 +294,7 @@ void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer comma
|
||||
1, &imageMemoryBarrier
|
||||
);
|
||||
|
||||
attachment.layout = imageMemoryBarrier.newLayout;
|
||||
attachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
@ -268,9 +312,9 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto
|
||||
std::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
VkClearValue clearValue;
|
||||
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } };
|
||||
} else if ( attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
}
|
||||
clearValues.push_back(clearValue);
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <uf/utils/camera/camera.h>
|
||||
#include <uf/utils/math/transform.h>
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
#include <uf/ext/gltf/graph.h>
|
||||
|
||||
// ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }), blitters({ blitter }) {
|
||||
ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }) {
|
||||
@ -64,11 +65,105 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
renderTarget.device = &device;
|
||||
renderTarget.width = this->width;
|
||||
renderTarget.height = this->height;
|
||||
|
||||
struct {
|
||||
size_t id, normals, uvs, albedo, depth, output;
|
||||
} attachments;
|
||||
size_t msaa = ext::vulkan::settings::msaa;
|
||||
|
||||
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UINT,
|
||||
/*.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.normals = 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,
|
||||
});
|
||||
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
|
||||
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UNORM,
|
||||
/*.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.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.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.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,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
attachments.output = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.id, attachments.normals, attachments.uvs },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.id, attachments.normals, attachments.uvs, attachments.depth },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
{ attachments.id, attachments.normals, attachments.albedo },
|
||||
{},
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
{
|
||||
renderTarget.addPass(
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
{ attachments.output },
|
||||
{ attachments.id, attachments.normals, attachments.albedo, attachments.depth },
|
||||
{},
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// attach targets
|
||||
struct {
|
||||
size_t albedo, normals, position, depth, output;
|
||||
} attachments;
|
||||
|
||||
attachments.albedo = renderTarget.attach( ext::vulkan::settings::formats::color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // albedo
|
||||
attachments.normals = renderTarget.attach( ext::vulkan::settings::formats::normal, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
|
||||
if ( !settings::experimental::deferredReconstructPosition )
|
||||
@ -121,6 +216,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
attachments.depth
|
||||
);
|
||||
}
|
||||
#endif
|
||||
renderTarget.initialize( device );
|
||||
{
|
||||
uf::BaseMesh<pod::Vertex_2F2F> mesh;
|
||||
@ -134,53 +230,62 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
|
||||
0, 1, 2, 0, 2, 3
|
||||
};
|
||||
blitter.descriptor.subpass = 1;
|
||||
blitter.descriptor.renderTarget = i++;
|
||||
blitter.descriptor.depth.test = false;
|
||||
blitter.descriptor.depth.write = false;
|
||||
|
||||
blitter.initialize( this->getName() );
|
||||
blitter.initializeGeometry( mesh );
|
||||
/*
|
||||
if ( i == 0 ) {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
// {"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
} else {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
}
|
||||
*/
|
||||
if ( settings::experimental::deferredReconstructPosition ) {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
} else {
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
}
|
||||
|
||||
blitter.material.initializeShaders({
|
||||
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& shader = blitter.material.shaders.back();
|
||||
|
||||
struct SpecializationConstant {
|
||||
uint32_t maxLights = 16;
|
||||
uint32_t maxTextures = 512;
|
||||
};
|
||||
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
|
||||
specializationConstants.maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
size_t maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
specializationConstants.maxTextures = metadata["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>();
|
||||
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
|
||||
if ( binding.descriptorCount > 1 )
|
||||
binding.descriptorCount = specializationConstants.maxLights;
|
||||
binding.descriptorCount = specializationConstants.maxTextures;
|
||||
}
|
||||
|
||||
std::vector<pod::Light::Storage> lights(maxLights);
|
||||
std::vector<pod::Material::Storage> materials(specializationConstants.maxTextures);
|
||||
std::vector<pod::Texture::Storage> textures(specializationConstants.maxTextures);
|
||||
std::vector<pod::DrawCall::Storage> drawCalls(specializationConstants.maxTextures);
|
||||
|
||||
for ( auto& material : materials ) material.colorBase = {0,0,0,0};
|
||||
|
||||
this->metadata["lightBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) lights.data(),
|
||||
lights.size() * sizeof(pod::Light::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
this->metadata["materialBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) materials.data(),
|
||||
materials.size() * sizeof(pod::Material::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
this->metadata["textureBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) textures.data(),
|
||||
textures.size() * sizeof(pod::Texture::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
this->metadata["drawCallBufferIndex"] = blitter.initializeBuffer(
|
||||
(void*) drawCalls.data(),
|
||||
drawCalls.size() * sizeof(pod::DrawCall::Storage),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
blitter.initializePipeline();
|
||||
}
|
||||
@ -258,7 +363,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
std::vector<VkClearValue> clearValues;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
VkClearValue clearValue;
|
||||
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
|
||||
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
|
||||
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
|
||||
clearValue.color = { {
|
||||
@ -270,7 +375,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
} else {
|
||||
clearValue.color = { { 0, 0, 0, 0 } };
|
||||
}
|
||||
} else if ( attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
clearValue.depthStencil = { 0.0f, 0 };
|
||||
}
|
||||
clearValues.push_back(clearValue);
|
||||
@ -311,11 +416,12 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdSetViewport(commands[i], 0, 1, &viewport);
|
||||
vkCmdSetScissor(commands[i], 0, 1, &scissor);
|
||||
size_t currentDraw = 0;
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor);
|
||||
graphic->record( commands[i], descriptor, eyePass );
|
||||
graphic->record( commands[i], descriptor, eyePass, currentDraw++ );
|
||||
}
|
||||
// render gui layer
|
||||
{
|
||||
@ -394,19 +500,19 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
|
||||
vkCmdBlitImage(
|
||||
@ -424,19 +530,19 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.layout;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.layout = imageMemoryBarrier.newLayout;
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
|
||||
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
|
||||
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,106 +3,94 @@
|
||||
#include <uf/ext/vulkan/initializers.h>
|
||||
#include <uf/utils/window/window.h>
|
||||
|
||||
void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFlags access, const std::vector<size_t>& colors, const std::vector<size_t>& inputs, size_t depth ) {
|
||||
void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFlags access, const std::vector<size_t>& colors, const std::vector<size_t>& inputs, const std::vector<size_t>& resolves, size_t depth ) {
|
||||
Subpass pass;
|
||||
pass.stage = stage;
|
||||
pass.access = access;
|
||||
for ( auto& i : colors ) pass.colors.push_back( { (uint32_t) i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } );
|
||||
for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
// for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
if ( depth < attachments.size() ) pass.depth = { (uint32_t) depth, attachments[depth].layout };
|
||||
for ( auto& i : colors ) pass.colors.push_back( { (uint32_t) i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } );
|
||||
for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
for ( auto& i : resolves ) pass.resolves.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
// for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
if ( depth < attachments.size() ) pass.depth = { (uint32_t) depth, attachments[depth].descriptor.layout };
|
||||
|
||||
if ( !resolves.empty() && resolves.size() != colors.size() )
|
||||
VK_VALIDATION_MESSAGE("Mismatching resolves count: Expecting " << colors.size() << ", got " << resolves.size());
|
||||
|
||||
passes.push_back(pass);
|
||||
}
|
||||
size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usage, VkImageLayout layout, bool blend, Attachment* attachment ) {
|
||||
size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descriptor, Attachment* attachment ) {
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
if ( !attachment ) {
|
||||
attachments.resize(attachments.size()+1);
|
||||
attachment = &attachments.back();
|
||||
// no MSAA for depth
|
||||
if ( false && usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
} else {
|
||||
switch ( samples ) {
|
||||
case 64: attachment->samples = VK_SAMPLE_COUNT_64_BIT; break;
|
||||
case 32: attachment->samples = VK_SAMPLE_COUNT_32_BIT; break;
|
||||
case 16: attachment->samples = VK_SAMPLE_COUNT_16_BIT; break;
|
||||
case 8: attachment->samples = VK_SAMPLE_COUNT_8_BIT; break;
|
||||
case 4: attachment->samples = VK_SAMPLE_COUNT_4_BIT; break;
|
||||
case 2: attachment->samples = VK_SAMPLE_COUNT_2_BIT; break;
|
||||
default: attachment->samples = VK_SAMPLE_COUNT_1_BIT; break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( attachment ) {
|
||||
if ( attachment->view ) {
|
||||
vkDestroyImageView(*device, attachment->view, nullptr);
|
||||
attachment->view = VK_NULL_HANDLE;
|
||||
}
|
||||
if ( attachment->image ) {
|
||||
// vkDestroyImage(*device, attachment->image, nullptr);
|
||||
vmaDestroyImage( allocator, attachment->image, attachment->allocation );
|
||||
attachment->image = VK_NULL_HANDLE;
|
||||
}
|
||||
if ( attachment->mem ) {
|
||||
// vkFreeMemory(*device, attachment->mem, nullptr);
|
||||
attachment->mem = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
VkImageAspectFlags aspectMask = 0;
|
||||
// specialization: depth buffer
|
||||
if ( usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; // | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
} else {
|
||||
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
attachment = &attachments.emplace_back();
|
||||
attachment->descriptor = descriptor;
|
||||
}
|
||||
// un-request transient attachments if not supported yet requested
|
||||
if ( attachment->descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ) {
|
||||
bool supported = false;
|
||||
auto& properties = device->memoryProperties;
|
||||
for ( uint32_t i = 0; i < properties.memoryTypeCount; ++i ) {
|
||||
auto prop = properties.memoryTypes[i].propertyFlags;
|
||||
if ( prop & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT ) {
|
||||
supported = true;
|
||||
}
|
||||
}
|
||||
if ( !supported ) {
|
||||
VK_VALIDATION_MESSAGE("Transient attachment requested yet not supported, disabling...");
|
||||
attachment->descriptor.usage &= ~VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
|
||||
}
|
||||
}
|
||||
attachment->layout = layout;
|
||||
attachment->format = format;
|
||||
attachment->usage = usage;
|
||||
|
||||
VkImageCreateInfo imageCreateInfo = {};
|
||||
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.format = format;
|
||||
imageCreateInfo.format = attachment->descriptor.format;
|
||||
imageCreateInfo.extent = { width, height, 1 };
|
||||
imageCreateInfo.mipLevels = 1;
|
||||
imageCreateInfo.arrayLayers = this->multiviews;
|
||||
imageCreateInfo.samples = attachment->samples;
|
||||
imageCreateInfo.arrayLayers = this->views;
|
||||
imageCreateInfo.samples = ext::vulkan::sampleCount( attachment->descriptor.samples );
|
||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageCreateInfo.usage = usage;
|
||||
imageCreateInfo.usage = attachment->descriptor.usage;
|
||||
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
VmaAllocationCreateInfo allocInfo = {};
|
||||
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||
if ( attachment->descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ) {
|
||||
allocInfo.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
|
||||
}
|
||||
VK_CHECK_RESULT(vmaCreateImage(allocator, &imageCreateInfo, &allocInfo, &attachment->image, &attachment->allocation, &attachment->allocationInfo));
|
||||
attachment->mem = attachment->allocationInfo.deviceMemory;
|
||||
/*
|
||||
VK_CHECK_RESULT(vkCreateImage(*device, &imageCreateInfo, nullptr, &attachment->image));
|
||||
|
||||
// Allocate memory for the image (device local) and bind it to our image
|
||||
VkMemoryAllocateInfo memAlloc = {};
|
||||
memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
VkMemoryRequirements memReqs;
|
||||
vkGetImageMemoryRequirements(*device, attachment->image, &memReqs);
|
||||
memAlloc.allocationSize = memReqs.size;
|
||||
memAlloc.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(*device, &memAlloc, nullptr, &attachment->mem));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(*device, attachment->image, attachment->mem, 0));
|
||||
*/
|
||||
|
||||
// Create a view for the depth stencil image
|
||||
// Images aren't directly accessed in Vulkan, but rather through views described by a subresource range
|
||||
// This allows for multiple views of one image with differing ranges (e.g. for different layers)
|
||||
VkImageAspectFlags aspectMask = 0;
|
||||
// specialization: depth buffer
|
||||
if ( attachment->descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; // | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
} else {
|
||||
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
VkImageViewCreateInfo imageView = {};
|
||||
imageView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
imageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
imageView.format = format;
|
||||
imageView.format = attachment->descriptor.format;
|
||||
imageView.subresourceRange = {};
|
||||
imageView.subresourceRange.aspectMask = aspectMask;
|
||||
imageView.subresourceRange.baseMipLevel = 0;
|
||||
imageView.subresourceRange.levelCount = 1;
|
||||
imageView.subresourceRange.baseArrayLayer = 0;
|
||||
imageView.subresourceRange.layerCount = this->multiviews;
|
||||
imageView.subresourceRange.layerCount = this->views;
|
||||
imageView.image = attachment->image;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->view));
|
||||
@ -111,7 +99,7 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
|
||||
VkBool32 blendEnabled = VK_FALSE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
|
||||
|
||||
if ( blend ) {
|
||||
if ( attachment->descriptor.blend ) {
|
||||
blendEnabled = VK_TRUE;
|
||||
writeMask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
}
|
||||
@ -121,30 +109,6 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
|
||||
blendEnabled
|
||||
);
|
||||
if ( blendEnabled == VK_TRUE ) {
|
||||
/*
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
*/
|
||||
/*
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA;
|
||||
*/
|
||||
/*
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
*/
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
@ -159,18 +123,15 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
|
||||
}
|
||||
void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
// Bind
|
||||
{
|
||||
this->device = &device;
|
||||
}
|
||||
this->device = &device;
|
||||
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
|
||||
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
|
||||
|
||||
// resize attachments if necessary
|
||||
if ( initialized ) {
|
||||
for ( auto& attachment: this->attachments ) {
|
||||
if ( attachment.aliased ) continue;
|
||||
bool blend = attachment.blendState.blendEnable == VK_TRUE;
|
||||
attach( attachment.format, attachment.usage, attachment.layout, blend, &attachment );
|
||||
if ( attachment.descriptor.aliased ) continue;
|
||||
attach( attachment.descriptor, &attachment );
|
||||
}
|
||||
}
|
||||
// ensure attachments are already created
|
||||
@ -182,14 +143,14 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
|
||||
for ( auto& attachment : this->attachments ) {
|
||||
VkAttachmentDescription description;
|
||||
description.format = attachment.format;
|
||||
description.samples = attachment.samples;
|
||||
description.format = attachment.descriptor.format;
|
||||
description.samples = ext::vulkan::sampleCount( attachment.descriptor.samples );
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.storeOp = attachment.descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
description.finalLayout = attachment.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : attachment.layout;
|
||||
description.finalLayout = attachment.descriptor.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : attachment.descriptor.layout;
|
||||
description.flags = 0;
|
||||
|
||||
attachments.push_back(description);
|
||||
@ -203,7 +164,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
|
||||
// dependency: transition from final
|
||||
VkSubpassDependency dependency;
|
||||
dependency.dependencyFlags = 0; //VK_DEPENDENCY_BY_REGION_BIT;
|
||||
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
|
||||
dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
@ -216,12 +177,12 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
description.colorAttachmentCount = pass.colors.size();
|
||||
description.pColorAttachments = &pass.colors[0];
|
||||
description.pDepthStencilAttachment = &pass.depth;
|
||||
description.pResolveAttachments = &pass.resolves[0];
|
||||
description.inputAttachmentCount = pass.inputs.size();
|
||||
description.pInputAttachments = &pass.inputs[0];
|
||||
description.pDepthStencilAttachment = &pass.depth;
|
||||
description.preserveAttachmentCount = 0;
|
||||
description.pPreserveAttachments = nullptr;
|
||||
description.pResolveAttachments = nullptr;
|
||||
description.flags = 0;
|
||||
for ( auto& input : pass.inputs ) {
|
||||
if ( input.attachment == pass.depth.attachment ) {
|
||||
@ -275,7 +236,6 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
{
|
||||
VkSubpassDependency dependency;
|
||||
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
|
||||
|
||||
dependency.srcSubpass = 0;
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
@ -309,7 +269,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
/*
|
||||
uint32_t mask = 0;
|
||||
std::vector<uint32_t> masks;
|
||||
for ( size_t i = 0; i < this->multiviews; ++i ) {
|
||||
for ( size_t i = 0; i < this->views; ++i ) {
|
||||
mask |= (0b00000001 << i);
|
||||
}
|
||||
for ( size_t i = 0; i < static_cast<uint32_t>(descriptions.size()); ++i ) {
|
||||
@ -322,7 +282,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
renderPassMultiviewInfo.pViewMasks = masks.data();
|
||||
renderPassMultiviewInfo.pCorrelationMasks = masks.data();
|
||||
renderPassMultiviewInfo.correlationMaskCount = 1;
|
||||
if ( this->multiviews > 1 ) {
|
||||
if ( this->views > 1 ) {
|
||||
renderPassInfo.pNext = &renderPassMultiviewInfo;
|
||||
}
|
||||
*/
|
||||
@ -340,7 +300,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
for ( size_t i = 0; i < framebuffers.size(); ++i ) {
|
||||
std::vector<VkImageView> attachments;
|
||||
for ( auto& attachment : this->attachments ) {
|
||||
if ( attachment.aliased && attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
|
||||
if ( attachment.descriptor.aliased && attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
|
||||
attachments.push_back(base.renderTarget.attachments[i].view);
|
||||
} else attachments.push_back(attachment.view);
|
||||
}
|
||||
@ -367,7 +327,7 @@ void ext::vulkan::RenderTarget::destroy() {
|
||||
for ( auto& framebuffer : framebuffers ) vkDestroyFramebuffer( *device, framebuffer, nullptr );
|
||||
|
||||
for ( auto& attachment : attachments ) {
|
||||
if ( attachment.aliased ) continue;
|
||||
if ( attachment.descriptor.aliased ) continue;
|
||||
vkDestroyImageView( *device, attachment.view, nullptr );
|
||||
attachment.view = VK_NULL_HANDLE;
|
||||
// vkDestroyImage( *device, attachment.image, nullptr );
|
||||
|
||||
@ -49,6 +49,38 @@ void ext::vulkan::Texture::initialize( Device& device, size_t width, size_t heig
|
||||
this->height = height;
|
||||
this->depth = depth;
|
||||
this->layers = layers;
|
||||
// implicitly set type
|
||||
if ( width > 1 && height > 1 && depth > 1 ) {
|
||||
this->type = VK_IMAGE_TYPE_3D;
|
||||
} else if ( (width == 1 && height > 1 && depth > 1) || (width > 1 && height == 1 && depth > 1) || (width > 1 && height > 1 && depth == 1) ) {
|
||||
this->type = VK_IMAGE_TYPE_2D;
|
||||
} else if ( (width > 1 && height == 1 && depth == 1) || (width == 1 && height > 1 && depth == 1) || (width == 1 && height == 1 && depth > 1) ) {
|
||||
this->type = VK_IMAGE_TYPE_1D;
|
||||
}
|
||||
if ( depth > 1 ) {
|
||||
if ( viewType == VK_IMAGE_VIEW_TYPE_1D ) viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
if ( viewType == VK_IMAGE_VIEW_TYPE_2D ) viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
if ( viewType == VK_IMAGE_VIEW_TYPE_CUBE ) viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::Texture::initialize( Device& device, VkImageViewType viewType, size_t width, size_t height, size_t depth, size_t layers ) {
|
||||
this->initialize( device, width, height, depth, layers );
|
||||
this->viewType = viewType;
|
||||
switch ( viewType ) {
|
||||
case VK_IMAGE_VIEW_TYPE_1D:
|
||||
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
|
||||
type = VK_IMAGE_TYPE_1D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_2D:
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE:
|
||||
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
||||
type = VK_IMAGE_TYPE_2D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_3D:
|
||||
type = VK_IMAGE_TYPE_3D;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::Texture::updateDescriptors() {
|
||||
descriptor.sampler = sampler.sampler;
|
||||
@ -70,11 +102,11 @@ void ext::vulkan::Texture::destroy() {
|
||||
vmaDestroyImage( allocator, image, allocation );
|
||||
image = VK_NULL_HANDLE;
|
||||
}
|
||||
sampler.destroy();
|
||||
if ( deviceMemory != VK_NULL_HANDLE ) {
|
||||
// vkFreeMemory(device->logicalDevice, deviceMemory, nullptr);
|
||||
deviceMemory = VK_NULL_HANDLE;
|
||||
}
|
||||
sampler.destroy();
|
||||
}
|
||||
void ext::vulkan::Texture::setImageLayout(
|
||||
VkCommandBuffer cmdbuffer,
|
||||
@ -188,7 +220,6 @@ void ext::vulkan::Texture::setImageLayout(
|
||||
srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
}
|
||||
|
||||
// Put barrier inside setup command buffer
|
||||
vkCmdPipelineBarrier(
|
||||
cmdbuffer,
|
||||
@ -214,7 +245,7 @@ void ext::vulkan::Texture::setImageLayout(
|
||||
subresourceRange.layerCount = 1;
|
||||
setImageLayout(cmdbuffer, image, oldImageLayout, newImageLayout, subresourceRange);
|
||||
}
|
||||
void ext::vulkan::Texture2D::loadFromFile(
|
||||
void ext::vulkan::Texture::loadFromFile(
|
||||
std::string filename,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags imageUsageFlags,
|
||||
@ -222,7 +253,7 @@ void ext::vulkan::Texture2D::loadFromFile(
|
||||
) {
|
||||
return loadFromFile( filename, ext::vulkan::device, format, imageUsageFlags, imageLayout );
|
||||
}
|
||||
void ext::vulkan::Texture2D::loadFromFile(
|
||||
void ext::vulkan::Texture::loadFromFile(
|
||||
std::string filename,
|
||||
Device& device,
|
||||
VkFormat format,
|
||||
@ -298,7 +329,7 @@ void ext::vulkan::Texture2D::loadFromFile(
|
||||
imageLayout
|
||||
);
|
||||
}
|
||||
void ext::vulkan::Texture2D::loadFromImage(
|
||||
void ext::vulkan::Texture::loadFromImage(
|
||||
uf::Image& image,
|
||||
VkFormat format,
|
||||
VkImageUsageFlags imageUsageFlags,
|
||||
@ -306,7 +337,7 @@ void ext::vulkan::Texture2D::loadFromImage(
|
||||
) {
|
||||
return loadFromImage( image, ext::vulkan::device, format, imageUsageFlags, imageLayout );
|
||||
}
|
||||
void ext::vulkan::Texture2D::loadFromImage(
|
||||
void ext::vulkan::Texture::loadFromImage(
|
||||
uf::Image& image,
|
||||
Device& device,
|
||||
VkFormat format,
|
||||
@ -369,7 +400,7 @@ void ext::vulkan::Texture2D::loadFromImage(
|
||||
);
|
||||
}
|
||||
|
||||
void ext::vulkan::Texture2D::fromBuffers(
|
||||
void ext::vulkan::Texture::fromBuffers(
|
||||
void* data,
|
||||
VkDeviceSize bufferSize,
|
||||
VkFormat format,
|
||||
@ -383,8 +414,9 @@ void ext::vulkan::Texture2D::fromBuffers(
|
||||
) {
|
||||
this->initialize(device, texWidth, texHeight, texDepth, layers);
|
||||
|
||||
if ( this->depth > 1 ) this->mips = 1; else
|
||||
{
|
||||
if ( this->mips == 0 ) {
|
||||
this->mips = 1;
|
||||
} else if ( this->depth == 1 ) {
|
||||
this->mips = static_cast<uint32_t>(std::floor(std::log2(std::max(texWidth, texHeight)))) + 1;
|
||||
VkFormatProperties formatProperties;
|
||||
vkGetPhysicalDeviceFormatProperties(device.physicalDevice, format, &formatProperties);
|
||||
@ -396,7 +428,7 @@ void ext::vulkan::Texture2D::fromBuffers(
|
||||
|
||||
// Create optimal tiled target image
|
||||
VkImageCreateInfo imageCreateInfo = ext::vulkan::initializers::imageCreateInfo();
|
||||
imageCreateInfo.imageType = this->depth > 1 ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.imageType = this->type;
|
||||
imageCreateInfo.format = this->format = format;
|
||||
imageCreateInfo.mipLevels = this->mips;
|
||||
imageCreateInfo.arrayLayers = this->layers;
|
||||
@ -414,6 +446,10 @@ void ext::vulkan::Texture2D::fromBuffers(
|
||||
if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
|
||||
imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
// Ensure cube maps get the compat flag bit
|
||||
if ( this->viewType == VK_IMAGE_VIEW_TYPE_CUBE || this->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY ) {
|
||||
imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
}
|
||||
|
||||
VmaAllocationCreateInfo allocInfo = {};
|
||||
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||
@ -425,21 +461,17 @@ void ext::vulkan::Texture2D::fromBuffers(
|
||||
sampler.descriptor.mip.max = static_cast<float>(this->mips);
|
||||
sampler.initialize( device );
|
||||
|
||||
// Create image view
|
||||
VkImageSubresourceRange subresourceRange = {};
|
||||
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
subresourceRange.baseMipLevel = 0;
|
||||
subresourceRange.levelCount = this->mips;
|
||||
subresourceRange.layerCount = this->layers;
|
||||
|
||||
// Create image view
|
||||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.pNext = NULL;
|
||||
viewCreateInfo.viewType = this->depth > 1 ? VK_IMAGE_VIEW_TYPE_3D : VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewCreateInfo.viewType = viewType;
|
||||
viewCreateInfo.format = format;
|
||||
viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
|
||||
viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
viewCreateInfo.subresourceRange.levelCount = 1;
|
||||
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewCreateInfo.subresourceRange.layerCount = this->layers;
|
||||
viewCreateInfo.subresourceRange.levelCount = this->mips;
|
||||
viewCreateInfo.image = image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device.logicalDevice, &viewCreateInfo, nullptr, &view));
|
||||
|
||||
@ -455,7 +487,7 @@ void ext::vulkan::Texture2D::fromBuffers(
|
||||
this->updateDescriptors();
|
||||
}
|
||||
|
||||
void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uint32_t height, VkFormat format ) {
|
||||
void ext::vulkan::Texture::asRenderTarget( Device& device, uint32_t width, uint32_t height, VkFormat format ) {
|
||||
// Prepare blit target texture
|
||||
this->initialize( device, width, height );
|
||||
|
||||
@ -466,7 +498,7 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
|
||||
assert(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
|
||||
|
||||
VkImageCreateInfo imageCreateInfo = ext::vulkan::initializers::imageCreateInfo();
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.imageType = type;
|
||||
imageCreateInfo.format = format;
|
||||
imageCreateInfo.extent = { width, height, depth };
|
||||
imageCreateInfo.mipLevels = this->mips = 1;
|
||||
@ -505,7 +537,7 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
|
||||
|
||||
// Create image view
|
||||
VkImageViewCreateInfo viewCreateInfo = ext::vulkan::initializers::imageViewCreateInfo();
|
||||
viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewCreateInfo.viewType = viewType;
|
||||
viewCreateInfo.format = format;
|
||||
viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
|
||||
viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
@ -515,7 +547,7 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
|
||||
// Initialize a descriptor for later use
|
||||
this->updateDescriptors();
|
||||
}
|
||||
void ext::vulkan::Texture2D::aliasTexture( const Texture2D& texture ) {
|
||||
void ext::vulkan::Texture::aliasTexture( const Texture& texture ) {
|
||||
image = texture.image;
|
||||
view = texture.view;
|
||||
imageLayout = texture.imageLayout;
|
||||
@ -524,10 +556,10 @@ void ext::vulkan::Texture2D::aliasTexture( const Texture2D& texture ) {
|
||||
|
||||
this->updateDescriptors();
|
||||
}
|
||||
void ext::vulkan::Texture2D::aliasAttachment( const RenderTarget::Attachment& attachment, bool createSampler ) {
|
||||
void ext::vulkan::Texture::aliasAttachment( const RenderTarget::Attachment& attachment, bool createSampler ) {
|
||||
image = attachment.image;
|
||||
view = attachment.view;
|
||||
imageLayout = attachment.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : attachment.layout;
|
||||
imageLayout = attachment.descriptor.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : attachment.descriptor.layout;
|
||||
deviceMemory = attachment.mem;
|
||||
|
||||
// Create sampler
|
||||
@ -536,13 +568,12 @@ void ext::vulkan::Texture2D::aliasAttachment( const RenderTarget::Attachment& at
|
||||
this->updateDescriptors();
|
||||
}
|
||||
|
||||
void ext::vulkan::Texture2D::update( uf::Image& image, VkImageLayout targetImageLayout, uint32_t layer ) {
|
||||
if ( width != image.getDimensions()[0] || height != image.getDimensions()[1] )
|
||||
return;
|
||||
void ext::vulkan::Texture::update( uf::Image& image, VkImageLayout targetImageLayout, uint32_t layer ) {
|
||||
if ( width != image.getDimensions()[0] || height != image.getDimensions()[1] ) return;
|
||||
return this->update( (void*) image.getPixelsPtr(), image.getPixels().size(), layer );
|
||||
}
|
||||
void ext::vulkan::Texture2D::update( void* data, VkDeviceSize bufferSize, VkImageLayout targetImageLayout, uint32_t layer ) {
|
||||
// Update descriptor image info member that can be used for setting up descriptor sets
|
||||
void ext::vulkan::Texture::update( void* data, VkDeviceSize bufferSize, VkImageLayout targetImageLayout, uint32_t layer ) {
|
||||
// Update descriptor image info member that can be used for setting up descriptor sets
|
||||
|
||||
auto& device = *this->device;
|
||||
|
||||
@ -617,7 +648,7 @@ void ext::vulkan::Texture2D::update( void* data, VkDeviceSize bufferSize, VkImag
|
||||
this->updateDescriptors();
|
||||
}
|
||||
|
||||
void ext::vulkan::Texture2D::generateMipmaps( VkCommandBuffer commandBuffer, uint32_t layer ) {
|
||||
void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint32_t layer ) {
|
||||
auto& device = *this->device;
|
||||
|
||||
if ( this->mips <= 1 ) return;
|
||||
@ -694,4 +725,17 @@ void ext::vulkan::Texture2D::generateMipmaps( VkCommandBuffer commandBuffer, uin
|
||||
if (mipHeight > 1) mipHeight /= 2;
|
||||
if (mipDepth > 1) mipDepth /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
ext::vulkan::Texture2D::Texture2D() {
|
||||
type = VK_IMAGE_TYPE_2D;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
}
|
||||
ext::vulkan::Texture3D::Texture3D() {
|
||||
type = VK_IMAGE_TYPE_3D;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||
}
|
||||
ext::vulkan::TextureCube::TextureCube() {
|
||||
type = VK_IMAGE_TYPE_2D;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
}
|
||||
@ -113,20 +113,18 @@ std::string ext::vulkan::errorString( VkResult result ) {
|
||||
return "UNKNOWN_ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ext::vulkan::getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) {
|
||||
// Iterate over all memory types available for the device used in this example
|
||||
for (uint32_t i = 0; i < ext::vulkan::device.memoryProperties.memoryTypeCount; i++) {
|
||||
if ((typeBits & 1) == 1) {
|
||||
if ((ext::vulkan::device.memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
typeBits >>= 1;
|
||||
}
|
||||
throw std::runtime_error("Could not find a suitable memory type!");
|
||||
VkSampleCountFlagBits ext::vulkan::sampleCount( uint8_t count ) {
|
||||
VkSampleCountFlags counts = std::min(ext::vulkan::device.properties.limits.framebufferColorSampleCounts, ext::vulkan::device.properties.limits.framebufferDepthSampleCounts);
|
||||
if ( count < counts ) counts = count;
|
||||
|
||||
if ( counts & VK_SAMPLE_COUNT_64_BIT ) return VK_SAMPLE_COUNT_64_BIT;
|
||||
if ( counts & VK_SAMPLE_COUNT_32_BIT ) return VK_SAMPLE_COUNT_32_BIT;
|
||||
if ( counts & VK_SAMPLE_COUNT_16_BIT ) return VK_SAMPLE_COUNT_16_BIT;
|
||||
if ( counts & VK_SAMPLE_COUNT_8_BIT ) return VK_SAMPLE_COUNT_8_BIT;
|
||||
if ( counts & VK_SAMPLE_COUNT_4_BIT ) return VK_SAMPLE_COUNT_4_BIT;
|
||||
if ( counts & VK_SAMPLE_COUNT_2_BIT ) return VK_SAMPLE_COUNT_2_BIT;
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
void* ext::vulkan::alignedAlloc( size_t size, size_t alignment ) {
|
||||
void *data = nullptr;
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
@ -211,21 +209,6 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
case 0: {
|
||||
device.initialize();
|
||||
swapchain.initialize( device );
|
||||
{
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.physicalDevice = device.physicalDevice;
|
||||
allocatorInfo.device = device.logicalDevice;
|
||||
vmaCreateAllocator(&allocatorInfo, &allocator);
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture2D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), VK_FORMAT_R8G8B8A8_UNORM, 2, 2, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->initialize(device);
|
||||
@ -246,12 +229,15 @@ void ext::vulkan::initialize( uint8_t stage ) {
|
||||
if ( !jobs.empty() ) {
|
||||
uf::thread::batchWorkers( jobs );
|
||||
}
|
||||
/*
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
renderMode->createCommandBuffers();
|
||||
{
|
||||
std::vector<uint8_t> pixels = {
|
||||
255, 0, 255, 255, 0, 0, 0, 255,
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
};
|
||||
Texture2D::empty.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
|
||||
Texture2D::empty.fromBuffers( (void*) &pixels[0], pixels.size(), VK_FORMAT_R8G8B8A8_UNORM, 2, 2, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT );
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
case 1: {
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
@ -400,8 +386,6 @@ void ext::vulkan::destroy() {
|
||||
renderMode = NULL;
|
||||
}
|
||||
|
||||
vmaDestroyAllocator( allocator );
|
||||
|
||||
swapchain.destroy();
|
||||
device.destroy();
|
||||
ext::vulkan::mutex.unlock();
|
||||
|
||||
@ -70,14 +70,14 @@ std::string uf::Image::getFilename() const {
|
||||
}
|
||||
|
||||
// from file
|
||||
bool uf::Image::open( const std::string& filename ) {
|
||||
bool uf::Image::open( const std::string& filename, bool flip ) {
|
||||
if ( !uf::io::exists(filename) ) throw std::runtime_error("does not exist: " + filename);
|
||||
this->m_filename = filename;
|
||||
this->m_pixels.clear();
|
||||
std::string extension = uf::io::extension(filename);
|
||||
#if 0
|
||||
if ( extension == "png" ) {
|
||||
uint mode = 2;
|
||||
#if 0
|
||||
png_byte header[8];
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
|
||||
@ -170,42 +170,43 @@ bool uf::Image::open( const std::string& filename ) {
|
||||
// this->convert(uf::Image::Format::RGBA, 32);
|
||||
}
|
||||
*/
|
||||
#else
|
||||
int width, height, channels, bit_depth;
|
||||
bit_depth = 8;
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
unsigned char* buffer = stbi_load(
|
||||
filename.c_str(),
|
||||
&width,
|
||||
&height,
|
||||
&channels,
|
||||
STBI_rgb_alpha
|
||||
);
|
||||
channels = 4;
|
||||
uint len = width * height * channels;
|
||||
this->m_dimensions.x = width;
|
||||
this->m_dimensions.y = height;
|
||||
this->m_bpp = bit_depth * channels;
|
||||
this->m_channels = channels;
|
||||
this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
|
||||
/*
|
||||
if ( this->m_channels != 4 ) {
|
||||
std::string from = "";
|
||||
switch ( this->m_channels ) {
|
||||
case 1: from = "r"; break;
|
||||
case 2: from = "ra"; break;
|
||||
case 3: from = "rgb"; break;
|
||||
}
|
||||
this->convert(from);
|
||||
}
|
||||
std::cout << "Hash of " << filename << ": " << uf::string::sha256( uf::io::readAsBuffer(filename) ) << std::endl;
|
||||
*/
|
||||
|
||||
stbi_image_free(buffer);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
int width, height, channels, bit_depth;
|
||||
bit_depth = 8;
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
unsigned char* buffer = stbi_load(
|
||||
filename.c_str(),
|
||||
&width,
|
||||
&height,
|
||||
&channels,
|
||||
STBI_rgb_alpha
|
||||
);
|
||||
channels = 4;
|
||||
uint len = width * height * channels;
|
||||
this->m_dimensions.x = width;
|
||||
this->m_dimensions.y = height;
|
||||
this->m_bpp = bit_depth * channels;
|
||||
this->m_channels = channels;
|
||||
this->m_pixels.insert( this->m_pixels.end(), (uint8_t*) buffer, buffer + len );
|
||||
/*
|
||||
if ( this->m_channels != 4 ) {
|
||||
std::string from = "";
|
||||
switch ( this->m_channels ) {
|
||||
case 1: from = "r"; break;
|
||||
case 2: from = "ra"; break;
|
||||
case 3: from = "rgb"; break;
|
||||
}
|
||||
this->convert(from);
|
||||
}
|
||||
std::cout << "Hash of " << filename << ": " << uf::string::sha256( uf::io::readAsBuffer(filename) ) << std::endl;
|
||||
*/
|
||||
|
||||
stbi_image_free(buffer);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
void uf::Image::loadFromBuffer( const Image::pixel_t::type_t* pointer, const pod::Vector2ui& size, std::size_t bit_depth, std::size_t channels, bool flip ) {
|
||||
this->m_dimensions = size;
|
||||
|
||||
@ -63,6 +63,8 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
renderMode.metadata["type"] = "depth";
|
||||
renderMode.metadata["depth bias"] = metadata["light"]["bias"];
|
||||
renderMode.metadata["renderMode"] = metadata["renderMode"];
|
||||
// std::cout << this->getName() << ": " << renderMode.metadata["renderMode"] << std::endl;
|
||||
|
||||
if ( metadata["light"]["type"].as<std::string>() == "point" ) {
|
||||
metadata["light"]["fov"] = 90.0f;
|
||||
|
||||
@ -130,7 +130,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
// initialize perlin noise
|
||||
{
|
||||
auto& texture = this->getComponent<uf::renderer::Texture2D>();
|
||||
auto& texture = this->getComponent<uf::renderer::Texture3D>();
|
||||
texture.sampler.descriptor.addressMode = {
|
||||
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
|
||||
@ -173,6 +173,41 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
texture.fromBuffers( (void*) pixels.data(), pixels.size(), VK_FORMAT_R8_UNORM, size.x, size.y, size.z, 1, ext::vulkan::device );
|
||||
}
|
||||
|
||||
// initialize cubemap
|
||||
{
|
||||
std::vector<std::string> filenames = {
|
||||
"./data/textures/skybox/front.png",
|
||||
"./data/textures/skybox/back.png",
|
||||
"./data/textures/skybox/up.png",
|
||||
"./data/textures/skybox/down.png",
|
||||
"./data/textures/skybox/right.png",
|
||||
"./data/textures/skybox/left.png",
|
||||
};
|
||||
uf::Image::container_t pixels;
|
||||
std::vector<uf::Image> images(filenames.size());
|
||||
|
||||
pod::Vector2ui size = {0,0};
|
||||
auto& texture = this->getComponent<uf::renderer::TextureCube>();
|
||||
for ( size_t i = 0; i < filenames.size(); ++i ) {
|
||||
auto& filename = filenames[i];
|
||||
auto& image = images[i];
|
||||
image.open(filename);
|
||||
image.flip();
|
||||
|
||||
if ( size.x == 0 && size.y == 0 ) {
|
||||
size = image.getDimensions();
|
||||
} else if ( size != image.getDimensions() ) {
|
||||
std::cout << "ERROR: MISMATCH CUBEMAP FACE SIZE" << std::endl;
|
||||
}
|
||||
|
||||
auto& p = image.getPixels();
|
||||
pixels.reserve( pixels.size() + p.size() );
|
||||
pixels.insert( pixels.end(), p.begin(), p.end() );
|
||||
}
|
||||
texture.mips = 0;
|
||||
texture.fromBuffers( (void*) pixels.data(), pixels.size(), VK_FORMAT_R8G8B8A8_UNORM, size.x, size.y, 1, filenames.size(), ext::vulkan::device );
|
||||
}
|
||||
}
|
||||
void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
@ -294,6 +329,9 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
struct Matrices {
|
||||
alignas(16) pod::Matrix4f view[2];
|
||||
alignas(16) pod::Matrix4f projection[2];
|
||||
alignas(16) pod::Matrix4f iView[2];
|
||||
alignas(16) pod::Matrix4f iProjection[2];
|
||||
alignas(16) pod::Matrix4f iProjectionView[2];
|
||||
} matrices;
|
||||
struct Mode {
|
||||
alignas(8) pod::Vector2ui type;
|
||||
@ -320,6 +358,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
alignas(4) uint32_t drawCalls = 0;
|
||||
} lengths;
|
||||
alignas(16) pod::Vector4f ambient;
|
||||
// alignas(16) pod::Vector4f position;
|
||||
};
|
||||
struct SpecializationConstant {
|
||||
uint32_t maxTextures = 512;
|
||||
@ -334,7 +373,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
};
|
||||
std::vector<LightInfo> entities;
|
||||
std::vector<pod::Graph*> graphs;
|
||||
// std::vector<uf::Entity*> graphs;
|
||||
|
||||
this->process([&]( uf::Entity* entity ) { if ( !entity ) return;
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
@ -405,9 +443,21 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
uniforms->matrices.view[i] = camera.getView( i );
|
||||
uniforms->matrices.projection[i] = camera.getProjection( i );
|
||||
uniforms->matrices.iView[i] = uf::matrix::inverse( uniforms->matrices.view[i] );
|
||||
uniforms->matrices.iProjection[i] = uf::matrix::inverse( uniforms->matrices.projection[i] );
|
||||
uniforms->matrices.iProjectionView[i] = uf::matrix::inverse( uniforms->matrices.projection[i] * uniforms->matrices.view[i] );
|
||||
}
|
||||
|
||||
uniforms->ambient = uf::vector::decode( metadata["light"]["ambient"], uniforms->ambient );
|
||||
/*
|
||||
pod::Transform<> transform = controller.getComponent<pod::Transform<>>();
|
||||
if ( controller.hasComponent<uf::Camera>() ) {
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
transform.position += camera.getTransform().position;
|
||||
transform = uf::transform::reorient( transform );
|
||||
}
|
||||
uniforms->position = transform.position;
|
||||
*/
|
||||
|
||||
uniforms->fog.color = uf::vector::decode( metadata["light"]["fog"]["color"], uniforms->fog.color );
|
||||
uniforms->fog.color.w = metadata["light"]["fog"]["step scale"].as<float>();
|
||||
@ -435,7 +485,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
|
||||
graphic.material.textures.clear();
|
||||
// add noise texture
|
||||
graphic.material.textures.emplace_back().aliasTexture(this->getComponent<uf::renderer::Texture2D>());
|
||||
graphic.material.textures.emplace_back().aliasTexture(this->getComponent<uf::renderer::Texture3D>());
|
||||
graphic.material.textures.emplace_back().aliasTexture(this->getComponent<uf::renderer::TextureCube>());
|
||||
|
||||
size_t updateThreshold = metadata["system"]["config"]["engine"]["scenes"]["lights"]["update threshold"].as<size_t>();
|
||||
size_t maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>();
|
||||
@ -451,7 +502,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
std::vector<pod::Texture::Storage> textures;
|
||||
textures.reserve(maxTextures);
|
||||
|
||||
std::vector<pod::DrawCall> drawCalls;
|
||||
std::vector<pod::DrawCall::Storage> drawCalls;
|
||||
drawCalls.reserve(maxTextures);
|
||||
|
||||
// add materials
|
||||
@ -459,7 +510,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
for ( auto* entity : graphs ) {
|
||||
auto& graph = *entity;
|
||||
|
||||
drawCalls.emplace_back(pod::DrawCall{
|
||||
drawCalls.emplace_back(pod::DrawCall::Storage{
|
||||
materials.size(),
|
||||
graph.materials.size(),
|
||||
textures.size(),
|
||||
@ -518,8 +569,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
size_t view = 0;
|
||||
for ( auto& attachment : renderMode.renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) continue;
|
||||
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) continue;
|
||||
|
||||
graphic.material.textures.emplace_back().aliasAttachment(attachment);
|
||||
|
||||
@ -552,7 +603,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
graphic.updateBuffer( (void*) lights.data(), uniforms->lengths.lights * sizeof(pod::Light::Storage), lightBufferIndex, false );
|
||||
graphic.updateBuffer( (void*) materials.data(), uniforms->lengths.materials * sizeof(pod::Material::Storage), materialBufferIndex, false );
|
||||
graphic.updateBuffer( (void*) textures.data(), uniforms->lengths.textures * sizeof(pod::Texture::Storage), textureBufferIndex, false );
|
||||
graphic.updateBuffer( (void*) drawCalls.data(), uniforms->lengths.drawCalls * sizeof(pod::DrawCall), drawCallBufferIndex, false );
|
||||
graphic.updateBuffer( (void*) drawCalls.data(), uniforms->lengths.drawCalls * sizeof(pod::DrawCall::Storage), drawCallBufferIndex, false );
|
||||
|
||||
graphic.updatePipelines();
|
||||
}
|
||||
|
||||
21
ext/main.cpp
21
ext/main.cpp
@ -379,20 +379,28 @@ void EXT_API ext::initialize() {
|
||||
uf::renderer::addRenderMode( renderMode, "Gui" );
|
||||
renderMode->blitter.descriptor.subpass = 1;
|
||||
}
|
||||
/*
|
||||
if ( ::config["engine"]["render modes"]["multiview stereo deferred"].as<bool>() )
|
||||
uf::renderer::addRenderMode( new uf::renderer::MultiviewStereoscopicDeferredRenderMode, "" );
|
||||
else if ( ::config["engine"]["render modes"]["stereo deferred"].as<bool>() )
|
||||
uf::renderer::addRenderMode( new uf::renderer::StereoscopicDeferredRenderMode, "" );
|
||||
else if ( ::config["engine"]["render modes"]["deferred"].as<bool>() )
|
||||
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
|
||||
|
||||
*/
|
||||
if ( ::config["engine"]["render modes"]["deferred"].as<bool>() ) {
|
||||
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
|
||||
if ( ::config["engine"]["render modes"]["stereo deferred"].as<bool>() ) {
|
||||
auto& renderMode = uf::renderer::getRenderMode("Deferred", true);
|
||||
renderMode.metadata["eyes"] = 2;
|
||||
}
|
||||
}
|
||||
if ( ext::openvr::enabled ) {
|
||||
ext::openvr::initialize();
|
||||
|
||||
uint32_t width, height;
|
||||
ext::openvr::recommendedResolution( width, height );
|
||||
|
||||
auto& renderMode = uf::renderer::getRenderMode("Stereoscopic Deferred", true);
|
||||
auto& renderMode = uf::renderer::getRenderMode("Deferred", true);
|
||||
renderMode.width = width;
|
||||
renderMode.height = height;
|
||||
|
||||
@ -678,6 +686,15 @@ void EXT_API ext::terminate() {
|
||||
|
||||
uf::scene::destroy();
|
||||
|
||||
/* Garbage collection */ if ( false ) {
|
||||
uint8_t mode = ::config["engine"]["debug"]["garbage collection"]["mode"].as<uint64_t>();
|
||||
bool announce = ::config["engine"]["debug"]["garbage collection"]["announce"].as<bool>();
|
||||
size_t collected = uf::instantiator::collect( mode );
|
||||
if ( announce && collected > 0 ) {
|
||||
uf::iostream << "GC collected " << (int) collected << " unused entities" << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Close vulkan */ {
|
||||
uf::renderer::destroy();
|
||||
}
|
||||
|
||||
@ -68,9 +68,7 @@ void ext::RayTracingSceneBehavior::initialize( uf::Object& self ) {
|
||||
renderMode.compute.initializeBuffer(
|
||||
(void*) shapes.data(),
|
||||
shapes.size() * sizeof(Shape),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
true
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user