summaryrefslogtreecommitdiff
path: root/src/core/hw/gpu.cpp
diff options
context:
space:
mode:
authorGravatar wwylele2016-09-27 21:03:44 +0800
committerGravatar wwylele2016-09-29 10:01:34 +0800
commit48470e57fc52f7883d825675e4410fb4fe735643 (patch)
treea57d39dc9d3790432d08e8d602393aa204a05b4d /src/core/hw/gpu.cpp
parentmemory: fix IsValidVirtualAddress for RasterizerCachedMemory (diff)
downloadyuzu-48470e57fc52f7883d825675e4410fb4fe735643.tar.gz
yuzu-48470e57fc52f7883d825675e4410fb4fe735643.tar.xz
yuzu-48470e57fc52f7883d825675e4410fb4fe735643.zip
gpu: add validity check for TextureCopy, DisplayTransfer and FillMemory
prevent further operation with invalid values which may cause assertion failure or divided by zero. needs more hwtest
Diffstat (limited to 'src/core/hw/gpu.cpp')
-rw-r--r--src/core/hw/gpu.cpp94
1 files changed, 88 insertions, 6 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 4b3e893db..b90f5e5f9 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -81,8 +81,27 @@ MICROPROFILE_DEFINE(GPU_DisplayTransfer, "GPU", "DisplayTransfer", MP_RGB(100, 1
81MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100)); 81MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100));
82 82
83static void MemoryFill(const Regs::MemoryFillConfig& config) { 83static void MemoryFill(const Regs::MemoryFillConfig& config) {
84 u8* start = Memory::GetPhysicalPointer(config.GetStartAddress()); 84 const PAddr start_addr = config.GetStartAddress();
85 u8* end = Memory::GetPhysicalPointer(config.GetEndAddress()); 85 const PAddr end_addr = config.GetEndAddress();
86
87 // TODO: do hwtest with these cases
88 if (!Memory::IsValidPhysicalAddress(start_addr)) {
89 LOG_CRITICAL(HW_GPU, "invalid start address 0x%08X", start_addr);
90 return;
91 }
92
93 if (!Memory::IsValidPhysicalAddress(end_addr)) {
94 LOG_CRITICAL(HW_GPU, "invalid end address 0x%08X", end_addr);
95 return;
96 }
97
98 if (end_addr <= start_addr) {
99 LOG_CRITICAL(HW_GPU, "invalid memory range from 0x%08X to 0x%08X", start_addr, end_addr);
100 return;
101 }
102
103 u8* start = Memory::GetPhysicalPointer(start_addr);
104 u8* end = Memory::GetPhysicalPointer(end_addr);
86 105
87 // TODO: Consider always accelerating and returning vector of 106 // TODO: Consider always accelerating and returning vector of
88 // regions that the accelerated fill did not cover to 107 // regions that the accelerated fill did not cover to
@@ -123,11 +142,45 @@ static void MemoryFill(const Regs::MemoryFillConfig& config) {
123} 142}
124 143
125static void DisplayTransfer(const Regs::DisplayTransferConfig& config) { 144static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
145 const PAddr src_addr = config.GetPhysicalInputAddress();
146 const PAddr dst_addr = config.GetPhysicalOutputAddress();
147
148 // TODO: do hwtest with these cases
149 if (!Memory::IsValidPhysicalAddress(src_addr)) {
150 LOG_CRITICAL(HW_GPU, "invalid input address 0x%08X", src_addr);
151 return;
152 }
153
154 if (!Memory::IsValidPhysicalAddress(dst_addr)) {
155 LOG_CRITICAL(HW_GPU, "invalid output address 0x%08X", dst_addr);
156 return;
157 }
158
159 if (config.input_width == 0) {
160 LOG_CRITICAL(HW_GPU, "zero input width");
161 return;
162 }
163
164 if (config.input_height == 0) {
165 LOG_CRITICAL(HW_GPU, "zero input height");
166 return;
167 }
168
169 if (config.output_width == 0) {
170 LOG_CRITICAL(HW_GPU, "zero output width");
171 return;
172 }
173
174 if (config.output_height == 0) {
175 LOG_CRITICAL(HW_GPU, "zero output height");
176 return;
177 }
178
126 if (VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config)) 179 if (VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config))
127 return; 180 return;
128 181
129 u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress()); 182 u8* src_pointer = Memory::GetPhysicalPointer(src_addr);
130 u8* dst_pointer = Memory::GetPhysicalPointer(config.GetPhysicalOutputAddress()); 183 u8* dst_pointer = Memory::GetPhysicalPointer(dst_addr);
131 184
132 if (config.scaling > config.ScaleXY) { 185 if (config.scaling > config.ScaleXY) {
133 LOG_CRITICAL(HW_GPU, "Unimplemented display transfer scaling mode %u", 186 LOG_CRITICAL(HW_GPU, "Unimplemented display transfer scaling mode %u",
@@ -262,11 +315,40 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
262} 315}
263 316
264static void TextureCopy(const Regs::DisplayTransferConfig& config) { 317static void TextureCopy(const Regs::DisplayTransferConfig& config) {
318 const PAddr src_addr = config.GetPhysicalInputAddress();
319 const PAddr dst_addr = config.GetPhysicalOutputAddress();
320
321 // TODO: do hwtest with these cases
322 if (!Memory::IsValidPhysicalAddress(src_addr)) {
323 LOG_CRITICAL(HW_GPU, "invalid input address 0x%08X", src_addr);
324 return;
325 }
326
327 if (!Memory::IsValidPhysicalAddress(dst_addr)) {
328 LOG_CRITICAL(HW_GPU, "invalid output address 0x%08X", dst_addr);
329 return;
330 }
331
332 if (config.texture_copy.input_width == 0) {
333 LOG_CRITICAL(HW_GPU, "zero input width");
334 return;
335 }
336
337 if (config.texture_copy.output_width == 0) {
338 LOG_CRITICAL(HW_GPU, "zero output width");
339 return;
340 }
341
342 if (config.texture_copy.size == 0) {
343 LOG_CRITICAL(HW_GPU, "zero size");
344 return;
345 }
346
265 if (VideoCore::g_renderer->Rasterizer()->AccelerateTextureCopy(config)) 347 if (VideoCore::g_renderer->Rasterizer()->AccelerateTextureCopy(config))
266 return; 348 return;
267 349
268 u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress()); 350 u8* src_pointer = Memory::GetPhysicalPointer(src_addr);
269 u8* dst_pointer = Memory::GetPhysicalPointer(config.GetPhysicalOutputAddress()); 351 u8* dst_pointer = Memory::GetPhysicalPointer(dst_addr);
270 352
271 u32 input_width = config.texture_copy.input_width * 16; 353 u32 input_width = config.texture_copy.input_width * 16;
272 u32 input_gap = config.texture_copy.input_gap * 16; 354 u32 input_gap = config.texture_copy.input_gap * 16;