diff options
| author | 2023-02-11 16:27:43 +0000 | |
|---|---|---|
| committer | 2023-02-11 16:27:43 +0000 | |
| commit | 2e02ed8bb574255383667969a46280d435964c2c (patch) | |
| tree | 0d3309c4e0f433c330650a0c69316938f7d052cc /src/audio_core/renderer | |
| parent | Fix depop prepare receiving bad mix infos and writing out of bounds, and upda... (diff) | |
| download | yuzu-2e02ed8bb574255383667969a46280d435964c2c.tar.gz yuzu-2e02ed8bb574255383667969a46280d435964c2c.tar.xz yuzu-2e02ed8bb574255383667969a46280d435964c2c.zip | |
Add fallback for memory read/write in case the address goes over a 4K page
Diffstat (limited to 'src/audio_core/renderer')
| -rw-r--r-- | src/audio_core/renderer/command/effect/aux_.cpp | 76 |
1 files changed, 64 insertions, 12 deletions
diff --git a/src/audio_core/renderer/command/effect/aux_.cpp b/src/audio_core/renderer/command/effect/aux_.cpp index 0c69dcc28..c5650effa 100644 --- a/src/audio_core/renderer/command/effect/aux_.cpp +++ b/src/audio_core/renderer/command/effect/aux_.cpp | |||
| @@ -20,10 +20,24 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in | |||
| 20 | return; | 20 | return; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))}; | 23 | AuxInfo::AuxInfoDsp info{}; |
| 24 | info->read_offset = 0; | 24 | auto info_ptr{&info}; |
| 25 | info->write_offset = 0; | 25 | bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <= |
| 26 | info->total_sample_count = 0; | 26 | (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))}; |
| 27 | |||
| 28 | if (host_safe) [[likely]] { | ||
| 29 | info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info); | ||
| 30 | } else { | ||
| 31 | memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 32 | } | ||
| 33 | |||
| 34 | info_ptr->read_offset = 0; | ||
| 35 | info_ptr->write_offset = 0; | ||
| 36 | info_ptr->total_sample_count = 0; | ||
| 37 | |||
| 38 | if (!host_safe) [[unlikely]] { | ||
| 39 | memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 40 | } | ||
| 27 | } | 41 | } |
| 28 | 42 | ||
| 29 | /** | 43 | /** |
| @@ -71,9 +85,18 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, | |||
| 71 | return 0; | 85 | return 0; |
| 72 | } | 86 | } |
| 73 | 87 | ||
| 74 | auto send_info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(send_info_))}; | 88 | AuxInfo::AuxInfoDsp send_info{}; |
| 89 | auto send_ptr = &send_info; | ||
| 90 | bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <= | ||
| 91 | (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp)); | ||
| 92 | |||
| 93 | if (host_safe) [[likely]] { | ||
| 94 | send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_); | ||
| 95 | } else { | ||
| 96 | memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 97 | } | ||
| 75 | 98 | ||
| 76 | u32 target_write_offset{send_info->write_offset + write_offset}; | 99 | u32 target_write_offset{send_ptr->write_offset + write_offset}; |
| 77 | if (target_write_offset > count_max) { | 100 | if (target_write_offset > count_max) { |
| 78 | return 0; | 101 | return 0; |
| 79 | } | 102 | } |
| @@ -82,7 +105,13 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, | |||
| 82 | u32 read_pos{0}; | 105 | u32 read_pos{0}; |
| 83 | while (write_count > 0) { | 106 | while (write_count > 0) { |
| 84 | u32 to_write{std::min(count_max - target_write_offset, write_count)}; | 107 | u32 to_write{std::min(count_max - target_write_offset, write_count)}; |
| 85 | if (to_write) { | 108 | const auto write_addr = send_buffer + target_write_offset * sizeof(s32); |
| 109 | bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <= | ||
| 110 | (Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))}; | ||
| 111 | if (write_safe) [[likely]] { | ||
| 112 | auto ptr = memory.GetPointer(write_addr); | ||
| 113 | std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32)); | ||
| 114 | } else { | ||
| 86 | memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32), | 115 | memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32), |
| 87 | &input[read_pos], to_write * sizeof(s32)); | 116 | &input[read_pos], to_write * sizeof(s32)); |
| 88 | } | 117 | } |
| @@ -92,7 +121,11 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_, | |||
| 92 | } | 121 | } |
| 93 | 122 | ||
| 94 | if (update_count) { | 123 | if (update_count) { |
| 95 | send_info->write_offset = (send_info->write_offset + update_count) % count_max; | 124 | send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max; |
| 125 | } | ||
| 126 | |||
| 127 | if (!host_safe) [[unlikely]] { | ||
| 128 | memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 96 | } | 129 | } |
| 97 | 130 | ||
| 98 | return write_count_; | 131 | return write_count_; |
| @@ -140,9 +173,18 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, | |||
| 140 | return 0; | 173 | return 0; |
| 141 | } | 174 | } |
| 142 | 175 | ||
| 143 | auto return_info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(return_info_))}; | 176 | AuxInfo::AuxInfoDsp return_info{}; |
| 177 | auto return_ptr = &return_info; | ||
| 178 | bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <= | ||
| 179 | (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp)); | ||
| 180 | |||
| 181 | if (host_safe) [[likely]] { | ||
| 182 | return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_); | ||
| 183 | } else { | ||
| 184 | memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 185 | } | ||
| 144 | 186 | ||
| 145 | u32 target_read_offset{return_info->read_offset + read_offset}; | 187 | u32 target_read_offset{return_ptr->read_offset + read_offset}; |
| 146 | if (target_read_offset > count_max) { | 188 | if (target_read_offset > count_max) { |
| 147 | return 0; | 189 | return 0; |
| 148 | } | 190 | } |
| @@ -151,7 +193,13 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, | |||
| 151 | u32 write_pos{0}; | 193 | u32 write_pos{0}; |
| 152 | while (read_count > 0) { | 194 | while (read_count > 0) { |
| 153 | u32 to_read{std::min(count_max - target_read_offset, read_count)}; | 195 | u32 to_read{std::min(count_max - target_read_offset, read_count)}; |
| 154 | if (to_read) { | 196 | const auto read_addr = return_buffer + target_read_offset * sizeof(s32); |
| 197 | bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <= | ||
| 198 | (Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))}; | ||
| 199 | if (read_safe) [[likely]] { | ||
| 200 | auto ptr = memory.GetPointer(read_addr); | ||
| 201 | std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32)); | ||
| 202 | } else { | ||
| 155 | memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32), | 203 | memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32), |
| 156 | &output[write_pos], to_read * sizeof(s32)); | 204 | &output[write_pos], to_read * sizeof(s32)); |
| 157 | } | 205 | } |
| @@ -161,7 +209,11 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_, | |||
| 161 | } | 209 | } |
| 162 | 210 | ||
| 163 | if (update_count) { | 211 | if (update_count) { |
| 164 | return_info->read_offset = (return_info->read_offset + update_count) % count_max; | 212 | return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max; |
| 213 | } | ||
| 214 | |||
| 215 | if (!host_safe) [[unlikely]] { | ||
| 216 | memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp)); | ||
| 165 | } | 217 | } |
| 166 | 218 | ||
| 167 | return read_count_; | 219 | return read_count_; |