rsx::pad_texture & rsx::convert_linear_swizzle moved to rsx_utils

Added rsx::convert_scale_image & rsx::clip_image to rsx_utils
This commit is contained in:
DHrpcs3 2016-01-05 18:42:54 +02:00
parent 5a4babb0fd
commit 836d14c8af
6 changed files with 158 additions and 86 deletions

View File

@ -10,6 +10,7 @@
#include "Emu/SysCalls/lv2/sys_time.h"
#include "Common/BufferUtils.h"
#include "rsx_utils.h"
extern "C"
{

View File

@ -226,92 +226,6 @@ namespace rsx
void read(void *dst, u32 width, u32 height, u32 pitch);
};
template<typename T>
void pad_texture(void* inputPixels, void* outputPixels, u16 inputWidth, u16 inputHeight, u16 outputWidth, u16 outputHeight)
{
T *src, *dst;
src = static_cast<T*>(inputPixels);
dst = static_cast<T*>(outputPixels);
for (u16 h = 0; h < inputHeight; ++h)
{
const u32 padded_pos = h * outputWidth;
const u32 pos = h * inputWidth;
for (u16 w = 0; w < inputWidth; ++w)
{
dst[padded_pos + w] = src[pos + w];
}
}
}
/* 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
* - It will handle any width and height that are a power of 2, square or non square
* Restriction: It has mixed results if the height or width is not a power of 2
*/
template<typename T>
void convert_linear_swizzle(void* inputPixels, void* outputPixels, u16 width, u16 height, bool inputIsSwizzled)
{
u32 log2width, log2height;
log2width = log2(width);
log2height = log2(height);
// Max mask possible for square texture
u32 x_mask = 0x55555555;
u32 y_mask = 0xAAAAAAAA;
// We have to limit the masks to the lower of the two dimensions to allow for non-square textures
u32 limit_mask = (log2width < log2height) ? log2width : log2height;
// double the limit mask to account for bits in both x and y
limit_mask = 1 << (limit_mask << 1);
//x_mask, bits above limit are 1's for x-carry
x_mask = (x_mask | ~(limit_mask - 1));
//y_mask. bits above limit are 0'd, as we use a different method for y-carry over
y_mask = (y_mask & (limit_mask - 1));
u32 offs_y = 0;
u32 offs_x = 0;
u32 offs_x0 = 0; //total y-carry offset for x
u32 y_incr = limit_mask;
T *src, *dst;
if (!inputIsSwizzled)
{
for (int y = 0; y < height; ++y)
{
src = static_cast<T*>(inputPixels) + y*width;
dst = static_cast<T*>(outputPixels) + offs_y;
offs_x = offs_x0;
for (int x = 0; x < width; ++x)
{
dst[offs_x] = src[x];
offs_x = (offs_x - x_mask) & x_mask;
}
offs_y = (offs_y - y_mask) & y_mask;
if (offs_y == 0) offs_x0 += y_incr;
}
}
else
{
for (int y = 0; y < height; ++y)
{
src = static_cast<T*>(inputPixels) + offs_y;
dst = static_cast<T*>(outputPixels) + y*width;
offs_x = offs_x0;
for (int x = 0; x < width; ++x)
{
dst[x] = src[offs_x];
offs_x = (offs_x - x_mask) & x_mask;
}
offs_y = (offs_y - y_mask) & y_mask;
if (offs_y == 0) offs_x0 += y_incr;
}
}
}
struct surface_info
{
u8 log2height;

View File

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "rsx_utils.h"
extern "C"
{
#include "libswscale/swscale.h"
}
namespace rsx
{
void convert_scale_image(u8 *dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch,
const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear)
{
std::unique_ptr<SwsContext, void(*)(SwsContext*)> sws(sws_getContext(src_width, src_height, src_format,
dst_width, dst_height, dst_format, bilinear ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL), sws_freeContext);
sws_scale(sws.get(), &src, &src_pitch, 0, src_slice_h, &dst, &dst_pitch);
}
void convert_scale_image(std::unique_ptr<u8[]>& dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch,
const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear)
{
dst.reset(new u8[dst_pitch * dst_height]);
convert_scale_image(dst.get(), dst_format, dst_width, dst_height, dst_pitch,
src, src_format, src_width, src_height, src_pitch, src_slice_h, bilinear);
}
void clip_image(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch)
{
for (int y = 0; y < clip_h; ++y)
{
u8 *dst_row = dst + y * dst_pitch;
const u8 *src_row = src + (y + clip_y) * src_pitch + clip_x * bpp;
std::memmove(dst_row, src_row, clip_w * bpp);
}
}
void clip_image(std::unique_ptr<u8[]>& dst, const u8 *src,
int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch)
{
dst.reset(new u8[clip_h * dst_pitch]);
clip_image(dst.get(), src, clip_x, clip_y, clip_w, clip_h, bpp, src_pitch, dst_pitch);
}
}

104
rpcs3/Emu/RSX/rsx_utils.h Normal file
View File

@ -0,0 +1,104 @@
#pragma once
extern "C"
{
#include <libavutil/pixfmt.h>
}
namespace rsx
{
template<typename T>
void pad_texture(void* inputPixels, void* outputPixels, u16 inputWidth, u16 inputHeight, u16 outputWidth, u16 outputHeight)
{
T *src, *dst;
src = static_cast<T*>(inputPixels);
dst = static_cast<T*>(outputPixels);
for (u16 h = 0; h < inputHeight; ++h)
{
const u32 padded_pos = h * outputWidth;
const u32 pos = h * inputWidth;
for (u16 w = 0; w < inputWidth; ++w)
{
dst[padded_pos + w] = src[pos + w];
}
}
}
/* 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
* - It will handle any width and height that are a power of 2, square or non square
* Restriction: It has mixed results if the height or width is not a power of 2
*/
template<typename T>
void convert_linear_swizzle(void* inputPixels, void* outputPixels, u16 width, u16 height, bool inputIsSwizzled)
{
u32 log2width, log2height;
log2width = log2(width);
log2height = log2(height);
// Max mask possible for square texture
u32 x_mask = 0x55555555;
u32 y_mask = 0xAAAAAAAA;
// We have to limit the masks to the lower of the two dimensions to allow for non-square textures
u32 limit_mask = (log2width < log2height) ? log2width : log2height;
// double the limit mask to account for bits in both x and y
limit_mask = 1 << (limit_mask << 1);
//x_mask, bits above limit are 1's for x-carry
x_mask = (x_mask | ~(limit_mask - 1));
//y_mask. bits above limit are 0'd, as we use a different method for y-carry over
y_mask = (y_mask & (limit_mask - 1));
u32 offs_y = 0;
u32 offs_x = 0;
u32 offs_x0 = 0; //total y-carry offset for x
u32 y_incr = limit_mask;
T *src, *dst;
if (!inputIsSwizzled)
{
for (int y = 0; y < height; ++y)
{
src = static_cast<T*>(inputPixels) + y*width;
dst = static_cast<T*>(outputPixels) + offs_y;
offs_x = offs_x0;
for (int x = 0; x < width; ++x)
{
dst[offs_x] = src[x];
offs_x = (offs_x - x_mask) & x_mask;
}
offs_y = (offs_y - y_mask) & y_mask;
if (offs_y == 0) offs_x0 += y_incr;
}
}
else
{
for (int y = 0; y < height; ++y)
{
src = static_cast<T*>(inputPixels) + offs_y;
dst = static_cast<T*>(outputPixels) + y*width;
offs_x = offs_x0;
for (int x = 0; x < width; ++x)
{
dst[x] = src[offs_x];
offs_x = (offs_x - x_mask) & x_mask;
}
offs_y = (offs_y - y_mask) & y_mask;
if (offs_y == 0) offs_x0 += y_incr;
}
}
}
void convert_scale_image(u8 *dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch,
const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear);
void convert_scale_image(std::unique_ptr<u8[]>& dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch,
const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear);
void clip_image(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch);
void clip_image(std::unique_ptr<u8[]>& dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch);
}

View File

@ -129,6 +129,7 @@
<ClCompile Include="Emu\RSX\Common\VertexProgramDecompiler.cpp" />
<ClCompile Include="Emu\RSX\GCM.cpp" />
<ClCompile Include="Emu\RSX\Null\NullGSRender.cpp" />
<ClCompile Include="Emu\RSX\rsx_utils.cpp" />
<ClCompile Include="Emu\state.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_dbg.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_fs.cpp" />
@ -574,6 +575,7 @@
<ClInclude Include="Emu\Memory\vm_ptr.h" />
<ClInclude Include="Emu\Memory\vm_ref.h" />
<ClInclude Include="Emu\Memory\vm_var.h" />
<ClInclude Include="Emu\RSX\rsx_utils.h" />
<ClInclude Include="Emu\state.h" />
<ClInclude Include="Emu\SysCalls\Callback.h" />
<ClInclude Include="Emu\SysCalls\CB_FUNC.h" />

View File

@ -927,6 +927,9 @@
<ClCompile Include="Emu\RSX\GCM.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\rsx_utils.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1773,5 +1776,8 @@
<ClInclude Include="..\Utilities\BitField.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\rsx_utils.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
</ItemGroup>
</Project>