diff options
| author | 2016-09-27 21:03:44 +0800 | |
|---|---|---|
| committer | 2016-09-29 10:01:34 +0800 | |
| commit | 48470e57fc52f7883d825675e4410fb4fe735643 (patch) | |
| tree | a57d39dc9d3790432d08e8d602393aa204a05b4d /src/core/hw/gpu.cpp | |
| parent | memory: fix IsValidVirtualAddress for RasterizerCachedMemory (diff) | |
| download | yuzu-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.cpp | 94 |
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 | |||
| 81 | MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100)); | 81 | MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100)); |
| 82 | 82 | ||
| 83 | static void MemoryFill(const Regs::MemoryFillConfig& config) { | 83 | static 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 | ||
| 125 | static void DisplayTransfer(const Regs::DisplayTransferConfig& config) { | 144 | static 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 | ||
| 264 | static void TextureCopy(const Regs::DisplayTransferConfig& config) { | 317 | static 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; |