diff options
author | ameerj <52414509+ameerj@users.noreply.github.com> | 2023-03-07 03:16:17 +0100 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2023-03-07 04:57:45 +0100 |
commit | 6b9cc0ed23b15a1b96b322b03feff2153e44a4a9 (patch) | |
tree | 6949cedbe90b6d34e2092c8eba57b243defb21dc /src/video_core/renderer_vulkan | |
parent | Merge pull request #9890 from Kelebek1/reverb_fix (diff) | |
download | yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.gz yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.bz2 yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.lz yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.xz yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.tar.zst yuzu-6b9cc0ed23b15a1b96b322b03feff2153e44a4a9.zip |
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 248 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 5 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 22 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 6 |
4 files changed, 57 insertions, 224 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f085d53a1..a00cf1569 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -770,232 +770,44 @@ bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 return buffer_cache.DMACopy(src_address, dest_address, amount); } -bool AccelerateDMA::ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info, - const Tegra::DMA::ImageOperand& src, - const Tegra::DMA::BufferOperand& dst) { +template <bool IS_IMAGE_UPLOAD> +bool AccelerateDMA::DmaBufferImageCopy(const Tegra::DMA::ImageCopy& copy_info, + const Tegra::DMA::BufferOperand& buffer_operand, + const Tegra::DMA::ImageOperand& image_operand) { std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; - auto query_image = texture_cache.ObtainImage(src, false); - if (!query_image) { + const auto image_id = texture_cache.DmaImageId(image_operand); + if (image_id == VideoCommon::NULL_IMAGE_ID) { return false; } - auto* image = query_image->first; - auto [level, base] = query_image->second; - const u32 buffer_size = static_cast<u32>(dst.pitch * dst.height); - const auto [buffer, offset] = buffer_cache.ObtainBuffer( - dst.address, buffer_size, VideoCommon::ObtainBufferSynchronize::FullSynchronize, - VideoCommon::ObtainBufferOperation::MarkAsWritten); - - const bool is_rescaled = image->IsRescaled(); - if (is_rescaled) { - image->ScaleDown(); - } - VkImageSubresourceLayers subresources{ - .aspectMask = image->AspectMask(), - .mipLevel = level, - .baseArrayLayer = base, - .layerCount = 1, - }; - const u32 bpp = VideoCore::Surface::BytesPerBlock(image->info.format); - const auto convert = [old_bpp = src.bytes_per_pixel, bpp](u32 value) { - return (old_bpp * value) / bpp; - }; - const u32 base_x = convert(src.params.origin.x.Value()); - const u32 base_y = src.params.origin.y.Value(); - const u32 length_x = convert(copy_info.length_x); - const u32 length_y = copy_info.length_y; - VkOffset3D image_offset{ - .x = static_cast<s32>(base_x), - .y = static_cast<s32>(base_y), - .z = 0, - }; - VkExtent3D image_extent{ - .width = length_x, - .height = length_y, - .depth = 1, - }; - auto buff_info(dst); - buff_info.pitch = convert(dst.pitch); - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([src_image = image->Handle(), dst_buffer = buffer->Handle(), - buffer_offset = offset, subresources, image_offset, image_extent, - buff_info](vk::CommandBuffer cmdbuf) { - const std::array buffer_copy_info{ - VkBufferImageCopy{ - .bufferOffset = buffer_offset, - .bufferRowLength = buff_info.pitch, - .bufferImageHeight = buff_info.height, - .imageSubresource = subresources, - .imageOffset = image_offset, - .imageExtent = image_extent, - }, - }; - const VkImageSubresourceRange range{ - .aspectMask = subresources.aspectMask, - .baseMipLevel = subresources.mipLevel, - .levelCount = 1, - .baseArrayLayer = subresources.baseArrayLayer, - .layerCount = 1, - }; - static constexpr VkMemoryBarrier WRITE_BARRIER{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, - }; - const std::array pre_barriers{ - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = src_image, - .subresourceRange = range, - }, - }; - const std::array post_barriers{ - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = src_image, - .subresourceRange = range, - }, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, {}, {}, pre_barriers); - cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_buffer, - buffer_copy_info); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, WRITE_BARRIER, nullptr, post_barriers); - }); - if (is_rescaled) { - image->ScaleUp(true); + const u32 buffer_size = static_cast<u32>(buffer_operand.pitch * buffer_operand.height); + static constexpr auto sync_info = VideoCommon::ObtainBufferSynchronize::FullSynchronize; + const auto post_op = IS_IMAGE_UPLOAD ? VideoCommon::ObtainBufferOperation::DoNothing + : VideoCommon::ObtainBufferOperation::MarkAsWritten; + const auto [buffer, offset] = + buffer_cache.ObtainBuffer(buffer_operand.address, buffer_size, sync_info, post_op); + + const auto [image, copy] = texture_cache.DmaBufferImageCopy( + copy_info, buffer_operand, image_operand, image_id, IS_IMAGE_UPLOAD); + const std::span copy_span{©, 1}; + + if constexpr (IS_IMAGE_UPLOAD) { + image->UploadMemory(buffer->Handle(), offset, copy_span); + } else { + image->DownloadMemory(buffer->Handle(), offset, copy_span); } return true; } +bool AccelerateDMA::ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info, + const Tegra::DMA::ImageOperand& image_operand, + const Tegra::DMA::BufferOperand& buffer_operand) { + return DmaBufferImageCopy<false>(copy_info, buffer_operand, image_operand); +} + bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info, - const Tegra::DMA::BufferOperand& src, - const Tegra::DMA::ImageOperand& dst) { - std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; - auto query_image = texture_cache.ObtainImage(dst, true); - if (!query_image) { - return false; - } - auto* image = query_image->first; - auto [level, base] = query_image->second; - const u32 buffer_size = static_cast<u32>(src.pitch * src.height); - const auto [buffer, offset] = buffer_cache.ObtainBuffer( - src.address, buffer_size, VideoCommon::ObtainBufferSynchronize::FullSynchronize, - VideoCommon::ObtainBufferOperation::DoNothing); - const bool is_rescaled = image->IsRescaled(); - if (is_rescaled) { - image->ScaleDown(true); - } - VkImageSubresourceLayers subresources{ - .aspectMask = image->AspectMask(), - .mipLevel = level, - .baseArrayLayer = base, - .layerCount = 1, - }; - const u32 bpp = VideoCore::Surface::BytesPerBlock(image->info.format); - const auto convert = [old_bpp = dst.bytes_per_pixel, bpp](u32 value) { - return (old_bpp * value) / bpp; - }; - const u32 base_x = convert(dst.params.origin.x.Value()); - const u32 base_y = dst.params.origin.y.Value(); - const u32 length_x = convert(copy_info.length_x); - const u32 length_y = copy_info.length_y; - VkOffset3D image_offset{ - .x = static_cast<s32>(base_x), - .y = static_cast<s32>(base_y), - .z = 0, - }; - VkExtent3D image_extent{ - .width = length_x, - .height = length_y, - .depth = 1, - }; - auto buff_info(src); - buff_info.pitch = convert(src.pitch); - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([dst_image = image->Handle(), src_buffer = buffer->Handle(), - buffer_offset = offset, subresources, image_offset, image_extent, - buff_info](vk::CommandBuffer cmdbuf) { - const std::array buffer_copy_info{ - VkBufferImageCopy{ - .bufferOffset = buffer_offset, - .bufferRowLength = buff_info.pitch, - .bufferImageHeight = buff_info.height, - .imageSubresource = subresources, - .imageOffset = image_offset, - .imageExtent = image_extent, - }, - }; - const VkImageSubresourceRange range{ - .aspectMask = subresources.aspectMask, - .baseMipLevel = subresources.mipLevel, - .levelCount = 1, - .baseArrayLayer = subresources.baseArrayLayer, - .layerCount = 1, - }; - static constexpr VkMemoryBarrier READ_BARRIER{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, - }; - const std::array pre_barriers{ - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = dst_image, - .subresourceRange = range, - }, - }; - const std::array post_barriers{ - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = dst_image, - .subresourceRange = range, - }, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, READ_BARRIER, {}, pre_barriers); - cmdbuf.CopyBufferToImage(src_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, buffer_copy_info); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, nullptr, nullptr, post_barriers); - }); - if (is_rescaled) { - image->ScaleUp(); - } - return true; + const Tegra::DMA::BufferOperand& buffer_operand, + const Tegra::DMA::ImageOperand& image_operand) { + return DmaBufferImageCopy<true>(copy_info, buffer_operand, image_operand); } void RasterizerVulkan::UpdateDynamicStates() { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 7746c5434..1659fbc13 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -59,6 +59,11 @@ public: const Tegra::DMA::ImageOperand& dst) override; private: + template <bool IS_IMAGE_UPLOAD> + bool DmaBufferImageCopy(const Tegra::DMA::ImageCopy& copy_info, + const Tegra::DMA::BufferOperand& src, + const Tegra::DMA::ImageOperand& dst); + BufferCache& buffer_cache; TextureCache& texture_cache; Scheduler& scheduler; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 8a204f93f..bf6389ff1 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1312,15 +1312,16 @@ Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBas Image::~Image() = default; -void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { +void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, + std::span<const VideoCommon::BufferImageCopy> copies) { // TODO: Move this to another API const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { ScaleDown(true); } scheduler->RequestOutsideRenderPassOperationContext(); - std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); - const VkBuffer src_buffer = map.buffer; + std::vector vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); + const VkBuffer src_buffer = buffer; const VkImage vk_image = *original_image; const VkImageAspectFlags vk_aspect_mask = aspect_mask; const bool is_initialized = std::exchange(initialized, true); @@ -1333,14 +1334,19 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag } } -void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { +void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { + UploadMemory(map.buffer, map.offset, copies); +} + +void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, + std::span<const VideoCommon::BufferImageCopy> copies) { const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { ScaleDown(); } - std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); + std::vector vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); scheduler->RequestOutsideRenderPassOperationContext(); - scheduler->Record([buffer = map.buffer, image = *original_image, aspect_mask = aspect_mask, + scheduler->Record([buffer, image = *original_image, aspect_mask = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -1395,6 +1401,10 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm } } +void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { + DownloadMemory(map.buffer, map.offset, copies); +} + bool Image::IsRescaled() const noexcept { return True(flags & ImageFlagBits::Rescaled); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 0ce39616f..d5ee23f8d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -132,9 +132,15 @@ public: Image(Image&&) = default; Image& operator=(Image&&) = default; + void UploadMemory(VkBuffer buffer, VkDeviceSize offset, + std::span<const VideoCommon::BufferImageCopy> copies); + void UploadMemory(const StagingBufferRef& map, std::span<const VideoCommon::BufferImageCopy> copies); + void DownloadMemory(VkBuffer buffer, VkDeviceSize offset, + std::span<const VideoCommon::BufferImageCopy> copies); + void DownloadMemory(const StagingBufferRef& map, std::span<const VideoCommon::BufferImageCopy> copies); |