2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

GPU: Implemented the nvmap Free ioctl.

It releases a reference to an nvmap object
This commit is contained in:
Subv 2018-05-20 14:23:49 -05:00
parent 72b5c448cf
commit 525492428d
2 changed files with 48 additions and 1 deletions

View file

@ -30,6 +30,8 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
return IocFromId(input, output); return IocFromId(input, output);
case IoctlCommand::Param: case IoctlCommand::Param:
return IocParam(input, output); return IocParam(input, output);
case IoctlCommand::Free:
return IocFree(input, output);
} }
UNIMPLEMENTED_MSG("Unimplemented ioctl"); UNIMPLEMENTED_MSG("Unimplemented ioctl");
@ -45,6 +47,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
object->id = next_id++; object->id = next_id++;
object->size = params.size; object->size = params.size;
object->status = Object::Status::Created; object->status = Object::Status::Created;
object->refcount = 1;
u32 handle = next_handle++; u32 handle = next_handle++;
handles[handle] = std::move(object); handles[handle] = std::move(object);
@ -101,6 +104,8 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
[&](const auto& entry) { return entry.second->id == params.id; }); [&](const auto& entry) { return entry.second->id == params.id; });
ASSERT(itr != handles.end()); ASSERT(itr != handles.end());
itr->second->refcount++;
// Return the existing handle instead of creating a new one. // Return the existing handle instead of creating a new one.
params.handle = itr->first; params.handle = itr->first;
@ -142,4 +147,34 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
return 0; return 0;
} }
u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
enum FreeFlags {
Freed = 0,
NotFreedYet = 1,
};
IocFreeParams params;
std::memcpy(&params, input.data(), sizeof(params));
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
auto itr = handles.find(params.handle);
ASSERT(itr != handles.end());
itr->second->refcount--;
params.refcount = itr->second->refcount;
params.size = itr->second->size;
if (itr->second->refcount == 0)
params.flags = Freed;
else
params.flags = NotFreedYet;
handles.erase(params.handle);
std::memcpy(output.data(), &params, sizeof(params));
return 0;
}
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View file

@ -34,6 +34,7 @@ public:
u8 kind; u8 kind;
VAddr addr; VAddr addr;
Status status; Status status;
u32 refcount;
}; };
std::shared_ptr<Object> GetObject(u32 handle) const { std::shared_ptr<Object> GetObject(u32 handle) const {
@ -59,7 +60,8 @@ private:
FromId = 0xC0080103, FromId = 0xC0080103,
Alloc = 0xC0200104, Alloc = 0xC0200104,
Param = 0xC00C0109, Param = 0xC00C0109,
GetId = 0xC008010E GetId = 0xC008010E,
Free = 0xC0180105,
}; };
struct IocCreateParams { struct IocCreateParams {
@ -102,11 +104,21 @@ private:
u32_le value; u32_le value;
}; };
struct IocFreeParams {
u32_le handle;
INSERT_PADDING_BYTES(4);
u64_le refcount;
u32_le size;
u32_le flags;
};
static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");
u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output); u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output); u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output); u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output); u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output);
u32 IocFree(const std::vector<u8>& input, std::vector<u8>& output);
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices