gpu: Correct display transfer output with vertical flip+crop lines (#6952)
This commit is contained in:
parent
6aa31d6ec2
commit
0b0d3a4ac3
|
@ -128,7 +128,7 @@ static void MemoryFill(const Regs::MemoryFillConfig& config) {
|
||||||
|
|
||||||
static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
|
static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
|
||||||
const PAddr src_addr = config.GetPhysicalInputAddress();
|
const PAddr src_addr = config.GetPhysicalInputAddress();
|
||||||
const PAddr dst_addr = config.GetPhysicalOutputAddress();
|
PAddr dst_addr = config.GetPhysicalOutputAddress();
|
||||||
|
|
||||||
// TODO: do hwtest with these cases
|
// TODO: do hwtest with these cases
|
||||||
if (!g_memory->IsValidPhysicalAddress(src_addr)) {
|
if (!g_memory->IsValidPhysicalAddress(src_addr)) {
|
||||||
|
@ -164,6 +164,14 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
|
||||||
if (VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config))
|
if (VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Using flip_vertically alongside crop_input_lines produces skewed output on hardware.
|
||||||
|
// We have to emulate this because some games rely on this behaviour to render correctly.
|
||||||
|
if (config.flip_vertically && config.crop_input_lines &&
|
||||||
|
config.input_width > config.output_width) {
|
||||||
|
dst_addr += (config.input_width - config.output_width) * (config.output_height - 1) *
|
||||||
|
GPU::Regs::BytesPerPixel(config.output_format);
|
||||||
|
}
|
||||||
|
|
||||||
u8* src_pointer = g_memory->GetPhysicalPointer(src_addr);
|
u8* src_pointer = g_memory->GetPhysicalPointer(src_addr);
|
||||||
u8* dst_pointer = g_memory->GetPhysicalPointer(dst_addr);
|
u8* dst_pointer = g_memory->GetPhysicalPointer(dst_addr);
|
||||||
|
|
||||||
|
|
|
@ -272,6 +272,14 @@ bool RasterizerCache<T>::AccelerateDisplayTransfer(const GPU::Regs::DisplayTrans
|
||||||
dst_params.pixel_format = PixelFormatFromGPUPixelFormat(config.output_format);
|
dst_params.pixel_format = PixelFormatFromGPUPixelFormat(config.output_format);
|
||||||
dst_params.UpdateParams();
|
dst_params.UpdateParams();
|
||||||
|
|
||||||
|
// Using flip_vertically alongside crop_input_lines produces skewed output on hardware.
|
||||||
|
// We have to emulate this because some games rely on this behaviour to render correctly.
|
||||||
|
if (config.flip_vertically && config.crop_input_lines &&
|
||||||
|
config.input_width > config.output_width) {
|
||||||
|
dst_params.addr += (config.input_width - config.output_width) * (config.output_height - 1) *
|
||||||
|
GPU::Regs::BytesPerPixel(config.output_format);
|
||||||
|
}
|
||||||
|
|
||||||
auto [src_surface_id, src_rect] = GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
auto [src_surface_id, src_rect] = GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
|
||||||
if (!src_surface_id) {
|
if (!src_surface_id) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Reference in New Issue