Fix implicit render pass dependencies and some more validation warnings
This commit is contained in:
parent
7a53ce8db4
commit
37866a9470
4 changed files with 139 additions and 66 deletions
|
@ -455,13 +455,20 @@ 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 (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 {
|
||||
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)) {
|
||||
texture->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
@ -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));
|
||||
|
|
|
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue