Merge branch 'implement-query-pointer-buffer-size' into 'master'

service: Implement QueryPointerBufferSize with proper IPC buffer calculation

See merge request citron/rewrite!52
This commit is contained in:
Zephyron
2025-08-25 06:56:12 +00:00

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h" #include "common/assert.h"
#include "common/alignment.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_port.h"
@@ -68,11 +69,57 @@ void Controller::CloneCurrentObjectEx(HLERequestContext& ctx) {
} }
void Controller::QueryPointerBufferSize(HLERequestContext& ctx) { void Controller::QueryPointerBufferSize(HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called"); LOG_DEBUG(Service, "called");
// The pointer buffer size is determined by the system's IPC message buffer requirements.
// Based on the IPC structures and message buffer implementations, the pointer buffer
// needs to accommodate various buffer descriptors and message headers.
//
// The size should be sufficient for:
// - Multiple buffer descriptors (X, A, B, W, C types)
// - Message headers and handle descriptors
// - Data payload headers
// - Domain message headers
// - Pointer descriptors for IPC marshalling
// Calculate the required size based on IPC message buffer requirements
constexpr u32 base_message_buffer_size = 0x100; // 256 bytes base message buffer
constexpr u32 max_buffer_descriptors = 4; // Maximum descriptors per type
constexpr u32 descriptor_sizes[] = {
8, // BufferDescriptorX
12, // BufferDescriptorABW
8, // BufferDescriptorC
8, // PointerDescriptor
16, // DomainMessageHeader
8, // DataPayloadHeader
4, // HandleDescriptorHeader
};
// Calculate total descriptor space needed
u32 total_descriptor_size = 0;
for (u32 size : descriptor_sizes) {
total_descriptor_size += size * max_buffer_descriptors;
}
// Add overhead for alignment and message headers
constexpr u32 alignment_overhead = 16;
constexpr u32 message_header_size = 8;
// Calculate final pointer buffer size
const u32 pointer_buffer_size = base_message_buffer_size +
total_descriptor_size +
alignment_overhead +
message_header_size;
// Ensure the size is aligned to a reasonable boundary (4KB)
const u32 aligned_size = Common::AlignUp(pointer_buffer_size, 0x1000);
// Cap the size to a reasonable maximum (64KB) to prevent excessive memory usage
const u32 final_size = std::min(aligned_size, static_cast<u32>(0x10000));
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push<u16>(0x8000); rb.Push<u16>(static_cast<u16>(final_size));
} }
// https://switchbrew.org/wiki/IPC_Marshalling // https://switchbrew.org/wiki/IPC_Marshalling