Archived
1
Fork 0

Fix implicit render pass dependencies and some more validation warnings

This commit is contained in:
Joshua Goins 2022-04-04 10:38:08 -04:00
parent 7a53ce8db4
commit 37866a9470
4 changed files with 139 additions and 66 deletions

View file

@ -455,12 +455,19 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
texture->format = imageFormat;
texture->aspect = imageAspect;
if (check_flag(info.usage, GFXTextureUsage::Attachment) &&
!check_flag(info.usage, GFXTextureUsage::Sampled)) {
if (info.format == GFXPixelFormat::DEPTH_32F) {
texture->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
if (check_flag(info.usage, GFXTextureUsage::Attachment)) {
if(check_flag(info.usage, GFXTextureUsage::Sampled)) {
if (info.format == GFXPixelFormat::DEPTH_32F) {
texture->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
} else {
texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
} else {
texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (info.format == GFXPixelFormat::DEPTH_32F) {
texture->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
} else {
texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
}
} else if (check_flag(info.usage, GFXTextureUsage::Storage) &&
check_flag(info.usage, GFXTextureUsage::ShaderWrite)) {
@ -679,19 +686,6 @@ GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& info) {
for (auto& attachment : info.attachments) {
auto texture = (GFXVulkanTexture*)attachment;
attachments.push_back(texture->view);
VkImageLayout expectedLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (texture->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
expectedLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkImageSubresourceRange range = {};
range.baseMipLevel = 0;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
transitionImageLayout(texture->handle, texture->format, texture->aspect,
range, texture->layout, expectedLayout);
}
VkFramebufferCreateInfo framebufferInfo = {};
@ -724,6 +718,9 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) {
std::vector<VkAttachmentDescription> descriptions;
std::vector<VkAttachmentReference> references;
std::vector<VkSubpassDependency> dependencies;
bool hasDepthAttachment = false;
VkAttachmentDescription depthAttachment;
@ -778,6 +775,52 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) {
descriptions.push_back(attachment);
references.push_back(attachmentRef);
}
if(isDepthAttachment) {
VkSubpassDependency implicitBeginDependency;
implicitBeginDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
implicitBeginDependency.dstSubpass = 0;
implicitBeginDependency.srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
implicitBeginDependency.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
implicitBeginDependency.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
implicitBeginDependency.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
implicitBeginDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies.push_back(implicitBeginDependency);
VkSubpassDependency implicitEndDependency;
implicitEndDependency.srcSubpass = 0;
implicitEndDependency.dstSubpass = VK_SUBPASS_EXTERNAL;
implicitEndDependency.srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
implicitEndDependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
implicitEndDependency.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
implicitEndDependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
implicitEndDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies.push_back(implicitEndDependency);
} else {
VkSubpassDependency implicitBeginDependency;
implicitBeginDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
implicitBeginDependency.dstSubpass = 0;
implicitBeginDependency.srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
implicitBeginDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
implicitBeginDependency.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
implicitBeginDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
implicitBeginDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies.push_back(implicitBeginDependency);
VkSubpassDependency implicitEndDependency;
implicitEndDependency.srcSubpass = 0;
implicitEndDependency.dstSubpass = VK_SUBPASS_EXTERNAL;
implicitEndDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
implicitEndDependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
implicitEndDependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
implicitEndDependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
implicitEndDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies.push_back(implicitEndDependency);
}
}
VkSubpassDescription subpass = {};
@ -799,6 +842,8 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) {
renderPassInfo.pAttachments = descriptions.data();
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.pDependencies = dependencies.data();
renderPassInfo.dependencyCount = dependencies.size();
vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass->handle);
@ -1856,6 +1901,20 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer,
texture->layout);
}
} break;
case GFXCommandType::MemoryBarrier:
{
vkCmdPipelineBarrier(cmd,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
0,
0,
nullptr,
0,
0,
0,
nullptr);
}
break;
default:
prism::log("Unhandled GFX Command Type {}",
utility::enum_to_string(command.type));

View file

@ -121,7 +121,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
const auto extent = target.extent;
const auto render_extent = target.get_render_extent();
if(index != nullptr && !platform::is_main_window(index)) {
if (index != nullptr && !platform::is_main_window(index)) {
GFXRenderPassBeginInfo beginInfo = {};
beginInfo.render_area.extent = render_extent;
@ -133,7 +133,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->set_viewport(viewport);
for(auto& pass : passes)
for (auto &pass: passes)
pass->render_post(commandbuffer, target, index);
return;
@ -148,14 +148,14 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
controller_continuity continuity;
if(scene != nullptr) {
if (scene != nullptr) {
commandbuffer->push_group("Shadow Rendering");
shadow_pass->render(commandbuffer, *scene);
commandbuffer->pop_group();
if(render_options.enable_ibl) {
if (render_options.enable_ibl) {
commandbuffer->push_group("Scene Capture");
scene_capture->render(commandbuffer, scene);
commandbuffer->pop_group();
@ -163,17 +163,19 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->set_render_pass(beginInfo);
const auto& cameras = scene->get_all<Camera>();
for(auto& [obj, camera] : cameras) {
const auto &cameras = scene->get_all<Camera>();
for (auto&[obj, camera]: cameras) {
const bool requires_limited_perspective = render_options.enable_depth_of_field;
if(requires_limited_perspective) {
if (requires_limited_perspective) {
camera.perspective = prism::perspective(radians(camera.fov),
static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
static_cast<float>(render_extent.width) /
static_cast<float>(render_extent.height),
camera.near,
100.0f);
} else {
camera.perspective = prism::infinite_perspective(radians(camera.fov),
static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
static_cast<float>(render_extent.width) /
static_cast<float>(render_extent.height),
camera.near);
}
@ -195,7 +197,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->pop_group();
if(render_options.enable_aa) {
if (render_options.enable_aa) {
commandbuffer->push_group("SMAA");
smaa_pass->render(commandbuffer, target);
@ -203,7 +205,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->pop_group();
}
if(render_options.enable_depth_of_field && dof_pass != nullptr)
if (render_options.enable_depth_of_field && dof_pass != nullptr)
dof_pass->render(commandbuffer, *scene);
commandbuffer->push_group("Post Processing");
@ -220,9 +222,9 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
const float lum_range = render_options.max_luminance - render_options.min_luminance;
prism::float4 params = prism::float4(render_options.min_luminance,
1.0f / lum_range,
static_cast<float>(render_extent.width),
static_cast<float>(render_extent.height));
1.0f / lum_range,
static_cast<float>(render_extent.width),
static_cast<float>(render_extent.height));
commandbuffer->set_push_constant(&params, sizeof(prism::float4));
@ -234,9 +236,9 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
params = prism::float4(render_options.min_luminance,
lum_range,
std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f),
static_cast<float>(render_extent.width * render_extent.height));
lum_range,
std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f),
static_cast<float>(render_extent.width * render_extent.height));
commandbuffer->set_push_constant(&params, sizeof(prism::float4));
@ -258,12 +260,16 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->set_graphics_pipeline(post_pipeline);
if(render_options.enable_depth_of_field)
if (render_options.enable_depth_of_field)
commandbuffer->bind_texture(dof_pass->normal_field, 1);
else
commandbuffer->bind_texture(target.offscreenColorTexture, 1);
commandbuffer->bind_texture(target.blend_texture, 3);
if (render_options.enable_aa) {
commandbuffer->bind_texture(target.blend_texture, 3);
} else {
commandbuffer->bind_texture(dummy_texture, 3);
}
if(auto texture = get_requested_texture(PassTextureType::SelectionSobel))
commandbuffer->bind_texture(texture, 5);

View file

@ -62,7 +62,7 @@ void ShadowPass::create_scene_resources(Scene& scene) {
cubeTextureInfo.width = render_options.shadow_resolution;
cubeTextureInfo.height = render_options.shadow_resolution;
cubeTextureInfo.format = GFXPixelFormat::R_32F;
cubeTextureInfo.usage = GFXTextureUsage::Sampled;
cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst;
cubeTextureInfo.array_length = max_point_shadows;
cubeTextureInfo.samplingMode = SamplingMode::ClampToBorder;
cubeTextureInfo.border_color = GFXBorderColor::OpaqueWhite;
@ -78,7 +78,7 @@ void ShadowPass::create_scene_resources(Scene& scene) {
spotTextureInfo.width = render_options.shadow_resolution;
spotTextureInfo.height = render_options.shadow_resolution;
spotTextureInfo.format = GFXPixelFormat::DEPTH_32F;
spotTextureInfo.usage = GFXTextureUsage::Sampled;
spotTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst;
spotTextureInfo.array_length = max_spot_shadows;
spotTextureInfo.samplingMode = SamplingMode::ClampToBorder;
spotTextureInfo.border_color = GFXBorderColor::OpaqueWhite;
@ -215,6 +215,8 @@ void ShadowPass::render_sun(GFXCommandBuffer* command_buffer, Scene& scene, pris
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), lightPos, Light::Type::Sun, frustum, 0);
scene.sun_light_dirty = false;
command_buffer->end_render_pass();
}
}
@ -250,6 +252,7 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(light_object).get_world_position(), Light::Type::Spot, frustum, 0);
command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0);
scene.spot_light_dirty[last_spot_light] = false;
@ -295,6 +298,7 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, pr
render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum, last_point_light);
command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0);
}
@ -390,7 +394,7 @@ void ShadowPass::create_offscreen_resources() {
textureInfo.width = render_options.shadow_resolution;
textureInfo.height = render_options.shadow_resolution;
textureInfo.format = GFXPixelFormat::R_32F;
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::TransferSrc;
textureInfo.samplingMode = SamplingMode::ClampToEdge;
offscreen_color_texture = gfx->create_texture(textureInfo);

View file

@ -73,6 +73,8 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
command_buffer->bind_texture(target.offscreenDepthTexture, 1); // depth
command_buffer->draw(0, 3, 0, 1);
command_buffer->end_render_pass();
}
// blend
@ -88,6 +90,8 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
command_buffer->bind_texture(search_image, 3);
command_buffer->draw(0, 3, 0, 1);
command_buffer->end_render_pass();
}
}