diff --git a/bin/dev_hdd0/game/TEST12345/USRDIR/handle_system_cmd.elf b/bin/dev_hdd0/game/TEST12345/USRDIR/handle_system_cmd.elf new file mode 100644 index 0000000000..2937c9e4ba Binary files /dev/null and b/bin/dev_hdd0/game/TEST12345/USRDIR/handle_system_cmd.elf differ diff --git a/rpcs3/Emu/GS/GL/GLBuffers.cpp b/rpcs3/Emu/GS/GL/GLBuffers.cpp index 053b64c324..bf4d94a177 100644 --- a/rpcs3/Emu/GS/GL/GLBuffers.cpp +++ b/rpcs3/Emu/GS/GL/GLBuffers.cpp @@ -178,7 +178,7 @@ u32 GLrbo::GetId(u32 num) const return m_id[num]; } -GLfbo::GLfbo() +GLfbo::GLfbo() : m_id(0) { } @@ -188,7 +188,7 @@ GLfbo::~GLfbo() void GLfbo::Create() { - if(m_id) + if(IsCreated()) { return; } diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index b7d15d2323..cca4498174 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/PPCInstrTable.h" #define CMD_DEBUG 0 -#define DUMP_VERTEX_DATA 1 +#define DUMP_VERTEX_DATA 0 #if CMD_DEBUG #define CMD_LOG ConLog.Write @@ -477,9 +477,7 @@ void GLGSRender::InitFragmentData() { const TransformConstant& c = m_fragment_constants[i]; - u32 id = c.id - m_cur_shader_prog->offset; - if(id < 32) - id = 32; + u32 id = c.id - m_cur_shader_prog->offset + 2 * 4 * 4; const wxString name = wxString::Format("fc%u", id); const int l = m_program.GetLocation(name); @@ -563,13 +561,15 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c m_fbo.Bind(GL_READ_FRAMEBUFFER); m_fbo.Bind(GL_DRAW_FRAMEBUFFER, 0); m_fbo.Blit( - 0, 0, m_width, m_height, - 0, 0, m_width, m_height, + m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, + m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); m_fbo.Bind(); + checkForGlError("m_fbo.Blit"); } m_frame->Flip(); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } m_gcm_current_buffer = args[0]; @@ -708,7 +708,20 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c break; case_16(NV4097_SET_TEXTURE_FILTER, 0x20): - //TODO + { + GLTexture& tex = m_frame->GetTexture(index); + u32 a0 = args[0]; + u16 bias = a0 & 0x1fff; + u8 conv = (a0 >> 13) & 0xf; + u8 min = (a0 >> 16) & 0x7; + u8 mag = (a0 >> 24) & 0x7; + u8 a_signed = (a0 >> 28) & 0x1; + u8 r_signed = (a0 >> 29) & 0x1; + u8 g_signed = (a0 >> 30) & 0x1; + u8 b_signed = (a0 >> 31) & 0x1; + + tex.SetFilter(bias, min, mag, conv, a_signed, r_signed, g_signed, b_signed); + } break; case_16(NV4097_SET_TEXTURE_ADDRESS, 0x20): @@ -801,7 +814,11 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c } */ - if(0) + gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr); + m_width = re(buffers[m_gcm_current_buffer].width); + m_height = re(buffers[m_gcm_current_buffer].height); + + if(1) { m_rbo.Create(2); checkForGlError("m_rbo.Create"); @@ -809,7 +826,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c m_rbo.Storage(GL_RGBA, m_width, m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); m_rbo.Bind(1); - m_rbo.Storage(GL_DEPTH_STENCIL, m_width, m_height); + m_rbo.Storage(GL_DEPTH24_STENCIL8, m_width, m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); m_fbo.Create(); checkForGlError("m_fbo.Create"); @@ -854,11 +871,24 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c break; case NV4097_SET_ALPHA_FUNC: - glAlphaFunc(args[0], args[1]); + m_set_alpha_func = true; + m_alpha_func = args[0]; + + if(count >= 2) + { + m_set_alpha_ref = true; + m_alpha_ref = args[1]; + } + break; + + case NV4097_SET_ALPHA_REF: + m_set_alpha_ref = true; + m_alpha_ref = args[0]; break; case NV4097_SET_CULL_FACE: - glCullFace(args[0]); + m_set_cull_face = true; + m_cull_face = args[0]; break; case NV4097_SET_VIEWPORT_VERTICAL: @@ -922,6 +952,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c if (a0 & 0x2) f |= GL_STENCIL_BUFFER_BIT; if (a0 & 0xF0) f |= GL_COLOR_BUFFER_BIT; glClear(f); + checkForGlError("glClear"); /* if(m_set_clear_surface) { @@ -1088,6 +1119,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c m_clear_color_g / 255.0f, m_clear_color_b / 255.0f, m_clear_color_a / 255.0f); + checkForGlError("glClearColor"); } break; @@ -1190,7 +1222,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c break; case NV4097_SET_CULL_FACE_ENABLE: - m_set_cull_face = args[0] ? true : false; + m_set_cull_face_enable = args[0] ? true : false; break; case NV4097_SET_DITHER_ENABLE: @@ -1546,9 +1578,46 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c break; case NV4097_SET_ZSTENCIL_CLEAR_VALUE: + { + u32 clear_valuei = args[0]; + //double clear_valuef = (double)clear_valuei / 0xffffffff; + //glClearDepth(clear_valuef); + glClearStencil(clear_valuei); + glClear(GL_STENCIL_BUFFER_BIT); + } + break; + case NV4097_SET_ZCULL_CONTROL0: + { + m_set_depth_func = true; + m_depth_func = args[0] >> 4; + } + break; + case NV4097_SET_ZCULL_CONTROL1: + { + //TODO + } + break; + case NV4097_SET_SCULL_CONTROL: + { + u32 a0 = args[0]; + m_set_stencil_func = m_set_stencil_func_ref = m_set_stencil_func_mask = true; + + m_stencil_func = a0 & 0xffff; + m_stencil_func_ref = (a0 >> 16) & 0xff; + m_stencil_func_mask = (a0 >> 24) & 0xff; + } + break; + + case NV4097_SET_ZCULL_EN: + { + u32 a0 = args[0]; + + m_depth_test_enable = a0 & 0x1 ? true : false; + m_set_stencil_test = a0 & 0x2 ? true : false; + } break; case NV4097_GET_REPORT: @@ -1800,8 +1869,9 @@ bool GLGSRender::LoadProgram() else { m_program.Create(m_cur_vertex_prog->id, m_cur_shader_prog->id); + checkForGlError("m_program.Create"); m_prog_buffer.Add(m_program, *m_cur_shader_prog, *m_cur_vertex_prog); - + checkForGlError("m_prog_buffer.Add"); m_program.Use(); GLint r = GL_FALSE; @@ -1833,9 +1903,7 @@ void GLGSRender::ExecCMD() { if(m_set_surface_clip_horizontal && m_set_surface_clip_vertical) { - m_width = m_surface_clip_w; - m_height = m_surface_clip_h; - //ConLog.Write("width: %d, height: %d, x: %d, y: %d", m_width, m_height, m_surface_clip_x, m_surface_clip_y); + //ConLog.Write("surface clip width: %d, height: %d, x: %d, y: %d", m_width, m_height, m_surface_clip_x, m_surface_clip_y); } if(m_set_color_mask) @@ -1885,7 +1953,7 @@ void GLGSRender::ExecCMD() Enable(m_set_depth_bounds_test, GL_DEPTH_CLAMP); Enable(m_set_blend, GL_BLEND); Enable(m_set_logic_op, GL_LOGIC_OP); - Enable(m_set_cull_face, GL_CULL_FACE); + Enable(m_set_cull_face_enable, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); @@ -1991,15 +2059,30 @@ void GLGSRender::ExecCMD() checkForGlError("glBlendColor"); } + if(m_set_cull_face) + { + glCullFace(m_cull_face); + checkForGlError("glCullFace"); + } + + if(m_set_alpha_func && m_set_alpha_ref) + { + glAlphaFunc(m_alpha_func, m_alpha_ref); + checkForGlError("glAlphaFunc"); + } + if(m_set_fog_mode) { glFogi(GL_FOG_MODE, m_fog_mode); + checkForGlError("glFogi(GL_FOG_MODE)"); } if(m_set_fog_params) { glFogf(GL_FOG_START, m_fog_param0); + checkForGlError("glFogf(GL_FOG_START)"); glFogf(GL_FOG_END, m_fog_param1); + checkForGlError("glFogf(GL_FOG_END)"); } if(m_indexed_array.m_count && m_draw_array_count) diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 805c694b3c..0040935796 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -41,6 +41,15 @@ class GLTexture u8 m_aniso_bias; u8 m_signed_remap; + u16 m_bias; + u8 m_min_filter; + u8 m_mag_filter; + u8 m_conv; + u8 m_a_signed; + u8 m_r_signed; + u8 m_g_signed; + u8 m_b_signed; + u32 m_remap; public: @@ -127,6 +136,18 @@ public: m_pitch = pitch; } + void SetFilter(u16 bias, u8 min, u8 mag, u8 conv, u8 a_signed, u8 r_signed, u8 g_signed, u8 b_signed) + { + m_bias = bias; + m_min_filter = min; + m_mag_filter = mag; + m_conv = conv; + m_a_signed = a_signed; + m_r_signed = r_signed; + m_g_signed = g_signed; + m_b_signed = b_signed; + } + u32 GetFormat() const { return m_format; } void SetOffset(const u32 offset) @@ -289,13 +310,25 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(m_wrapr)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[m_zfunc]); - glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_aniso_bias); + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_bias); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, m_minlod); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, m_maxlod); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_maxaniso); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + static const int gl_tex_filter[] = + { + GL_NEAREST, + GL_NEAREST, + GL_LINEAR, + GL_NEAREST_MIPMAP_NEAREST, + GL_LINEAR_MIPMAP_NEAREST, + GL_NEAREST_MIPMAP_LINEAR, + GL_LINEAR_MIPMAP_LINEAR, + GL_NEAREST, + }; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[m_min_filter]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[m_mag_filter]); //Unbind(); } diff --git a/rpcs3/Emu/GS/GSRender.cpp b/rpcs3/Emu/GS/GSRender.cpp index 225ae860de..75664a9a1a 100644 --- a/rpcs3/Emu/GS/GSRender.cpp +++ b/rpcs3/Emu/GS/GSRender.cpp @@ -94,6 +94,7 @@ u32 GSRender::GetAddress(u32 offset, u8 location) } ConLog.Error("GetAddress(offset=0x%x, location=0x%x", location); + assert(0); return 0; } diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 28a61a0898..78dc31eae3 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -22,7 +22,7 @@ public: bool m_set_depth_bounds_test; bool m_depth_test_enable; bool m_set_logic_op; - bool m_set_cull_face; + bool m_set_cull_face_enable; bool m_set_dither; bool m_set_stencil_test; bool m_set_line_smooth; @@ -196,6 +196,15 @@ public: u16 m_surface_clip_y; u16 m_surface_clip_h; + bool m_set_cull_face; + u32 m_cull_face; + + bool m_set_alpha_func; + u32 m_alpha_func; + + bool m_set_alpha_ref; + u32 m_alpha_ref; + u8 m_begin_end; public: @@ -222,7 +231,7 @@ public: m_set_blend_sfactor = false; m_set_blend_dfactor = false; m_set_logic_op = false; - m_set_cull_face = false; + m_set_cull_face_enable = false; m_set_dither = false; m_set_stencil_test = false; m_set_stencil_mask = false; @@ -259,6 +268,9 @@ public: m_set_context_dma_z = false; m_set_surface_clip_horizontal = false; m_set_surface_clip_vertical = false; + m_set_cull_face = false; + m_set_alpha_func = false; + m_set_alpha_ref = false; m_begin_end = 0; }