Browse Source

[hle] BufferDescritorC

eds-true-adreno-fixes
CamilleLaVey 3 weeks ago
committed by Caio Oliveira
parent
commit
98b4bfb461
No known key found for this signature in database GPG Key ID: AAAE6C7FD4186B0C
  1. 71
      src/core/hle/service/hle_ipc.cpp
  2. 1
      src/core/hle/service/hle_ipc.h

71
src/core/hle/service/hle_ipc.cpp

@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cstring>
#include <sstream> #include <sstream>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
@ -187,7 +188,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
buffer_w_descriptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>()); buffer_w_descriptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
} }
const auto buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
if (!command_header->IsTipc()) { if (!command_header->IsTipc()) {
// Padding to align to 16 bytes // Padding to align to 16 bytes
@ -294,7 +295,15 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer() {
} }
// Write the domain objects to the command buffer, these go after the raw untranslated data. // Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
if (buffer_c_offset != 0 && !buffer_c_descriptors.empty()) {
constexpr u32 WORDS_PER_DESCRIPTOR = sizeof(IPC::BufferDescriptorC) / sizeof(u32);
u32 descriptor_offset = buffer_c_offset;
for (const auto& descriptor : buffer_c_descriptors) {
std::memcpy(&cmd_buf[descriptor_offset], &descriptor, sizeof(descriptor));
descriptor_offset += WORDS_PER_DESCRIPTOR;
}
}
if (GetManager()->IsDomain()) { if (GetManager()->IsDomain()) {
current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size()); current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size());
@ -393,10 +402,14 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
BufferDescriptorB()[buffer_index].Size()}; BufferDescriptorB()[buffer_index].Size()};
const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBuffer target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) { if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
} }
if (is_buffer_b) { if (is_buffer_b) {
@ -418,15 +431,25 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size, std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size,
std::size_t buffer_index) const { std::size_t buffer_index) const {
if (buffer_index >= BufferDescriptorB().size() || size == 0) {
if (buffer_index >= BufferDescriptorB().size()) {
LOG_WARNING(Core, "WriteBufferB invalid buffer index {}", buffer_index);
return 0;
}
if (size == 0) {
LOG_WARNING(Core, "skip empty buffer write (B)");
return 0; return 0;
} }
const auto buffer_size{BufferDescriptorB()[buffer_index].Size()}; const auto buffer_size{BufferDescriptorB()[buffer_index].Size()};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBufferB target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) { if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
} }
memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size);
@ -435,15 +458,25 @@ std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size
std::size_t HLERequestContext::WriteBufferC(const void* buffer, std::size_t size, std::size_t HLERequestContext::WriteBufferC(const void* buffer, std::size_t size,
std::size_t buffer_index) const { std::size_t buffer_index) const {
if (buffer_index >= BufferDescriptorC().size() || size == 0) {
if (buffer_index >= BufferDescriptorC().size()) {
LOG_WARNING(Core, "WriteBufferC invalid buffer index {}", buffer_index);
return 0;
}
if (size == 0) {
LOG_WARNING(Core, "skip empty buffer write (C)");
return 0; return 0;
} }
const auto buffer_size{BufferDescriptorC()[buffer_index].Size()}; const auto buffer_size{BufferDescriptorC()[buffer_index].Size()};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBufferC target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) { if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
} }
memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size);
@ -473,12 +506,20 @@ std::size_t HLERequestContext::GetWriteBufferSize(std::size_t buffer_index) cons
ASSERT_OR_EXECUTE_MSG( ASSERT_OR_EXECUTE_MSG(
BufferDescriptorB().size() > buffer_index, { return 0; }, BufferDescriptorB().size() > buffer_index, { return 0; },
"BufferDescriptorB invalid buffer_index {}", buffer_index); "BufferDescriptorB invalid buffer_index {}", buffer_index);
return BufferDescriptorB()[buffer_index].Size();
const auto size = BufferDescriptorB()[buffer_index].Size();
if (size == 0) {
LOG_WARNING(Core, "BufferDescriptorB index {} has zero size", buffer_index);
}
return size;
} else { } else {
ASSERT_OR_EXECUTE_MSG( ASSERT_OR_EXECUTE_MSG(
BufferDescriptorC().size() > buffer_index, { return 0; }, BufferDescriptorC().size() > buffer_index, { return 0; },
"BufferDescriptorC invalid buffer_index {}", buffer_index); "BufferDescriptorC invalid buffer_index {}", buffer_index);
return BufferDescriptorC()[buffer_index].Size();
const auto size = BufferDescriptorC()[buffer_index].Size();
if (size == 0) {
LOG_WARNING(Core, "BufferDescriptorC index {} has zero size", buffer_index);
}
return size;
} }
return 0; return 0;
} }

1
src/core/hle/service/hle_ipc.h

@ -422,6 +422,7 @@ private:
u32 data_payload_offset{}; u32 data_payload_offset{};
u32 handles_offset{}; u32 handles_offset{};
u32 domain_offset{}; u32 domain_offset{};
u32 buffer_c_offset{};
std::weak_ptr<SessionRequestManager> manager{}; std::weak_ptr<SessionRequestManager> manager{};
bool is_deferred{false}; bool is_deferred{false};

Loading…
Cancel
Save