NV3089_IMAGE_IN_SIZE

This commit is contained in:
Nekotekina 2015-02-09 01:44:55 +03:00
parent 4ba915bbdd
commit 4e28a007c8
2 changed files with 170 additions and 49 deletions

View file

@ -11,6 +11,11 @@
#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/SysCalls/lv2/sys_time.h" #include "Emu/SysCalls/lv2/sys_time.h"
extern "C"
{
#include "libswscale/swscale.h"
}
#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].value()) #define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].value())
#define CMD_DEBUG 0 #define CMD_DEBUG 0
@ -2002,43 +2007,86 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// NV3062 // NV3062
case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN: case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN:
{
if (count == 1)
{ {
m_context_dma_img_dst = ARGS(0); m_context_dma_img_dst = ARGS(0);
}
else
{
LOG_ERROR(RSX, "NV3062_SET_CONTEXT_DMA_IMAGE__DESTIN: unknown arg count (%d)", count);
}
break; break;
} }
case NV3062_SET_OFFSET_DESTIN: case NV3062_SET_OFFSET_DESTIN:
{
if (count == 1)
{ {
m_dst_offset = ARGS(0); m_dst_offset = ARGS(0);
}
else
{
LOG_ERROR(RSX, "NV3062_SET_OFFSET_DESTIN: unknown arg count (%d)", count);
}
break; break;
} }
case NV3062_SET_COLOR_FORMAT: case NV3062_SET_COLOR_FORMAT:
{
if (count == 2 || count == 4)
{ {
m_color_format = ARGS(0); m_color_format = ARGS(0);
m_color_format_src_pitch = ARGS(1); m_color_format_src_pitch = ARGS(1);
m_color_format_dst_pitch = ARGS(1) >> 16; m_color_format_dst_pitch = ARGS(1) >> 16;
if (count == 4)
{
if (ARGS(2))
{
LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg2 value (0x%x)", ARGS(2));
}
m_dst_offset = ARGS(3);
}
LOG_WARNING(RSX, "NV3062_SET_COLOR_FORMAT: format=%d, src_pitch=%d, dst_pitch=%d", m_color_format, m_color_format_src_pitch, m_color_format_dst_pitch);
}
else
{
LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg count (%d)", count);
}
break; break;
} }
// NV309E // NV309E
case NV309E_SET_CONTEXT_DMA_IMAGE: case NV309E_SET_CONTEXT_DMA_IMAGE:
{ {
if (u32 value = ARGS(0)) if (count == 1)
{ {
LOG_WARNING(RSX, "TODO: NV309E_SET_CONTEXT_DMA_IMAGE: 0x%x", value); LOG_WARNING(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: m_context_dma_img_src -> 0x%x", ARGS(0));
m_context_dma_img_src = ARGS(0);
}
else
{
LOG_ERROR(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count);
} }
break; break;
} }
case NV309E_SET_FORMAT: case NV309E_SET_FORMAT:
{ {
const u8 height = ARGS(0) >> 24; if (count == 2)
const u8 width = ARGS(0) >> 16; {
const u8 format = ARGS(0); m_swizzle_format = ARGS(0);
const u32 offset = ARGS(1); m_swizzle_width = ARGS(0) >> 16;
m_swizzle_height = ARGS(0) >> 24;
LOG_WARNING(RSX, "TODO: NV309E_SET_FORMAT: Format:0x%x, Width:%d, Height:%d, Offset:0x%x", format, width, height, offset); m_swizzle_offset = ARGS(1);
}
else
{
LOG_ERROR(RSX, "NV309E_SET_FORMAT: unknown arg count (%d)", count);
}
break; break;
} }
@ -2097,70 +2145,136 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// NV3089 // NV3089
case NV3089_SET_CONTEXT_DMA_IMAGE: case NV3089_SET_CONTEXT_DMA_IMAGE:
{
if (count == 1)
{ {
m_context_dma_img_src = ARGS(0); m_context_dma_img_src = ARGS(0);
}
else
{
LOG_ERROR(RSX, "NV3089_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count);
}
break; break;
} }
case NV3089_SET_CONTEXT_SURFACE: case NV3089_SET_CONTEXT_SURFACE:
{ {
if (ARGS(0) != CELL_GCM_CONTEXT_SURFACE2D) if (count == 1)
{ {
LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: Unsupported surface (0x%x)", ARGS(0)); m_context_surface = ARGS(0);
if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D && m_context_surface != CELL_GCM_CONTEXT_SWIZZLE2D)
{
LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown surface (0x%x)", ARGS(0));
}
}
else
{
LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown arg count (%d)", count);
} }
break; break;
} }
case NV3089_IMAGE_IN_SIZE: case NV3089_IMAGE_IN_SIZE:
{ {
u16 width = ARGS(0); const u16 width = ARGS(0);
u16 height = ARGS(0) >> 16; const u16 height = ARGS(0) >> 16;
const u16 pitch = ARGS(1);
u16 pitch = ARGS(1); const u8 origin = ARGS(1) >> 16;
u8 origin = ARGS(1) >> 16; if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */)
u8 inter = ARGS(1) >> 24; {
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", origin);
}
u32 offset = ARGS(2); const u8 inter = ARGS(1) >> 24;
if (inter != 0 /* CELL_GCM_TRANSFER_INTERPOLATOR_ZOH */ && inter != 1 /* CELL_GCM_TRANSFER_INTERPOLATOR_FOH */)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", inter);
}
u16 u = ARGS(3); const u32 offset = ARGS(2);
u16 v = ARGS(3) >> 16;
const u16 u = ARGS(3); // inX
const u16 v = ARGS(3) >> 16; // inY
u8* pixels_src = vm::get_ptr<u8>(GetAddress(offset, m_context_dma_img_src - 0xfeed0000)); u8* pixels_src = vm::get_ptr<u8>(GetAddress(offset, m_context_dma_img_src - 0xfeed0000));
u8* pixels_dst = vm::get_ptr<u8>(GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)); u8* pixels_dst = vm::get_ptr<u8>(GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000));
LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: width=%d, height=%d, pitch=%d, origin=%d, inter=%d, offset=0x%x, u=%d, v=%d", width, height, pitch, origin, inter, offset, u, v); if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D)
LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: m_dst_offset=0x%x, m_color: conv_in_h=0x%x, format_src_pitch=0x%x, conv_in_x=0x%x, conv_in_y=0x%x, conv_out_x=0x%x, conv_out_y=0x%x", {
m_dst_offset, m_color_conv_in_h, m_color_format_src_pitch, m_color_conv_in_x, m_color_conv_in_y, m_color_conv_out_x, m_color_conv_out_y); LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", m_context_surface);
}
for (u16 y=0; y<m_color_conv_in_h; ++y) if (m_color_format != 4 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 */ && m_color_format != 10 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 */)
{ {
for (u16 x=0; x<m_color_format_src_pitch/4/*m_color_conv_in_w*/; ++x) LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_color_format (%d)", m_color_format);
{
const u32 src_offset = (m_color_conv_in_y + y) * m_color_format_src_pitch + (m_color_conv_in_x + x) * 4;
const u32 dst_offset = (m_color_conv_out_y + y) * m_color_format_dst_pitch + (m_color_conv_out_x + x) * 4;
//(u32&)pixels_dst[dst_offset] = (u32&)pixels_src[src_offset];
}
} }
LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: w=%d, h=%d, pitch=%d, offset=0x%x (src=0x%x), inX=%f, inY=%f",
width, height, pitch, offset, vm::get_addr(pixels_src), double(u) / 16, double(v) / 16);
//LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: m_dst_offset=0x%x, format_dst_pitch=0x%x, m_color_conv_in_w=%d, m_color_conv_in_h=%d",
// m_dst_offset, m_color_format_dst_pitch, m_color_conv_in_w, m_color_conv_in_h);
//for (u16 y=0; y<height; ++y)
//{
// for (u16 x=0; x<pitch/4; ++x)
// {
// const u32 src_offset = (m_color_conv_in_y + y) * pitch + (m_color_conv_in_x + x) * 4;
// const u32 dst_offset = (m_color_conv_out_y + y) * m_color_format_dst_pitch + (m_color_conv_out_x + x) * 4;
// (u32&)pixels_dst[dst_offset] = (u32&)pixels_src[src_offset];
// }
//}
AVPixelFormat in_format = m_color_format == 4 ? AV_PIX_FMT_RGB565LE : AV_PIX_FMT_ARGB; // ???
AVPixelFormat out_format = m_color_conv_fmt == 7 ? AV_PIX_FMT_RGB565LE : AV_PIX_FMT_ARGB; // ???
std::unique_ptr<u8[]> temp(new u8[m_color_format_dst_pitch * m_color_conv_out_h]);
SwsContext* sws = sws_getContext(width, height, in_format, m_color_conv_out_w, m_color_conv_out_h, out_format, inter ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL);
int in_line = pitch;
u8* out_ptr = temp.get();
int out_line = m_color_format_dst_pitch;
sws_scale(sws, &pixels_src, &in_line, 0, height, &out_ptr, &out_line);
sws_freeContext(sws);
break; break;
} }
case NV3089_SET_COLOR_CONVERSION: case NV3089_SET_COLOR_CONVERSION:
{ {
m_color_conv = ARGS(0); m_color_conv = ARGS(0);
if (m_color_conv != 1 /* CELL_GCM_TRANSFER_CONVERSION_TRUNCATE */)
{
LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv (%d)", m_color_conv);
}
m_color_conv_fmt = ARGS(1); m_color_conv_fmt = ARGS(1);
if (m_color_conv_fmt != 3 /* CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8 */ && m_color_conv_fmt != 7 /* CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 */)
{
LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown format (%d)", m_color_conv_fmt);
}
m_color_conv_op = ARGS(2); m_color_conv_op = ARGS(2);
m_color_conv_in_x = ARGS(3); if (m_color_conv_op != 3 /* CELL_GCM_TRANSFER_OPERATION_SRCCOPY */)
m_color_conv_in_y = ARGS(3) >> 16; {
m_color_conv_in_w = ARGS(4); LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv op (%d)", m_color_conv_op);
m_color_conv_in_h = ARGS(4) >> 16; }
m_color_conv_clip_x = ARGS(3);
m_color_conv_clip_y = ARGS(3) >> 16;
m_color_conv_clip_w = ARGS(4);
m_color_conv_clip_h = ARGS(4) >> 16;
m_color_conv_out_x = ARGS(5); m_color_conv_out_x = ARGS(5);
m_color_conv_out_y = ARGS(5) >> 16; m_color_conv_out_y = ARGS(5) >> 16;
m_color_conv_out_w = ARGS(6); m_color_conv_out_w = ARGS(6);
m_color_conv_out_h = ARGS(6) >> 16; m_color_conv_out_h = ARGS(6) >> 16;
LOG_WARNING(RSX, "NV3089_SET_COLOR_CONVERSION: clip=[x=%d,y=%d,w=%d,h=%d], out=[x=%d,y=%d,w=%d,h=%d]",
m_color_conv_clip_x, m_color_conv_clip_y, m_color_conv_clip_w, m_color_conv_clip_h, m_color_conv_out_x, m_color_conv_out_y, m_color_conv_out_w, m_color_conv_out_h);
m_color_conv_dsdx = ARGS(7); m_color_conv_dsdx = ARGS(7);
m_color_conv_dtdy = ARGS(8); m_color_conv_dtdy = ARGS(8);
LOG_WARNING(RSX, "TODO: NV3089_SET_COLOR_CONVERSION");
break; break;
} }

View file

@ -330,16 +330,16 @@ public:
u32 m_color_conv; u32 m_color_conv;
u32 m_color_conv_fmt; u32 m_color_conv_fmt;
u32 m_color_conv_op; u32 m_color_conv_op;
u16 m_color_conv_in_x; s16 m_color_conv_clip_x;
u16 m_color_conv_in_y; s16 m_color_conv_clip_y;
u16 m_color_conv_in_w; u16 m_color_conv_clip_w;
u16 m_color_conv_in_h; u16 m_color_conv_clip_h;
u16 m_color_conv_out_x; s16 m_color_conv_out_x;
u16 m_color_conv_out_y; s16 m_color_conv_out_y;
u16 m_color_conv_out_w; u16 m_color_conv_out_w;
u16 m_color_conv_out_h; u16 m_color_conv_out_h;
u32 m_color_conv_dsdx; s32 m_color_conv_dsdx;
u32 m_color_conv_dtdy; s32 m_color_conv_dtdy;
// Semaphore // Semaphore
bool m_set_semaphore_offset; bool m_set_semaphore_offset;
@ -398,12 +398,19 @@ public:
u32 m_context_dma_color_d; u32 m_context_dma_color_d;
bool m_set_context_dma_z; bool m_set_context_dma_z;
u32 m_context_dma_z; u32 m_context_dma_z;
u32 m_context_surface;
u32 m_context_dma_img_src; u32 m_context_dma_img_src;
u32 m_context_dma_img_dst; u32 m_context_dma_img_dst;
u32 m_context_dma_buffer_in_src; u32 m_context_dma_buffer_in_src;
u32 m_context_dma_buffer_in_dst; u32 m_context_dma_buffer_in_dst;
u32 m_dst_offset; u32 m_dst_offset;
// Swizzle2D?
u16 m_swizzle_format;
u8 m_swizzle_width;
u8 m_swizzle_height;
u32 m_swizzle_offset;
// Cull face // Cull face
bool m_set_cull_face; bool m_set_cull_face;
u32 m_cull_face; u32 m_cull_face;