repaired occlusion culling via depth pyramids

This commit is contained in:
ecker 2026-04-20 23:40:55 -05:00
parent 42aaf444ff
commit fd9036ee39
6 changed files with 124 additions and 129 deletions

View File

@ -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",

View File

@ -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"
} }

View File

@ -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));
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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);
} }