Skip to content

Commit

Permalink
rsx image_in: Initial implementation of backwards reading
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Dec 2, 2018
1 parent 67ab7ad commit c43273f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
36 changes: 31 additions & 5 deletions rpcs3/Emu/RSX/rsx_decode.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "Utilities/types.h"
#include "Utilities/BitField.h"
#include "Utilities/StrFmt.h"
Expand Down Expand Up @@ -2243,9 +2243,22 @@ struct registers_decoder<NV3089_DS_DX>
public:
decoded_type(u32 raw_value) { m_data.raw_value = raw_value; }

u32 ds_dx() const
// Convert signed fixed point 32-bit format
f32 ds_dx() const
{
return m_data.raw_value;
const u32 val = m_data.raw_value;

if ((val & ~(1<<31)) == 0)
{
return 0;
}

if (val & (1<<31))
{
fmt::throw_exception("NV3089_DS_DX: value is negative!" HERE);
}

return 1048576.f / val;
}
};

Expand All @@ -2268,9 +2281,22 @@ struct registers_decoder<NV3089_DT_DY>
public:
decoded_type(u32 raw_value) { m_data.raw_value = raw_value; }

u32 dt_dy() const
// Convert signed fixed point 32-bit format
f32 dt_dy() const
{
return m_data.raw_value;
const u32 val = m_data.raw_value;

if ((val & ~(1<<31)) == 0)
{
return 0;
}

if ((s32)val < 0)
{
return 1. / (((val & ~(1<<31)) / 1048576.f) - 2048.f);
}

return 1048576.f / val;
}
};

Expand Down
38 changes: 24 additions & 14 deletions rpcs3/Emu/RSX/rsx_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,16 +803,18 @@ namespace rsx
const blit_engine::transfer_interpolator in_inter = method_registers.blit_engine_input_inter();
const rsx::blit_engine::transfer_source_format src_color_format = method_registers.blit_engine_src_color_format();

const f32 in_x = std::ceil(method_registers.blit_engine_in_x());
const f32 in_y = std::ceil(method_registers.blit_engine_in_y());
f32 scale_x = method_registers.blit_engine_ds_dx();
f32 scale_y = method_registers.blit_engine_dt_dy();

f32 in_x = std::ceil(method_registers.blit_engine_in_x());
f32 in_y = std::ceil(method_registers.blit_engine_in_y());

//Clipping
//Validate that clipping rect will fit onto both src and dst regions
const u16 clip_w = std::min(method_registers.blit_engine_clip_width(), out_w);
const u16 clip_h = std::min(method_registers.blit_engine_clip_height(), out_h);

// Check both clip dimensions and dst dimensions
if (clip_w == 0 || clip_h == 0)
if (clip_w == 0 || clip_h == 0 || scale_x == 0 || scale_y == 0)
{
LOG_WARNING(RSX, "NV3089_IMAGE_IN: Operation NOPed out due to empty regions");
return;
Expand Down Expand Up @@ -900,15 +902,12 @@ namespace rsx
fmt::throw_exception("NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)" HERE, (u8)src_color_format);
}

f32 scale_x = 1048576.f / method_registers.blit_engine_ds_dx();
f32 scale_y = 1048576.f / method_registers.blit_engine_dt_dy();

u32 convert_w = (u32)(scale_x * in_w);
u32 convert_h = (u32)(scale_y * in_h);
u32 convert_w = (u32)(std::abs(scale_x) * in_w);
u32 convert_h = (u32)(std::abs(scale_y) * in_h);

if (convert_w == 0 || convert_h == 0)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN: Invalid dimensions or scaling factor. Request ignored (ds_dx=%d, dt_dy=%d)",
LOG_ERROR(RSX, "NV3089_IMAGE_IN: Invalid dimensions or scaling factor. Request ignored (ds_dx=%f, dt_dy=%f)",
method_registers.blit_engine_ds_dx(), method_registers.blit_engine_dt_dy());
return;
}
Expand Down Expand Up @@ -952,7 +951,7 @@ namespace rsx
dst_info.max_tile_h = static_cast<u16>((dst_region.tile->size - dst_region.base) / out_pitch);
}

if (!g_cfg.video.force_cpu_blit_processing && (dst_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER || src_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER))
if (!g_cfg.video.force_cpu_blit_processing && (dst_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER || src_dma == CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER) && scale_y > 0)
{
//For now, only use this for actual scaled images, there are use cases that should not go through 3d engine, e.g program ucode transfer
//TODO: Figure out more instances where we can use this without problems
Expand Down Expand Up @@ -999,12 +998,18 @@ namespace rsx
clip_x > 0 || clip_y > 0 ||
convert_w != out_w || convert_h != out_h;

const bool need_convert = out_format != in_format || scale_x != 1.0 || scale_y != 1.0;
const bool need_convert = out_format != in_format || std::abs(scale_x) != 1.0 || std::abs(scale_y) != 1.0;
const s32 stride_y = scale_y < 0 ? -1 : 1;

if (method_registers.blit_engine_context_surface() != blit_engine::context_surface::swizzle2d)
{
if (need_convert || need_clip)
{
if (stride_y < 0)
{
fmt::throw_exception("NV3089_IMAGE_IN: trying to scale backwards!" HERE);
}

if (need_clip)
{
if (need_convert)
Expand All @@ -1027,12 +1032,12 @@ namespace rsx
}
else
{
if (out_pitch != in_pitch || out_pitch != out_bpp * out_w)
if (out_pitch != in_pitch || out_pitch != out_bpp * out_w || stride_y < 0)
{
for (u32 y = 0; y < out_h; ++y)
{
u8 *dst = pixels_dst + out_pitch * y;
u8 *src = pixels_src + in_pitch * y;
u8 *src = pixels_src + in_pitch * (y * stride_y);

std::memmove(dst, src, out_w * out_bpp);
}
Expand All @@ -1045,6 +1050,11 @@ namespace rsx
}
else
{
if (stride_y < 0)
{
fmt::throw_exception("NV3089_IMAGE_IN: reading backwards with swizzling!" HERE);
}

if (need_convert || need_clip)
{
if (need_clip)
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/rsx_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -1469,12 +1469,12 @@ namespace rsx
return decode<NV309E_SET_FORMAT>().format();
}

u32 blit_engine_ds_dx() const
f32 blit_engine_ds_dx() const
{
return decode<NV3089_DS_DX>().ds_dx();
}

u32 blit_engine_dt_dy() const
f32 blit_engine_dt_dy() const
{
return decode<NV3089_DT_DY>().dt_dy();
}
Expand Down

0 comments on commit c43273f

Please sign in to comment.