From 1880a4bdf49960c3c16d9cfc971a3118c9b4bed8 Mon Sep 17 00:00:00 2001 From: emufan4568 Date: Sat, 13 Aug 2022 08:51:53 +0300 Subject: [PATCH] video_core: Minor fixes --- .../renderer_vulkan/vk_framebuffer.cpp | 2 +- .../renderer_vulkan/vk_pipeline.cpp | 5 +- .../renderer_vulkan/vk_renderpass_cache.cpp | 19 ++----- .../renderer_vulkan/vk_task_scheduler.cpp | 2 +- src/video_core/renderer_vulkan/vk_texture.cpp | 50 ++++++++++++++++--- 5 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_framebuffer.cpp b/src/video_core/renderer_vulkan/vk_framebuffer.cpp index fd587b0d1..b8780f13b 100644 --- a/src/video_core/renderer_vulkan/vk_framebuffer.cpp +++ b/src/video_core/renderer_vulkan/vk_framebuffer.cpp @@ -110,7 +110,7 @@ void Framebuffer::PrepareAttachments() { if (info.depth_stencil.IsValid()) { Texture* depth_stencil = static_cast(info.depth_stencil.Get()); - depth_stencil->Transition(command_buffer, vk::ImageLayout::eDepthAttachmentOptimal); + depth_stencil->Transition(command_buffer, vk::ImageLayout::eDepthStencilAttachmentOptimal); } } diff --git a/src/video_core/renderer_vulkan/vk_pipeline.cpp b/src/video_core/renderer_vulkan/vk_pipeline.cpp index 1857b2cab..b1f15dae4 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline.cpp @@ -266,14 +266,15 @@ Pipeline::Pipeline(Instance& instance, CommandScheduler& scheduler, PoolManager& }; const vk::PipelineColorBlendAttachmentState colorblend_attachment = { - .blendEnable = true, + .blendEnable = info.blending.blend_enable.Value(), .srcColorBlendFactor = PicaToVK::BlendFunc(info.blending.src_color_blend_factor), .dstColorBlendFactor = PicaToVK::BlendFunc(info.blending.dst_color_blend_factor), .colorBlendOp = PicaToVK::BlendEquation(info.blending.color_blend_eq), .srcAlphaBlendFactor = PicaToVK::BlendFunc(info.blending.src_alpha_blend_factor), .dstAlphaBlendFactor = PicaToVK::BlendFunc(info.blending.dst_alpha_blend_factor), .alphaBlendOp = PicaToVK::BlendEquation(info.blending.alpha_blend_eq), - .colorWriteMask = static_cast(info.blending.color_write_mask) + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA }; const vk::PipelineColorBlendStateCreateInfo color_blending = { diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index 37c78dd51..d767cfa69 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -83,7 +83,7 @@ vk::RenderPass RenderpassCache::GetRenderpass(TextureFormat color, TextureFormat const u32 color_index = static_cast(color); const u32 depth_index = (depth == TextureFormat::Undefined ? 0 : (static_cast(depth) - MAX_COLOR_FORMATS)); - ASSERT(color_index < MAX_COLOR_FORMATS && depth_index < MAX_DEPTH_FORMATS); + ASSERT(color_index <= MAX_COLOR_FORMATS && depth_index <= MAX_DEPTH_FORMATS); return cached_renderpasses[color_index][depth_index][is_clear]; } @@ -137,19 +137,6 @@ vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format de use_depth = true; } - const vk::SubpassDependency subpass_dependency = { - .srcSubpass = VK_SUBPASS_EXTERNAL, - .dstSubpass = 0, - .srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | - vk::PipelineStageFlagBits::eEarlyFragmentTests, - .dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | - vk::PipelineStageFlagBits::eEarlyFragmentTests, - .srcAccessMask = vk::AccessFlagBits::eNone, - .dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | - vk::AccessFlagBits::eDepthStencilAttachmentWrite, - .dependencyFlags = vk::DependencyFlagBits::eByRegion - }; - // We also require only one subpass const vk::SubpassDescription subpass = { .pipelineBindPoint = vk::PipelineBindPoint::eGraphics, @@ -166,8 +153,8 @@ vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format de .pAttachments = attachments.data(), .subpassCount = 1, .pSubpasses = &subpass, - .dependencyCount = 1, - .pDependencies = &subpass_dependency + .dependencyCount = 0, + .pDependencies = nullptr }; // Create the renderpass diff --git a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp index f083b8ad3..7bc7a3623 100644 --- a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp @@ -13,7 +13,7 @@ namespace VideoCore::Vulkan { // 16MB should be enough for a single frame constexpr BufferInfo STAGING_INFO = { - .capacity = 16 * 1024 * 1024, + .capacity = 32 * 1024 * 1024, .usage = BufferUsage::Staging }; diff --git a/src/video_core/renderer_vulkan/vk_texture.cpp b/src/video_core/renderer_vulkan/vk_texture.cpp index 100089fb1..150dae515 100644 --- a/src/video_core/renderer_vulkan/vk_texture.cpp +++ b/src/video_core/renderer_vulkan/vk_texture.cpp @@ -411,11 +411,17 @@ void Texture::Download(Rect2D rectangle, u32 stride, std::span data, u32 lev Buffer& staging = scheduler.GetCommandUploadBuffer(); const u64 staging_offset = staging.GetCurrentOffset(); - // TODO: Handle format convertions and depth/stencil downloads - ASSERT(aspect == vk::ImageAspectFlagBits::eColor && + if (advertised_format == vk::Format::eD24UnormS8Uint) { + ASSERT(16 * 1024 * 1024 - staging_offset >= data.size() * 2); + } else { + ASSERT(aspect == vk::ImageAspectFlagBits::eColor && advertised_format == internal_format); + } - const vk::BufferImageCopy copy_region = { + u32 region_count = 0; + std::array copy_regions; + + vk::BufferImageCopy copy_region = { .bufferOffset = staging_offset, .bufferRowLength = stride, .bufferImageHeight = rectangle.height, @@ -429,18 +435,50 @@ void Texture::Download(Rect2D rectangle, u32 stride, std::span data, u32 lev .imageExtent = {rectangle.width, rectangle.height, 1} }; + if (aspect & vk::ImageAspectFlagBits::eColor) { + copy_regions[region_count++] = copy_region; + } else if (aspect & vk::ImageAspectFlagBits::eStencil) { + // Depth aspect download + copy_region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eDepth; + copy_regions[region_count++] = copy_region; + + // Stencil aspect download + copy_region.bufferOffset += data.size(); + copy_region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eStencil; + copy_regions[region_count++] = copy_region; + } + Transition(command_buffer, vk::ImageLayout::eTransferSrcOptimal); // Copy pixel data to the staging buffer command_buffer.copyImageToBuffer(image, vk::ImageLayout::eTransferSrcOptimal, - staging.GetHandle(), copy_region); + staging.GetHandle(), region_count, copy_regions.data()); // TODO: Async downloads scheduler.Submit(true); // Copy data to the destination - auto memory = staging.Map(byte_count); - std::memcpy(data.data(), memory.data(), byte_count); + if (advertised_format == vk::Format::eD24UnormS8Uint) { + const u32 new_byte_count = data.size() + (data.size() / 4); + auto memory = staging.Map(new_byte_count); + + u32 depth_offset = 0; + u32 stencil_offset = data.size(); + for (u32 dst_offset = 0; dst_offset < byte_count; dst_offset += 4) { + float depth; + std::memcpy(&depth, memory.data() + depth_offset, sizeof(float)); + u32 depth_uint = depth * 0xFFFFFF; + + std::memcpy(data.data() + dst_offset, &depth_uint, 3); + data[dst_offset+3] = memory[stencil_offset]; + + depth_offset += 4; + stencil_offset += 1; + } + } else { + auto memory = staging.Map(byte_count); + std::memcpy(data.data(), memory.data(), byte_count); + } } Transition(command_buffer, vk::ImageLayout::eShaderReadOnlyOptimal);