diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 961c1eb641..757f7079a4 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -11,6 +11,11 @@ #include "Emu/SysCalls/CB_FUNC.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 CMD_DEBUG 0 @@ -2003,42 +2008,85 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const // NV3062 case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN: { - m_context_dma_img_dst = ARGS(0); + if (count == 1) + { + m_context_dma_img_dst = ARGS(0); + } + else + { + LOG_ERROR(RSX, "NV3062_SET_CONTEXT_DMA_IMAGE__DESTIN: unknown arg count (%d)", count); + } break; } case NV3062_SET_OFFSET_DESTIN: { - m_dst_offset = ARGS(0); + if (count == 1) + { + m_dst_offset = ARGS(0); + } + else + { + LOG_ERROR(RSX, "NV3062_SET_OFFSET_DESTIN: unknown arg count (%d)", count); + } break; } case NV3062_SET_COLOR_FORMAT: { - m_color_format = ARGS(0); - m_color_format_src_pitch = ARGS(1); - m_color_format_dst_pitch = ARGS(1) >> 16; + if (count == 2 || count == 4) + { + m_color_format = ARGS(0); + m_color_format_src_pitch = ARGS(1); + 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; } // NV309E 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; } case NV309E_SET_FORMAT: { - const u8 height = ARGS(0) >> 24; - const u8 width = ARGS(0) >> 16; - const u8 format = ARGS(0); - const u32 offset = ARGS(1); - - LOG_WARNING(RSX, "TODO: NV309E_SET_FORMAT: Format:0x%x, Width:%d, Height:%d, Offset:0x%x", format, width, height, offset); + if (count == 2) + { + m_swizzle_format = ARGS(0); + m_swizzle_width = ARGS(0) >> 16; + m_swizzle_height = ARGS(0) >> 24; + m_swizzle_offset = ARGS(1); + } + else + { + LOG_ERROR(RSX, "NV309E_SET_FORMAT: unknown arg count (%d)", count); + } break; } @@ -2098,69 +2146,135 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const // NV3089 case NV3089_SET_CONTEXT_DMA_IMAGE: { - m_context_dma_img_src = ARGS(0); + if (count == 1) + { + m_context_dma_img_src = ARGS(0); + } + else + { + LOG_ERROR(RSX, "NV3089_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count); + } break; } 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; } case NV3089_IMAGE_IN_SIZE: { - u16 width = ARGS(0); - u16 height = ARGS(0) >> 16; + const u16 width = ARGS(0); + const u16 height = ARGS(0) >> 16; + const u16 pitch = ARGS(1); - u16 pitch = ARGS(1); - u8 origin = ARGS(1) >> 16; - u8 inter = ARGS(1) >> 24; + const u8 origin = ARGS(1) >> 16; + if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */) + { + 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); - u16 v = ARGS(3) >> 16; + const u32 offset = ARGS(2); + + const u16 u = ARGS(3); // inX + const u16 v = ARGS(3) >> 16; // inY u8* pixels_src = vm::get_ptr(GetAddress(offset, m_context_dma_img_src - 0xfeed0000)); u8* pixels_dst = vm::get_ptr(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); - 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); - - for (u16 y=0; y 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; } case NV3089_SET_COLOR_CONVERSION: { 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); + 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_in_x = ARGS(3); - m_color_conv_in_y = ARGS(3) >> 16; - m_color_conv_in_w = ARGS(4); - m_color_conv_in_h = ARGS(4) >> 16; + if (m_color_conv_op != 3 /* CELL_GCM_TRANSFER_OPERATION_SRCCOPY */) + { + LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv op (%d)", m_color_conv_op); + } + + 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_y = ARGS(5) >> 16; m_color_conv_out_w = ARGS(6); 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_dtdy = ARGS(8); - - LOG_WARNING(RSX, "TODO: NV3089_SET_COLOR_CONVERSION"); break; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index bb6a177ab0..af13521527 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -330,16 +330,16 @@ public: u32 m_color_conv; u32 m_color_conv_fmt; u32 m_color_conv_op; - u16 m_color_conv_in_x; - u16 m_color_conv_in_y; - u16 m_color_conv_in_w; - u16 m_color_conv_in_h; - u16 m_color_conv_out_x; - u16 m_color_conv_out_y; + s16 m_color_conv_clip_x; + s16 m_color_conv_clip_y; + u16 m_color_conv_clip_w; + u16 m_color_conv_clip_h; + s16 m_color_conv_out_x; + s16 m_color_conv_out_y; u16 m_color_conv_out_w; u16 m_color_conv_out_h; - u32 m_color_conv_dsdx; - u32 m_color_conv_dtdy; + s32 m_color_conv_dsdx; + s32 m_color_conv_dtdy; // Semaphore bool m_set_semaphore_offset; @@ -398,12 +398,19 @@ public: u32 m_context_dma_color_d; bool m_set_context_dma_z; u32 m_context_dma_z; + u32 m_context_surface; u32 m_context_dma_img_src; u32 m_context_dma_img_dst; u32 m_context_dma_buffer_in_src; u32 m_context_dma_buffer_in_dst; u32 m_dst_offset; + // Swizzle2D? + u16 m_swizzle_format; + u8 m_swizzle_width; + u8 m_swizzle_height; + u32 m_swizzle_offset; + // Cull face bool m_set_cull_face; u32 m_cull_face;