diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index d7a65ce445..a7551ec154 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -256,103 +256,61 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) { } NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) { - if (params.type > supported_types) { - LOG_ERROR(Service_NVDRV, "ZBCSetTable: invalid type {:#X}", params.type); - return NvResult::BadParameter; - } - - std::scoped_lock lk(zbc_mutex); - - switch (static_cast(params.type)) { - case ZBCTypes::color: { - ZbcColorEntry color_entry{}; - std::copy_n(std::begin(params.color_ds), color_entry.color_ds.size(), color_entry.color_ds.begin()); - std::copy_n(std::begin(params.color_l2), color_entry.color_l2.size(), color_entry.color_l2.begin()); - color_entry.format = params.format; - color_entry.ref_cnt = 1u; - - auto color_it = std::ranges::find_if(zbc_colors, - [&](const ZbcColorEntry& color_in_question) { - return color_entry.format == color_in_question.format && - color_entry.color_ds == color_in_question.color_ds && - color_entry.color_l2 == color_in_question.color_l2; - }); - - if (color_it != zbc_colors.end()) { - ++color_it->ref_cnt; - LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused color entry fmt={:#X}, ref_cnt={:#X}", - params.format, color_it->ref_cnt); - } else { - zbc_colors.push_back(color_entry); - LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added color entry fmt={:#X}, index={:#X}", - params.format, zbc_colors.size() - 1); - } - break; - } - case ZBCTypes::depth: { - ZbcDepthEntry depth_entry{params.depth, params.format, 1u}; - - auto depth_it = std::ranges::find_if(zbc_depths, - [&](const ZbcDepthEntry& depth_entry_in_question) { - return depth_entry.format == depth_entry_in_question.format && - depth_entry.depth == depth_entry_in_question.depth; - }); - - if (depth_it != zbc_depths.end()) { - ++depth_it->ref_cnt; - LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused depth entry fmt={:#X}, ref_cnt={:#X}", - depth_entry.format, depth_it->ref_cnt); - } else { - zbc_depths.push_back(depth_entry); - LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added depth entry fmt={:#X}, index={:#X}", - depth_entry.format, zbc_depths.size() - 1); - } + 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) { - if (params.type > supported_types) { - LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid type {:#X}", params.type); - return NvResult::BadParameter; - } - - std::scoped_lock lk(zbc_mutex); - - switch (static_cast(params.type)) { - case ZBCTypes::color: { - if (params.index_size >= zbc_colors.size()) { - LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid color index {:#X}", params.index_size); - return NvResult::BadParameter; - } - - const auto& colors = zbc_colors[params.index_size]; - std::copy_n(colors.color_ds.begin(), colors.color_ds.size(), std::begin(params.color_ds)); - std::copy_n(colors.color_l2.begin(), colors.color_l2.size(), std::begin(params.color_l2)); - params.depth = 0; - params.ref_cnt = colors.ref_cnt; - params.format = colors.format; - params.index_size = static_cast(zbc_colors.size()); - break; - } - case ZBCTypes::depth: { - if (params.index_size >= zbc_depths.size()) { - LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid depth index {:#X}", params.index_size); - return NvResult::BadParameter; - } - - const auto& depth_entry = zbc_depths[params.index_size]; - std::fill(std::begin(params.color_ds), std::end(params.color_ds), 0); - std::fill(std::begin(params.color_l2), std::end(params.color_l2), 0); - params.depth = depth_entry.depth; - params.ref_cnt = depth_entry.ref_cnt; - params.format = depth_entry.format; - params.index_size = static_cast(zbc_depths.size()); + 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; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index e0603f9a71..c36fcbaa69 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -37,11 +34,6 @@ public: Kernel::KEvent* QueryEvent(u32 event_id) override; private: - enum class ZBCTypes { - color = 1, - depth = 2, - }; - struct IoctlGpuCharacteristics { u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200) u32_le impl; // 0xB (NVGPU_GPU_IMPL_GM20B) @@ -147,21 +139,6 @@ private: }; static_assert(sizeof(IoctlZbcQueryTable) == 52, "IoctlZbcQueryTable is incorrect size"); - struct ZbcColorEntry { - std::array color_ds{}; - std::array color_l2{}; - u32 format{}; - u32 ref_cnt{}; - }; - static_assert(sizeof(ZbcColorEntry) == 40, "ZbcColorEntry is incorrect size"); - - struct ZbcDepthEntry { - u32 depth{}; - u32 format{}; - u32 ref_cnt{}; - }; - static_assert(sizeof(ZbcDepthEntry) == 12, "ZbcDepthEntry is incorrect size"); - struct IoctlFlushL2 { u32_le flush; // l2_flush | l2_invalidate << 1 | fb_flush << 2 u32_le reserved; @@ -205,11 +182,17 @@ private: Kernel::KEvent* error_notifier_event; Kernel::KEvent* unknown_event; - // ZBC Tables - std::mutex zbc_mutex{}; - std::vector zbc_colors{}; - std::vector zbc_depths{}; - const u32 supported_types = 2u; + struct ZbcEntry { + u32_le color_ds[4]; + u32_le color_l2[4]; + u32_le depth; + u32_le type; + u32_le format; + }; + std::array color_entries; + std::array depth_entries; + u8 max_color_entries; + u8 max_depth_entries; }; } // namespace Service::Nvidia::Devices