summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-05-20 14:23:49 -0500
committerGravatar Subv2018-05-20 14:25:57 -0500
commit525492428d3b1ccbe2096944a7525b242d4c9e7b (patch)
treed80f659bdafec951221326e58b0a3aeb02bd349b /src
parentGPU: Implemented nvhost-as-gpu's UnmapBuffer ioctl. (diff)
downloadyuzu-525492428d3b1ccbe2096944a7525b242d4c9e7b.tar.gz
yuzu-525492428d3b1ccbe2096944a7525b242d4c9e7b.tar.xz
yuzu-525492428d3b1ccbe2096944a7525b242d4c9e7b.zip
GPU: Implemented the nvmap Free ioctl.
It releases a reference to an nvmap object
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp35
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h14
2 files changed, 48 insertions, 1 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 8d883209f..d66fb3a9c 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -30,6 +30,8 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
30 return IocFromId(input, output); 30 return IocFromId(input, output);
31 case IoctlCommand::Param: 31 case IoctlCommand::Param:
32 return IocParam(input, output); 32 return IocParam(input, output);
33 case IoctlCommand::Free:
34 return IocFree(input, output);
33 } 35 }
34 36
35 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 37 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -45,6 +47,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
45 object->id = next_id++; 47 object->id = next_id++;
46 object->size = params.size; 48 object->size = params.size;
47 object->status = Object::Status::Created; 49 object->status = Object::Status::Created;
50 object->refcount = 1;
48 51
49 u32 handle = next_handle++; 52 u32 handle = next_handle++;
50 handles[handle] = std::move(object); 53 handles[handle] = std::move(object);
@@ -101,6 +104,8 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
101 [&](const auto& entry) { return entry.second->id == params.id; }); 104 [&](const auto& entry) { return entry.second->id == params.id; });
102 ASSERT(itr != handles.end()); 105 ASSERT(itr != handles.end());
103 106
107 itr->second->refcount++;
108
104 // Return the existing handle instead of creating a new one. 109 // Return the existing handle instead of creating a new one.
105 params.handle = itr->first; 110 params.handle = itr->first;
106 111
@@ -142,4 +147,34 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
142 return 0; 147 return 0;
143} 148}
144 149
150u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
151 enum FreeFlags {
152 Freed = 0,
153 NotFreedYet = 1,
154 };
155
156 IocFreeParams params;
157 std::memcpy(&params, input.data(), sizeof(params));
158
159 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
160
161 auto itr = handles.find(params.handle);
162 ASSERT(itr != handles.end());
163
164 itr->second->refcount--;
165
166 params.refcount = itr->second->refcount;
167 params.size = itr->second->size;
168
169 if (itr->second->refcount == 0)
170 params.flags = Freed;
171 else
172 params.flags = NotFreedYet;
173
174 handles.erase(params.handle);
175
176 std::memcpy(output.data(), &params, sizeof(params));
177 return 0;
178}
179
145} // namespace Service::Nvidia::Devices 180} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 431eb3773..5a3044167 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -34,6 +34,7 @@ public:
34 u8 kind; 34 u8 kind;
35 VAddr addr; 35 VAddr addr;
36 Status status; 36 Status status;
37 u32 refcount;
37 }; 38 };
38 39
39 std::shared_ptr<Object> GetObject(u32 handle) const { 40 std::shared_ptr<Object> GetObject(u32 handle) const {
@@ -59,7 +60,8 @@ private:
59 FromId = 0xC0080103, 60 FromId = 0xC0080103,
60 Alloc = 0xC0200104, 61 Alloc = 0xC0200104,
61 Param = 0xC00C0109, 62 Param = 0xC00C0109,
62 GetId = 0xC008010E 63 GetId = 0xC008010E,
64 Free = 0xC0180105,
63 }; 65 };
64 66
65 struct IocCreateParams { 67 struct IocCreateParams {
@@ -102,11 +104,21 @@ private:
102 u32_le value; 104 u32_le value;
103 }; 105 };
104 106
107 struct IocFreeParams {
108 u32_le handle;
109 INSERT_PADDING_BYTES(4);
110 u64_le refcount;
111 u32_le size;
112 u32_le flags;
113 };
114 static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");
115
105 u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output); 116 u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
106 u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); 117 u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
107 u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output); 118 u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
108 u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output); 119 u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
109 u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output); 120 u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output);
121 u32 IocFree(const std::vector<u8>& input, std::vector<u8>& output);
110}; 122};
111 123
112} // namespace Service::Nvidia::Devices 124} // namespace Service::Nvidia::Devices