repaired occlusion culling via depth pyramids
This commit is contained in:
parent
42aaf444ff
commit
fd9036ee39
@ -4,13 +4,13 @@
|
||||
"start": "StartMenu",
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"meshes": { "interleaved": false },
|
||||
"lights": { "enabled": true,
|
||||
"lights": { "enabled": false,
|
||||
"useLightmaps": false,
|
||||
"max": 32,
|
||||
"max": 16,
|
||||
"shadows": {
|
||||
"enabled": true,
|
||||
"update": 8,
|
||||
"max": 32,
|
||||
"enabled": false,
|
||||
"update": 4,
|
||||
"max": 16,
|
||||
"samples": 2
|
||||
},
|
||||
"bloom": {
|
||||
@ -29,8 +29,8 @@
|
||||
}
|
||||
},
|
||||
"vxgi": {
|
||||
// "limiter": 0,
|
||||
"limiter": 0.0125,
|
||||
"limiter": 0,
|
||||
// "limiter": 0.0125,
|
||||
"size": 256,
|
||||
"dispatch": 16,
|
||||
"cascades": 3,
|
||||
@ -117,7 +117,7 @@
|
||||
"gui": true,
|
||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||
"hdr": true,
|
||||
"vxgi": true,
|
||||
"vxgi": false,
|
||||
"culling": true,
|
||||
"bloom": true,
|
||||
"rt": false,
|
||||
@ -355,7 +355,7 @@
|
||||
"render modes": { "gui": true, "deferred": true },
|
||||
"limiters": {
|
||||
"deltaTime": 5,
|
||||
"framerate": 0 // "auto" // for some reason drops to 60
|
||||
"framerate": 120 // "auto" // for some reason drops to 60
|
||||
},
|
||||
"threads": {
|
||||
"workers" : "auto",
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
// "import": "./rp_downtown_v2.json"
|
||||
// "import": "./ss2_medsci1.json"
|
||||
"import": "./ss2_medsci1.json"
|
||||
// "import": "./test_grid.json"
|
||||
// "import": "./sh2_mcdonalds.json"
|
||||
// "import": "./animal_crossing.json"
|
||||
"import": "./mds_mcdonalds.json"
|
||||
// "import": "./mds_mcdonalds.json"
|
||||
// "import": "./gm_construct.json"
|
||||
}
|
||||
@ -16,15 +16,20 @@ layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 3) uniform sampler2D inImage[MIPS];
|
||||
layout (binding = 4, r32f) uniform writeonly image2D outImage[MIPS];
|
||||
layout (binding = 0) uniform sampler2D samplerDepth;
|
||||
layout (binding = 1) uniform sampler2D inImage[MIPS];
|
||||
layout (binding = 2, r32f) uniform writeonly image2D outImage[MIPS];
|
||||
|
||||
void main() {
|
||||
vec2 imageSize = imageSize(outImage[PushConstant.pass]);
|
||||
uvec2 pos = gl_GlobalInvocationID.xy;
|
||||
if ( pos.x >= imageSize.x || pos.y >= imageSize.y ) return;
|
||||
int mip = int(PushConstant.pass);
|
||||
|
||||
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 {
|
||||
uint pass;
|
||||
uint passes;
|
||||
uint pass;
|
||||
uint passes;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
@ -73,10 +73,6 @@ layout (std140, binding = 3) buffer Objects {
|
||||
|
||||
layout (binding = 4) uniform sampler2D samplerDepth;
|
||||
|
||||
struct Frustum {
|
||||
vec4 planes[6];
|
||||
};
|
||||
|
||||
vec4 normalizePlane( vec4 p ) {
|
||||
return p / length(p.xyz);
|
||||
}
|
||||
@ -90,7 +86,7 @@ bool frustumCull( uint id ) {
|
||||
|
||||
if ( drawCommand.indices == 0 || drawCommand.vertices == 0 ) return false;
|
||||
|
||||
bool visible = true;
|
||||
bool visible = false;
|
||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * object.model;
|
||||
vec4 planes[6]; {
|
||||
@ -104,62 +100,69 @@ bool frustumCull( uint id ) {
|
||||
}
|
||||
}
|
||||
bool insideFrustum = true;
|
||||
for ( uint p = 0; p < 6; ++p ) {
|
||||
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.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||
|
||||
if (d < -planes[p].w) {
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !visible ) break;
|
||||
for ( uint p = 0; p < 6; ++p ) {
|
||||
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.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||
|
||||
if (d < -planes[p].w) {
|
||||
insideFrustum = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( insideFrustum ) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
bool occlusionCull( uint id ) {
|
||||
if ( PushConstant.passes == 0 ) return true;
|
||||
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[id];
|
||||
const Instance instance = instances[drawCommand.instanceID];
|
||||
const Object object = objects[instance.objectID];
|
||||
|
||||
bool visible = true;
|
||||
bool visible = false;
|
||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||
vec4 aabb;
|
||||
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;
|
||||
float radius = (object.model * vec4(sphere.w, 0, 0, 0)).x;
|
||||
float radius = scale * sphere.w;
|
||||
|
||||
mat4 proj = camera.viewport[pass].projection;
|
||||
float znear = proj[3][2];
|
||||
float P00 = proj[0][0];
|
||||
float P11 = proj[1][1];
|
||||
if (projectSphere(center, radius, znear, P00, P11, aabb)) {
|
||||
ivec2 pyramidSize = textureSize( samplerDepth, 0 );
|
||||
float mips = mipLevels( pyramidSize );
|
||||
|
||||
if ( projectSphere( center, radius, znear, P00, P11, aabb ) ) {
|
||||
vec2 pyramidSize = vec2(textureSize( samplerDepth, 0 ));
|
||||
|
||||
float width = (aabb.z - aabb.x) * pyramidSize.x;
|
||||
float height = (aabb.w - aabb.y) * pyramidSize.y;
|
||||
|
||||
//find the mipmap level that will match the screen size of the sphere
|
||||
float level = floor(log2(max(width, height)));
|
||||
// if ( level == mips )
|
||||
--level;
|
||||
level = clamp( level, 0, mips );
|
||||
float level = max(0.0, floor(log2(max(width, height))));
|
||||
|
||||
//sample the depth pyramid at that specific level
|
||||
float depth = textureLod(samplerDepth, (aabb.xy + aabb.zw) * 0.5, level).x;
|
||||
float d1 = textureLod(samplerDepth, vec2(aabb.x, aabb.y), 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);
|
||||
|
||||
instances[drawCommand.instanceID].bounds.padding1 = depth;
|
||||
instances[drawCommand.instanceID].bounds.padding2 = proj[3][2];
|
||||
|
||||
//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;
|
||||
if ( depthSphere >= depth - DEPTH_BIAS ) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return visible;
|
||||
@ -170,6 +173,6 @@ void main() {
|
||||
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
|
||||
|
||||
bool visible = frustumCull( gID );
|
||||
// if ( visible ) visible = occlusionCull( gID );
|
||||
if ( visible ) visible = occlusionCull( gID );
|
||||
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
|
||||
|
||||
// increasing these make things lag for reasons I can imagine why
|
||||
uint32_t broadphaseBvhCapacity = 4; // number of bodies per leaf node
|
||||
uint32_t meshBvhCapacity = 4; // number of triangles per leaf node
|
||||
uint32_t broadphaseBvhCapacity = 2; // number of bodies 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
|
||||
bool flattenBvhBodies = true;
|
||||
bool flattenBvhMeshes = true;
|
||||
|
||||
// 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 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 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.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,
|
||||
/*.blend = */false,
|
||||
/*.samples = */1,
|
||||
/*.mips = */1
|
||||
/*.mips = */mips,
|
||||
});
|
||||
|
||||
metadata.attachments["id"] = attachments.id;
|
||||
@ -347,19 +348,18 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
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");
|
||||
blitter.material.attachShader(computeShaderFilename, uf::renderer::enums::Shader::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 } );
|
||||
shader.setSpecializationConstants({
|
||||
{ "MIPS", mips - 1 },
|
||||
{ "MIPS", mips },
|
||||
});
|
||||
shader.setDescriptorCounts({
|
||||
{ "inImage", mips - 1 },
|
||||
{ "outImage", mips - 1 },
|
||||
{ "inImage", mips },
|
||||
{ "outImage", mips },
|
||||
});
|
||||
|
||||
shader.aliasAttachment("depth", this);
|
||||
@ -373,11 +373,11 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
VK_UNREGISTER_HANDLE(view);
|
||||
}
|
||||
::depthPyramidViews.clear();
|
||||
::depthPyramidViews.resize(mips-1);
|
||||
::depthPyramidViews.resize(mips);
|
||||
shader.textures.clear();
|
||||
|
||||
for ( auto i = 1; i < mips; ++i ) {
|
||||
auto& view = ::depthPyramidViews[i-1];
|
||||
for ( auto i = 0; i < mips; ++i ) {
|
||||
auto& view = ::depthPyramidViews[i];
|
||||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.pNext = NULL;
|
||||
@ -389,22 +389,23 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
viewCreateInfo.viewType = source.viewType;
|
||||
viewCreateInfo.format = source.format;
|
||||
viewCreateInfo.image = source.image;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImageView(device.logicalDevice, &viewCreateInfo, nullptr, &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();
|
||||
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.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.pipeline = "depth-pyramid";
|
||||
descriptor.subpass = 0;
|
||||
@ -473,18 +474,19 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
rebuild = true;
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
|
||||
if ( false && settings::pipelines::culling ) {
|
||||
if ( settings::pipelines::culling ) {
|
||||
auto& shader = blitter.material.getShader("compute", "depth-pyramid");
|
||||
auto attachment = this->getAttachment("depth");
|
||||
auto mips = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||
shader.setSpecializationConstants({
|
||||
{ "MIPS", mips - 1 },
|
||||
{ "MIPS", mips },
|
||||
});
|
||||
shader.setDescriptorCounts({
|
||||
{ "inImage", mips - 1 },
|
||||
{ "outImage", mips - 1 },
|
||||
{ "inImage", mips },
|
||||
{ "outImage", mips },
|
||||
});
|
||||
|
||||
shader.aliasAttachment("depth", this);
|
||||
|
||||
ext::vulkan::Texture2D source; source.aliasAttachment( this->getAttachment("depthPyramid") );
|
||||
source.sampler.descriptor.reduction.enabled = true;
|
||||
source.sampler.descriptor.reduction.mode = VK_SAMPLER_REDUCTION_MODE_MIN;
|
||||
@ -494,11 +496,11 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
VK_UNREGISTER_HANDLE(view);
|
||||
}
|
||||
::depthPyramidViews.clear();
|
||||
::depthPyramidViews.resize(mips-1);
|
||||
::depthPyramidViews.resize(mips);
|
||||
shader.textures.clear();
|
||||
|
||||
for ( auto i = 1; i < mips; ++i ) {
|
||||
auto& view = ::depthPyramidViews[i-1];
|
||||
for ( auto i = 0; i < mips; ++i ) {
|
||||
auto& view = ::depthPyramidViews[i];
|
||||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.pNext = NULL;
|
||||
@ -510,22 +512,24 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
viewCreateInfo.viewType = source.viewType;
|
||||
viewCreateInfo.format = source.format;
|
||||
viewCreateInfo.image = source.image;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &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();
|
||||
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.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.pipeline = "depth-pyramid";
|
||||
descriptor.subpass = 0;
|
||||
@ -896,55 +900,39 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
}
|
||||
|
||||
// construct depth-pyramid
|
||||
#if 0
|
||||
#if 1
|
||||
if ( settings::pipelines::culling && blitter.material.hasShader("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 } );
|
||||
|
||||
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
|
||||
descriptor.renderMode = "";
|
||||
descriptor.aux = uf::vector::mips( pod::Vector2ui{ width, height } );
|
||||
descriptor.aux = mips;
|
||||
descriptor.pipeline = "depth-pyramid";
|
||||
descriptor.bind.width = width;
|
||||
descriptor.bind.height = height;
|
||||
descriptor.bind.depth = metadata.eyes;
|
||||
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
|
||||
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
|
||||
VkMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
||||
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
for ( auto i = 0; i < mips - 1; ++i ) {
|
||||
descriptor.bind.width = width >> i;
|
||||
descriptor.bind.height = height >> i;
|
||||
if ( descriptor.bind.width < 1 ) descriptor.bind.width = 1;
|
||||
if ( descriptor.bind.height < 1 ) descriptor.bind.height = 1;
|
||||
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "setImageLayout" );
|
||||
::transitionAttachmentsTo( this, shader, commandBuffer );
|
||||
|
||||
for ( auto i = 0; i < mips; ++i ) {
|
||||
// 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
// transition attachments to general attachments for imageStore
|
||||
uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, subresourceRange );
|
||||
*/
|
||||
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "setImageLayout" );
|
||||
::transitionAttachmentsFrom( this, shader, commandBuffer );
|
||||
}
|
||||
#endif
|
||||
// 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 );
|
||||
#endif
|
||||
|
||||
|
||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||
texture.generateMipmaps(commandBuffer, eye);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user