summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Subv2018-05-20 14:21:06 -0500
committerGravatar Subv2018-05-20 14:25:56 -0500
commit72b5c448cfe5d21fea9dd7a996ca8b50539ec64a (patch)
tree7cd6e266d128e057791033c74af65b3666b31953 /src/core
parentMerge pull request #436 from bunnei/multi-core (diff)
downloadyuzu-72b5c448cfe5d21fea9dd7a996ca8b50539ec64a.tar.gz
yuzu-72b5c448cfe5d21fea9dd7a996ca8b50539ec64a.tar.xz
yuzu-72b5c448cfe5d21fea9dd7a996ca8b50539ec64a.zip
GPU: Implemented nvhost-as-gpu's UnmapBuffer ioctl.
It removes a mapping previously created with the MapBufferEx ioctl.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp33
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h17
2 files changed, 50 insertions, 0 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index cb4913b07..c1eea861d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -26,6 +26,8 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto
26 return BindChannel(input, output); 26 return BindChannel(input, output);
27 case IoctlCommand::IocGetVaRegionsCommand: 27 case IoctlCommand::IocGetVaRegionsCommand:
28 return GetVARegions(input, output); 28 return GetVARegions(input, output);
29 case IoctlCommand::IocUnmapBufferCommand:
30 return UnmapBuffer(input, output);
29 } 31 }
30 32
31 if (static_cast<IoctlCommand>(command.cmd.Value()) == IoctlCommand::IocRemapCommand) 33 if (static_cast<IoctlCommand>(command.cmd.Value()) == IoctlCommand::IocRemapCommand)
@@ -125,6 +127,37 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou
125 params.offset = gpu.memory_manager->MapBufferEx(object->addr, object->size); 127 params.offset = gpu.memory_manager->MapBufferEx(object->addr, object->size);
126 } 128 }
127 129
130 // Create a new mapping entry for this operation.
131 ASSERT_MSG(buffer_mappings.find(params.offset) == buffer_mappings.end(),
132 "Offset is already mapped");
133
134 BufferMapping mapping{};
135 mapping.nvmap_handle = params.nvmap_handle;
136 mapping.offset = params.offset;
137 mapping.size = object->size;
138
139 buffer_mappings[params.offset] = mapping;
140
141 std::memcpy(output.data(), &params, output.size());
142 return 0;
143}
144
145u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
146 IoctlUnmapBuffer params{};
147 std::memcpy(&params, input.data(), input.size());
148
149 NGLOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
150
151 auto& gpu = Core::System::GetInstance().GPU();
152
153 auto itr = buffer_mappings.find(params.offset);
154
155 ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping");
156
157 params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size);
158
159 buffer_mappings.erase(itr->second.offset);
160
128 std::memcpy(output.data(), &params, output.size()); 161 std::memcpy(output.data(), &params, output.size());
129 return 0; 162 return 0;
130} 163}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index f2dd0c3b3..d4c4b4db3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <unordered_map>
8#include <utility> 9#include <utility>
9#include <vector> 10#include <vector>
10#include "common/common_types.h" 11#include "common/common_types.h"
@@ -30,6 +31,7 @@ private:
30 IocMapBufferExCommand = 0xC0284106, 31 IocMapBufferExCommand = 0xC0284106,
31 IocBindChannelCommand = 0x40044101, 32 IocBindChannelCommand = 0x40044101,
32 IocGetVaRegionsCommand = 0xC0404108, 33 IocGetVaRegionsCommand = 0xC0404108,
34 IocUnmapBufferCommand = 0xC0084105,
33 }; 35 };
34 36
35 struct IoctlInitalizeEx { 37 struct IoctlInitalizeEx {
@@ -76,6 +78,11 @@ private:
76 }; 78 };
77 static_assert(sizeof(IoctlMapBufferEx) == 40, "IoctlMapBufferEx is incorrect size"); 79 static_assert(sizeof(IoctlMapBufferEx) == 40, "IoctlMapBufferEx is incorrect size");
78 80
81 struct IoctlUnmapBuffer {
82 u64_le offset;
83 };
84 static_assert(sizeof(IoctlUnmapBuffer) == 8, "IoctlUnmapBuffer is incorrect size");
85
79 struct IoctlBindChannel { 86 struct IoctlBindChannel {
80 u32_le fd; 87 u32_le fd;
81 }; 88 };
@@ -98,12 +105,22 @@ private:
98 static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2, 105 static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2,
99 "IoctlGetVaRegions is incorrect size"); 106 "IoctlGetVaRegions is incorrect size");
100 107
108 struct BufferMapping {
109 u64 offset;
110 u64 size;
111 u32 nvmap_handle;
112 };
113
114 /// Map containing the nvmap object mappings in GPU memory.
115 std::unordered_map<u64, BufferMapping> buffer_mappings;
116
101 u32 channel{}; 117 u32 channel{};
102 118
103 u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); 119 u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output);
104 u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); 120 u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output);
105 u32 Remap(const std::vector<u8>& input, std::vector<u8>& output); 121 u32 Remap(const std::vector<u8>& input, std::vector<u8>& output);
106 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); 122 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
123 u32 UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
107 u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); 124 u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output);
108 u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); 125 u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output);
109 126