From 9ae5a09655a568b55279f9b3cb6704144d9c442f Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Thu, 23 Jul 2015 16:25:59 -0300 Subject: GPU: Implement TextureCopy-mode display transfers Fixes glitchy garbage in Fire Emblem 3D scenes. --- src/core/hle/service/gsp_gpu.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/core/hle/service/gsp_gpu.cpp') diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index e93c1b436..3c41e656c 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -418,7 +418,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { case CommandId::SET_DISPLAY_TRANSFER: { - auto& params = command.image_copy; + auto& params = command.display_transfer; WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.input_address)), Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.output_address)), @@ -433,17 +433,22 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { // TODO: Check if texture copies are implemented correctly.. case CommandId::SET_TEXTURE_COPY: { - auto& params = command.image_copy; - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.input_address)), + auto& params = command.texture_copy; + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.input_address), Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.output_address)), + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.output_address), Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.input_size)), params.in_buffer_size); - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.output_size)), params.out_buffer_size); - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.flags)), params.flags); - - // TODO: Should this register be set to 1 or should instead its value be OR-ed with 1? - WriteGPURegister(static_cast(GPU_REG_INDEX(display_transfer_config.trigger)), 1); + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.size), + params.size); + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.input_size), + params.in_width_gap); + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.output_size), + params.out_width_gap); + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.flags), + params.flags); + + // NOTE: Actual GSP ORs 1 with current register instead of overwriting. Doesn't seem to matter. + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.trigger), 1); break; } -- cgit v1.2.3