diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 32 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 8 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.cpp | 47 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 5 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 3 | ||||
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 52 | ||||
| -rw-r--r-- | src/yuzu/main.h | 9 |
17 files changed, 159 insertions, 64 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5168a16cb..d44d67562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -249,7 +249,7 @@ if(ENABLE_QT) | |||
| 249 | # Check for system Qt on Linux, fallback to bundled Qt | 249 | # Check for system Qt on Linux, fallback to bundled Qt |
| 250 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") | 250 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") |
| 251 | if (NOT YUZU_USE_BUNDLED_QT) | 251 | if (NOT YUZU_USE_BUNDLED_QT) |
| 252 | find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets) | 252 | find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus) |
| 253 | endif() | 253 | endif() |
| 254 | if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT) | 254 | if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT) |
| 255 | # Check for dependencies, then enable bundled Qt download | 255 | # Check for dependencies, then enable bundled Qt download |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 99982e5a3..f2f88c147 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -806,6 +806,33 @@ ResultCode KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | |||
| 806 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); | 806 | KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); |
| 807 | 807 | ||
| 808 | block_manager->Update(addr, size / PageSize, state, KMemoryPermission::ReadAndWrite); | 808 | block_manager->Update(addr, size / PageSize, state, KMemoryPermission::ReadAndWrite); |
| 809 | return ResultSuccess; | ||
| 810 | } | ||
| 811 | |||
| 812 | ResultCode KPageTable::SetMemoryPermission(VAddr addr, std::size_t size, | ||
| 813 | Svc::MemoryPermission svc_perm) { | ||
| 814 | const size_t num_pages = size / PageSize; | ||
| 815 | |||
| 816 | // Lock the table. | ||
| 817 | std::lock_guard lock{page_table_lock}; | ||
| 818 | |||
| 819 | // Verify we can change the memory permission. | ||
| 820 | KMemoryState old_state; | ||
| 821 | KMemoryPermission old_perm; | ||
| 822 | R_TRY(this->CheckMemoryState( | ||
| 823 | std::addressof(old_state), std::addressof(old_perm), nullptr, addr, size, | ||
| 824 | KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect, KMemoryPermission::None, | ||
| 825 | KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None)); | ||
| 826 | |||
| 827 | // Determine new perm. | ||
| 828 | const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm); | ||
| 829 | R_SUCCEED_IF(old_perm == new_perm); | ||
| 830 | |||
| 831 | // Perform mapping operation. | ||
| 832 | R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions)); | ||
| 833 | |||
| 834 | // Update the blocks. | ||
| 835 | block_manager->Update(addr, num_pages, old_state, new_perm, KMemoryAttribute::None); | ||
| 809 | 836 | ||
| 810 | return ResultSuccess; | 837 | return ResultSuccess; |
| 811 | } | 838 | } |
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index d784aa67e..db08ea8ce 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -47,6 +47,7 @@ public: | |||
| 47 | KMemoryInfo QueryInfo(VAddr addr); | 47 | KMemoryInfo QueryInfo(VAddr addr); |
| 48 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); | 48 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 49 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); | 49 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); |
| 50 | ResultCode SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm); | ||
| 50 | ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask, | 51 | ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask, |
| 51 | KMemoryAttribute value); | 52 | KMemoryAttribute value); |
| 52 | ResultCode SetHeapCapacity(std::size_t new_heap_capacity); | 53 | ResultCode SetHeapCapacity(std::size_t new_heap_capacity); |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 752592e2e..b8c993748 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "core/hle/kernel/k_resource_limit.h" | 26 | #include "core/hle/kernel/k_resource_limit.h" |
| 27 | #include "core/hle/kernel/k_scheduler.h" | 27 | #include "core/hle/kernel/k_scheduler.h" |
| 28 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 28 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 29 | #include "core/hle/kernel/k_system_control.h" | ||
| 29 | #include "core/hle/kernel/k_thread.h" | 30 | #include "core/hle/kernel/k_thread.h" |
| 30 | #include "core/hle/kernel/k_thread_queue.h" | 31 | #include "core/hle/kernel/k_thread_queue.h" |
| 31 | #include "core/hle/kernel/kernel.h" | 32 | #include "core/hle/kernel/kernel.h" |
| @@ -50,6 +51,7 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, | |||
| 50 | VAddr entry_point, u64 arg) { | 51 | VAddr entry_point, u64 arg) { |
| 51 | context = {}; | 52 | context = {}; |
| 52 | context.cpu_registers[0] = arg; | 53 | context.cpu_registers[0] = arg; |
| 54 | context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; | ||
| 53 | context.pc = entry_point; | 55 | context.pc = entry_point; |
| 54 | context.sp = stack_top; | 56 | context.sp = stack_top; |
| 55 | // TODO(merry): Perform a hardware test to determine the below value. | 57 | // TODO(merry): Perform a hardware test to determine the below value. |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 37d67b72e..68cb47211 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -164,6 +164,36 @@ static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_s | |||
| 164 | return result; | 164 | return result; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) { | ||
| 168 | switch (perm) { | ||
| 169 | case MemoryPermission::None: | ||
| 170 | case MemoryPermission::Read: | ||
| 171 | case MemoryPermission::ReadWrite: | ||
| 172 | return true; | ||
| 173 | default: | ||
| 174 | return false; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 size, | ||
| 179 | MemoryPermission perm) { | ||
| 180 | // Validate address / size. | ||
| 181 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | ||
| 182 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 183 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 184 | R_UNLESS((address < address + size), ResultInvalidCurrentMemory); | ||
| 185 | |||
| 186 | // Validate the permission. | ||
| 187 | R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 188 | |||
| 189 | // Validate that the region is in range for the current process. | ||
| 190 | auto& page_table = system.Kernel().CurrentProcess()->PageTable(); | ||
| 191 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | ||
| 192 | |||
| 193 | // Set the memory attribute. | ||
| 194 | return page_table.SetMemoryPermission(address, size, perm); | ||
| 195 | } | ||
| 196 | |||
| 167 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 197 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 168 | u32 attribute) { | 198 | u32 attribute) { |
| 169 | LOG_DEBUG(Kernel_SVC, | 199 | LOG_DEBUG(Kernel_SVC, |
| @@ -2724,7 +2754,7 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2724 | static const FunctionDef SVC_Table_64[] = { | 2754 | static const FunctionDef SVC_Table_64[] = { |
| 2725 | {0x00, nullptr, "Unknown"}, | 2755 | {0x00, nullptr, "Unknown"}, |
| 2726 | {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, | 2756 | {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, |
| 2727 | {0x02, nullptr, "SetMemoryPermission"}, | 2757 | {0x02, SvcWrap64<SetMemoryPermission>, "SetMemoryPermission"}, |
| 2728 | {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, | 2758 | {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, |
| 2729 | {0x04, SvcWrap64<MapMemory>, "MapMemory"}, | 2759 | {0x04, SvcWrap64<MapMemory>, "MapMemory"}, |
| 2730 | {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, | 2760 | {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 86255fe6d..a60adfcab 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -249,6 +249,14 @@ void SvcWrap64(Core::System& system) { | |||
| 249 | func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw); | 249 | func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | // Used by SetMemoryPermission | ||
| 253 | template <ResultCode func(Core::System&, u64, u64, Svc::MemoryPermission)> | ||
| 254 | void SvcWrap64(Core::System& system) { | ||
| 255 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), | ||
| 256 | static_cast<Svc::MemoryPermission>(Param(system, 2))) | ||
| 257 | .raw); | ||
| 258 | } | ||
| 259 | |||
| 252 | // Used by MapSharedMemory | 260 | // Used by MapSharedMemory |
| 253 | template <ResultCode func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)> | 261 | template <ResultCode func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)> |
| 254 | void SvcWrap64(Core::System& system) { | 262 | void SvcWrap64(Core::System& system) { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index 081b2c8e0..6f98d0998 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp | |||
| @@ -86,7 +86,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal | |||
| 86 | } | 86 | } |
| 87 | switch (attr) { | 87 | switch (attr) { |
| 88 | case IR::Attribute::PrimitiveId: | 88 | case IR::Attribute::PrimitiveId: |
| 89 | ctx.Add("MOV.S {}.x,primitive.id;", inst); | 89 | ctx.Add("MOV.F {}.x,primitive.id;", inst); |
| 90 | break; | 90 | break; |
| 91 | case IR::Attribute::PositionX: | 91 | case IR::Attribute::PositionX: |
| 92 | case IR::Attribute::PositionY: | 92 | case IR::Attribute::PositionY: |
| @@ -113,13 +113,13 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal | |||
| 113 | ctx.Add("MOV.F {}.x,vertex.tesscoord.{};", inst, swizzle); | 113 | ctx.Add("MOV.F {}.x,vertex.tesscoord.{};", inst, swizzle); |
| 114 | break; | 114 | break; |
| 115 | case IR::Attribute::InstanceId: | 115 | case IR::Attribute::InstanceId: |
| 116 | ctx.Add("MOV.S {}.x,{}.instance;", inst, ctx.attrib_name); | 116 | ctx.Add("MOV.F {}.x,{}.instance;", inst, ctx.attrib_name); |
| 117 | break; | 117 | break; |
| 118 | case IR::Attribute::VertexId: | 118 | case IR::Attribute::VertexId: |
| 119 | ctx.Add("MOV.S {}.x,{}.id;", inst, ctx.attrib_name); | 119 | ctx.Add("MOV.F {}.x,{}.id;", inst, ctx.attrib_name); |
| 120 | break; | 120 | break; |
| 121 | case IR::Attribute::FrontFace: | 121 | case IR::Attribute::FrontFace: |
| 122 | ctx.Add("CMP.S {}.x,{}.facing.x,0,-1;", inst, ctx.attrib_name); | 122 | ctx.Add("CMP.F {}.x,{}.facing.x,0,-1;", inst, ctx.attrib_name); |
| 123 | break; | 123 | break; |
| 124 | default: | 124 | default: |
| 125 | throw NotImplementedException("Get attribute {}", attr); | 125 | throw NotImplementedException("Get attribute {}", attr); |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 14e6522f2..3c1f79a27 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -1047,7 +1047,7 @@ bool Image::ScaleDown(bool ignore) { | |||
| 1047 | } | 1047 | } |
| 1048 | 1048 | ||
| 1049 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 1049 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, |
| 1050 | ImageId image_id_, Image& image) | 1050 | ImageId image_id_, Image& image, const SlotVector<Image>&) |
| 1051 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} { | 1051 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} { |
| 1052 | const Device& device = runtime.device; | 1052 | const Device& device = runtime.device; |
| 1053 | if (True(image.flags & ImageFlagBits::Converted)) { | 1053 | if (True(image.flags & ImageFlagBits::Converted)) { |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index dbf1df79c..7f425631f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -36,6 +36,7 @@ using VideoCommon::ImageViewType; | |||
| 36 | using VideoCommon::NUM_RT; | 36 | using VideoCommon::NUM_RT; |
| 37 | using VideoCommon::Region2D; | 37 | using VideoCommon::Region2D; |
| 38 | using VideoCommon::RenderTargets; | 38 | using VideoCommon::RenderTargets; |
| 39 | using VideoCommon::SlotVector; | ||
| 39 | 40 | ||
| 40 | struct ImageBufferMap { | 41 | struct ImageBufferMap { |
| 41 | ~ImageBufferMap(); | 42 | ~ImageBufferMap(); |
| @@ -234,7 +235,8 @@ class ImageView : public VideoCommon::ImageViewBase { | |||
| 234 | friend Image; | 235 | friend Image; |
| 235 | 236 | ||
| 236 | public: | 237 | public: |
| 237 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); | 238 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&, |
| 239 | const SlotVector<Image>&); | ||
| 238 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, | 240 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, |
| 239 | const VideoCommon::ImageViewInfo&, GPUVAddr); | 241 | const VideoCommon::ImageViewInfo&, GPUVAddr); |
| 240 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, | 242 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, |
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index cd5995897..2c3914459 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -518,53 +518,6 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb | |||
| 518 | scheduler.InvalidateState(); | 518 | scheduler.InvalidateState(); |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 522 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | ||
| 523 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | ||
| 524 | const VkImageView src_view = src_image_view.ColorView(); | ||
| 525 | const VkSampler sampler = *nearest_sampler; | ||
| 526 | const VkExtent2D extent{ | ||
| 527 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | ||
| 528 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 529 | }; | ||
| 530 | scheduler.RequestRenderpass(dst_framebuffer); | ||
| 531 | scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift, | ||
| 532 | this](vk::CommandBuffer cmdbuf) { | ||
| 533 | const VkOffset2D offset{ | ||
| 534 | .x = 0, | ||
| 535 | .y = 0, | ||
| 536 | }; | ||
| 537 | const VkViewport viewport{ | ||
| 538 | .x = 0.0f, | ||
| 539 | .y = 0.0f, | ||
| 540 | .width = static_cast<float>(extent.width), | ||
| 541 | .height = static_cast<float>(extent.height), | ||
| 542 | .minDepth = 0.0f, | ||
| 543 | .maxDepth = 0.0f, | ||
| 544 | }; | ||
| 545 | const VkRect2D scissor{ | ||
| 546 | .offset = offset, | ||
| 547 | .extent = extent, | ||
| 548 | }; | ||
| 549 | const PushConstants push_constants{ | ||
| 550 | .tex_scale = {viewport.width, viewport.height}, | ||
| 551 | .tex_offset = {0.0f, 0.0f}, | ||
| 552 | }; | ||
| 553 | const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); | ||
| 554 | UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); | ||
| 555 | |||
| 556 | // TODO: Barriers | ||
| 557 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); | ||
| 558 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, | ||
| 559 | nullptr); | ||
| 560 | cmdbuf.SetViewport(0, viewport); | ||
| 561 | cmdbuf.SetScissor(0, scissor); | ||
| 562 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); | ||
| 563 | cmdbuf.Draw(3, 1, 0, 0); | ||
| 564 | }); | ||
| 565 | scheduler.InvalidateState(); | ||
| 566 | } | ||
| 567 | |||
| 568 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 521 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 569 | ImageView& src_image_view) { | 522 | ImageView& src_image_view) { |
| 570 | const VkPipelineLayout layout = *two_textures_pipeline_layout; | 523 | const VkPipelineLayout layout = *two_textures_pipeline_layout; |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 1d9f61a52..85e7dca5b 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -60,9 +60,6 @@ private: | |||
| 60 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 60 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 61 | const ImageView& src_image_view); | 61 | const ImageView& src_image_view); |
| 62 | 62 | ||
| 63 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 64 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | ||
| 65 | |||
| 66 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 63 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 67 | ImageView& src_image_view); | 64 | ImageView& src_image_view); |
| 68 | 65 | ||
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 1941170cb..c3050887c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1473,8 +1473,7 @@ bool Image::BlitScaleHelper(bool scale_up) { | |||
| 1473 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 1473 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, |
| 1474 | ImageId image_id_, Image& image) | 1474 | ImageId image_id_, Image& image) |
| 1475 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, | 1475 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, |
| 1476 | src_image{&image}, image_handle{image.Handle()}, | 1476 | image_handle{image.Handle()}, samples(ConvertSampleCount(image.info.num_samples)) { |
| 1477 | samples(ConvertSampleCount(image.info.num_samples)) { | ||
| 1478 | using Shader::TextureType; | 1477 | using Shader::TextureType; |
| 1479 | 1478 | ||
| 1480 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); | 1479 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); |
| @@ -1557,6 +1556,12 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI | |||
| 1557 | } | 1556 | } |
| 1558 | } | 1557 | } |
| 1559 | 1558 | ||
| 1559 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | ||
| 1560 | ImageId image_id_, Image& image, const SlotVector<Image>& slot_imgs) | ||
| 1561 | : ImageView{runtime, info, image_id_, image} { | ||
| 1562 | slot_images = &slot_imgs; | ||
| 1563 | } | ||
| 1564 | |||
| 1560 | ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, | 1565 | ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, |
| 1561 | const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) | 1566 | const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) |
| 1562 | : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, | 1567 | : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, |
| @@ -1613,10 +1618,12 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type, | |||
| 1613 | } | 1618 | } |
| 1614 | 1619 | ||
| 1615 | bool ImageView::IsRescaled() const noexcept { | 1620 | bool ImageView::IsRescaled() const noexcept { |
| 1616 | if (!src_image) { | 1621 | if (!slot_images) { |
| 1617 | return false; | 1622 | return false; |
| 1618 | } | 1623 | } |
| 1619 | return src_image->IsRescaled(); | 1624 | const auto& slots = *slot_images; |
| 1625 | const auto& src_image = slots[image_id]; | ||
| 1626 | return src_image.IsRescaled(); | ||
| 1620 | } | 1627 | } |
| 1621 | 1628 | ||
| 1622 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { | 1629 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index c592f2666..2f12be78b 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -23,6 +23,7 @@ using VideoCommon::ImageId; | |||
| 23 | using VideoCommon::NUM_RT; | 23 | using VideoCommon::NUM_RT; |
| 24 | using VideoCommon::Region2D; | 24 | using VideoCommon::Region2D; |
| 25 | using VideoCommon::RenderTargets; | 25 | using VideoCommon::RenderTargets; |
| 26 | using VideoCommon::SlotVector; | ||
| 26 | using VideoCore::Surface::PixelFormat; | 27 | using VideoCore::Surface::PixelFormat; |
| 27 | 28 | ||
| 28 | class ASTCDecoderPass; | 29 | class ASTCDecoderPass; |
| @@ -170,6 +171,8 @@ private: | |||
| 170 | class ImageView : public VideoCommon::ImageViewBase { | 171 | class ImageView : public VideoCommon::ImageViewBase { |
| 171 | public: | 172 | public: |
| 172 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); | 173 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); |
| 174 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&, | ||
| 175 | const SlotVector<Image>&); | ||
| 173 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, | 176 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, |
| 174 | const VideoCommon::ImageViewInfo&, GPUVAddr); | 177 | const VideoCommon::ImageViewInfo&, GPUVAddr); |
| 175 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&); | 178 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&); |
| @@ -226,7 +229,7 @@ private: | |||
| 226 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); | 229 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); |
| 227 | 230 | ||
| 228 | const Device* device = nullptr; | 231 | const Device* device = nullptr; |
| 229 | const Image* src_image{}; | 232 | const SlotVector<Image>* slot_images = nullptr; |
| 230 | 233 | ||
| 231 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; | 234 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; |
| 232 | std::unique_ptr<StorageViews> storage_views; | 235 | std::unique_ptr<StorageViews> storage_views; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 2e19fced2..b494152b8 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1397,7 +1397,8 @@ ImageViewId TextureCache<P>::FindOrEmplaceImageView(ImageId image_id, const Imag | |||
| 1397 | if (const ImageViewId image_view_id = image.FindView(info); image_view_id) { | 1397 | if (const ImageViewId image_view_id = image.FindView(info); image_view_id) { |
| 1398 | return image_view_id; | 1398 | return image_view_id; |
| 1399 | } | 1399 | } |
| 1400 | const ImageViewId image_view_id = slot_image_views.insert(runtime, info, image_id, image); | 1400 | const ImageViewId image_view_id = |
| 1401 | slot_image_views.insert(runtime, info, image_id, image, slot_images); | ||
| 1401 | image.InsertView(info, image_view_id); | 1402 | image.InsertView(info, image_view_id); |
| 1402 | return image_view_id; | 1403 | return image_view_id; |
| 1403 | } | 1404 | } |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 732e8c276..30902101d 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -251,6 +251,9 @@ target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include) | |||
| 251 | if (NOT WIN32) | 251 | if (NOT WIN32) |
| 252 | target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) | 252 | target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) |
| 253 | endif() | 253 | endif() |
| 254 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") | ||
| 255 | target_link_libraries(yuzu PRIVATE Qt5::DBus) | ||
| 256 | endif() | ||
| 254 | 257 | ||
| 255 | target_compile_definitions(yuzu PRIVATE | 258 | target_compile_definitions(yuzu PRIVATE |
| 256 | # Use QStringBuilder for string concatenation to reduce | 259 | # Use QStringBuilder for string concatenation to reduce |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index a7271e075..1e02d715b 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1236,11 +1236,58 @@ void GMainWindow::OnDisplayTitleBars(bool show) { | |||
| 1236 | } | 1236 | } |
| 1237 | } | 1237 | } |
| 1238 | 1238 | ||
| 1239 | #ifdef __linux__ | ||
| 1240 | static std::optional<QDBusObjectPath> HoldWakeLockLinux(u32 window_id = 0) { | ||
| 1241 | if (!QDBusConnection::sessionBus().isConnected()) { | ||
| 1242 | return {}; | ||
| 1243 | } | ||
| 1244 | // reference: https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Inhibit | ||
| 1245 | QDBusInterface xdp(QString::fromLatin1("org.freedesktop.portal.Desktop"), | ||
| 1246 | QString::fromLatin1("/org/freedesktop/portal/desktop"), | ||
| 1247 | QString::fromLatin1("org.freedesktop.portal.Inhibit")); | ||
| 1248 | if (!xdp.isValid()) { | ||
| 1249 | LOG_WARNING(Frontend, "Couldn't connect to XDP D-Bus endpoint"); | ||
| 1250 | return {}; | ||
| 1251 | } | ||
| 1252 | QVariantMap options = {}; | ||
| 1253 | //: TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the | ||
| 1254 | //: computer from sleeping | ||
| 1255 | options.insert(QString::fromLatin1("reason"), | ||
| 1256 | QCoreApplication::translate("GMainWindow", "yuzu is running a game")); | ||
| 1257 | // 0x4: Suspend lock; 0x8: Idle lock | ||
| 1258 | QDBusReply<QDBusObjectPath> reply = | ||
| 1259 | xdp.call(QString::fromLatin1("Inhibit"), | ||
| 1260 | QString::fromLatin1("x11:") + QString::number(window_id, 16), 12U, options); | ||
| 1261 | |||
| 1262 | if (reply.isValid()) { | ||
| 1263 | return reply.value(); | ||
| 1264 | } | ||
| 1265 | LOG_WARNING(Frontend, "Couldn't read Inhibit reply from XDP: {}", | ||
| 1266 | reply.error().message().toStdString()); | ||
| 1267 | return {}; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | static void ReleaseWakeLockLinux(QDBusObjectPath lock) { | ||
| 1271 | if (!QDBusConnection::sessionBus().isConnected()) { | ||
| 1272 | return; | ||
| 1273 | } | ||
| 1274 | QDBusInterface unlocker(QString::fromLatin1("org.freedesktop.portal.Desktop"), lock.path(), | ||
| 1275 | QString::fromLatin1("org.freedesktop.portal.Request")); | ||
| 1276 | unlocker.call(QString::fromLatin1("Close")); | ||
| 1277 | } | ||
| 1278 | #endif // __linux__ | ||
| 1279 | |||
| 1239 | void GMainWindow::PreventOSSleep() { | 1280 | void GMainWindow::PreventOSSleep() { |
| 1240 | #ifdef _WIN32 | 1281 | #ifdef _WIN32 |
| 1241 | SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); | 1282 | SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); |
| 1242 | #elif defined(HAVE_SDL2) | 1283 | #elif defined(HAVE_SDL2) |
| 1243 | SDL_DisableScreenSaver(); | 1284 | SDL_DisableScreenSaver(); |
| 1285 | #ifdef __linux__ | ||
| 1286 | auto reply = HoldWakeLockLinux(winId()); | ||
| 1287 | if (reply) { | ||
| 1288 | wake_lock = std::move(reply.value()); | ||
| 1289 | } | ||
| 1290 | #endif | ||
| 1244 | #endif | 1291 | #endif |
| 1245 | } | 1292 | } |
| 1246 | 1293 | ||
| @@ -1249,6 +1296,11 @@ void GMainWindow::AllowOSSleep() { | |||
| 1249 | SetThreadExecutionState(ES_CONTINUOUS); | 1296 | SetThreadExecutionState(ES_CONTINUOUS); |
| 1250 | #elif defined(HAVE_SDL2) | 1297 | #elif defined(HAVE_SDL2) |
| 1251 | SDL_EnableScreenSaver(); | 1298 | SDL_EnableScreenSaver(); |
| 1299 | #ifdef __linux__ | ||
| 1300 | if (!wake_lock.path().isEmpty()) { | ||
| 1301 | ReleaseWakeLockLinux(wake_lock); | ||
| 1302 | } | ||
| 1303 | #endif | ||
| 1252 | #endif | 1304 | #endif |
| 1253 | } | 1305 | } |
| 1254 | 1306 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 0fd41ed4f..7870bb963 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -17,6 +17,12 @@ | |||
| 17 | #include "yuzu/compatibility_list.h" | 17 | #include "yuzu/compatibility_list.h" |
| 18 | #include "yuzu/hotkeys.h" | 18 | #include "yuzu/hotkeys.h" |
| 19 | 19 | ||
| 20 | #ifdef __linux__ | ||
| 21 | #include <QVariant> | ||
| 22 | #include <QtDBus/QDBusInterface> | ||
| 23 | #include <QtDBus/QtDBus> | ||
| 24 | #endif | ||
| 25 | |||
| 20 | class Config; | 26 | class Config; |
| 21 | class EmuThread; | 27 | class EmuThread; |
| 22 | class GameList; | 28 | class GameList; |
| @@ -394,6 +400,9 @@ private: | |||
| 394 | 400 | ||
| 395 | // Applets | 401 | // Applets |
| 396 | QtSoftwareKeyboardDialog* software_keyboard = nullptr; | 402 | QtSoftwareKeyboardDialog* software_keyboard = nullptr; |
| 403 | #ifdef __linux__ | ||
| 404 | QDBusObjectPath wake_lock{}; | ||
| 405 | #endif | ||
| 397 | 406 | ||
| 398 | protected: | 407 | protected: |
| 399 | void dropEvent(QDropEvent* event) override; | 408 | void dropEvent(QDropEvent* event) override; |