summaryrefslogtreecommitdiff
path: root/src/core/hw/gpu.cpp
diff options
context:
space:
mode:
authorGravatar wwylele2017-06-27 23:20:13 +0300
committerGravatar wwylele2017-06-27 23:20:23 +0300
commitbf16c73260787f80de2a0bc13b11737471695d0f (patch)
tree14c048ae681cb4b9c72278dd11369433eaef57e7 /src/core/hw/gpu.cpp
parentMerge pull request #2778 from Subv/uds_more (diff)
downloadyuzu-bf16c73260787f80de2a0bc13b11737471695d0f.tar.gz
yuzu-bf16c73260787f80de2a0bc13b11737471695d0f.tar.xz
yuzu-bf16c73260787f80de2a0bc13b11737471695d0f.zip
gpu: fix edge cases for TextureCopy
Diffstat (limited to 'src/core/hw/gpu.cpp')
-rw-r--r--src/core/hw/gpu.cpp41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 42809c731..a0a523822 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -5,6 +5,7 @@
5#include <cstring> 5#include <cstring>
6#include <numeric> 6#include <numeric>
7#include <type_traits> 7#include <type_traits>
8#include "common/alignment.h"
8#include "common/color.h" 9#include "common/color.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "common/logging/log.h" 11#include "common/logging/log.h"
@@ -313,7 +314,7 @@ static void TextureCopy(const Regs::DisplayTransferConfig& config) {
313 const PAddr src_addr = config.GetPhysicalInputAddress(); 314 const PAddr src_addr = config.GetPhysicalInputAddress();
314 const PAddr dst_addr = config.GetPhysicalOutputAddress(); 315 const PAddr dst_addr = config.GetPhysicalOutputAddress();
315 316
316 // TODO: do hwtest with these cases 317 // TODO: do hwtest with invalid addresses
317 if (!Memory::IsValidPhysicalAddress(src_addr)) { 318 if (!Memory::IsValidPhysicalAddress(src_addr)) {
318 LOG_CRITICAL(HW_GPU, "invalid input address 0x%08X", src_addr); 319 LOG_CRITICAL(HW_GPU, "invalid input address 0x%08X", src_addr);
319 return; 320 return;
@@ -324,31 +325,36 @@ static void TextureCopy(const Regs::DisplayTransferConfig& config) {
324 return; 325 return;
325 } 326 }
326 327
327 if (config.texture_copy.input_width == 0) { 328 if (VideoCore::g_renderer->Rasterizer()->AccelerateTextureCopy(config))
328 LOG_CRITICAL(HW_GPU, "zero input width");
329 return; 329 return;
330 }
331 330
332 if (config.texture_copy.output_width == 0) { 331 u8* src_pointer = Memory::GetPhysicalPointer(src_addr);
333 LOG_CRITICAL(HW_GPU, "zero output width"); 332 u8* dst_pointer = Memory::GetPhysicalPointer(dst_addr);
334 return;
335 }
336 333
337 if (config.texture_copy.size == 0) { 334 u32 remaining_size = Common::AlignDown(config.texture_copy.size, 16);
335
336 if (remaining_size == 0) {
337 // Real hardware freeze on this
338 LOG_CRITICAL(HW_GPU, "zero size"); 338 LOG_CRITICAL(HW_GPU, "zero size");
339 return; 339 return;
340 } 340 }
341 341
342 if (VideoCore::g_renderer->Rasterizer()->AccelerateTextureCopy(config))
343 return;
344
345 u8* src_pointer = Memory::GetPhysicalPointer(src_addr);
346 u8* dst_pointer = Memory::GetPhysicalPointer(dst_addr);
347
348 u32 input_width = config.texture_copy.input_width * 16;
349 u32 input_gap = config.texture_copy.input_gap * 16; 342 u32 input_gap = config.texture_copy.input_gap * 16;
350 u32 output_width = config.texture_copy.output_width * 16; 343 u32 input_width = input_gap == 0 ? remaining_size : config.texture_copy.input_width * 16;
351 u32 output_gap = config.texture_copy.output_gap * 16; 344 u32 output_gap = config.texture_copy.output_gap * 16;
345 u32 output_width = output_gap == 0 ? remaining_size : config.texture_copy.output_width * 16;
346
347 if (input_width == 0) {
348 // Real hardware freeze on this
349 LOG_CRITICAL(HW_GPU, "zero input width");
350 return;
351 }
352
353 if (output_width == 0) {
354 // Real hardware freeze on this
355 LOG_CRITICAL(HW_GPU, "zero output width");
356 return;
357 }
352 358
353 size_t contiguous_input_size = 359 size_t contiguous_input_size =
354 config.texture_copy.size / input_width * (input_width + input_gap); 360 config.texture_copy.size / input_width * (input_width + input_gap);
@@ -360,7 +366,6 @@ static void TextureCopy(const Regs::DisplayTransferConfig& config) {
360 Memory::RasterizerFlushAndInvalidateRegion(config.GetPhysicalOutputAddress(), 366 Memory::RasterizerFlushAndInvalidateRegion(config.GetPhysicalOutputAddress(),
361 static_cast<u32>(contiguous_output_size)); 367 static_cast<u32>(contiguous_output_size));
362 368
363 u32 remaining_size = config.texture_copy.size;
364 u32 remaining_input = input_width; 369 u32 remaining_input = input_width;
365 u32 remaining_output = output_width; 370 u32 remaining_output = output_width;
366 while (remaining_size > 0) { 371 while (remaining_size > 0) {