summaryrefslogtreecommitdiff
path: root/src/audio_core/renderer
diff options
context:
space:
mode:
authorGravatar Kelebek12023-02-11 16:27:43 +0000
committerGravatar Kelebek12023-02-11 16:27:43 +0000
commit2e02ed8bb574255383667969a46280d435964c2c (patch)
tree0d3309c4e0f433c330650a0c69316938f7d052cc /src/audio_core/renderer
parentFix depop prepare receiving bad mix infos and writing out of bounds, and upda... (diff)
downloadyuzu-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_.cpp76
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_;