diff --git a/README.md b/README.md index dc015f1d2..69f5cee75 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3925. +This is the source code for early-access 3926. ## Legal Notice diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt index 593786250..0fad24642 100755 --- a/externals/nx_tzdb/CMakeLists.txt +++ b/externals/nx_tzdb/CMakeLists.txt @@ -27,7 +27,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID) set(CAN_BUILD_NX_TZDB false) endif() -set(NX_TZDB_VERSION "220816") +set(NX_TZDB_VERSION "221202") set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip") set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp index 478b5f621..6946d970d 100755 --- a/src/core/hle/service/caps/caps.cpp +++ b/src/core/hle/service/caps/caps.cpp @@ -16,7 +16,7 @@ namespace Service::Capture { void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - auto album_manager = std::make_shared(); + auto album_manager = std::make_shared(system); server_manager->RegisterNamedService( "caps:a", std::make_shared(system, album_manager)); diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index 2df6a930a..693c4a507 100755 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -8,12 +8,15 @@ #include "common/fs/file.h" #include "common/fs/path_util.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_result.h" +#include "core/hle/service/time/time_manager.h" +#include "core/hle/service/time/time_zone_content_manager.h" namespace Service::Capture { -AlbumManager::AlbumManager() {} +AlbumManager::AlbumManager(Core::System& system_) : system{system_} {} AlbumManager::~AlbumManager() = default; @@ -83,8 +86,36 @@ Result AlbumManager::GetAlbumFileList(std::vector& out_entries, Albu } Result AlbumManager::GetAlbumFileList(std::vector& out_entries, + ContentType contex_type, s64 start_posix_time, + s64 end_posix_time, u64 aruid) { + if (!is_mounted) { + return ResultIsNotMounted; + } + + std::vector album_entries; + const auto start_date = ConvertToAlbumDateTime(start_posix_time); + const auto end_date = ConvertToAlbumDateTime(end_posix_time); + const auto result = GetAlbumFileList(album_entries, contex_type, start_date, end_date, aruid); + + if (result.IsError()) { + return result; + } + + for (const auto& album_entry : album_entries) { + ApplicationAlbumFileEntry entry{ + .entry = album_entry, + .datetime = album_entry.datetime, + .unknown = {}, + }; + out_entries.push_back(entry); + } + + return ResultSuccess; +} + +Result AlbumManager::GetAlbumFileList(std::vector& out_entries, ContentType contex_type, AlbumFileDateTime start_date, - AlbumFileDateTime end_date, u64 aruid) const { + AlbumFileDateTime end_date, u64 aruid) { if (!is_mounted) { return ResultIsNotMounted; } @@ -93,31 +124,25 @@ Result AlbumManager::GetAlbumFileList(std::vector& ou if (file_id.type != contex_type) { continue; } - if (file_id.date > start_date) { continue; } - if (file_id.date < end_date) { continue; } - if (out_entries.size() >= SdAlbumFileLimit) { break; } const auto entry_size = Common::FS::GetSize(path); - ApplicationAlbumFileEntry entry{.entry = - { - .size = entry_size, - .hash{}, - .datetime = file_id.date, - .storage = file_id.storage, - .content = contex_type, - .unknown = 1, - }, - .datetime = file_id.date, - .unknown = {}}; + ApplicationAlbumEntry entry{ + .size = entry_size, + .hash{}, + .datetime = file_id.date, + .storage = file_id.storage, + .content = contex_type, + .unknown = 1, + }; out_entries.push_back(entry); } @@ -274,12 +299,12 @@ Result AlbumManager::GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem: .application_id = static_cast(std::stoll(application, 0, 16)), .date = { - .year = static_cast(std::stoi(year)), - .month = static_cast(std::stoi(month)), - .day = static_cast(std::stoi(day)), - .hour = static_cast(std::stoi(hour)), - .minute = static_cast(std::stoi(minute)), - .second = static_cast(std::stoi(second)), + .year = static_cast(std::stoi(year)), + .month = static_cast(std::stoi(month)), + .day = static_cast(std::stoi(day)), + .hour = static_cast(std::stoi(hour)), + .minute = static_cast(std::stoi(minute)), + .second = static_cast(std::stoi(second)), .unique_id = 0, }, .storage = AlbumStorage::Sd, @@ -339,4 +364,23 @@ Result AlbumManager::LoadImage(std::span out_image, const std::filesystem::p return ResultSuccess; } + +AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { + Time::TimeZone::CalendarInfo calendar_date{}; + const auto& time_zone_manager = + system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager(); + + time_zone_manager.ToCalendarTimeWithMyRules(posix_time, calendar_date); + + return { + .year = calendar_date.time.year, + .month = calendar_date.time.month, + .day = calendar_date.time.day, + .hour = calendar_date.time.hour, + .minute = calendar_date.time.minute, + .second = calendar_date.time.second, + .unique_id = 0, + }; +} + } // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h index 8337c655c..426c3cd11 100755 --- a/src/core/hle/service/caps/caps_manager.h +++ b/src/core/hle/service/caps/caps_manager.h @@ -37,7 +37,7 @@ namespace Service::Capture { class AlbumManager { public: - explicit AlbumManager(); + explicit AlbumManager(Core::System& system_); ~AlbumManager(); Result DeleteAlbumFile(const AlbumFileId& file_id); @@ -45,8 +45,11 @@ public: Result GetAlbumFileList(std::vector& out_entries, AlbumStorage storage, u8 flags) const; Result GetAlbumFileList(std::vector& out_entries, + ContentType contex_type, s64 start_posix_time, s64 end_posix_time, + u64 aruid); + Result GetAlbumFileList(std::vector& out_entries, ContentType contex_type, AlbumFileDateTime start_date, - AlbumFileDateTime end_date, u64 aruid) const; + AlbumFileDateTime end_date, u64 aruid); Result GetAutoSavingStorage(bool& out_is_autosaving) const; Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, std::vector& out_image, const AlbumFileId& file_id, @@ -65,8 +68,12 @@ private: Result LoadImage(std::span out_image, const std::filesystem::path& path, int width, int height, ScreenShotDecoderFlag flag) const; + AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const; + bool is_mounted{}; std::unordered_map album_files; + + Core::System& system; }; } // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps_types.h b/src/core/hle/service/caps/caps_types.h index bf6061273..7fd357954 100755 --- a/src/core/hle/service/caps/caps_types.h +++ b/src/core/hle/service/caps/caps_types.h @@ -41,13 +41,13 @@ enum class ScreenShotDecoderFlag : u64 { // This is nn::capsrv::AlbumFileDateTime struct AlbumFileDateTime { - u16 year{}; - u8 month{}; - u8 day{}; - u8 hour{}; - u8 minute{}; - u8 second{}; - u8 unique_id{}; + s16 year{}; + s8 month{}; + s8 day{}; + s8 hour{}; + s8 minute{}; + s8 second{}; + s8 unique_id{}; friend constexpr bool operator==(const AlbumFileDateTime&, const AlbumFileDateTime&) = default; friend constexpr bool operator>(const AlbumFileDateTime& a, const AlbumFileDateTime& b) { diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp index 1d38b8feb..7d37f3b7f 100755 --- a/src/core/hle/service/caps/caps_u.cpp +++ b/src/core/hle/service/caps/caps_u.cpp @@ -50,22 +50,35 @@ void IAlbumApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) { void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto pid{rp.Pop()}; - const auto content_type{rp.PopEnum()}; - const auto start_posix_time{rp.Pop()}; - const auto end_posix_time{rp.Pop()}; - const auto applet_resource_user_id{rp.Pop()}; + struct Parameters { + ContentType content_type; + INSERT_PADDING_BYTES(7); + s64 start_posix_time; + s64 end_posix_time; + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; LOG_WARNING(Service_Capture, - "(STUBBED) called. pid={}, content_type={}, start_posix_time={}, " - "end_posix_time={}, applet_resource_user_id={}", - pid, content_type, start_posix_time, end_posix_time, applet_resource_user_id); + "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, " + "applet_resource_user_id={}", + parameters.content_type, parameters.start_posix_time, parameters.end_posix_time, + parameters.applet_resource_user_id); - // TODO: Translate posix to DateTime + Result result = ResultSuccess; + + if (result.IsSuccess()) { + result = manager->IsAlbumMounted(AlbumStorage::Sd); + } std::vector entries; - const Result result = - manager->GetAlbumFileList(entries, content_type, {}, {}, applet_resource_user_id); + if (result.IsSuccess()) { + result = manager->GetAlbumFileList(entries, parameters.content_type, + parameters.start_posix_time, parameters.end_posix_time, + parameters.applet_resource_user_id); + } if (!entries.empty()) { ctx.WriteBuffer(entries); @@ -78,19 +91,38 @@ void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestCo void IAlbumApplicationService::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto pid{rp.Pop()}; - const auto content_type{rp.PopEnum()}; - const auto start_date_time{rp.PopRaw()}; - const auto end_date_time{rp.PopRaw()}; - const auto applet_resource_user_id{rp.Pop()}; + struct Parameters { + ContentType content_type; + INSERT_PADDING_BYTES(1); + AlbumFileDateTime start_date_time; + AlbumFileDateTime end_date_time; + INSERT_PADDING_BYTES(6); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; LOG_WARNING(Service_Capture, - "(STUBBED) called. pid={}, content_type={}, applet_resource_user_id={}", pid, - content_type, applet_resource_user_id); + "(STUBBED) called. content_type={}, start_date={}/{}/{}, " + "end_date={}/{}/{}, applet_resource_user_id={}", + parameters.content_type, parameters.start_date_time.year, + parameters.start_date_time.month, parameters.start_date_time.day, + parameters.end_date_time.year, parameters.end_date_time.month, + parameters.end_date_time.day, parameters.applet_resource_user_id); - std::vector entries; - const Result result = manager->GetAlbumFileList(entries, content_type, start_date_time, - end_date_time, applet_resource_user_id); + Result result = ResultSuccess; + + if (result.IsSuccess()) { + result = manager->IsAlbumMounted(AlbumStorage::Sd); + } + + std::vector entries; + if (result.IsSuccess()) { + result = + manager->GetAlbumFileList(entries, parameters.content_type, parameters.start_date_time, + parameters.end_date_time, parameters.applet_resource_user_id); + } if (!entries.empty()) { ctx.WriteBuffer(entries); diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index b2f34a787..c63e3a132 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -118,6 +118,8 @@ public: void InsertUploadMemoryBarrier(); + void TransitionImageLayout(Image& image) {} + FormatProperties FormatInfo(VideoCommon::ImageType type, GLenum internal_format) const; bool HasNativeBgr() const noexcept { diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index c131816b7..d7e7352da 100755 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -456,7 +456,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler, - src_view](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + src_view](vk::CommandBuffer cmdbuf) { // TODO: Barriers const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); @@ -481,8 +481,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([this, dst_framebuffer, src_image_view, src_image, src_sampler, dst_region, - src_region, src_size, pipeline, - layout](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + src_region, src_size, pipeline, layout](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, src_image, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL); BeginRenderPass(cmdbuf, dst_framebuffer); const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); @@ -515,7 +514,7 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key); scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view, - src_stencil_view, this](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + src_stencil_view, this](vk::CommandBuffer cmdbuf) { // TODO: Barriers const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, @@ -591,17 +590,17 @@ void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_ma const VkPipeline pipeline = FindOrEmplaceClearColorPipeline(key); const VkPipelineLayout layout = *clear_color_pipeline_layout; scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record([pipeline, layout, color_mask, clear_color, - dst_region](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - const std::array blend_color = { - (color_mask & 0x1) ? 1.0f : 0.0f, (color_mask & 0x2) ? 1.0f : 0.0f, - (color_mask & 0x4) ? 1.0f : 0.0f, (color_mask & 0x8) ? 1.0f : 0.0f}; - cmdbuf.SetBlendConstants(blend_color.data()); - BindBlitState(cmdbuf, dst_region); - cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_color); - cmdbuf.Draw(3, 1, 0, 0); - }); + scheduler.Record( + [pipeline, layout, color_mask, clear_color, dst_region](vk::CommandBuffer cmdbuf) { + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + const std::array blend_color = { + (color_mask & 0x1) ? 1.0f : 0.0f, (color_mask & 0x2) ? 1.0f : 0.0f, + (color_mask & 0x4) ? 1.0f : 0.0f, (color_mask & 0x8) ? 1.0f : 0.0f}; + cmdbuf.SetBlendConstants(blend_color.data()); + BindBlitState(cmdbuf, dst_region); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_color); + cmdbuf.Draw(3, 1, 0, 0); + }); scheduler.InvalidateState(); } @@ -618,15 +617,14 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key); const VkPipelineLayout layout = *clear_color_pipeline_layout; scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record( - [pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - constexpr std::array blend_constants{0.0f, 0.0f, 0.0f, 0.0f}; - cmdbuf.SetBlendConstants(blend_constants.data()); - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - BindBlitState(cmdbuf, dst_region); - cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth); - cmdbuf.Draw(3, 1, 0, 0); - }); + scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) { + constexpr std::array blend_constants{0.0f, 0.0f, 0.0f, 0.0f}; + cmdbuf.SetBlendConstants(blend_constants.data()); + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + BindBlitState(cmdbuf, dst_region); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth); + cmdbuf.Draw(3, 1, 0, 0); + }); scheduler.InvalidateState(); } @@ -638,8 +636,7 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb const VkExtent2D extent = GetConversionExtent(src_image_view); scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { const VkOffset2D offset{ .x = 0, .y = 0, @@ -685,7 +682,7 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, - this](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + this](vk::CommandBuffer cmdbuf) { const VkOffset2D offset{ .x = 0, .y = 0, diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index e29e1f8f3..fd013e35c 100755 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -239,7 +239,7 @@ void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& fr memory_allocator.CreateBuffer(dst_buffer_info, MemoryUsage::Download); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([&](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([&](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index a72eb9c4a..40bf52db1 100755 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -202,44 +202,43 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, .depth = 1, }, }; - scheduler.Record( - [this, copy, index = image_index](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - const VkImage image = *raw_images[index]; - const VkImageMemoryBarrier base_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = 0, - .dstAccessMask = 0, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = image, - .subresourceRange{ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }; - VkImageMemoryBarrier read_barrier = base_barrier; - read_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; - read_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - read_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + scheduler.Record([this, copy, index = image_index](vk::CommandBuffer cmdbuf) { + const VkImage image = *raw_images[index]; + const VkImageMemoryBarrier base_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = 0, + .dstAccessMask = 0, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange{ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + VkImageMemoryBarrier read_barrier = base_barrier; + read_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + read_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + read_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - VkImageMemoryBarrier write_barrier = base_barrier; - write_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - write_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + VkImageMemoryBarrier write_barrier = base_barrier; + write_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + write_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, read_barrier); - cmdbuf.CopyBufferToImage(*buffer, image, VK_IMAGE_LAYOUT_GENERAL, copy); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - 0, write_barrier); - }); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, + read_barrier); + cmdbuf.CopyBufferToImage(*buffer, image, VK_IMAGE_LAYOUT_GENERAL, copy); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, write_barrier); + }); } const auto anti_alias_pass = Settings::values.anti_aliasing.GetValue(); @@ -252,7 +251,7 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, .height = (up_scale * framebuffer.height) >> down_shift, }; scheduler.Record([this, index = image_index, size, - anti_alias_pass](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + anti_alias_pass](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier base_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -377,7 +376,7 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, } scheduler.Record([this, host_framebuffer, index = image_index, - size = render_area](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + size = render_area](vk::CommandBuffer cmdbuf) { const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f; const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f; const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f; diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 7c7cb2005..9678eb5bb 100755 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -179,8 +179,7 @@ public: if (!host_visible) { scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([src_buffer = staging.buffer, src_offset = staging.offset, - dst_buffer = *buffer, - size_bytes](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + dst_buffer = *buffer, size_bytes](vk::CommandBuffer cmdbuf) { const VkBufferCopy copy{ .srcOffset = src_offset, .dstOffset = 0, @@ -211,10 +210,9 @@ public: const size_t sub_first_offset = static_cast(first % 4) * GetQuadsNum(num_indices); const size_t offset = (sub_first_offset + GetQuadsNum(first)) * 6ULL * BytesPerIndex(index_type); - scheduler.Record( - [buffer_ = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.BindIndexBuffer(buffer_, offset, index_type_); - }); + scheduler.Record([buffer_ = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf) { + cmdbuf.BindIndexBuffer(buffer_, offset, index_type_); + }); } protected: @@ -402,26 +400,25 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer, boost::container::small_vector vk_copies(copies.size()); std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy); if (src_buffer == staging_pool.StreamBuf() && can_reorder_upload) { - scheduler.Record([src_buffer, dst_buffer, vk_copies](vk::CommandBuffer, - vk::CommandBuffer upload_cmdbuf) { + scheduler.RecordWithUploadBuffer([src_buffer, dst_buffer, vk_copies]( + vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) { upload_cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies); }); return; } scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record( - [src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - if (barrier) { - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); - } - cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies); - if (barrier) { - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); - } - }); + scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) { + if (barrier) { + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); + } + cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies); + if (barrier) { + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); + } + }); } void BufferCacheRuntime::PreCopyBarrier() { @@ -432,7 +429,7 @@ void BufferCacheRuntime::PreCopyBarrier() { .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, }; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); }); @@ -446,7 +443,7 @@ void BufferCacheRuntime::PostCopyBarrier() { .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, }; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); }); @@ -470,14 +467,13 @@ void BufferCacheRuntime::ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t si }; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record( - [dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); - cmdbuf.FillBuffer(dest_buffer, offset, size, value); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); - }); + scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) { + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, READ_BARRIER); + cmdbuf.FillBuffer(dest_buffer, offset, size, value); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + 0, WRITE_BARRIER); + }); } void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat index_format, @@ -502,16 +498,15 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat ReserveNullBuffer(); vk_buffer = *null_buffer; } - scheduler.Record( - [vk_buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.BindIndexBuffer(vk_buffer, vk_offset, vk_index_type); - }); + scheduler.Record([vk_buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf) { + cmdbuf.BindIndexBuffer(vk_buffer, vk_offset, vk_index_type); + }); } void BufferCacheRuntime::BindQuadIndexBuffer(PrimitiveTopology topology, u32 first, u32 count) { if (count == 0) { ReserveNullBuffer(); - scheduler.Record([this](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this](vk::CommandBuffer cmdbuf) { cmdbuf.BindIndexBuffer(*null_buffer, 0, VK_INDEX_TYPE_UINT32); }); return; @@ -532,20 +527,19 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset return; } if (device.IsExtExtendedDynamicStateSupported()) { - scheduler.Record( - [index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0; - const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; - const VkDeviceSize vk_stride = stride; - cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride); - }); + scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) { + const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0; + const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; + const VkDeviceSize vk_stride = stride; + cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride); + }); } else { if (!device.HasNullDescriptor() && buffer == VK_NULL_HANDLE) { ReserveNullBuffer(); buffer = *null_buffer; offset = 0; } - scheduler.Record([index, buffer, offset](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([index, buffer, offset](vk::CommandBuffer cmdbuf) { cmdbuf.BindVertexBuffer(index, buffer, offset); }); } @@ -567,8 +561,7 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings& bi } if (device.IsExtExtendedDynamicStateSupported()) { scheduler.Record([this, bindings_ = std::move(bindings), - buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, std::min(bindings_.max_index - bindings_.min_index, device.GetMaxVertexInputBindings()), @@ -577,8 +570,7 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings& bi }); } else { scheduler.Record([this, bindings_ = std::move(bindings), - buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { cmdbuf.BindVertexBuffers(bindings_.min_index, std::min(bindings_.max_index - bindings_.min_index, device.GetMaxVertexInputBindings()), @@ -601,7 +593,7 @@ void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, offset = 0; size = 0; } - scheduler.Record([index, buffer, offset, size](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([index, buffer, offset, size](vk::CommandBuffer cmdbuf) { const VkDeviceSize vk_offset = offset; const VkDeviceSize vk_size = size; cmdbuf.BindTransformFeedbackBuffersEXT(index, 1, &buffer, &vk_offset, &vk_size); @@ -617,8 +609,8 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings< for (u32 index = 0; index < bindings.buffers.size(); ++index) { buffer_handles.push_back(bindings.buffers[index]->Handle()); } - scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles)]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([bindings_ = std::move(bindings), + buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast(buffer_handles_.size()), buffer_handles_.data(), bindings_.offsets.data(), bindings_.sizes.data()); @@ -649,7 +641,7 @@ void BufferCacheRuntime::ReserveNullBuffer() { } scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([buffer = *null_buffer](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([buffer = *null_buffer](vk::CommandBuffer cmdbuf) { cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0); }); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 84ed2d383..81c8b5f17 100755 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -324,23 +324,22 @@ std::pair Uint8Pass::Assemble(u32 num_vertices, VkBuffer const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record( - [this, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - static constexpr u32 DISPATCH_SIZE = 1024; - static constexpr VkMemoryBarrier WRITE_BARRIER{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - }; - const VkDescriptorSet set = descriptor_allocator.Commit(); - device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); - cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); - cmdbuf.Dispatch(Common::DivCeil(num_vertices, DISPATCH_SIZE), 1, 1); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, WRITE_BARRIER); - }); + scheduler.Record([this, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf) { + static constexpr u32 DISPATCH_SIZE = 1024; + static constexpr VkMemoryBarrier WRITE_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + }; + const VkDescriptorSet set = descriptor_allocator.Commit(); + device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); + cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); + cmdbuf.Dispatch(Common::DivCeil(num_vertices, DISPATCH_SIZE), 1, 1); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, WRITE_BARRIER); + }); return {staging.buffer, staging.offset}; } @@ -384,7 +383,7 @@ std::pair QuadIndexedPass::Assemble( scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([this, descriptor_data, num_tri_vertices, base_vertex, index_shift, - is_strip](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + is_strip](vk::CommandBuffer cmdbuf) { static constexpr u32 DISPATCH_SIZE = 1024; static constexpr VkMemoryBarrier WRITE_BARRIER{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, @@ -424,7 +423,7 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_ const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([this, descriptor_data](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this, descriptor_data](vk::CommandBuffer cmdbuf) { static constexpr VkMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, .pNext = nullptr, @@ -484,7 +483,7 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([this, descriptor_data, min_accumulation_limit, max_accumulation_limit, - runs_to_do, used_offset](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + runs_to_do, used_offset](vk::CommandBuffer cmdbuf) { static constexpr VkMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, .pNext = nullptr, @@ -549,8 +548,8 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, const VkImageAspectFlags aspect_mask = image.AspectMask(); const VkImage vk_image = image.Handle(); const bool is_initialized = image.ExchangeInitialization(); - scheduler.Record([vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([vk_pipeline, vk_image, aspect_mask, + is_initialized](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier image_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -593,7 +592,7 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, ASSERT(params.destination == (std::array{0, 0, 0})); ASSERT(params.bytes_per_block_log2 == 4); scheduler.Record([this, num_dispatches_x, num_dispatches_y, num_dispatches_z, block_dims, - params, descriptor_data](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + params, descriptor_data](vk::CommandBuffer cmdbuf) { const AstcPushConstants uniforms{ .blocks_dims = block_dims, .layer_stride = params.layer_stride, @@ -609,7 +608,7 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, cmdbuf.Dispatch(num_dispatches_x, num_dispatches_y, num_dispatches_z); }); } - scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier image_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -700,7 +699,7 @@ void MSAACopyPass::CopyImage(Image& dst_image, Image& src_image, }; scheduler.Record([this, dst = dst_image.Handle(), msaa_pipeline, num_dispatches, - descriptor_data](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + descriptor_data](vk::CommandBuffer cmdbuf) { const VkDescriptorSet set = descriptor_allocator.Commit(); device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, msaa_pipeline); diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 9ab3161f7..42a3e8fae 100755 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -199,15 +199,15 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, if (!is_built.load(std::memory_order::relaxed)) { // Wait for the pipeline to be built - scheduler.Record([this](vk::CommandBuffer, vk::CommandBuffer) { + scheduler.Record([this](vk::CommandBuffer) { std::unique_lock lock{build_mutex}; build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); }); } const void* const descriptor_data{guest_descriptor_queue.UpdateData()}; const bool is_rescaling = !info.texture_descriptors.empty() || !info.image_descriptors.empty(); - scheduler.Record([this, descriptor_data, is_rescaling, rescaling_data = rescaling.Data()]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this, descriptor_data, is_rescaling, + rescaling_data = rescaling.Data()](vk::CommandBuffer cmdbuf) { cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); if (!descriptor_set_layout) { return; diff --git a/src/video_core/renderer_vulkan/vk_fsr.cpp b/src/video_core/renderer_vulkan/vk_fsr.cpp index 029100e6f..e0bf4e679 100755 --- a/src/video_core/renderer_vulkan/vk_fsr.cpp +++ b/src/video_core/renderer_vulkan/vk_fsr.cpp @@ -38,8 +38,7 @@ VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView imag UpdateDescriptorSet(image_index, image_view); - scheduler.Record([this, image_index, input_image_extent, crop_rect](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([this, image_index, input_image_extent, crop_rect](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier base_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 83604690a..0f82316a3 100755 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -493,7 +493,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling, if (!is_built.load(std::memory_order::relaxed)) { // Wait for the pipeline to be built - scheduler.Record([this](vk::CommandBuffer, vk::CommandBuffer) { + scheduler.Record([this](vk::CommandBuffer) { std::unique_lock lock{build_mutex}; build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); }); @@ -502,43 +502,42 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling, const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)}; const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)}; const void* const descriptor_data{guest_descriptor_queue.UpdateData()}; - scheduler.Record( - [this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), is_rescaling, - update_rescaling, uses_render_area = render_area.uses_render_area, - render_area_data = render_area.words](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - if (bind_pipeline) { - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); - } + scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), + is_rescaling, update_rescaling, + uses_render_area = render_area.uses_render_area, + render_area_data = render_area.words](vk::CommandBuffer cmdbuf) { + if (bind_pipeline) { + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + } + cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, + RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data), + rescaling_data.data()); + if (update_rescaling) { + const f32 config_down_factor{Settings::values.resolution_info.down_factor}; + const f32 scale_down_factor{is_rescaling ? config_down_factor : 1.0f}; cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, - RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data), - rescaling_data.data()); - if (update_rescaling) { - const f32 config_down_factor{Settings::values.resolution_info.down_factor}; - const f32 scale_down_factor{is_rescaling ? config_down_factor : 1.0f}; - cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, - RESCALING_LAYOUT_DOWN_FACTOR_OFFSET, sizeof(scale_down_factor), - &scale_down_factor); - } - if (uses_render_area) { - cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, - RENDERAREA_LAYOUT_OFFSET, sizeof(render_area_data), - &render_area_data); - } - if (!descriptor_set_layout) { - return; - } - if (uses_push_descriptor) { - cmdbuf.PushDescriptorSetWithTemplateKHR(*descriptor_update_template, - *pipeline_layout, 0, descriptor_data); - } else { - const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()}; - const vk::Device& dev{device.GetLogical()}; - dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, - descriptor_data); - cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0, - descriptor_set, nullptr); - } - }); + RESCALING_LAYOUT_DOWN_FACTOR_OFFSET, sizeof(scale_down_factor), + &scale_down_factor); + } + if (uses_render_area) { + cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, + RENDERAREA_LAYOUT_OFFSET, sizeof(render_area_data), + &render_area_data); + } + if (!descriptor_set_layout) { + return; + } + if (uses_push_descriptor) { + cmdbuf.PushDescriptorSetWithTemplateKHR(*descriptor_update_template, *pipeline_layout, + 0, descriptor_data); + } else { + const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()}; + const vk::Device& dev{device.GetLogical()}; + dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, descriptor_data); + cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0, + descriptor_set, nullptr); + } + }); } void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 5ba2b3bb3..2ef36583b 100755 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -165,7 +165,7 @@ void PresentManager::Present(Frame* frame) { return; } - scheduler.Record([this, frame](vk::CommandBuffer, vk::CommandBuffer) { + scheduler.Record([this, frame](vk::CommandBuffer) { std::unique_lock lock{queue_mutex}; present_queue.push(frame); frame_cv.notify_one(); diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 17f25ba42..d6237cb4b 100755 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -138,10 +138,9 @@ public: }; accumulation_buffer = memory_allocator.CreateBuffer(buffer_ci, MemoryUsage::DeviceLocal); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record( - [buffer = *accumulation_buffer](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.FillBuffer(buffer, 0, 8, 0); - }); + scheduler.Record([buffer = *accumulation_buffer](vk::CommandBuffer cmdbuf) { + cmdbuf.FillBuffer(buffer, 0, 8, 0); + }); } ~SamplesStreamer() = default; @@ -151,8 +150,8 @@ public: return; } ReserveHostQuery(); - scheduler.Record([query_pool = current_query_pool, query_index = current_bank_slot]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([query_pool = current_query_pool, + query_index = current_bank_slot](vk::CommandBuffer cmdbuf) { const bool use_precise = Settings::IsGPULevelHigh(); cmdbuf.BeginQuery(query_pool, static_cast(query_index), use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0); @@ -164,8 +163,8 @@ public: if (!has_started) { return; } - scheduler.Record([query_pool = current_query_pool, query_index = current_bank_slot]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([query_pool = current_query_pool, + query_index = current_bank_slot](vk::CommandBuffer cmdbuf) { cmdbuf.EndQuery(query_pool, static_cast(query_index)); }); has_started = false; @@ -228,8 +227,8 @@ public: auto& resolve_buffer = buffers[resolve_buffer_index]; VkQueryPool query_pool = bank->GetInnerPool(); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([start, amount, base_offset, query_pool, buffer = *resolve_buffer]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([start, amount, base_offset, query_pool, + buffer = *resolve_buffer](vk::CommandBuffer cmdbuf) { const VkBufferMemoryBarrier copy_query_pool_barrier{ .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .pNext = nullptr, @@ -292,10 +291,9 @@ public: } else { scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record( - [buffer = *accumulation_buffer](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.FillBuffer(buffer, 0, 8, 0); - }); + scheduler.Record([buffer = *accumulation_buffer](vk::CommandBuffer cmdbuf) { + cmdbuf.FillBuffer(buffer, 0, 8, 0); + }); } ReplicateCurrentQueryIfNeeded(); @@ -611,7 +609,7 @@ public: void Sync(StagingBufferRef& stagging_buffer, size_t extra_offset, size_t start, size_t size) { scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([this, dst_buffer = stagging_buffer.buffer, extra_offset, start, - size](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + size](vk::CommandBuffer cmdbuf) { std::array copy{VkBufferCopy{ .srcOffset = start * QUERY_SIZE, .dstOffset = extra_offset, @@ -796,7 +794,7 @@ public: .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, }; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); }); @@ -844,14 +842,13 @@ private: } has_flushed_end_pending = true; if (!has_started || buffers_count == 0) { - scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); }); UpdateBuffers(); return; } - scheduler.Record([this, total = static_cast(buffers_count)](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([this, total = static_cast(buffers_count)](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, total, counter_buffers.data(), offsets.data()); }); UpdateBuffers(); @@ -865,12 +862,12 @@ private: has_flushed_end_pending = false; if (buffers_count == 0) { - scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.EndTransformFeedbackEXT(0, 0, nullptr, nullptr); }); } else { - scheduler.Record([this, total = static_cast(buffers_count)]( - vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this, + total = static_cast(buffers_count)](vk::CommandBuffer cmdbuf) { cmdbuf.EndTransformFeedbackEXT(0, total, counter_buffers.data(), offsets.data()); }); } @@ -922,7 +919,7 @@ private: scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([dst_buffer = current_bank->GetBuffer(), src_buffer = counter_buffers[stream], src_offset = offsets[stream], - slot](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + slot](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); std::array copy{VkBufferCopy{ @@ -1257,9 +1254,8 @@ void QueryCacheRuntime::PauseHostConditionalRendering() { return; } if (impl->is_hcr_running) { - impl->scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.EndConditionalRenderingEXT(); - }); + impl->scheduler.Record( + [](vk::CommandBuffer cmdbuf) { cmdbuf.EndConditionalRenderingEXT(); }); } impl->is_hcr_running = false; } @@ -1269,10 +1265,9 @@ void QueryCacheRuntime::ResumeHostConditionalRendering() { return; } if (!impl->is_hcr_running) { - impl->scheduler.Record( - [hcr_setup = impl->hcr_setup](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.BeginConditionalRenderingEXT(hcr_setup); - }); + impl->scheduler.Record([hcr_setup = impl->hcr_setup](vk::CommandBuffer cmdbuf) { + cmdbuf.BeginConditionalRenderingEXT(hcr_setup); + }); } impl->is_hcr_running = true; } @@ -1442,12 +1437,12 @@ void QueryCacheRuntime::Barriers(bool is_prebarrier) { .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, }; if (is_prebarrier) { - impl->scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + impl->scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); }); } else { - impl->scheduler.Record([](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + impl->scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); }); @@ -1542,14 +1537,13 @@ void QueryCacheRuntime::SyncValues(std::span values, VkBuffer ba } impl->scheduler.RequestOutsideRenderPassOperationContext(); - impl->scheduler.Record( - [src_buffer, dst_buffers = std::move(impl->buffers_to_upload_to), - vk_copies = std::move(impl->copies_setup)](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - size_t size = dst_buffers.size(); - for (size_t i = 0; i < size; i++) { - cmdbuf.CopyBuffer(src_buffer, dst_buffers[i].first, vk_copies[i]); - } - }); + impl->scheduler.Record([src_buffer, dst_buffers = std::move(impl->buffers_to_upload_to), + vk_copies = std::move(impl->copies_setup)](vk::CommandBuffer cmdbuf) { + size_t size = dst_buffers.size(); + for (size_t i = 0; i < size; i++) { + cmdbuf.CopyBuffer(src_buffer, dst_buffers[i].first, vk_copies[i]); + } + }); } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 169cc7e83..3fe6c95d7 100755 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -216,7 +216,7 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) { const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); const u32 num_instances{instance_count}; const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed)}; - scheduler.Record([draw_params](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) { if (draw_params.is_indexed) { cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances, draw_params.first_index, draw_params.base_vertex, @@ -238,7 +238,7 @@ void RasterizerVulkan::DrawIndirect() { const auto& offset = indirect_buffer.second; if (params.is_byte_count) { scheduler.Record([buffer_obj = buffer->Handle(), offset, - stride = params.stride](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + stride = params.stride](vk::CommandBuffer cmdbuf) { cmdbuf.DrawIndirectByteCountEXT(1, 0, buffer_obj, offset, 0, static_cast(stride)); }); @@ -250,7 +250,7 @@ void RasterizerVulkan::DrawIndirect() { const auto& offset_base = count.second; scheduler.Record([draw_buffer_obj = draw_buffer->Handle(), buffer_obj = buffer->Handle(), offset_base, offset, - params](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + params](vk::CommandBuffer cmdbuf) { if (params.is_indexed) { cmdbuf.DrawIndexedIndirectCount( buffer_obj, offset, draw_buffer_obj, offset_base, @@ -263,8 +263,7 @@ void RasterizerVulkan::DrawIndirect() { }); return; } - scheduler.Record([buffer_obj = buffer->Handle(), offset, params](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([buffer_obj = buffer->Handle(), offset, params](vk::CommandBuffer cmdbuf) { if (params.is_indexed) { cmdbuf.DrawIndexedIndirect(buffer_obj, offset, static_cast(params.max_draw_counts), @@ -388,8 +387,7 @@ void RasterizerVulkan::Clear(u32 layer_count) { if (regs.clear_surface.R && regs.clear_surface.G && regs.clear_surface.B && regs.clear_surface.A) { - scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) { const VkClearAttachment attachment{ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .colorAttachment = color_attachment, @@ -436,7 +434,7 @@ void RasterizerVulkan::Clear(u32 layer_count) { regs.stencil_front_func_mask, dst_region); } else { scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, - clear_rect, aspect_flags](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) { VkClearAttachment attachment; attachment.aspectMask = aspect_flags; attachment.colorAttachment = 0; @@ -468,16 +466,14 @@ void RasterizerVulkan::DispatchCompute() { buffer_cache.ObtainBuffer(*indirect_address, 12, sync_info, post_op); scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([indirect_buffer = buffer->Handle(), - indirect_offset = offset](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + indirect_offset = offset](vk::CommandBuffer cmdbuf) { cmdbuf.DispatchIndirect(indirect_buffer, indirect_offset); }); return; } const std::array dim{qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([dim](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.Dispatch(dim[0], dim[1], dim[2]); - }); + scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); }); } void RasterizerVulkan::ResetCounter(VideoCommon::QueryType type) { @@ -695,7 +691,7 @@ void RasterizerVulkan::WaitForIdle() { query_cache.NotifyWFI(); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([event = *wfi_event, flags](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([event = *wfi_event, flags](vk::CommandBuffer cmdbuf) { cmdbuf.SetEvent(event, flags); cmdbuf.WaitEvents(event, flags, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, {}, {}, {}); }); @@ -953,9 +949,7 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg .minDepth = 0.0f, .maxDepth = 1.0f, }; - scheduler.Record([viewport](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetViewport(0, viewport); - }); + scheduler.Record([viewport](vk::CommandBuffer cmdbuf) { cmdbuf.SetViewport(0, viewport); }); return; } const bool is_rescaling{texture_cache.IsRescaling()}; @@ -970,7 +964,7 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg GetViewportState(device, regs, 12, scale), GetViewportState(device, regs, 13, scale), GetViewportState(device, regs, 14, scale), GetViewportState(device, regs, 15, scale), }; - scheduler.Record([this, viewport_list](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this, viewport_list](vk::CommandBuffer cmdbuf) { const u32 num_viewports = std::min(device.GetMaxViewports(), Maxwell::NumViewports); const vk::Span viewports(viewport_list.data(), num_viewports); cmdbuf.SetViewport(0, viewports); @@ -1005,7 +999,7 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs GetScissorState(regs, 14, up_scale, down_shift), GetScissorState(regs, 15, up_scale, down_shift), }; - scheduler.Record([this, scissor_list](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([this, scissor_list](vk::CommandBuffer cmdbuf) { const u32 num_scissors = std::min(device.GetMaxViewports(), Maxwell::NumViewports); const vk::Span scissors(scissor_list.data(), num_scissors); cmdbuf.SetScissor(0, scissors); @@ -1038,23 +1032,22 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { units = static_cast(static_cast(units) * rescale_factor); return false; })(); - scheduler.Record( - [constant = units, clamp = regs.depth_bias_clamp, factor = regs.slope_scale_depth_bias, - force_unorm, - precise = device.HasExactDepthBiasControl()](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - if (force_unorm) { - VkDepthBiasRepresentationInfoEXT info{ - .sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT, - .pNext = nullptr, - .depthBiasRepresentation = - VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT, - .depthBiasExact = precise ? VK_TRUE : VK_FALSE, - }; - cmdbuf.SetDepthBias(constant, clamp, factor, &info); - return; - } - cmdbuf.SetDepthBias(constant, clamp, factor); - }); + scheduler.Record([constant = units, clamp = regs.depth_bias_clamp, + factor = regs.slope_scale_depth_bias, force_unorm, + precise = device.HasExactDepthBiasControl()](vk::CommandBuffer cmdbuf) { + if (force_unorm) { + VkDepthBiasRepresentationInfoEXT info{ + .sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT, + .pNext = nullptr, + .depthBiasRepresentation = + VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT, + .depthBiasExact = precise ? VK_TRUE : VK_FALSE, + }; + cmdbuf.SetDepthBias(constant, clamp, factor, &info); + return; + } + cmdbuf.SetDepthBias(constant, clamp, factor); + }); } void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1063,19 +1056,16 @@ void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& reg } const std::array blend_color = {regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a}; - scheduler.Record([blend_color](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetBlendConstants(blend_color.data()); - }); + scheduler.Record( + [blend_color](vk::CommandBuffer cmdbuf) { cmdbuf.SetBlendConstants(blend_color.data()); }); } void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchDepthBounds()) { return; } - scheduler.Record([min = regs.depth_bounds[0], - max = regs.depth_bounds[1]](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetDepthBounds(min, max); - }); + scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( + vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBounds(min, max); }); } void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1103,8 +1093,7 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) } } scheduler.Record([front_ref = regs.stencil_front_ref, back_ref = regs.stencil_back_ref, - two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf) { const bool set_back = two_sided && front_ref != back_ref; // Front face cmdbuf.SetStencilReference(set_back ? VK_STENCIL_FACE_FRONT_BIT @@ -1130,8 +1119,7 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) } scheduler.Record([front_write_mask = regs.stencil_front_mask, back_write_mask = regs.stencil_back_mask, - two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf) { const bool set_back = two_sided && front_write_mask != back_write_mask; // Front face cmdbuf.SetStencilWriteMask(set_back ? VK_STENCIL_FACE_FRONT_BIT @@ -1157,8 +1145,7 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) } scheduler.Record([front_test_mask = regs.stencil_front_func_mask, back_test_mask = regs.stencil_back_func_mask, - two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + two_sided = regs.stencil_two_side_enable](vk::CommandBuffer cmdbuf) { const bool set_back = two_sided && front_test_mask != back_test_mask; // Front face cmdbuf.SetStencilCompareMask(set_back ? VK_STENCIL_FACE_FRONT_BIT @@ -1179,8 +1166,7 @@ void RasterizerVulkan::UpdateLineWidth(Tegra::Engines::Maxwell3D::Regs& regs) { } const float width = regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased; - scheduler.Record( - [width](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { cmdbuf.SetLineWidth(width); }); + scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); }); } void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1188,7 +1174,7 @@ void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) { return; } scheduler.Record([enabled = regs.gl_cull_test_enabled, - cull_face = regs.gl_cull_face](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + cull_face = regs.gl_cull_face](vk::CommandBuffer cmdbuf) { cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE); }); } @@ -1202,7 +1188,7 @@ void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Re LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); enabled = false; } - scheduler.Record([enable = enabled](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([enable = enabled](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBoundsTestEnableEXT(enable); }); } @@ -1211,40 +1197,36 @@ void RasterizerVulkan::UpdateDepthTestEnable(Tegra::Engines::Maxwell3D::Regs& re if (!state_tracker.TouchDepthTestEnable()) { return; } - scheduler.Record( - [enable = regs.depth_test_enable](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetDepthTestEnableEXT(enable); - }); + scheduler.Record([enable = regs.depth_test_enable](vk::CommandBuffer cmdbuf) { + cmdbuf.SetDepthTestEnableEXT(enable); + }); } void RasterizerVulkan::UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchDepthWriteEnable()) { return; } - scheduler.Record( - [enable = regs.depth_write_enabled](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetDepthWriteEnableEXT(enable); - }); + scheduler.Record([enable = regs.depth_write_enabled](vk::CommandBuffer cmdbuf) { + cmdbuf.SetDepthWriteEnableEXT(enable); + }); } void RasterizerVulkan::UpdatePrimitiveRestartEnable(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchPrimitiveRestartEnable()) { return; } - scheduler.Record( - [enable = regs.primitive_restart.enabled](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetPrimitiveRestartEnableEXT(enable); - }); + scheduler.Record([enable = regs.primitive_restart.enabled](vk::CommandBuffer cmdbuf) { + cmdbuf.SetPrimitiveRestartEnableEXT(enable); + }); } void RasterizerVulkan::UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchRasterizerDiscardEnable()) { return; } - scheduler.Record( - [disable = regs.rasterize_enable](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetRasterizerDiscardEnableEXT(disable == 0); - }); + scheduler.Record([disable = regs.rasterize_enable](vk::CommandBuffer cmdbuf) { + cmdbuf.SetRasterizerDiscardEnableEXT(disable == 0); + }); } void RasterizerVulkan::UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1278,16 +1260,15 @@ void RasterizerVulkan::UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& re }; const u32 topology_index = static_cast(maxwell3d->draw_manager->GetDrawState().topology); const u32 enable = enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]]; - scheduler.Record([enable](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetDepthBiasEnableEXT(enable != 0); - }); + scheduler.Record( + [enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBiasEnableEXT(enable != 0); }); } void RasterizerVulkan::UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchLogicOpEnable()) { return; } - scheduler.Record([enable = regs.logic_op.enable](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([enable = regs.logic_op.enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEnableEXT(enable != 0); }); } @@ -1302,16 +1283,15 @@ void RasterizerVulkan::UpdateDepthClampEnable(Tegra::Engines::Maxwell3D::Regs& r Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || regs.viewport_clip_control.geometry_clip == Maxwell::ViewportClipControl::GeometryClip::FrustumZ); - scheduler.Record([is_enabled](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetDepthClampEnableEXT(is_enabled); - }); + scheduler.Record( + [is_enabled](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthClampEnableEXT(is_enabled); }); } void RasterizerVulkan::UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchDepthCompareOp()) { return; } - scheduler.Record([func = regs.depth_test_func](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([func = regs.depth_test_func](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthCompareOpEXT(MaxwellToVK::ComparisonOp(func)); }); } @@ -1326,9 +1306,8 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) { front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; } - scheduler.Record([front_face](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetFrontFaceEXT(front_face); - }); + scheduler.Record( + [front_face](vk::CommandBuffer cmdbuf) { cmdbuf.SetFrontFaceEXT(front_face); }); } void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1346,7 +1325,7 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { const Maxwell::StencilOp::Op back_zpass = regs.stencil_back_op.zpass; const Maxwell::ComparisonOp back_compare = regs.stencil_back_op.func; scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass, - back_compare](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + back_compare](vk::CommandBuffer cmdbuf) { cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail), MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), MaxwellToVK::ComparisonOp(compare)); @@ -1357,12 +1336,11 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { }); } else { // Front face defines the stencil op of both faces - scheduler.Record( - [fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), - MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), - MaxwellToVK::ComparisonOp(compare)); - }); + scheduler.Record([fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf) { + cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), + MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), + MaxwellToVK::ComparisonOp(compare)); + }); } } @@ -1373,8 +1351,7 @@ void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) { const auto op_value = static_cast(regs.logic_op.op); auto op = op_value >= 0x1500 && op_value < 0x1510 ? static_cast(op_value - 0x1500) : VK_LOGIC_OP_NO_OP; - scheduler.Record( - [op](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { cmdbuf.SetLogicOpEXT(op); }); + scheduler.Record([op](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEXT(op); }); } void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1400,7 +1377,7 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { current |= VK_COLOR_COMPONENT_A_BIT; } } - scheduler.Record([setup_masks](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([setup_masks](vk::CommandBuffer cmdbuf) { cmdbuf.SetColorWriteMaskEXT(0, setup_masks); }); } @@ -1410,7 +1387,7 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { std::ranges::transform( regs.blend.enable, setup_enables.begin(), [&](const auto& is_enabled) { return is_enabled != 0 ? VK_TRUE : VK_FALSE; }); - scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) { cmdbuf.SetColorBlendEnableEXT(0, setup_enables); }); } @@ -1433,7 +1410,7 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { } blend_setup(regs.blend_per_target[index]); } - scheduler.Record([setup_blends](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([setup_blends](vk::CommandBuffer cmdbuf) { cmdbuf.SetColorBlendEquationEXT(0, setup_blends); }); } @@ -1443,7 +1420,7 @@ void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& if (!state_tracker.TouchStencilTestEnable()) { return; } - scheduler.Record([enable = regs.stencil_enable](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([enable = regs.stencil_enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetStencilTestEnableEXT(enable); }); } @@ -1501,7 +1478,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) .divisor = is_instanced ? input_binding.frequency : 1, }); } - scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) { cmdbuf.SetVertexInputEXT(bindings, attributes); }); } diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 54ab47751..c92bc239f 100755 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -103,23 +103,22 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) { state.framebuffer = framebuffer_handle; state.render_area = render_area; - Record( - [renderpass, framebuffer_handle, render_area](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { - const VkRenderPassBeginInfo renderpass_bi{ - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = nullptr, - .renderPass = renderpass, - .framebuffer = framebuffer_handle, - .renderArea = - { - .offset = {.x = 0, .y = 0}, - .extent = render_area, - }, - .clearValueCount = 0, - .pClearValues = nullptr, - }; - cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); - }); + Record([renderpass, framebuffer_handle, render_area](vk::CommandBuffer cmdbuf) { + const VkRenderPassBeginInfo renderpass_bi{ + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = nullptr, + .renderPass = renderpass, + .framebuffer = framebuffer_handle, + .renderArea = + { + .offset = {.x = 0, .y = 0}, + .extent = render_area, + }, + .clearValueCount = 0, + .pClearValues = nullptr, + }; + cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); + }); num_renderpass_images = framebuffer->NumImages(); renderpass_images = framebuffer->Images(); renderpass_image_ranges = framebuffer->ImageRanges(); @@ -221,8 +220,8 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se InvalidateState(); const u64 signal_value = master_semaphore->NextTick(); - Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf, - vk::CommandBuffer upload_cmdbuf) { + RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value, + this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) { upload_cmdbuf.End(); cmdbuf.End(); @@ -286,7 +285,7 @@ void Scheduler::EndRenderPass() { return; } Record([num_images = num_renderpass_images, images = renderpass_images, - ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) { std::array barriers; for (size_t i = 0; i < num_images; ++i) { barriers[i] = VkImageMemoryBarrier{ diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index ab0ec3e9f..c523557bd 100755 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -80,7 +80,8 @@ public: /// Send work to a separate thread. template - void Record(T&& command) { + requires std::is_invocable_v + void RecordWithUploadBuffer(T&& command) { if (chunk->Record(command)) { return; } @@ -88,6 +89,15 @@ public: (void)chunk->Record(command); } + template + requires std::is_invocable_v + void Record(T&& c) { + this->RecordWithUploadBuffer( + [command = std::move(c)](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + command(cmdbuf); + }); + } + /// Returns the current command buffer tick. [[nodiscard]] u64 CurrentTick() const noexcept { return master_semaphore->CurrentTick(); diff --git a/src/video_core/renderer_vulkan/vk_smaa.cpp b/src/video_core/renderer_vulkan/vk_smaa.cpp index 5870a2b25..70644ea82 100755 --- a/src/video_core/renderer_vulkan/vk_smaa.cpp +++ b/src/video_core/renderer_vulkan/vk_smaa.cpp @@ -103,7 +103,7 @@ void UploadImage(const Device& device, MemoryAllocator& allocator, Scheduler& sc }}}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([&](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([&](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_UNDEFINED); cmdbuf.CopyBufferToImage(*upload_buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -672,7 +672,7 @@ void SMAA::UploadImages(Scheduler& scheduler) { UploadImage(m_device, m_allocator, scheduler, m_static_images[Search], search_extent, VK_FORMAT_R8_UNORM, ARRAY_TO_SPAN(searchTexBytes)); - scheduler.Record([&](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([&](vk::CommandBuffer cmdbuf) { for (auto& images : m_dynamic_images) { for (size_t i = 0; i < MaxDynamicImage; i++) { ClearColorImage(cmdbuf, *images.images[i]); @@ -707,7 +707,7 @@ VkImageView SMAA::Draw(Scheduler& scheduler, size_t image_index, VkImage source_ UpdateDescriptorSets(source_image_view, image_index); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([=, this](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + scheduler.Record([=, this](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL); BeginRenderPass(cmdbuf, m_renderpasses[EdgeDetection], edge_detection_framebuffer, diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index f4510a7b2..3250d4faa 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -710,7 +710,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution, is_2d, - vk_filter, up_scaling](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + vk_filter, up_scaling](vk::CommandBuffer cmdbuf) { const VkOffset2D src_size{ .x = static_cast(up_scaling ? extent.width : resolution.ScaleUp(extent.width)), .y = static_cast(is_2d && up_scaling ? extent.height @@ -956,7 +956,7 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, const VkImage src_image = src.Handle(); scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([dst_image, src_image, copy_buffer, src_aspect_mask, dst_aspect_mask, - vk_in_copies, vk_out_copies](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + vk_in_copies, vk_out_copies](vk::CommandBuffer cmdbuf) { RangedBarrierRange dst_range; RangedBarrierRange src_range; for (const VkBufferImageCopy& copy : vk_in_copies) { @@ -1105,7 +1105,7 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst const bool is_resolve = is_src_msaa && !is_dst_msaa; scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([filter, dst_region, src_region, dst_image, src_image, dst_layers, src_layers, - aspect_mask, is_resolve](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + aspect_mask, is_resolve](vk::CommandBuffer cmdbuf) { const std::array read_barriers{ VkImageMemoryBarrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -1244,8 +1244,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src, const VkImage dst_image = dst.Handle(); const VkImage src_image = src.Handle(); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([dst_image, src_image, aspect_mask, vk_copies](vk::CommandBuffer cmdbuf, - vk::CommandBuffer) { + scheduler.Record([dst_image, src_image, aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { RangedBarrierRange dst_range; RangedBarrierRange src_range; for (const VkImageCopy& copy : vk_copies) { @@ -1407,7 +1406,7 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, const VkImageAspectFlags vk_aspect_mask = aspect_mask; const bool is_initialized = std::exchange(initialized, true); scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, - vk_copies](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + vk_copies](vk::CommandBuffer cmdbuf) { CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); }); if (is_rescaled) { @@ -1446,8 +1445,7 @@ void Image::DownloadMemory(std::span buffers_span, std::spanRequestOutsideRenderPassOperationContext(); scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, - aspect_mask_ = aspect_mask, - vk_copies](vk::CommandBuffer cmdbuf, vk::CommandBuffer) { + aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -2015,4 +2013,32 @@ void TextureCacheRuntime::AccelerateImageUpload( ASSERT(false); } +void TextureCacheRuntime::TransitionImageLayout(Image& image) { + if (!image.ExchangeInitialization()) { + VkImageMemoryBarrier barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_NONE, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image.Handle(), + .subresourceRange{ + .aspectMask = image.AspectMask(), + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([barrier = barrier](vk::CommandBuffer cmdbuf) { + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); + }); + } +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 5c8e8e55d..4471ec74f 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -92,6 +92,8 @@ public: void InsertUploadMemoryBarrier() {} + void TransitionImageLayout(Image& image); + bool HasBrokenTextureViewFormats() const noexcept { // No known Vulkan driver has broken image views return false; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 7249f0d44..3008a89db 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1016,6 +1016,7 @@ void TextureCache

::RefreshContents(Image& image, ImageId image_id) { if (image.info.num_samples > 1 && !runtime.CanUploadMSAA()) { LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented"); + runtime.TransitionImageLayout(image); return; } if (True(image.flags & ImageFlagBits::AsynchronousDecode)) {