summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hw/gpu.cpp41
-rw-r--r--src/core/hw/gpu.h2
2 files changed, 24 insertions, 19 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 42809c731..6838e449c 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);
333
334 u32 remaining_size = Common::AlignDown(config.texture_copy.size, 16);
335
336 if (remaining_size == 0) {
337 LOG_CRITICAL(HW_GPU, "zero size. Real hardware freezes on this.");
334 return; 338 return;
335 } 339 }
336 340
337 if (config.texture_copy.size == 0) { 341 u32 input_gap = config.texture_copy.input_gap * 16;
338 LOG_CRITICAL(HW_GPU, "zero size"); 342 u32 output_gap = config.texture_copy.output_gap * 16;
343
344 // Zero gap means contiguous input/output even if width = 0. To avoid infinite loop below, width
345 // is assigned with the total size if gap = 0.
346 u32 input_width = input_gap == 0 ? remaining_size : config.texture_copy.input_width * 16;
347 u32 output_width = output_gap == 0 ? remaining_size : config.texture_copy.output_width * 16;
348
349 if (input_width == 0) {
350 LOG_CRITICAL(HW_GPU, "zero input width. Real hardware freezes on this.");
339 return; 351 return;
340 } 352 }
341 353
342 if (VideoCore::g_renderer->Rasterizer()->AccelerateTextureCopy(config)) 354 if (output_width == 0) {
355 LOG_CRITICAL(HW_GPU, "zero output width. Real hardware freezes on this.");
343 return; 356 return;
344 357 }
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;
350 u32 output_width = config.texture_copy.output_width * 16;
351 u32 output_gap = config.texture_copy.output_gap * 16;
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) {
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index bdd997b2a..21b127fee 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -225,7 +225,7 @@ struct Regs {
225 INSERT_PADDING_WORDS(0x1); 225 INSERT_PADDING_WORDS(0x1);
226 226
227 struct { 227 struct {
228 u32 size; 228 u32 size; // The lower 4 bits are ignored
229 229
230 union { 230 union {
231 u32 input_size; 231 u32 input_size;