Vulkan: Create depth/stencil buffers on demand

This commit is contained in:
Henrik Rydgård 2022-10-02 15:52:52 +02:00
parent f21fd36708
commit be37de106c
4 changed files with 19 additions and 9 deletions

View file

@ -1611,7 +1611,7 @@ VKRRenderPass *VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKR
renderPass = GetRenderPass(key);
VKRFramebuffer *fb = step.render.framebuffer;
framebuf = fb->Get(renderPass, step.render.renderPassType);
framebuf = fb->Get(renderPass, step.render.renderPassType, cmd);
w = fb->width;
h = fb->height;
@ -1799,7 +1799,8 @@ void VulkanQueueRunner::PerformBlit(const VKRStep &step, VkCommandBuffer cmd) {
// We can't copy only depth or only stencil unfortunately.
if (step.blit.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
_dbg_assert_(src->depth.image != VK_NULL_HANDLE);
_dbg_assert_(dst->depth.image != VK_NULL_HANDLE);
dst->EnsureDepthImage(cmd);
if (src->depth.layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
SetupTransitionToTransferSrc(src->depth, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, &recordBarrier_);

View file

@ -161,9 +161,6 @@ VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VKRRe
_dbg_assert_(tag);
CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true, tag);
if (createDepthStencilBuffer) {
CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false, tag);
}
UpdateTag(tag);
@ -172,6 +169,7 @@ VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VKRRe
}
void VKRFramebuffer::UpdateTag(const char *newTag) {
tag_ = newTag;
char name[128];
snprintf(name, sizeof(name), "fb_color_%s", tag_.c_str());
vulkan_->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, name);
@ -189,7 +187,14 @@ void VKRFramebuffer::UpdateTag(const char *newTag) {
}
}
VkFramebuffer VKRFramebuffer::Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType) {
void VKRFramebuffer::EnsureDepthImage(VkCommandBuffer initCmd) {
if (!depth.image) {
CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false, tag_.c_str());
UpdateTag(tag_.c_str());
}
}
VkFramebuffer VKRFramebuffer::Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType, VkCommandBuffer initCmd) {
if (framebuf[(int)rpType]) {
return framebuf[(int)rpType];
}
@ -201,7 +206,8 @@ VkFramebuffer VKRFramebuffer::Get(VKRRenderPass *compatibleRenderPass, RenderPas
views[0] = color.imageView;
if (hasDepth) {
_dbg_assert_(depth.imageView != VK_NULL_HANDLE);
// Make sure there's a depth buffer!
EnsureDepthImage(initCmd);
views[1] = depth.imageView;
}
fbci.renderPass = compatibleRenderPass->Get(vulkan_, rpType);

View file

@ -46,7 +46,10 @@ public:
VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VKRRenderPass *compatibleRenderPass, int _width, int _height, bool createDepthStencilBuffer, const char *tag);
~VKRFramebuffer();
VkFramebuffer Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType);
void EnsureDepthImage(VkCommandBuffer initCmd);
// Needs a command buffer in case it need to initialize the depth buffer on-demand.
VkFramebuffer Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType, VkCommandBuffer initCmd);
int width = 0;
int height = 0;

View file

@ -170,7 +170,7 @@ void UIContext::ActivateTopScissor() {
int h = std::max(0.0f, ceilf(scale_y * bounds.h));
if (x < 0 || y < 0 || x + w > pixel_xres || y + h > pixel_yres) {
// This won't actually report outside a game, but we can try.
ERROR_LOG_REPORT(G3D, "UI scissor out of bounds in %sScreen: %d,%d-%d,%d / %d,%d", screenTag_ ? screenTag_ : "N/A", x, y, w, h, pixel_xres, pixel_yres);
WARN_LOG(G3D, "UI scissor out of bounds in %sScreen: %d,%d-%d,%d / %d,%d", screenTag_ ? screenTag_ : "N/A", x, y, w, h, pixel_xres, pixel_yres);
x = std::max(0, x);
y = std::max(0, y);
w = std::min(w, pixel_xres - x);