repaired occlusion culling via depth pyramids
This commit is contained in:
parent
42aaf444ff
commit
fd9036ee39
@ -4,13 +4,13 @@
|
|||||||
"start": "StartMenu",
|
"start": "StartMenu",
|
||||||
"matrix": { "reverseInfinite": true },
|
"matrix": { "reverseInfinite": true },
|
||||||
"meshes": { "interleaved": false },
|
"meshes": { "interleaved": false },
|
||||||
"lights": { "enabled": true,
|
"lights": { "enabled": false,
|
||||||
"useLightmaps": false,
|
"useLightmaps": false,
|
||||||
"max": 32,
|
"max": 16,
|
||||||
"shadows": {
|
"shadows": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"update": 8,
|
"update": 4,
|
||||||
"max": 32,
|
"max": 16,
|
||||||
"samples": 2
|
"samples": 2
|
||||||
},
|
},
|
||||||
"bloom": {
|
"bloom": {
|
||||||
@ -29,8 +29,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vxgi": {
|
"vxgi": {
|
||||||
// "limiter": 0,
|
"limiter": 0,
|
||||||
"limiter": 0.0125,
|
// "limiter": 0.0125,
|
||||||
"size": 256,
|
"size": 256,
|
||||||
"dispatch": 16,
|
"dispatch": 16,
|
||||||
"cascades": 3,
|
"cascades": 3,
|
||||||
@ -117,7 +117,7 @@
|
|||||||
"gui": true,
|
"gui": true,
|
||||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||||
"hdr": true,
|
"hdr": true,
|
||||||
"vxgi": true,
|
"vxgi": false,
|
||||||
"culling": true,
|
"culling": true,
|
||||||
"bloom": true,
|
"bloom": true,
|
||||||
"rt": false,
|
"rt": false,
|
||||||
@ -355,7 +355,7 @@
|
|||||||
"render modes": { "gui": true, "deferred": true },
|
"render modes": { "gui": true, "deferred": true },
|
||||||
"limiters": {
|
"limiters": {
|
||||||
"deltaTime": 5,
|
"deltaTime": 5,
|
||||||
"framerate": 0 // "auto" // for some reason drops to 60
|
"framerate": 120 // "auto" // for some reason drops to 60
|
||||||
},
|
},
|
||||||
"threads": {
|
"threads": {
|
||||||
"workers" : "auto",
|
"workers" : "auto",
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
// "import": "./rp_downtown_v2.json"
|
// "import": "./rp_downtown_v2.json"
|
||||||
// "import": "./ss2_medsci1.json"
|
"import": "./ss2_medsci1.json"
|
||||||
// "import": "./test_grid.json"
|
// "import": "./test_grid.json"
|
||||||
// "import": "./sh2_mcdonalds.json"
|
// "import": "./sh2_mcdonalds.json"
|
||||||
// "import": "./animal_crossing.json"
|
// "import": "./animal_crossing.json"
|
||||||
"import": "./mds_mcdonalds.json"
|
// "import": "./mds_mcdonalds.json"
|
||||||
// "import": "./gm_construct.json"
|
// "import": "./gm_construct.json"
|
||||||
}
|
}
|
||||||
@ -16,15 +16,20 @@ layout( push_constant ) uniform PushBlock {
|
|||||||
uint pass;
|
uint pass;
|
||||||
} PushConstant;
|
} PushConstant;
|
||||||
|
|
||||||
layout (binding = 3) uniform sampler2D inImage[MIPS];
|
layout (binding = 0) uniform sampler2D samplerDepth;
|
||||||
layout (binding = 4, r32f) uniform writeonly image2D outImage[MIPS];
|
layout (binding = 1) uniform sampler2D inImage[MIPS];
|
||||||
|
layout (binding = 2, r32f) uniform writeonly image2D outImage[MIPS];
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 imageSize = imageSize(outImage[PushConstant.pass]);
|
int mip = int(PushConstant.pass);
|
||||||
uvec2 pos = gl_GlobalInvocationID.xy;
|
|
||||||
if ( pos.x >= imageSize.x || pos.y >= imageSize.y ) return;
|
|
||||||
|
|
||||||
float depth = texture(inImage[PushConstant.pass], (vec2(pos) + vec2(0.5)) / imageSize).x;
|
float depth;
|
||||||
|
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
if ( mip == 0 ) {
|
||||||
|
depth = texelFetch(samplerDepth, pos, 0).r;
|
||||||
|
} else {
|
||||||
|
depth = texture(inImage[mip - 1], (vec2(gl_GlobalInvocationID.xy) + vec2(0.5)) / imageSize( outImage[mip] )).x;
|
||||||
|
}
|
||||||
|
|
||||||
imageStore(outImage[PushConstant.pass], ivec2(pos), vec4(depth));
|
imageStore(outImage[mip], pos, vec4(depth));
|
||||||
}
|
}
|
||||||
@ -51,8 +51,8 @@ bool projectSphere(vec3 C, float r, float znear, float P00, float P11, out vec4
|
|||||||
}
|
}
|
||||||
|
|
||||||
layout( push_constant ) uniform PushBlock {
|
layout( push_constant ) uniform PushBlock {
|
||||||
uint pass;
|
uint pass;
|
||||||
uint passes;
|
uint passes;
|
||||||
} PushConstant;
|
} PushConstant;
|
||||||
|
|
||||||
layout (binding = 0) uniform Camera {
|
layout (binding = 0) uniform Camera {
|
||||||
@ -73,10 +73,6 @@ layout (std140, binding = 3) buffer Objects {
|
|||||||
|
|
||||||
layout (binding = 4) uniform sampler2D samplerDepth;
|
layout (binding = 4) uniform sampler2D samplerDepth;
|
||||||
|
|
||||||
struct Frustum {
|
|
||||||
vec4 planes[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
vec4 normalizePlane( vec4 p ) {
|
vec4 normalizePlane( vec4 p ) {
|
||||||
return p / length(p.xyz);
|
return p / length(p.xyz);
|
||||||
}
|
}
|
||||||
@ -90,7 +86,7 @@ bool frustumCull( uint id ) {
|
|||||||
|
|
||||||
if ( drawCommand.indices == 0 || drawCommand.vertices == 0 ) return false;
|
if ( drawCommand.indices == 0 || drawCommand.vertices == 0 ) return false;
|
||||||
|
|
||||||
bool visible = true;
|
bool visible = false;
|
||||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||||
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * object.model;
|
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * object.model;
|
||||||
vec4 planes[6]; {
|
vec4 planes[6]; {
|
||||||
@ -104,62 +100,69 @@ bool frustumCull( uint id ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool insideFrustum = true;
|
bool insideFrustum = true;
|
||||||
for ( uint p = 0; p < 6; ++p ) {
|
for ( uint p = 0; p < 6; ++p ) {
|
||||||
float d = max(instance.bounds.min.x * planes[p].x, instance.bounds.max.x * planes[p].x)
|
float d = max(instance.bounds.min.x * planes[p].x, instance.bounds.max.x * planes[p].x)
|
||||||
+ max(instance.bounds.min.y * planes[p].y, instance.bounds.max.y * planes[p].y)
|
+ max(instance.bounds.min.y * planes[p].y, instance.bounds.max.y * planes[p].y)
|
||||||
+ max(instance.bounds.min.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
+ max(instance.bounds.min.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||||
|
|
||||||
if (d < -planes[p].w) {
|
if (d < -planes[p].w) {
|
||||||
visible = false;
|
insideFrustum = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !visible ) break;
|
|
||||||
|
if ( insideFrustum ) {
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool occlusionCull( uint id ) {
|
bool occlusionCull( uint id ) {
|
||||||
if ( PushConstant.passes == 0 ) return true;
|
if ( PushConstant.passes == 0 ) return true;
|
||||||
|
|
||||||
const DrawCommand drawCommand = drawCommands[id];
|
const DrawCommand drawCommand = drawCommands[id];
|
||||||
const Instance instance = instances[drawCommand.instanceID];
|
const Instance instance = instances[drawCommand.instanceID];
|
||||||
const Object object = objects[instance.objectID];
|
const Object object = objects[instance.objectID];
|
||||||
|
|
||||||
bool visible = true;
|
bool visible = false;
|
||||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||||
vec4 aabb;
|
vec4 aabb;
|
||||||
vec4 sphere = aabbToSphere( instance.bounds );
|
vec4 sphere = aabbToSphere( instance.bounds );
|
||||||
|
|
||||||
|
float scale = length(object.model[0].xyz);
|
||||||
vec3 center = (camera.viewport[pass].view * object.model * vec4(sphere.xyz, 1)).xyz;
|
vec3 center = (camera.viewport[pass].view * object.model * vec4(sphere.xyz, 1)).xyz;
|
||||||
float radius = (object.model * vec4(sphere.w, 0, 0, 0)).x;
|
float radius = scale * sphere.w;
|
||||||
|
|
||||||
mat4 proj = camera.viewport[pass].projection;
|
mat4 proj = camera.viewport[pass].projection;
|
||||||
float znear = proj[3][2];
|
float znear = proj[3][2];
|
||||||
float P00 = proj[0][0];
|
float P00 = proj[0][0];
|
||||||
float P11 = proj[1][1];
|
float P11 = proj[1][1];
|
||||||
if (projectSphere(center, radius, znear, P00, P11, aabb)) {
|
|
||||||
ivec2 pyramidSize = textureSize( samplerDepth, 0 );
|
if ( projectSphere( center, radius, znear, P00, P11, aabb ) ) {
|
||||||
float mips = mipLevels( pyramidSize );
|
vec2 pyramidSize = vec2(textureSize( samplerDepth, 0 ));
|
||||||
|
|
||||||
float width = (aabb.z - aabb.x) * pyramidSize.x;
|
float width = (aabb.z - aabb.x) * pyramidSize.x;
|
||||||
float height = (aabb.w - aabb.y) * pyramidSize.y;
|
float height = (aabb.w - aabb.y) * pyramidSize.y;
|
||||||
|
|
||||||
//find the mipmap level that will match the screen size of the sphere
|
float level = max(0.0, floor(log2(max(width, height))));
|
||||||
float level = floor(log2(max(width, height)));
|
|
||||||
// if ( level == mips )
|
|
||||||
--level;
|
|
||||||
level = clamp( level, 0, mips );
|
|
||||||
|
|
||||||
//sample the depth pyramid at that specific level
|
float d1 = textureLod(samplerDepth, vec2(aabb.x, aabb.y), level).x;
|
||||||
float depth = textureLod(samplerDepth, (aabb.xy + aabb.zw) * 0.5, level).x;
|
float d2 = textureLod(samplerDepth, vec2(aabb.z, aabb.y), level).x;
|
||||||
|
float d3 = textureLod(samplerDepth, vec2(aabb.x, aabb.w), level).x;
|
||||||
|
float d4 = textureLod(samplerDepth, vec2(aabb.z, aabb.w), level).x;
|
||||||
|
|
||||||
|
float depth = min(min(d1, d2), min(d3, d4)); // min for reverse-z projection, max for standard
|
||||||
float depthSphere = znear / (center.z - radius);
|
float depthSphere = znear / (center.z - radius);
|
||||||
|
|
||||||
instances[drawCommand.instanceID].bounds.padding1 = depth;
|
if ( depthSphere >= depth - DEPTH_BIAS ) {
|
||||||
instances[drawCommand.instanceID].bounds.padding2 = proj[3][2];
|
visible = true;
|
||||||
|
break;
|
||||||
//if the depth of the sphere is in front of the depth pyramid value, then the object is visible
|
}
|
||||||
visible = visible && depthSphere >= depth - DEPTH_BIAS;
|
} else {
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return visible;
|
return visible;
|
||||||
@ -170,6 +173,6 @@ void main() {
|
|||||||
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
|
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
|
||||||
|
|
||||||
bool visible = frustumCull( gID );
|
bool visible = frustumCull( gID );
|
||||||
// if ( visible ) visible = occlusionCull( gID );
|
if ( visible ) visible = occlusionCull( gID );
|
||||||
drawCommands[gID].instances = visible ? 1 : 0;
|
drawCommands[gID].instances = visible ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -237,15 +237,15 @@ namespace pod {
|
|||||||
uint32_t reserveCount = 32; // amount of elements to reserve for vectors used in this system, to-do: have it tie to a memory pool allocator
|
uint32_t reserveCount = 32; // amount of elements to reserve for vectors used in this system, to-do: have it tie to a memory pool allocator
|
||||||
|
|
||||||
// increasing these make things lag for reasons I can imagine why
|
// increasing these make things lag for reasons I can imagine why
|
||||||
uint32_t broadphaseBvhCapacity = 4; // number of bodies per leaf node
|
uint32_t broadphaseBvhCapacity = 2; // number of bodies per leaf node
|
||||||
uint32_t meshBvhCapacity = 4; // number of triangles per leaf node
|
uint32_t meshBvhCapacity = 2; // number of triangles per leaf node
|
||||||
|
|
||||||
// additionally flattens a BVH for linear iteration, rather than a recursive / stack-based traversal
|
// additionally flattens a BVH for linear iteration, rather than a recursive / stack-based traversal
|
||||||
bool flattenBvhBodies = true;
|
bool flattenBvhBodies = true;
|
||||||
bool flattenBvhMeshes = true;
|
bool flattenBvhMeshes = true;
|
||||||
|
|
||||||
// use surface area heuristics for building the BVH, rather than naive splits
|
// use surface area heuristics for building the BVH, rather than naive splits
|
||||||
bool useBvhSahBodies = true; // it actually seems slower to use these......
|
bool useBvhSahBodies = true;
|
||||||
bool useBvhSahMeshes = true;
|
bool useBvhSahMeshes = true;
|
||||||
|
|
||||||
bool useSplitBvhs = true; // creates separate BVHs for static / dynamic objects
|
bool useSplitBvhs = true; // creates separate BVHs for static / dynamic objects
|
||||||
|
|||||||
@ -56,6 +56,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
|
|
||||||
uint32_t width = this->width > 0 ? this->width : (ext::vulkan::settings::width * this->scale);
|
uint32_t width = this->width > 0 ? this->width : (ext::vulkan::settings::width * this->scale);
|
||||||
uint32_t height = this->height > 0 ? this->height : (ext::vulkan::settings::height * this->scale);
|
uint32_t height = this->height > 0 ? this->height : (ext::vulkan::settings::height * this->scale);
|
||||||
|
uint32_t mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
|
|
||||||
renderTarget.device = &device;
|
renderTarget.device = &device;
|
||||||
renderTarget.views = metadata.eyes;
|
renderTarget.views = metadata.eyes;
|
||||||
@ -148,7 +149,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
/*.usage = */ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
/*.usage = */ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
/*.blend = */false,
|
/*.blend = */false,
|
||||||
/*.samples = */1,
|
/*.samples = */1,
|
||||||
/*.mips = */1
|
/*.mips = */mips,
|
||||||
});
|
});
|
||||||
|
|
||||||
metadata.attachments["id"] = attachments.id;
|
metadata.attachments["id"] = attachments.id;
|
||||||
@ -347,19 +348,18 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL);
|
shader.aliasAttachment("scratch", this, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( false && settings::pipelines::culling ) {
|
if ( settings::pipelines::culling ) {
|
||||||
uf::stl::string computeShaderFilename = uf::io::resolveURI(uf::io::root+"/shaders/display/depth-pyramid/comp.spv");
|
uf::stl::string computeShaderFilename = uf::io::resolveURI(uf::io::root+"/shaders/display/depth-pyramid/comp.spv");
|
||||||
blitter.material.attachShader(computeShaderFilename, uf::renderer::enums::Shader::COMPUTE, "depth-pyramid");
|
blitter.material.attachShader(computeShaderFilename, uf::renderer::enums::Shader::COMPUTE, "depth-pyramid");
|
||||||
|
|
||||||
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
||||||
auto attachment = this->getAttachment("depth");
|
|
||||||
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
shader.setSpecializationConstants({
|
shader.setSpecializationConstants({
|
||||||
{ "MIPS", mips - 1 },
|
{ "MIPS", mips },
|
||||||
});
|
});
|
||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "inImage", mips - 1 },
|
{ "inImage", mips },
|
||||||
{ "outImage", mips - 1 },
|
{ "outImage", mips },
|
||||||
});
|
});
|
||||||
|
|
||||||
shader.aliasAttachment("depth", this);
|
shader.aliasAttachment("depth", this);
|
||||||
@ -373,11 +373,11 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
VK_UNREGISTER_HANDLE(view);
|
VK_UNREGISTER_HANDLE(view);
|
||||||
}
|
}
|
||||||
::depthPyramidViews.clear();
|
::depthPyramidViews.clear();
|
||||||
::depthPyramidViews.resize(mips-1);
|
::depthPyramidViews.resize(mips);
|
||||||
shader.textures.clear();
|
shader.textures.clear();
|
||||||
|
|
||||||
for ( auto i = 1; i < mips; ++i ) {
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
auto& view = ::depthPyramidViews[i-1];
|
auto& view = ::depthPyramidViews[i];
|
||||||
VkImageViewCreateInfo viewCreateInfo = {};
|
VkImageViewCreateInfo viewCreateInfo = {};
|
||||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
viewCreateInfo.pNext = NULL;
|
viewCreateInfo.pNext = NULL;
|
||||||
@ -389,22 +389,23 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
viewCreateInfo.viewType = source.viewType;
|
viewCreateInfo.viewType = source.viewType;
|
||||||
viewCreateInfo.format = source.format;
|
viewCreateInfo.format = source.format;
|
||||||
viewCreateInfo.image = source.image;
|
viewCreateInfo.image = source.image;
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateImageView(device.logicalDevice, &viewCreateInfo, nullptr, &view));
|
VK_CHECK_RESULT(vkCreateImageView(device.logicalDevice, &viewCreateInfo, nullptr, &view));
|
||||||
VK_REGISTER_HANDLE(view);
|
VK_REGISTER_HANDLE(view);
|
||||||
|
|
||||||
if ( i + 1 < mips ) {
|
|
||||||
auto& texture = shader.textures.emplace_back();
|
|
||||||
texture.aliasTexture( source );
|
|
||||||
texture.view = view;
|
|
||||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
||||||
texture.updateDescriptors();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for ( auto i = 1; i < mips; ++i ) {
|
|
||||||
auto& view = ::depthPyramidViews[i-1];
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
auto& texture = shader.textures.emplace_back();
|
auto& texture = shader.textures.emplace_back();
|
||||||
texture.aliasTexture( source );
|
texture.aliasTexture( source );
|
||||||
texture.view = view;
|
texture.view = ::depthPyramidViews[i];
|
||||||
|
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
texture.updateDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
|
auto& texture = shader.textures.emplace_back();
|
||||||
|
texture.aliasTexture( source );
|
||||||
|
texture.view = ::depthPyramidViews[i];
|
||||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
texture.updateDescriptors();
|
texture.updateDescriptors();
|
||||||
}
|
}
|
||||||
@ -444,7 +445,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( false && settings::pipelines::culling ) {
|
if ( settings::pipelines::culling ) {
|
||||||
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
descriptor.pipeline = "depth-pyramid";
|
descriptor.pipeline = "depth-pyramid";
|
||||||
descriptor.subpass = 0;
|
descriptor.subpass = 0;
|
||||||
@ -473,18 +474,19 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
|||||||
rebuild = true;
|
rebuild = true;
|
||||||
renderTarget.initialize( *renderTarget.device );
|
renderTarget.initialize( *renderTarget.device );
|
||||||
|
|
||||||
if ( false && settings::pipelines::culling ) {
|
if ( settings::pipelines::culling ) {
|
||||||
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
||||||
auto attachment = this->getAttachment("depth");
|
|
||||||
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
shader.setSpecializationConstants({
|
shader.setSpecializationConstants({
|
||||||
{ "MIPS", mips - 1 },
|
{ "MIPS", mips },
|
||||||
});
|
});
|
||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "inImage", mips - 1 },
|
{ "inImage", mips },
|
||||||
{ "outImage", mips - 1 },
|
{ "outImage", mips },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
shader.aliasAttachment("depth", this);
|
||||||
|
|
||||||
ext::vulkan::Texture2D source; source.aliasAttachment( this->getAttachment("depthPyramid") );
|
ext::vulkan::Texture2D source; source.aliasAttachment( this->getAttachment("depthPyramid") );
|
||||||
source.sampler.descriptor.reduction.enabled = true;
|
source.sampler.descriptor.reduction.enabled = true;
|
||||||
source.sampler.descriptor.reduction.mode = VK_SAMPLER_REDUCTION_MODE_MIN;
|
source.sampler.descriptor.reduction.mode = VK_SAMPLER_REDUCTION_MODE_MIN;
|
||||||
@ -494,11 +496,11 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
|||||||
VK_UNREGISTER_HANDLE(view);
|
VK_UNREGISTER_HANDLE(view);
|
||||||
}
|
}
|
||||||
::depthPyramidViews.clear();
|
::depthPyramidViews.clear();
|
||||||
::depthPyramidViews.resize(mips-1);
|
::depthPyramidViews.resize(mips);
|
||||||
shader.textures.clear();
|
shader.textures.clear();
|
||||||
|
|
||||||
for ( auto i = 1; i < mips; ++i ) {
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
auto& view = ::depthPyramidViews[i-1];
|
auto& view = ::depthPyramidViews[i];
|
||||||
VkImageViewCreateInfo viewCreateInfo = {};
|
VkImageViewCreateInfo viewCreateInfo = {};
|
||||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
viewCreateInfo.pNext = NULL;
|
viewCreateInfo.pNext = NULL;
|
||||||
@ -510,22 +512,24 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
|||||||
viewCreateInfo.viewType = source.viewType;
|
viewCreateInfo.viewType = source.viewType;
|
||||||
viewCreateInfo.format = source.format;
|
viewCreateInfo.format = source.format;
|
||||||
viewCreateInfo.image = source.image;
|
viewCreateInfo.image = source.image;
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view));
|
VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view));
|
||||||
VK_REGISTER_HANDLE(view);
|
VK_REGISTER_HANDLE(view);
|
||||||
|
|
||||||
if ( i + 1 < mips ) {
|
|
||||||
auto& texture = shader.textures.emplace_back();
|
|
||||||
texture.aliasTexture( source );
|
|
||||||
texture.view = view;
|
|
||||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
||||||
texture.updateDescriptors();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for ( auto i = 1; i < mips; ++i ) {
|
|
||||||
auto& view = ::depthPyramidViews[i-1];
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
auto& texture = shader.textures.emplace_back();
|
auto& texture = shader.textures.emplace_back();
|
||||||
texture.aliasTexture( source );
|
texture.aliasTexture( source );
|
||||||
texture.view = view;
|
texture.view = ::depthPyramidViews[i];
|
||||||
|
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
texture.updateDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
|
auto& texture = shader.textures.emplace_back();
|
||||||
|
texture.aliasTexture( source );
|
||||||
|
texture.view = ::depthPyramidViews[i];
|
||||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
texture.updateDescriptors();
|
texture.updateDescriptors();
|
||||||
}
|
}
|
||||||
@ -588,7 +592,7 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( false && settings::pipelines::culling ) {
|
if ( settings::pipelines::culling ) {
|
||||||
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
descriptor.pipeline = "depth-pyramid";
|
descriptor.pipeline = "depth-pyramid";
|
||||||
descriptor.subpass = 0;
|
descriptor.subpass = 0;
|
||||||
@ -896,55 +900,39 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// construct depth-pyramid
|
// construct depth-pyramid
|
||||||
#if 0
|
#if 1
|
||||||
if ( settings::pipelines::culling && blitter.material.hasShader("compute", "depth-pyramid") ) {
|
if ( settings::pipelines::culling && blitter.material.hasShader("compute", "depth-pyramid") ) {
|
||||||
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
||||||
// auto mips = attachment.descriptor.mips; // uf::vector::mips( pod::Vector2ui{ renderTarget.width, renderTarget.height } );
|
|
||||||
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||||
|
|
||||||
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
|
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
|
||||||
descriptor.renderMode = "";
|
descriptor.renderMode = "";
|
||||||
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
descriptor.aux = mips;
|
||||||
descriptor.pipeline = "depth-pyramid";
|
descriptor.pipeline = "depth-pyramid";
|
||||||
descriptor.bind.width = width;
|
|
||||||
descriptor.bind.height = height;
|
|
||||||
descriptor.bind.depth = metadata.eyes;
|
descriptor.bind.depth = metadata.eyes;
|
||||||
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
|
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
|
||||||
descriptor.subpass = 0;
|
descriptor.subpass = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
// transition attachments to general attachments for imageStore
|
|
||||||
VkImageSubresourceRange subresourceRange;
|
|
||||||
subresourceRange.baseMipLevel = 0;
|
|
||||||
subresourceRange.levelCount = 1;
|
|
||||||
subresourceRange.baseArrayLayer = 0;
|
|
||||||
subresourceRange.layerCount = mips;
|
|
||||||
subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
subresourceRange.layerCount = this->metadata.eyes;
|
|
||||||
|
|
||||||
auto& attachment = this->getAttachment("depth");
|
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, subresourceRange );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// dispatch compute shader
|
// dispatch compute shader
|
||||||
VkMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
VkMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
||||||
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
|
||||||
for ( auto i = 0; i < mips - 1; ++i ) {
|
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "setImageLayout" );
|
||||||
descriptor.bind.width = width >> i;
|
::transitionAttachmentsTo( this, shader, commandBuffer );
|
||||||
descriptor.bind.height = height >> i;
|
|
||||||
if ( descriptor.bind.width < 1 ) descriptor.bind.width = 1;
|
for ( auto i = 0; i < mips; ++i ) {
|
||||||
if ( descriptor.bind.height < 1 ) descriptor.bind.height = 1;
|
// for some reason it dispatches at half the width without offsetting back...
|
||||||
|
descriptor.bind.width = std::max(1u, width >> (i - 1));
|
||||||
|
descriptor.bind.height = std::max(1u, height >> (i - 1));
|
||||||
|
|
||||||
|
blitter.record(commandBuffer, descriptor, 0, i);
|
||||||
|
|
||||||
blitter.record(commandBuffer, descriptor, 0, i, frame);
|
|
||||||
vkCmdPipelineBarrier( commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 1, &memoryBarrier, 0, NULL, 0, NULL );
|
vkCmdPipelineBarrier( commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 1, &memoryBarrier, 0, NULL, 0, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "setImageLayout" );
|
||||||
// transition attachments to general attachments for imageStore
|
::transitionAttachmentsFrom( this, shader, commandBuffer );
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, subresourceRange );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// post-renderpass commands
|
// post-renderpass commands
|
||||||
@ -968,7 +956,6 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
|||||||
uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageMemoryBarrier.subresourceRange );
|
uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageMemoryBarrier.subresourceRange );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||||
texture.generateMipmaps(commandBuffer, eye);
|
texture.generateMipmaps(commandBuffer, eye);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user