diff options
Diffstat (limited to 'src')
| -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_vulkan/blit_image.cpp | 47 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 3 |
8 files changed, 73 insertions, 55 deletions
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_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 | ||