mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 23:11:25 +12:00
rsx: fix image_in arg and swizzle fix
This commit is contained in:
parent
d5c879e8e7
commit
ac53fc54dc
3 changed files with 29 additions and 18 deletions
|
@ -4064,21 +4064,23 @@ struct registers_decoder<NV3089_IMAGE_IN>
|
||||||
public:
|
public:
|
||||||
decoded_type(u32 raw_value) { m_data.raw_value = raw_value; }
|
decoded_type(u32 raw_value) { m_data.raw_value = raw_value; }
|
||||||
|
|
||||||
u16 x() const
|
// x and y given as 16 bit fixed point
|
||||||
|
|
||||||
|
f32 x() const
|
||||||
{
|
{
|
||||||
return m_data.x;
|
return m_data.x / 16.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 y() const
|
f32 y() const
|
||||||
{
|
{
|
||||||
return m_data.y;
|
return m_data.y / 16.f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string dump(decoded_type &&decoded_values)
|
static std::string dump(decoded_type &&decoded_values)
|
||||||
{
|
{
|
||||||
return "NV3089: in x = " + std::to_string(decoded_values.x() / 16.f) +
|
return "NV3089: in x = " + std::to_string(decoded_values.x()) +
|
||||||
" y = " + std::to_string(decoded_values.y() / 16.f);
|
" y = " + std::to_string(decoded_values.y());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -576,8 +576,8 @@ namespace rsx
|
||||||
const blit_engine::transfer_interpolator in_inter = method_registers.blit_engine_input_inter();
|
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 rsx::blit_engine::transfer_source_format src_color_format = method_registers.blit_engine_src_color_format();
|
||||||
|
|
||||||
const f32 in_x = method_registers.blit_engine_in_x();
|
const f32 in_x = std::ceil(method_registers.blit_engine_in_x());
|
||||||
const f32 in_y = method_registers.blit_engine_in_y();
|
const f32 in_y = std::ceil(method_registers.blit_engine_in_y());
|
||||||
|
|
||||||
//Clipping
|
//Clipping
|
||||||
//Validate that clipping rect will fit onto both src and dst regions
|
//Validate that clipping rect will fit onto both src and dst regions
|
||||||
|
@ -855,7 +855,9 @@ namespace rsx
|
||||||
pixels_src = temp2.get();
|
pixels_src = temp2.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 sw_width_log2 = method_registers.nv309e_sw_width_log2();
|
// It looks like rsx may ignore the requested swizzle size and just always
|
||||||
|
// round up to nearest power of 2
|
||||||
|
/*u8 sw_width_log2 = method_registers.nv309e_sw_width_log2();
|
||||||
u8 sw_height_log2 = method_registers.nv309e_sw_height_log2();
|
u8 sw_height_log2 = method_registers.nv309e_sw_height_log2();
|
||||||
|
|
||||||
// 0 indicates height of 1 pixel
|
// 0 indicates height of 1 pixel
|
||||||
|
@ -864,31 +866,31 @@ namespace rsx
|
||||||
// swizzle based on destination size
|
// swizzle based on destination size
|
||||||
u16 sw_width = 1 << sw_width_log2;
|
u16 sw_width = 1 << sw_width_log2;
|
||||||
u16 sw_height = 1 << sw_height_log2;
|
u16 sw_height = 1 << sw_height_log2;
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 sw_width = next_pow2(out_w);
|
||||||
|
u32 sw_height = next_pow2(out_h);
|
||||||
|
|
||||||
temp2.reset(new u8[out_bpp * sw_width * sw_height]);
|
temp2.reset(new u8[out_bpp * sw_width * sw_height]);
|
||||||
|
|
||||||
u8* linear_pixels = pixels_src;
|
u8* linear_pixels = pixels_src;
|
||||||
u8* swizzled_pixels = temp2.get();
|
u8* swizzled_pixels = temp2.get();
|
||||||
|
|
||||||
// restrict output to size of swizzle
|
// Check and pad texture out if we are given non power of 2 output
|
||||||
const u16 sw_in_w = std::min(out_w, sw_width);
|
if (sw_width != out_w || sw_height != out_h)
|
||||||
const u16 sw_in_h = std::min(out_h, sw_height);
|
|
||||||
|
|
||||||
// Check and pad texture out if we are given non square texture for swizzle to be correct
|
|
||||||
if (sw_width != sw_in_w || sw_height != sw_in_h)
|
|
||||||
{
|
{
|
||||||
sw_temp.reset(new u8[out_bpp * sw_width * sw_height]);
|
sw_temp.reset(new u8[out_bpp * sw_width * sw_height]);
|
||||||
|
|
||||||
switch (out_bpp)
|
switch (out_bpp)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
pad_texture<u8>(linear_pixels, sw_temp.get(), sw_in_w, sw_in_h, sw_width, sw_height);
|
pad_texture<u8>(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
pad_texture<u16>(linear_pixels, sw_temp.get(), sw_in_w, sw_in_h, sw_width, sw_height);
|
pad_texture<u16>(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
pad_texture<u32>(linear_pixels, sw_temp.get(), sw_in_w, sw_in_h, sw_width, sw_height);
|
pad_texture<u32>(linear_pixels, sw_temp.get(), out_w, out_h, sw_width, sw_height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,13 @@ namespace rsx
|
||||||
return value <= 1 ? 0 : ::cntlz32((value - 1) << 1, true) ^ 31;
|
return value <= 1 ? 0 : ::cntlz32((value - 1) << 1, true) ^ 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 next_pow2(u32 x)
|
||||||
|
{
|
||||||
|
if (x <= 2) return x;
|
||||||
|
|
||||||
|
return (1ULL << 32) >> ::cntlz32(x - 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: What the ps3 calls swizzling in this case is actually z-ordering / morton ordering of pixels
|
/* Note: What the ps3 calls swizzling in this case is actually z-ordering / morton ordering of pixels
|
||||||
* - Input can be swizzled or linear, bool flag handles conversion to and from
|
* - Input can be swizzled or linear, bool flag handles conversion to and from
|
||||||
* - It will handle any width and height that are a power of 2, square or non square
|
* - It will handle any width and height that are a power of 2, square or non square
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue