mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 02:08:49 +12:00
111 lines
3.4 KiB
C++
111 lines
3.4 KiB
C++
#pragma once
|
|
|
|
extern "C"
|
|
{
|
|
#include <libavutil/pixfmt.h>
|
|
}
|
|
|
|
namespace rsx
|
|
{
|
|
template<typename T>
|
|
void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 output_height)
|
|
{
|
|
T *src = static_cast<T*>(input_pixels);
|
|
T *dst = static_cast<T*>(output_pixels);
|
|
|
|
for (u16 h = 0; h < input_height; ++h)
|
|
{
|
|
const u32 padded_pos = h * output_width;
|
|
const u32 pos = h * input_width;
|
|
for (u16 w = 0; w < input_width; ++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* input_pixels, void* output_pixels, u16 width, u16 height, bool input_is_swizzled)
|
|
{
|
|
u16 log2width = gsl::narrow<u16>(ceil(log2(width)));
|
|
u16 log2height = gsl::narrow<u16>(ceil(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;
|
|
|
|
if (!input_is_swizzled)
|
|
{
|
|
for (int y = 0; y < height; ++y)
|
|
{
|
|
T *src = static_cast<T*>(input_pixels) + y * width;
|
|
T *dst = static_cast<T*>(output_pixels) + 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)
|
|
{
|
|
T *src = static_cast<T*>(input_pixels) + offs_y;
|
|
T *dst = static_cast<T*>(output_pixels) + 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);
|
|
}
|