mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-22 10:25:45 +00:00
[nvdrv] ZBC table implement stubs (#83)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/83 This commit introduces an implementation for `ZBCSetTable` in `nvhost_ctrl_gpu`, which is invoked by games and system services to configure default clear values for depth, stencil, and color attachments on the GPU, allowing better instructions on how the ZCull Block Compression expects to work within the emulated GPU. This is an important step for compatibility with titles or system modules that expect ZBC configuration support. Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
e8e0d7fa20
commit
12a690e15f
2 changed files with 101 additions and 4 deletions
|
@ -35,6 +35,7 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
|
|||
return WrapFixed(this, &nvhost_ctrl_gpu::ZBCSetTable, input, output);
|
||||
case 0x4:
|
||||
return WrapFixed(this, &nvhost_ctrl_gpu::ZBCQueryTable, input, output);
|
||||
//deviation
|
||||
case 0x5:
|
||||
return WrapFixed(this, &nvhost_ctrl_gpu::GetCharacteristics1, input, output);
|
||||
case 0x6:
|
||||
|
@ -50,7 +51,29 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
|
|||
}
|
||||
break;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
// still unimplemented
|
||||
std::string_view friendly_name = [raw = command.raw]() {
|
||||
switch (raw) {
|
||||
case 0x0d: return "INVAL_ICACHE";
|
||||
case 0x0e: return "SET_MMU_DEBUG_MODE ";
|
||||
case 0x0f: return "SET_SM_DEBUG_MODE";
|
||||
case 0x10: return "WAIT_FOR_PAUSE";
|
||||
case 0x11: return "GET_TPC_EXCEPTION_EN_STATUS";
|
||||
case 0x12: return "NUM_VSMS";
|
||||
case 0x13: return "VSMS_MAPPING";
|
||||
case 0x14: return "ZBC_GET_ACTIVE_SLOT_MASK";
|
||||
case 0x15: return "PMU_GET_GPU_LOAD";
|
||||
case 0x16: return "SET_CG_CONTROLS";
|
||||
case 0x17: return "GET_CG_CONTROLS";
|
||||
case 0x18: return "SET_PG_CONTROLS";
|
||||
case 0x19: return "GET_PG_CONTROLS";
|
||||
case 0x1A: return "PMU_GET_ELPG_RESIDENCY_GATING";
|
||||
case 0x1B: return "GET_ERROR_CHANNEL_USER_DATA";
|
||||
case 0x1D: return "GET_CPU_TIME_CORRELATION_INFO";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}();
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X} {}", command.raw, friendly_name);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
|
@ -230,18 +253,70 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) {
|
|||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) {
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
ZbcEntry entry = {};
|
||||
std::memset(&entry, 0, sizeof(entry));
|
||||
// TODO(ogniK): What does this even actually do?
|
||||
// TODO(myself): This thing I guess
|
||||
if (params.type == 1) {
|
||||
for (auto i = 0; i < 4; ++i) {
|
||||
entry.color_ds[i] = params.color_ds[i];
|
||||
entry.color_l2[i] = params.color_l2[i];
|
||||
}
|
||||
ASSERT(this->max_color_entries < 16);
|
||||
this->color_entries[this->max_color_entries] = entry;
|
||||
++this->max_color_entries;
|
||||
} else if (params.type == 2) {
|
||||
entry.depth = params.depth;
|
||||
ASSERT(this->max_depth_entries < 16);
|
||||
this->depth_entries[this->max_depth_entries] = entry;
|
||||
++this->max_depth_entries;
|
||||
}
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) {
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
struct ZbcQueryParams {
|
||||
u32_le color_ds[4];
|
||||
u32_le color_l2[4];
|
||||
u32_le depth;
|
||||
u32_le ref_cnt;
|
||||
u32_le format;
|
||||
u32_le type;
|
||||
u32_le index_size;
|
||||
} entry = {};
|
||||
std::memset(&entry, 0, sizeof(entry));
|
||||
auto const index = params.index_size;
|
||||
if (params.type == 0) { //no
|
||||
entry.index_size = 15;
|
||||
} else if (params.type == 1) { //color
|
||||
ASSERT(index < 16);
|
||||
for (auto i = 0; i < 4; ++i) {
|
||||
params.color_ds[i] = this->color_entries[index].color_ds[i];
|
||||
params.color_l2[i] = this->color_entries[index].color_l2[i];
|
||||
}
|
||||
// TODO: Only if no error thrown (otherwise dont modify)
|
||||
params.format = this->color_entries[index].format;
|
||||
//params.ref_cnt = this->color_entries[index].ref_cnt;
|
||||
} else if (params.type == 2) { //depth
|
||||
ASSERT(index < 16);
|
||||
params.depth = this->depth_entries[index].depth;
|
||||
// TODO: Only if no error thrown (otherwise dont modify)
|
||||
params.format = this->depth_entries[index].format;
|
||||
//params.ref_cnt = this->depth_entries[index].ref_cnt;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::FlushL2(IoctlFlushL2& params) {
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_NVDRV, "called 0x{:X}", params.flush);
|
||||
// if ((params.flush & 0x01) != 0) //l2 flush
|
||||
// /* we dont emulate l2 */;
|
||||
// if ((params.flush & 0x04) != 0) //fb flush
|
||||
// /* we dont emulate fb */;
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,16 @@ private:
|
|||
};
|
||||
static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
|
||||
|
||||
struct IoctlGetCpuTimeCorrelationInfo {
|
||||
struct {
|
||||
u64_le cpu_timestamp;
|
||||
u64_le gpu_timestamp;
|
||||
} samples[16];
|
||||
u32_le count;
|
||||
u32_le source_id;
|
||||
};
|
||||
static_assert(sizeof(IoctlGetCpuTimeCorrelationInfo) == 264);
|
||||
|
||||
NvResult GetCharacteristics1(IoctlCharacteristics& params);
|
||||
NvResult GetCharacteristics3(IoctlCharacteristics& params,
|
||||
std::span<IoctlGpuCharacteristics> gpu_characteristics);
|
||||
|
@ -171,6 +181,18 @@ private:
|
|||
// Events
|
||||
Kernel::KEvent* error_notifier_event;
|
||||
Kernel::KEvent* unknown_event;
|
||||
|
||||
struct ZbcEntry {
|
||||
u32_le color_ds[4];
|
||||
u32_le color_l2[4];
|
||||
u32_le depth;
|
||||
u32_le type;
|
||||
u32_le format;
|
||||
};
|
||||
std::array<ZbcEntry, 16> color_entries;
|
||||
std::array<ZbcEntry, 16> depth_entries;
|
||||
u8 max_color_entries;
|
||||
u8 max_depth_entries;
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue