mirror of
https://git.citron-emu.org/Citron/Citron.git
synced 2025-02-12 11:36:26 +01:00
nvdrv: Add GetTpcMasks2 support and improve memory mapping validation
This commit makes two main changes: 1. Adds support for GetTpcMasks2 (ioctl 0x13) in nvhost_ctrl_gpu: - Implements new GetTpcMasks2 method to handle TPC mask queries - Adds IoctlGetTpcMasks structure to store mask parameters - Returns conservative single TPC configuration for compatibility 2. Enhances memory mapping validation in HostMemory: - Adds verification check after memory mapping operations - Improves error handling for direct mapped address enabling - Adds logging for mapping and direct address failures Additional changes: - Updates copyright headers to include citron Emulator Project - Improves error handling and validation in several paths - Adds debug logging for TPC mask operations This improves GPU virtualization support and memory mapping reliability.
This commit is contained in:
parent
e8bbdbce42
commit
ecc32958ec
3 changed files with 49 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -720,10 +721,18 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
|||
ASSERT(length % PageAlignment == 0);
|
||||
ASSERT(virtual_offset + length <= virtual_size);
|
||||
ASSERT(host_offset + length <= backing_size);
|
||||
|
||||
if (length == 0 || !virtual_base || !impl) {
|
||||
return;
|
||||
}
|
||||
|
||||
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
|
||||
|
||||
// Verify mapping was successful
|
||||
if (!impl->IsValidMapping(virtual_offset + virtual_base_offset, length)) {
|
||||
LOG_CRITICAL(Common_Memory, "Failed to verify memory mapping: virtual_offset={:x}, host_offset={:x}, length={:x}",
|
||||
virtual_offset, host_offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
|
||||
|
@ -756,9 +765,18 @@ void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 f
|
|||
}
|
||||
|
||||
void HostMemory::EnableDirectMappedAddress() {
|
||||
if (impl) {
|
||||
impl->EnableDirectMappedAddress();
|
||||
if (!impl) {
|
||||
LOG_ERROR(Common_Memory, "Implementation not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
impl->EnableDirectMappedAddress();
|
||||
|
||||
// Only update virtual_size if the direct mapping was successful
|
||||
if (impl->IsDirectMappingEnabled()) {
|
||||
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
|
||||
} else {
|
||||
LOG_ERROR(Common_Memory, "Failed to enable direct mapped address");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
|
@ -45,6 +46,8 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
|
|||
return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output);
|
||||
case 0x1c:
|
||||
return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output);
|
||||
case 0x13:
|
||||
return WrapFixed(this, &nvhost_ctrl_gpu::GetTpcMasks2, input, output);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -261,6 +264,24 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) {
|
|||
return NvResult::Success;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::GetTpcMasks2(IoctlGetTpcMasks& params) {
|
||||
LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size={}", params.mask_buf_size);
|
||||
|
||||
// Validate input parameters
|
||||
if (params.mask_buf_size == 0 || params.mask_buf_size > params.tpc_mask_buf.size()) {
|
||||
LOG_ERROR(Service_NVDRV, "Invalid mask buffer size {}", params.mask_buf_size);
|
||||
return NvResult::InvalidValue;
|
||||
}
|
||||
|
||||
// Set up TPC mask values based on GPU configuration
|
||||
// Using conservative values for compatibility
|
||||
params.mask_buf_size = 1;
|
||||
params.tpc_mask_buf[0] = 0x1; // Enable first TPC only
|
||||
|
||||
LOG_DEBUG(Service_NVDRV, "TPC mask set to 0x{:x}", params.tpc_mask_buf[0]);
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
|
||||
switch (event_id) {
|
||||
case 1:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
@ -34,6 +35,11 @@ public:
|
|||
|
||||
Kernel::KEvent* QueryEvent(u32 event_id) override;
|
||||
|
||||
struct IoctlGetTpcMasks {
|
||||
u32 mask_buf_size{};
|
||||
std::array<u32, 1> tpc_mask_buf{};
|
||||
};
|
||||
|
||||
private:
|
||||
static constexpr std::size_t MaxZBCTableSize = 16;
|
||||
static constexpr std::size_t MaxZBCFormats = 32;
|
||||
|
@ -201,6 +207,8 @@ private:
|
|||
NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params);
|
||||
NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask);
|
||||
|
||||
NvResult GetTpcMasks2(IoctlGetTpcMasks& params);
|
||||
|
||||
NvResult GetActiveSlotMask(IoctlActiveSlotMask& params);
|
||||
NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params);
|
||||
NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params);
|
||||
|
|
Loading…
Reference in a new issue