mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
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:
parent
5a4babb0fd
commit
836d14c8af
@ -10,6 +10,7 @@
|
||||
#include "Emu/SysCalls/lv2/sys_time.h"
|
||||
|
||||
#include "Common/BufferUtils.h"
|
||||
#include "rsx_utils.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -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;
|
||||
|
45
rpcs3/Emu/RSX/rsx_utils.cpp
Normal file
45
rpcs3/Emu/RSX/rsx_utils.cpp
Normal 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
104
rpcs3/Emu/RSX/rsx_utils.h
Normal 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);
|
||||
}
|
@ -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" />
|
||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user