diff --git a/rpcs3/Emu/GS/GCM.h b/rpcs3/Emu/GS/GCM.h index 80218b991e..483f67eec3 100644 --- a/rpcs3/Emu/GS/GCM.h +++ b/rpcs3/Emu/GS/GCM.h @@ -1,4 +1,5 @@ #pragma once +#include "rpcs3.h" enum { @@ -39,6 +40,104 @@ struct gcmInfo u32 control_addr; }; +struct CellGcmSurface +{ + u8 type; + u8 antialias; + + u8 color_format; + u8 color_target; + u8 color_location[4]; + u32 color_offset[4]; + u32 color_pitch[4]; + + u8 depth_format; + u8 depth_location; + u16 pad; + u32 depth_offset; + u32 depth_pitch; + + u16 width; + u16 height; + u16 x; + u16 y; +}; + +struct CellGcmReportData +{ + u64 timer; + u32 value; + u32 pad; +}; + +struct CellGcmZcullInfo +{ + u32 region; + u32 size; + u32 start; + u32 offset; + u32 status0; + u32 status1; +}; + +struct CellGcmTileInfo +{ + u32 tile; + u32 limit; + u32 pitch; + u32 format; +}; + +struct GcmZcullInfo +{ + u32 m_offset; + u32 m_width; + u32 m_height; + u32 m_cullStart; + u32 m_zFormat; + u32 m_aaFormat; + u32 m_zCullDir; + u32 m_zCullFormat; + u32 m_sFunc; + u32 m_sRef; + u32 m_sMask; + bool m_binded; + + GcmZcullInfo() + { + memset(this, 0, sizeof(*this)); + } +}; + +struct GcmTileInfo +{ + u8 m_location; + u32 m_offset; + u32 m_size; + u32 m_pitch; + u8 m_comp; + u16 m_base; + u8 m_bank; + bool m_binded; + + GcmTileInfo() + { + memset(this, 0, sizeof(*this)); + } + + CellGcmTileInfo Pack() + { + CellGcmTileInfo ret; + + re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31)); + re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31)); + re(ret.pitch, (m_pitch / 0x100) << 8); + re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30)); + + return ret; + } +}; + enum { CELL_GCM_LOCATION_LOCAL, diff --git a/rpcs3/Emu/GS/GL/FragmentProgram.cpp b/rpcs3/Emu/GS/GL/GLFragmentProgram.cpp similarity index 92% rename from rpcs3/Emu/GS/GL/FragmentProgram.cpp rename to rpcs3/Emu/GS/GL/GLFragmentProgram.cpp index c093029007..f0b25a2896 100644 --- a/rpcs3/Emu/GS/GL/FragmentProgram.cpp +++ b/rpcs3/Emu/GS/GL/GLFragmentProgram.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" -#include "FragmentProgram.h" +#include "GLFragmentProgram.h" -void FragmentDecompilerThread::AddCode(wxString code, bool append_mask) +void GLFragmentDecompilerThread::AddCode(wxString code, bool append_mask) { if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return; @@ -79,7 +79,7 @@ void FragmentDecompilerThread::AddCode(wxString code, bool append_mask) main += "\t" + code + ";\n"; } -wxString FragmentDecompilerThread::GetMask() +wxString GLFragmentDecompilerThread::GetMask() { wxString ret = wxEmptyString; @@ -96,7 +96,7 @@ wxString FragmentDecompilerThread::GetMask() return ret.IsEmpty() || strncmp(ret, dst_mask, 4) == 0 ? wxEmptyString : ("." + ret); } -wxString FragmentDecompilerThread::AddReg(u32 index, int fp16) +wxString GLFragmentDecompilerThread::AddReg(u32 index, int fp16) { /* if(HasReg(index, fp16)) @@ -110,18 +110,18 @@ wxString FragmentDecompilerThread::AddReg(u32 index, int fp16) wxString::Format((fp16 ? "h%u" : "r%u"), index), fp16 ? -1 : index); } -bool FragmentDecompilerThread::HasReg(u32 index, int fp16) +bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16) { return m_parr.HasParam(PARAM_OUT, "vec4", wxString::Format((fp16 ? "h%u" : "r%u"), index)); } -wxString FragmentDecompilerThread::AddCond(int fp16) +wxString GLFragmentDecompilerThread::AddCond(int fp16) { return m_parr.AddParam(PARAM_NONE , "vec4", wxString::Format(fp16 ? "hc%d" : "rc%d", src0.cond_mod_reg_index)); } -wxString FragmentDecompilerThread::AddConst() +wxString GLFragmentDecompilerThread::AddConst() { mem32_ptr_t data(m_addr + m_size + m_offset); @@ -134,12 +134,12 @@ wxString FragmentDecompilerThread::AddConst() wxString::Format("vec4(%f, %f, %f, %f)", (float&)x, (float&)y, (float&)z, (float&)w)); } -wxString FragmentDecompilerThread::AddTex() +wxString GLFragmentDecompilerThread::AddTex() { return m_parr.AddParam(PARAM_UNIFORM, "sampler2D", wxString::Format("tex%d", dst.tex_num)); } -template wxString FragmentDecompilerThread::GetSRC(T src) +template wxString GLFragmentDecompilerThread::GetSRC(T src) { wxString ret = wxEmptyString; @@ -204,7 +204,7 @@ template wxString FragmentDecompilerThread::GetSRC(T src) return ret; } -wxString FragmentDecompilerThread::BuildCode() +wxString GLFragmentDecompilerThread::BuildCode() { wxString p = wxEmptyString; @@ -222,7 +222,7 @@ wxString FragmentDecompilerThread::BuildCode() return wxString::Format(prot, p, main); } -void FragmentDecompilerThread::Task() +void GLFragmentDecompilerThread::Task() { mem32_ptr_t data(m_addr); m_size = 0; @@ -322,13 +322,13 @@ void FragmentDecompilerThread::Task() main.Clear(); } -ShaderProgram::ShaderProgram() +GLShaderProgram::GLShaderProgram() : m_decompiler_thread(nullptr) , id(0) { } -ShaderProgram::~ShaderProgram() +GLShaderProgram::~GLShaderProgram() { if(m_decompiler_thread) { @@ -345,7 +345,7 @@ ShaderProgram::~ShaderProgram() Delete(); } -void ShaderProgram::Decompile() +void GLShaderProgram::Decompile(RSXShaderProgram& prog) { #if 0 FragmentDecompilerThread(shader, parr, addr).Entry(); @@ -362,12 +362,12 @@ void ShaderProgram::Decompile() m_decompiler_thread = nullptr; } - m_decompiler_thread = new FragmentDecompilerThread(shader, parr, addr, size); + m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size); m_decompiler_thread->Start(); #endif } -void ShaderProgram::Compile() +void GLShaderProgram::Compile() { if(id) glDeleteShader(id); @@ -401,7 +401,7 @@ void ShaderProgram::Compile() //else ConLog.Write("Shader compiled successfully!"); } -void ShaderProgram::Delete() +void GLShaderProgram::Delete() { for(u32 i=0; i> 16; } }; -struct ShaderProgram +struct GLShaderProgram { - ShaderProgram(); - ~ShaderProgram(); + GLShaderProgram(); + ~GLShaderProgram(); - FragmentDecompilerThread* m_decompiler_thread; + GLFragmentDecompilerThread* m_decompiler_thread; - ParamArray parr; + GLParamArray parr; - u32 size; - u32 addr; - u32 offset; wxString shader; u32 id; @@ -158,7 +156,7 @@ struct ShaderProgram m_decompiler_thread->Wait(); } } - void Decompile(); + void Decompile(RSXShaderProgram& prog); void Compile(); void Delete(); diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 14ddd1a541..2a2910ae25 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -84,18 +84,17 @@ void GLGSFrame::SetViewport(int x, int y, u32 w, u32 h) GLGSRender::GLGSRender() : GSRender() , m_frame(nullptr) - , m_rsx_thread(nullptr) , m_fp_buf_num(-1) , m_vp_buf_num(-1) + , m_context(nullptr) { - m_draw = false; m_frame = new GLGSFrame(); } GLGSRender::~GLGSRender() { - Close(); m_frame->Close(); + delete m_context; } void GLGSRender::Enable(bool enable, const u32 cap) @@ -110,154 +109,11 @@ void GLGSRender::Enable(bool enable, const u32 cap) } } -GLRSXThread::GLRSXThread(wxWindow* parent) - : ThreadBase(true, "OpenGL Thread") - , m_parent(parent) -{ -} - extern CellGcmContextData current_context; -void GLRSXThread::Task() -{ - ConLog.Write("GL RSX thread entry"); - - GLGSRender& p = *(GLGSRender*)m_parent; - wxGLContext cntxt(p.m_frame->GetCanvas()); - p.m_frame->GetCanvas()->SetCurrent(cntxt); - InitProcTable(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_SCISSOR_TEST); - glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); - - bool draw = true; - u32 drawed = 0; - u32 skipped = 0; - - p.Init(); - - while(!TestDestroy() && p.m_frame && !p.m_frame->IsBeingDeleted()) - { - wxCriticalSectionLocker lock(p.m_cs_main); - - const u32 get = re(p.m_ctrl->get); - const u32 put = re(p.m_ctrl->put); - if(put == get || !Emu.IsRunning()) - { - if(put == get) - SemaphorePostAndWait(p.m_sem_flush); - - Sleep(1); - continue; - } - - //ConLog.Write("addr = 0x%x", p.m_ioAddress + get); - const u32 cmd = Memory.Read32(p.m_ioAddress + get); - const u32 count = (cmd >> 18) & 0x7ff; - //if(cmd == 0) continue; - - if(cmd & CELL_GCM_METHOD_FLAG_JUMP) - { - u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT); - //ConLog.Warning("rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", addr, p.m_ioAddress + get, cmd, get, put); - re(p.m_ctrl->get, addr); - continue; - } - if(cmd & CELL_GCM_METHOD_FLAG_CALL) - { - call_stack.Push(get + 4); - u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; - u32 addr = p.m_ioAddress + offs; - //ConLog.Warning("rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); - p.m_ctrl->get = re32(offs); - continue; - } - if(cmd == CELL_GCM_METHOD_FLAG_RETURN) - { - //ConLog.Warning("rsx return!"); - u32 get = call_stack.Pop(); - //ConLog.Warning("rsx return(0x%x)", get); - p.m_ctrl->get = re32(get); - continue; - } - if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) - { - //ConLog.Warning("non increment cmd! 0x%x", cmd); - } - - if(cmd == 0) - { - ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", p.m_ioAddress + get, re(p.m_ctrl->put), get); - Emu.Pause(); - continue; - } - - mem32_ptr_t args(p.m_ioAddress + get + 4); - - if(!draw) - { - if((cmd & 0x3ffff) == NV406E_SET_REFERENCE) - { - p.m_ctrl->ref = re32(args[0]); - } - } - else - { - p.DoCmd(cmd, cmd & 0x3ffff, args, count); - } - - re(p.m_ctrl->get, get + (count + 1) * 4); - //memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4); - } - - ConLog.Write("GL RSX thread exit..."); - - call_stack.Clear(); - p.CloseOpenGL(); -} - -void GLGSRender::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) -{ - if(m_frame->IsShown()) return; - - m_draw_frames = 1; - m_skip_frames = 0; - m_width = 720; - m_height = 576; - - last_width = 0; - last_height = 0; - last_depth_format = 0; - - m_frame->Show(); - - m_ioAddress = ioAddress; - m_ioSize = ioSize; - m_ctrlAddress = ctrlAddress; - m_local_mem_addr = localAddress; - m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress); - - m_cur_vertex_prog = nullptr; - m_cur_shader_prog = nullptr; - m_cur_shader_prog_num = 0; - - (m_rsx_thread = new GLRSXThread(this))->Start(); -} - -void GLGSRender::Draw() -{ - m_draw = true; - //if(m_frame && !m_frame->IsBeingDeleted()) m_frame->Flip(); -} - void GLGSRender::Close() { - if(m_rsx_thread) - { - m_rsx_thread->Stop(); - delete m_rsx_thread; - } + if(IsAlive()) Stop(); if(m_frame->IsShown()) m_frame->Hide(); m_ctrl = nullptr; @@ -265,10 +121,10 @@ void GLGSRender::Close() void GLGSRender::EnableVertexData(bool indexed_draw) { - static u32 offset_list[16]; + static u32 offset_list[m_vertex_count]; u32 cur_offset = 0; - for(u32 i=0; i<16; ++i) + for(u32 i=0; ioffset + 2 * 4 * 4; @@ -495,1256 +351,6 @@ void GLGSRender::InitFragmentData() } } -#define case_16(a, m) \ - case a + m: \ - case a + m * 2: \ - case a + m * 3: \ - case a + m * 4: \ - case a + m * 5: \ - case a + m * 6: \ - case a + m * 7: \ - case a + m * 8: \ - case a + m * 9: \ - case a + m * 10: \ - case a + m * 11: \ - case a + m * 12: \ - case a + m * 13: \ - case a + m * 14: \ - case a + m * 15: \ - index = (cmd - a) / m; \ - case a \ - -void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count) -{ -#if CMD_DEBUG - wxString debug = GetMethodName(cmd); - debug += "("; - for(u32 i=0; i= m_skip_frames) - { - skipped = 0; - draw = true; - } - } - else - { - if(drawed++ >= m_draw_frames) - { - drawed = 0; - draw = false; - } - } - }*/ - - //if(draw) - { - //if(m_frame->GetClientSize() != wxSize(m_viewport_w, m_viewport_h)) - // m_frame->SetClientSize(m_viewport_w, m_viewport_h); - - if(m_fbo.IsCreated()) - { - m_fbo.Bind(GL_READ_FRAMEBUFFER); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - GLfbo::Blit( - 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(); - } - m_frame->Flip(); - } - - m_gcm_current_buffer = args[0]; - - m_flip_status = 0; - if(m_flip_handler) - { - m_flip_handler.Handle(1, 0, 0); - m_flip_handler.Branch(false); - } - - SemaphorePostAndWait(m_sem_flip); - } - } - break; - - case NV4097_NO_OPERATION: - break; - - case NV406E_SET_REFERENCE: - m_ctrl->ref = re32(args[0]); - break; - - case_16(NV4097_SET_TEXTURE_OFFSET, 0x20): - { - GLTexture& tex = m_frame->GetTexture(index); - const u32 offset = args[0]; - u32 a1 = args[1]; - u8 location = (a1 & 0x3) - 1; - const bool cubemap = (a1 >> 2) & 0x1; - const u8 dimension = (a1 >> 4) & 0xf; - const u8 format = (a1 >> 8) & 0xff; - const u16 mipmap = (a1 >> 16) & 0xffff; - CMD_LOG("index = %d, offset=0x%x, location=0x%x, cubemap=0x%x, dimension=0x%x, format=0x%x, mipmap=0x%x", - index, offset, location, cubemap, dimension, format, mipmap); - - if(location == 2) - { - ConLog.Error("Bad texture location."); - location = 1; - } - u32 tex_addr = GetAddress(offset, location); - //ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location); - tex.SetOffset(tex_addr); - tex.SetFormat(cubemap, dimension, format, mipmap); - } - break; - - case_16(NV4097_SET_TEXTURE_CONTROL0, 0x20): - { - GLTexture& tex = m_frame->GetTexture(index); - u32 a0 = args[0]; - bool enable = a0 >> 31 ? true : false; - u16 minlod = (a0 >> 19) & 0xfff; - u16 maxlod = (a0 >> 7) & 0xfff; - u8 maxaniso = (a0 >> 2) & 0x7; - tex.SetControl0(enable, minlod, maxlod, maxaniso); - } - break; - - case_16(NV4097_SET_VERTEX_DATA4UB_M, 4): - { - u32 v = args[0]; - u8 v0 = v; - u8 v1 = v >> 8; - u8 v2 = v >> 16; - u8 v3 = v >> 24; - - m_vertex_data[index].size = 4; - m_vertex_data[index].type = 4; - m_vertex_data[index].data.AddCpy(v0); - m_vertex_data[index].data.AddCpy(v1); - m_vertex_data[index].data.AddCpy(v2); - m_vertex_data[index].data.AddCpy(v3); - //ConLog.Warning("index = %d, v0 = 0x%x, v1 = 0x%x, v2 = 0x%x, v3 = 0x%x", index, v0, v1, v2, v3); - } - break; - - case_16(NV4097_SET_VERTEX_DATA2F_M, 8): - { - u32 a0 = args[0]; - u32 a1 = args[1]; - - float v0 = (float&)a0; - float v1 = (float&)a1; - - m_vertex_data[index].type = 2; - m_vertex_data[index].size = 2; - m_vertex_data[index].data.SetCount(sizeof(float) * 2); - (float&)m_vertex_data[index].data[sizeof(float)*0] = v0; - (float&)m_vertex_data[index].data[sizeof(float)*1] = v1; - - //ConLog.Warning("index = %d, v0 = %f, v1 = %f", index, v0, v1); - } - break; - - case_16(NV4097_SET_VERTEX_DATA4F_M, 16): - { - u32 a0 = args[0]; - u32 a1 = args[1]; - u32 a2 = args[2]; - u32 a3 = args[3]; - - float v0 = (float&)a0; - float v1 = (float&)a1; - float v2 = (float&)a2; - float v3 = (float&)a3; - - m_vertex_data[index].type = 2; - m_vertex_data[index].size = 4; - m_vertex_data[index].data.SetCount(sizeof(float) * 4); - (float&)m_vertex_data[index].data[sizeof(float)*0] = v0; - (float&)m_vertex_data[index].data[sizeof(float)*1] = v1; - (float&)m_vertex_data[index].data[sizeof(float)*2] = v2; - (float&)m_vertex_data[index].data[sizeof(float)*3] = v3; - - //ConLog.Warning("index = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", index, v0, v1, v2, v3); - } - break; - - case_16(NV4097_SET_TEXTURE_CONTROL1, 0x20): - { - GLTexture& tex = m_frame->GetTexture(index); - tex.SetControl1(args[0]); - } - break; - - case_16(NV4097_SET_TEXTURE_CONTROL3, 4): - { - GLTexture& tex = m_frame->GetTexture(index); - u32 a0 = args[0]; - u32 pitch = a0 & 0xFFFFF; - u16 depth = a0 >> 20; - tex.SetControl3(pitch, depth); - } - break; - - case_16(NV4097_SET_TEXTURE_FILTER, 0x20): - { - 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): - { - GLTexture& tex = m_frame->GetTexture(index); - - u32 a0 = args[0]; - u8 wraps = a0 & 0xf; - u8 aniso_bias = (a0 >> 4) & 0xf; - u8 wrapt = (a0 >> 8) & 0xf; - u8 unsigned_remap = (a0 >> 12) & 0xf; - u8 wrapr = (a0 >> 16) & 0xf; - u8 gamma = (a0 >> 20) & 0xf; - u8 signed_remap = (a0 >> 24) & 0xf; - u8 zfunc = a0 >> 28; - - tex.SetAddress(wraps, wrapt, wrapr, unsigned_remap, zfunc, gamma, aniso_bias, signed_remap); - } - break; - - case_16(NV4097_SET_TEX_COORD_CONTROL, 4): - //TODO - break; - - case_16(NV4097_SET_TEXTURE_IMAGE_RECT, 32): - { - GLTexture& tex = m_frame->GetTexture(index); - - const u16 height = args[0] & 0xffff; - const u16 width = args[0] >> 16; - CMD_LOG("width=%d, height=%d", width, height); - tex.SetRect(width, height); - } - break; - - case NV4097_SET_SURFACE_FORMAT: - { - u32 a0 = args[0]; - m_set_surface_format = true; - m_surface_color_format = a0 & 0x1f; - m_surface_depth_format = (a0 >> 5) & 0x7; - m_surface_type = (a0 >> 8) & 0xf; - m_surface_antialias = (a0 >> 12) & 0xf; - m_surface_width = (a0 >> 16) & 0xff; - m_surface_height = (a0 >> 24) & 0xff; - m_surface_pitch_a = args[1]; - m_surface_offset_a = args[2]; - m_surface_offset_z = args[3]; - m_surface_offset_b = args[4]; - m_surface_pitch_b = args[5]; - - 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); - } - break; - - case NV4097_SET_COLOR_MASK_MRT: - { - } - break; - - case NV4097_SET_COLOR_MASK: - { - const u32 flags = args[0]; - - m_set_color_mask = true; - m_color_mask_a = flags & 0x1000000 ? true : false; - m_color_mask_r = flags & 0x0010000 ? true : false; - m_color_mask_g = flags & 0x0000100 ? true : false; - m_color_mask_b = flags & 0x0000001 ? true : false; - } - break; - - case NV4097_SET_ALPHA_TEST_ENABLE: - m_set_alpha_test = args[0] ? true : false; - break; - - case NV4097_SET_BLEND_ENABLE: - m_set_blend = args[0] ? true : false; - break; - - case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: - m_set_depth_bounds_test = args[0] ? true : false; - break; - - case NV4097_SET_ALPHA_FUNC: - 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: - m_set_cull_face = true; - m_cull_face = args[0]; - break; - - case NV4097_SET_VIEWPORT_VERTICAL: - { - m_set_viewport_vertical = true; - m_viewport_y = args[0] & 0xffff; - m_viewport_h = args[0] >> 16; - } - break; - - case NV4097_SET_VIEWPORT_HORIZONTAL: - { - m_set_viewport_horizontal = true; - m_viewport_x = args[0] & 0xffff; - m_viewport_w = args[0] >> 16; - - if(count == 2) - { - m_set_viewport_vertical = true; - m_viewport_y = args[1] & 0xffff; - m_viewport_h = args[1] >> 16; - } - - CMD_LOG("x=%d, y=%d, w=%d, h=%d", m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); - } - break; - - case NV4097_SET_CLIP_MIN: - { - const u32 clip_min = args[0]; - const u32 clip_max = args[1]; - - m_set_clip = true; - m_clip_min = (float&)clip_min; - m_clip_max = (float&)clip_max; - - CMD_LOG("clip_min=%.01f, clip_max=%.01f", m_clip_min, m_clip_max); - } - break; - - case NV4097_SET_DEPTH_FUNC: - m_set_depth_func = true; - m_depth_func = args[0]; - break; - - case NV4097_SET_DEPTH_TEST_ENABLE: - m_depth_test_enable = args[0] ? true : false; - break; - - case NV4097_SET_FRONT_POLYGON_MODE: - m_set_front_polygon_mode = true; - m_front_polygon_mode = args[0]; - break; - - case NV4097_CLEAR_SURFACE: - { - u32 a0 = args[0]; - - if(a0 & 0x01) m_clear_surface_z = m_clear_z; - if(a0 & 0x02) m_clear_surface_s = m_clear_s; - if(a0 & 0x10) m_clear_surface_color_r = m_clear_color_r; - if(a0 & 0x20) m_clear_surface_color_g = m_clear_color_g; - if(a0 & 0x40) m_clear_surface_color_b = m_clear_color_b; - if(a0 & 0x80) m_clear_surface_color_a = m_clear_color_a; - - m_clear_surface_mask |= a0; - } - break; - - case NV4097_SET_BLEND_FUNC_SFACTOR: - { - m_set_blend_sfactor = true; - m_blend_sfactor_rgb = args[0] & 0xffff; - m_blend_sfactor_alpha = args[0] >> 16; - - if(count >= 2) - { - m_set_blend_dfactor = true; - m_blend_dfactor_rgb = args[1] & 0xffff; - m_blend_dfactor_alpha = args[1] >> 16; - } - } - break; - - case NV4097_SET_BLEND_FUNC_DFACTOR: - { - m_set_blend_dfactor = true; - m_blend_dfactor_rgb = args[0] & 0xffff; - m_blend_dfactor_alpha = args[0] >> 16; - } - break; - - case_16(NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4): - { - const u32 addr = GetAddress(args[0] & 0x7fffffff, args[0] >> 31); - CMD_LOG("num=%d, addr=0x%x", index, addr); - m_vertex_data[index].addr = addr; - } - break; - - case_16(NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4): - { - u32 a0 = args[0]; - const u16 frequency = a0 >> 16; - const u8 stride = (a0 >> 8) & 0xff; - const u8 size = (a0 >> 4) & 0xf; - const u8 type = a0 & 0xf; - - CMD_LOG("index=%d, frequency=%d, stride=%d, size=%d, type=%d", - index, frequency, stride, size, type); - - VertexData& cv = m_vertex_data[index]; - cv.frequency = frequency; - cv.stride = stride; - cv.size = size; - cv.type = type; - } - break; - - case NV4097_DRAW_ARRAYS: - { - for(u32 c=0; c> 24) + 1; - - LoadVertexData(first, _count); - - m_draw_array_count += _count; - } - } - break; - - case NV4097_SET_INDEX_ARRAY_ADDRESS: - { - m_indexed_array.m_addr = GetAddress(args[0], args[1] & 0xf); - m_indexed_array.m_type = args[1] >> 4; - } - break; - - case NV4097_DRAW_INDEX_ARRAY: - { - for(u32 c=0; c> 24) + 1; - - if(first < m_indexed_array.m_first) m_indexed_array.m_first = first; - - for(u32 i=first; i<_count; ++i) - { - u32 index; - switch(m_indexed_array.m_type) - { - case 0: - { - int pos = m_indexed_array.m_data.GetCount(); - m_indexed_array.m_data.InsertRoomEnd(4); - index = Memory.Read32(m_indexed_array.m_addr + i * 4); - *(u32*)&m_indexed_array.m_data[pos] = index; - //ConLog.Warning("index 4: %d", *(u32*)&m_indexed_array.m_data[pos]); - } - break; - - case 1: - { - int pos = m_indexed_array.m_data.GetCount(); - m_indexed_array.m_data.InsertRoomEnd(2); - index = Memory.Read16(m_indexed_array.m_addr + i * 2); - //ConLog.Warning("index 2: %d", index); - *(u16*)&m_indexed_array.m_data[pos] = index; - } - break; - } - - if(index < m_indexed_array.index_min) m_indexed_array.index_min = index; - if(index > m_indexed_array.index_max) m_indexed_array.index_max = index; - } - - m_indexed_array.m_count += _count; - } - } - break; - - case NV4097_SET_BEGIN_END: - { - if(args[0]) - { - //begin - if(Emu.GetCallbackManager().m_exit_callback.m_callbacks.GetCount()) - { - //Emu.GetCallbackManager().m_exit_callback.Handle(0x0121, 0); - } - m_draw_mode = args[0] - 1; - } - else - { - //end - ExecCMD(); - if(Emu.GetCallbackManager().m_exit_callback.m_callbacks.GetCount()) - { - //Emu.GetCallbackManager().m_exit_callback.Handle(0x0122, 0); - } - } - } - break; - - case NV4097_SET_COLOR_CLEAR_VALUE: - { - const u32 color = args[0]; - m_clear_color_a = (color >> 24) & 0xff; - m_clear_color_r = (color >> 16) & 0xff; - m_clear_color_g = (color >> 8) & 0xff; - m_clear_color_b = color & 0xff; - } - break; - - case NV4097_SET_SHADER_PROGRAM: - { - m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num++]; - m_cur_shader_prog->Delete(); - u32 a0 = args[0]; - m_cur_shader_prog->offset = a0 & ~0x3; - m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); - } - break; - - case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: - { - //VertexData[0].prog.attributeOutputMask = args[0]; - //FragmentData.prog.attributeInputMask = args[0]/* & ~0x20*/; - } - break; - - case NV4097_SET_SHADER_CONTROL: - { - const u32 arg0 = args[0]; - - //const u8 controlTxp = (arg0 >> 15) & 0x1; - //FragmentData.prog.registerCount = arg0 >> 24; - //FragmentData.prog. - } - break; - - case NV4097_SET_TRANSFORM_PROGRAM_LOAD: - { - m_cur_vertex_prog = &m_vertex_progs[args[0]]; - m_cur_vertex_prog->Delete(); - - if(count == 2) - { - const u32 start = args[1]; - if(start) - ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start); - } - } - break; - - case NV4097_SET_TRANSFORM_PROGRAM: - { - if(!m_cur_vertex_prog) - { - ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL"); - break; - } - - for(u32 i=0; idata.AddCpy(args[i]); - } - break; - - case NV4097_SET_TRANSFORM_TIMEOUT: - - if(!m_cur_vertex_prog) - { - ConLog.Warning("NV4097_SET_TRANSFORM_TIMEOUT: m_cur_vertex_prog == NULL"); - break; - } - - //m_cur_vertex_prog->Decompile(); - break; - - case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: - //VertexData[0].prog.attributeInputMask = args[0]; - break; - - case NV4097_INVALIDATE_VERTEX_CACHE_FILE: - break; - - case NV4097_SET_TRANSFORM_CONSTANT_LOAD: - { - if((count - 1) % 4) - { - CMD_LOG("NV4097_SET_TRANSFORM_CONSTANT_LOAD [%d]", count); - break; - } - - for(u32 id = args[0], i = 1; i= 2) - { - m_set_stencil_func_ref = true; - m_stencil_func_ref = args[1]; - - if(count >= 3) - { - m_set_stencil_func_mask = true; - m_stencil_func_mask = args[2]; - } - } - break; - - case NV4097_SET_STENCIL_FUNC_REF: - m_set_stencil_func_ref = true; - m_stencil_func_ref = args[0]; - break; - - case NV4097_SET_STENCIL_FUNC_MASK: - m_set_stencil_func_mask = true; - m_stencil_func_mask = args[0]; - break; - - case NV4097_SET_STENCIL_OP_FAIL: - m_set_stencil_fail = true; - m_stencil_fail = args[0]; - if(count >= 2) - { - m_set_stencil_zfail = true; - m_stencil_zfail = args[1]; - - if(count >= 3) - { - m_set_stencil_zpass = true; - m_stencil_zpass = args[2]; - } - } - break; - - case NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE: - m_set_two_sided_stencil_test_enable = args[0] ? true : false; - break; - - case NV4097_SET_BACK_STENCIL_MASK: - m_set_back_stencil_mask = true; - m_back_stencil_mask = args[0]; - break; - - case NV4097_SET_BACK_STENCIL_FUNC: - m_set_back_stencil_func = true; - m_back_stencil_func = args[0]; - if(count >= 2) - { - m_set_back_stencil_func_ref = true; - m_back_stencil_func_ref = args[1]; - - if(count >= 3) - { - m_set_back_stencil_func_mask = true; - m_back_stencil_func_mask = args[2]; - } - } - break; - - case NV4097_SET_BACK_STENCIL_FUNC_REF: - m_set_back_stencil_func_ref = true; - m_back_stencil_func_ref = args[0]; - break; - - case NV4097_SET_BACK_STENCIL_FUNC_MASK: - m_set_back_stencil_func_mask = true; - m_back_stencil_func_mask = args[0]; - break; - - case NV4097_SET_BACK_STENCIL_OP_FAIL: - m_set_stencil_fail = true; - m_stencil_fail = args[0]; - if(count >= 2) - { - m_set_back_stencil_zfail = true; - m_back_stencil_zfail = args[1]; - - if(count >= 3) - { - m_set_back_stencil_zpass = true; - m_back_stencil_zpass = args[2]; - } - } - break; - - case NV4097_SET_POLY_OFFSET_FILL_ENABLE: - if(args[0]) ConLog.Error("NV4097_SET_POLY_OFFSET_FILL_ENABLE"); - break; - - case NV4097_SET_RESTART_INDEX_ENABLE: - if(args[0]) ConLog.Error("NV4097_SET_RESTART_INDEX_ENABLE"); - break; - - case NV4097_SET_POINT_PARAMS_ENABLE: - if(args[0]) ConLog.Error("NV4097_SET_POINT_PARAMS_ENABLE"); - break; - - case NV4097_SET_POINT_SPRITE_CONTROL: - if(args[0] & 0x1) - { - ConLog.Error("NV4097_SET_POINT_SPRITE_CONTROL enable"); - } - break; - - case NV4097_SET_POLY_SMOOTH_ENABLE: - m_set_poly_smooth = args[0] ? true : false; - break; - - case NV4097_SET_BLEND_COLOR: - m_set_blend_color = true; - m_blend_color_r = args[0] & 0xff; - m_blend_color_g = (args[0] >> 8) & 0xff; - m_blend_color_b = (args[0] >> 16) & 0xff; - m_blend_color_a = (args[0] >> 24) & 0xff; - break; - - case NV4097_SET_BLEND_COLOR2: - if(args[0]) ConLog.Error("NV4097_SET_BLEND_COLOR2"); - break; - - case NV4097_SET_BLEND_EQUATION: - m_set_blend_equation = true; - m_blend_equation_rgb = args[0] & 0xffff; - m_blend_equation_alpha = args[0] >> 16; - break; - - case NV4097_SET_REDUCE_DST_COLOR: - if(args[0]) ConLog.Error("NV4097_SET_REDUCE_DST_COLOR"); - break; - - case NV4097_SET_DEPTH_MASK: - m_set_depth_mask = true; - m_depth_mask = args[0]; - break; - - case NV4097_SET_SCISSOR_VERTICAL: - { - m_set_scissor_vertical = true; - m_scissor_y = args[0] & 0xffff; - m_scissor_h = args[0] >> 16; - } - break; - - case NV4097_SET_SCISSOR_HORIZONTAL: - { - m_set_scissor_horizontal = true; - m_scissor_x = args[0] & 0xffff; - m_scissor_w = args[0] >> 16; - - if(count == 2) - { - m_set_scissor_vertical = true; - m_scissor_y = args[1] & 0xffff; - m_scissor_h = args[1] >> 16; - } - } - break; - - case NV4097_INVALIDATE_VERTEX_FILE: break; - - case NV4097_SET_VIEWPORT_OFFSET: - { - //TODO - } - break; - - case NV4097_SET_SEMAPHORE_OFFSET: - case NV406E_SEMAPHORE_OFFSET: - { - m_set_semaphore_offset = true; - m_semaphore_offset = args[0]; - } - break; - - case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: - { - if(m_set_semaphore_offset) - { - m_set_semaphore_offset = false; - u32 value = args[0]; - value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); - - Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, value); - } - } - break; - - case NV406E_SEMAPHORE_RELEASE: - case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: - if(m_set_semaphore_offset) - { - m_set_semaphore_offset = false; - Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, args[0]); - } - break; - - case NV406E_SEMAPHORE_ACQUIRE: - { - //TODO - } - break; - - case NV4097_SET_RESTART_INDEX: - { - //TODO - } - break; - - case NV4097_INVALIDATE_L2: - { - //TODO - } - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_A: - { - m_set_context_dma_color_a = true; - m_context_dma_color_a = args[0]; - } - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_B: - { - m_set_context_dma_color_b = true; - m_context_dma_color_b = args[0]; - } - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_C: - { - m_set_context_dma_color_c = true; - m_context_dma_color_c = args[0]; - - if(count > 1) - { - m_set_context_dma_color_d = true; - m_context_dma_color_d = args[1]; - } - } - break; - - case NV4097_SET_CONTEXT_DMA_ZETA: - { - m_set_context_dma_z = true; - m_context_dma_z = args[0]; - } - break; - /* - case NV4097_SET_SURFACE_PITCH_A: - { - //TODO - } - break; - - case NV4097_SET_SURFACE_PITCH_B: - { - //TODO - } - break; - */ - case NV4097_SET_SURFACE_PITCH_C: - { - if(count != 4) - { - ConLog.Error("NV4097_SET_SURFACE_PITCH_C: Bad count (%d)", count); - break; - } - - m_surface_pitch_c = args[0]; - m_surface_pitch_d = args[1]; - m_surface_offset_c = args[2]; - m_surface_offset_d = args[3]; - } - break; - - case NV4097_SET_SURFACE_PITCH_Z: - { - m_surface_pitch_z = args[0]; - } - break; - - case NV4097_SET_SHADER_WINDOW: - { - u32 a0 = args[0]; - m_shader_window_height = a0 & 0xfff; - m_shader_window_origin = (a0 >> 12) & 0xf; - m_shader_window_pixel_centers = a0 >> 16; - } - break; - - case NV4097_SET_SURFACE_CLIP_VERTICAL: - { - u32 a0 = args[0]; - m_set_surface_clip_vertical = true; - m_surface_clip_y = a0; - m_surface_clip_h = a0 >> 16; - } - break; - - case NV4097_SET_SURFACE_CLIP_HORIZONTAL: - { - u32 a0 = args[0]; - - m_set_surface_clip_horizontal = true; - m_surface_clip_x = a0; - m_surface_clip_w = a0 >> 16; - - if(count >= 2) - { - u32 a1 = args[1]; - m_set_surface_clip_vertical = true; - m_surface_clip_y = a1; - m_surface_clip_h = a1 >> 16; - } - } - break; - - case NV4097_SET_WINDOW_OFFSET: - { - //TODO - } - break; - - case NV4097_SET_SURFACE_COLOR_TARGET: - { - m_surface_colour_target = args[0]; - } - break; - - case NV4097_SET_ANTI_ALIASING_CONTROL: - { - //TODO - } - break; - - case NV4097_SET_LINE_SMOOTH_ENABLE: - m_set_line_smooth = args[0] ? true : false; - break; - - case NV4097_SET_LINE_WIDTH: - m_set_line_width = true; - m_line_width = args[0]; - break; - - case NV4097_SET_SHADE_MODE: - m_set_shade_mode = true; - m_shade_mode = args[0]; - break; - - case NV4097_SET_ZSTENCIL_CLEAR_VALUE: - { - u32 a0 = args[0]; - m_clear_s = a0 & 0xff; - m_clear_z = a0 >> 8; - } - 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: - { - u32 a0 = args[0]; - u8 type = a0 >> 24; - u32 offset = a0 & 0xffffff; - - u64 data; - switch(type) - { - case 1: - data = std::chrono::steady_clock::now().time_since_epoch().count(); - data *= 1000000; - break; - - default: - data = 0; - ConLog.Error("NV4097_GET_REPORT: bad type %d", type); - break; - } - - Memory.Write64(m_local_mem_addr + offset, data); - } - break; - - case NV3062_SET_OFFSET_DESTIN: - m_dst_offset = args[0]; - break; - - case NV308A_COLOR: - { - TransformConstant c; - c.id = m_dst_offset; - - if(count >= 1) - { - u32 a = args[0]; - a = a << 16 | a >> 16; - c.x = (float&)a; - } - - if(count >= 2) - { - u32 a = args[1]; - a = a << 16 | a >> 16; - c.y = (float&)a; - } - - if(count >= 3) - { - u32 a = args[2]; - a = a << 16 | a >> 16; - c.z = (float&)a; - } - - if(count >= 4) - { - u32 a = args[3]; - a = a << 16 | a >> 16; - c.w = (float&)a; - } - - if(count >= 5) - { - ConLog.Warning("NV308A_COLOR: count = %d", count); - } - - //ConLog.Warning("NV308A_COLOR: [%d]: %f, %f, %f, %f", c.id, c.x, c.y, c.z, c.w); - m_fragment_constants.AddCpy(c); - } - break; - - case NV308A_POINT: - //TODO - 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; - } - break; - - case NV3089_SET_COLOR_CONVERSION: - { - m_color_conv = args[0]; - m_color_conv_fmt = args[1]; - 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; - 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; - m_color_conv_dsdx = args[7]; - m_color_conv_dtdy = args[8]; - } - break; - - case NV3089_IMAGE_IN_SIZE: - { - u16 w = args[0]; - u16 h = args[0] >> 16; - u16 pitch = args[1]; - u8 origin = args[1] >> 16; - u8 inter = args[1] >> 24; - u32 offset = args[2]; - u16 u = args[3]; - u16 v = args[3] >> 16; - - u8* pixels_src = &Memory[GetAddress(offset, m_context_dma_img_src - 0xfeed0000)]; - u8* pixels_dst = &Memory[GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)]; - - for(u16 y=0; y> 4) & 0xf; - m_clip_plane_2 = (a0 >> 8) & 0xf; - m_clip_plane_3 = (a0 >> 12) & 0xf; - m_clip_plane_4 = (a0 >> 16) & 0xf; - m_clip_plane_5 = a0 >> 20; - } - break; - - case NV4097_SET_FOG_PARAMS: - { - m_set_fog_params = true; - u32 a0 = args[0]; - u32 a1 = args[1]; - m_fog_param0 = (float&)a0; - m_fog_param1 = (float&)a1; - } - break; - - default: - { - wxString log = GetMethodName(cmd); - log += "("; - for(u32 i=0; iDecompile(); + if(m_fp_buf_num == -1) m_shader_prog.Decompile(*m_cur_shader_prog); if(!m_cur_vertex_prog) { @@ -1765,37 +371,34 @@ bool GLGSRender::LoadProgram() return false; } - if(m_program.IsCreated()) - { - m_program.Use(); - return true; - } //ConLog.Write("Create program"); - m_vp_buf_num = m_prog_buffer.SearchVp(*m_cur_vertex_prog); + m_vp_buf_num = m_prog_buffer.SearchVp(*m_cur_vertex_prog, m_vertex_prog); if(m_vp_buf_num == -1) { ConLog.Warning("VP not found in buffer!"); - m_cur_vertex_prog->Decompile(); + m_vertex_prog.Decompile(*m_cur_vertex_prog); } if(m_fp_buf_num == -1) { ConLog.Warning("FP not found in buffer!"); - m_cur_shader_prog->Wait(); - m_cur_shader_prog->Compile(); + m_shader_prog.Wait(); + m_shader_prog.Compile(); + checkForGlError("m_shader_prog.Compile"); wxFile f(wxGetCwd() + "/FragmentProgram.txt", wxFile::write); - f.Write(m_cur_shader_prog->shader); + f.Write(m_shader_prog.shader); } if(m_vp_buf_num == -1) { - m_cur_vertex_prog->Wait(); - m_cur_vertex_prog->Compile(); + m_vertex_prog.Wait(); + m_vertex_prog.Compile(); + checkForGlError("m_vertex_prog.Compile"); wxFile f(wxGetCwd() + "/VertexProgram.txt", wxFile::write); - f.Write(m_cur_vertex_prog->shader); + f.Write(m_vertex_prog.shader); } if(m_fp_buf_num != -1 && m_vp_buf_num != -1) @@ -1809,9 +412,9 @@ bool GLGSRender::LoadProgram() } else { - m_program.Create(m_cur_vertex_prog->id, m_cur_shader_prog->id); + m_program.Create(m_vertex_prog.id, m_shader_prog.id); checkForGlError("m_program.Create"); - m_prog_buffer.Add(m_program, *m_cur_shader_prog, *m_cur_vertex_prog); + m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_shader_prog, m_vertex_prog, *m_cur_vertex_prog); checkForGlError("m_prog_buffer.Add"); m_program.Use(); @@ -1983,419 +586,48 @@ void GLGSRender::WriteBuffers() } } -void GLGSRender::ExecCMD() +void GLGSRender::OnInit() { - if(LoadProgram()) - { - if(m_width != last_width || m_height != last_height || last_depth_format != m_surface_depth_format) - { - ConLog.Warning("New FBO (%dx%d)", m_width, m_height); - last_width = m_width; - last_height = m_height; - last_depth_format = m_surface_depth_format; + m_draw_frames = 1; + m_skip_frames = 0; + m_width = 720; + m_height = 576; - m_fbo.Create(); - checkForGlError("m_fbo.Create"); - m_fbo.Bind(); + last_width = 0; + last_height = 0; + last_depth_format = 0; - m_rbo.Create(4 + 1); - checkForGlError("m_rbo.Create"); - - for(int i=0; i<4; ++i) - { - m_rbo.Bind(i); - m_rbo.Storage(GL_RGBA, m_width, m_height); - checkForGlError("m_rbo.Storage(GL_RGBA)"); - } - - m_rbo.Bind(4); - - switch(m_surface_depth_format) - { - case 1: - m_rbo.Storage(GL_DEPTH_COMPONENT16, m_width, m_height); - checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); - break; - - case 2: - m_rbo.Storage(GL_DEPTH24_STENCIL8, m_width, m_height); - checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); - break; - - default: - ConLog.Error("Bad depth format! (%d)", m_surface_depth_format); - assert(0); - break; - } - - for(int i=0; i<4; ++i) - { - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); - checkForGlError(wxString::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); - } - - m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); - - if(m_surface_depth_format == 2) - { - m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); - } - } - - if(!m_set_surface_clip_horizontal) - { - m_surface_clip_x = 0; - m_surface_clip_w = m_width; - } - - if(!m_set_surface_clip_vertical) - { - m_surface_clip_y = 0; - m_surface_clip_h = m_height; - } - - m_fbo.Bind(); - WriteDepthBuffer(); - static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - - switch(m_surface_colour_target) - { - case 0x0: - break; - - case 0x1: - glDrawBuffer(draw_buffers[0]); - break; - - case 0x2: - glDrawBuffer(draw_buffers[1]); - break; - - case 0x13: - glDrawBuffers(2, draw_buffers); - break; - - case 0x17: - glDrawBuffers(3, draw_buffers); - break; - - case 0x1f: - glDrawBuffers(4, draw_buffers); - break; - - default: - ConLog.Error("Bad surface colour target: %d", m_surface_colour_target); - break; - } - - if(m_set_color_mask) - { - glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); - checkForGlError("glColorMask"); - } - - if(m_set_viewport_horizontal && m_set_viewport_vertical) - { - glViewport(m_scissor_x, m_height-m_viewport_y-m_viewport_h, m_viewport_w, m_viewport_h); - checkForGlError("glViewport"); - } - - if(m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_height-m_scissor_y-m_scissor_h, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - - if(m_clear_surface_mask) - { - GLbitfield f = 0; - - if (m_clear_surface_mask & 0x1) - { - glClearDepth(m_clear_surface_z / (float)0xffffff); - - f |= GL_DEPTH_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0x2) - { - glClearStencil(m_clear_surface_s); - - f |= GL_STENCIL_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0xF0) - { - glClearColor( - m_clear_surface_color_r / 255.0f, - m_clear_surface_color_g / 255.0f, - m_clear_surface_color_b / 255.0f, - m_clear_surface_color_a / 255.0f); - - f |= GL_COLOR_BUFFER_BIT; - } - - glClear(f); - } - - if(m_set_front_polygon_mode) - { - glPolygonMode(GL_FRONT, m_front_polygon_mode); - checkForGlError("glPolygonMode"); - } - - Enable(m_depth_test_enable, GL_DEPTH_TEST); - Enable(m_set_alpha_test, GL_ALPHA_TEST); - 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_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); - Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); - - if(m_set_clip_plane) - { - Enable(m_clip_plane_0, GL_CLIP_PLANE0); - Enable(m_clip_plane_1, GL_CLIP_PLANE1); - Enable(m_clip_plane_2, GL_CLIP_PLANE2); - Enable(m_clip_plane_3, GL_CLIP_PLANE3); - Enable(m_clip_plane_4, GL_CLIP_PLANE4); - Enable(m_clip_plane_5, GL_CLIP_PLANE5); - - checkForGlError("m_set_clip_plane"); - } - - checkForGlError("glEnable"); - - if(m_set_two_sided_stencil_test_enable) - { - if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOpSeparate"); - } - - if(m_set_stencil_mask) - { - glStencilMaskSeparate(GL_FRONT, m_stencil_mask); - checkForGlError("glStencilMaskSeparate"); - } - - if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFuncSeparate"); - } - - if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) - { - glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); - checkForGlError("glStencilOpSeparate(GL_BACK)"); - } - - if(m_set_back_stencil_mask) - { - glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); - checkForGlError("glStencilMaskSeparate(GL_BACK)"); - } - - if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) - { - glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); - checkForGlError("glStencilFuncSeparate(GL_BACK)"); - } - } - else - { - if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOp"); - } - - if(m_set_stencil_mask) - { - glStencilMask(m_stencil_mask); - checkForGlError("glStencilMask"); - } - - if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFunc"); - } - } - - if(m_set_shade_mode) - { - glShadeModel(m_shade_mode); - checkForGlError("glShadeModel"); - } - - if(m_set_depth_mask) - { - glDepthMask(m_depth_mask); - checkForGlError("glDepthMask"); - } - - if(m_set_depth_func) - { - glDepthFunc(m_depth_func); - checkForGlError("glDepthFunc"); - } - - if(m_set_clip) - { - glDepthRangef(m_clip_min, m_clip_max); - checkForGlError("glDepthRangef"); - } - - if(m_set_line_width) - { - glLineWidth(m_line_width / 255.f); - checkForGlError("glLineWidth"); - } - - if(m_set_blend_equation) - { - glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); - checkForGlError("glBlendEquationSeparate"); - } - - if(m_set_blend_sfactor && m_set_blend_dfactor) - { - glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); - checkForGlError("glBlendFuncSeparate"); - } - - if(m_set_blend_color) - { - glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); - 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) - { - ConLog.Warning("m_indexed_array.m_count && draw_array_count"); - } - - for(u32 i=0; iGetTexture(i); - if(!tex.IsEnabled()) continue; - - glActiveTexture(GL_TEXTURE0 + i); - checkForGlError("glActiveTexture"); - tex.Create(); - tex.Bind(); - checkForGlError("tex.Bind"); - m_program.SetTex(i); - tex.Init(); - checkForGlError("tex.Init"); - //tex.Save(); - } - - m_vao.Bind(); - if(m_indexed_array.m_count) - { - LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); - } - - EnableVertexData(m_indexed_array.m_count ? true : false); - - InitVertexData(); - InitFragmentData(); - - if(m_indexed_array.m_count) - { - switch(m_indexed_array.m_type) - { - case 0: - glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); - checkForGlError("glDrawElements #4"); - break; - - case 1: - glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); - checkForGlError("glDrawElements #2"); - break; - - default: - ConLog.Error("Bad indexed array type (%d)", m_indexed_array.m_type); - break; - } - - DisableVertexData(); - m_indexed_array.Reset(); - } - - if(m_draw_array_count) - { - glDrawArrays(m_draw_mode, 0, m_draw_array_count); - checkForGlError("glDrawArrays"); - DisableVertexData(); - m_draw_array_count = 0; - } - - m_fragment_constants.Clear(); - - WriteBuffers(); - } - else - { - ConLog.Error("LoadProgram failed."); - Emu.Pause(); - } - - Reset(); + m_frame->Show(); } -void GLGSRender::Reset() +void GLGSRender::OnInitThread() +{ + m_context = new wxGLContext(m_frame->GetCanvas()); + + m_frame->GetCanvas()->SetCurrent(*m_context); + InitProcTable(); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_SCISSOR_TEST); + glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); +} + +void GLGSRender::OnExitThread() +{ + m_program.Delete(); + m_rbo.Delete(); + m_fbo.Delete(); + m_vbo.Delete(); + m_vao.Delete(); + m_prog_buffer.Clear(); +} + +void GLGSRender::OnReset() { m_program.UnUse(); - //m_prog_buffer.Clear(); - if(m_cur_shader_prog) - m_cur_shader_prog->id = 0; - if(m_cur_vertex_prog) - m_cur_vertex_prog->id = 0; - - m_cur_shader_prog_num = 0; - m_transform_constants.Clear(); - for(uint i=0; iFlip(); } \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 2b307d4cf3..ca8ec5cd53 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -3,9 +3,9 @@ #include "Emu/GS/RSXThread.h" #include "wx/glcanvas.h" #include "GLBuffers.h" -#include "Program.h" +#include "GLProgram.h" #include "OpenGL.h" -#include "ProgramBuffer.h" +#include "GLProgramBuffer.h" #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "gl.lib") @@ -15,57 +15,10 @@ void checkForGlError(const char* situation); class GLTexture { - u32 m_width, m_height; u32 m_id; - u32 m_offset; - bool m_enabled; - - bool m_cubemap; - u8 m_dimension; - u32 m_format; - u16 m_mipmap; - - u32 m_pitch; - u16 m_depth; - - u16 m_minlod; - u16 m_maxlod; - u8 m_maxaniso; - - u8 m_wraps; - u8 m_wrapt; - u8 m_wrapr; - u8 m_unsigned_remap; - u8 m_zfunc; - u8 m_gamma; - 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: - GLTexture() - : m_width(0), m_height(0) - , m_id(0) - , m_offset(0) - , m_enabled(false) - - , m_cubemap(false) - , m_dimension(0) - , m_format(0) - , m_mipmap(0) - , m_minlod(0) - , m_maxlod(1000) - , m_maxaniso(0) + GLTexture() : m_id(0) { } @@ -81,85 +34,9 @@ public: glGenTextures(1, &m_id); checkForGlError("GLTexture::Init() -> glGenTextures"); Bind(); - - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); } } - void SetRect(const u32 width, const u32 height) - { - m_width = width; - m_height = height; - } - - u32 GetOffset() const { return m_offset; } - - void SetFormat(const bool cubemap, const u8 dimension, const u32 format, const u16 mipmap) - { - m_cubemap = cubemap; - m_dimension = dimension; - m_format = format; - m_mipmap = mipmap; - } - - void SetAddress(u8 wraps, u8 wrapt, u8 wrapr, u8 unsigned_remap, u8 zfunc, u8 gamma, u8 aniso_bias, u8 signed_remap) - { - m_wraps = wraps; - m_wrapt = wrapt; - m_wrapr = wrapr; - m_unsigned_remap = unsigned_remap; - m_zfunc = zfunc; - m_gamma = gamma; - m_aniso_bias = aniso_bias; - m_signed_remap = signed_remap; - } - - void SetControl0(const bool enable, const u16 minlod, const u16 maxlod, const u8 maxaniso) - { - m_enabled = enable; - m_minlod = minlod; - m_maxlod = maxlod; - m_maxaniso = maxaniso; - } - - void SetControl1(u32 remap) - { - m_remap = remap; - } - - void SetControl3(u16 depth, u32 pitch) - { - m_depth = depth; - 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) - { - m_offset = offset; - } - - wxSize GetRect() const - { - return wxSize(m_width, m_height); - } - int GetGlWrap(int wrap) { switch(wrap) @@ -176,12 +53,12 @@ public: return GL_REPEAT; } - void Init() + void Init(RSXTexture& tex) { Bind(); - if(!Memory.IsGoodAddr(m_offset)) + if(!Memory.IsGoodAddr(tex.GetOffset())) { - ConLog.Error("Bad texture address=0x%x", m_offset); + ConLog.Error("Bad texture address=0x%x", tex.GetOffset()); return; } //ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", @@ -189,16 +66,16 @@ public: //TODO: safe init checkForGlError("GLTexture::Init() -> glBindTexture"); - int format = m_format & ~(0x20 | 0x40); - bool is_swizzled = (m_format & 0x20) == 0; + int format = tex.GetFormat() & ~(0x20 | 0x40); + bool is_swizzled = (tex.GetFormat() & 0x20) == 0; - glPixelStorei(GL_PACK_ALIGNMENT, m_pitch); - char* pixels = (char*)Memory.GetMemFromAddr(m_offset); + glPixelStorei(GL_PACK_ALIGNMENT, tex.m_pitch); + char* pixels = (char*)Memory.GetMemFromAddr(tex.GetOffset()); switch(format) { case 0x81: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); @@ -210,39 +87,39 @@ public: break; case 0x85: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); break; case 0x86: { - u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8; + u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 8; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, m_width, m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.m_width, tex.m_height, 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x87: { - u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; + u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, m_width, m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.m_width, tex.m_height, 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x88: { - u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; + u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, m_width, m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.m_width, tex.m_height, 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x94: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RED, GL_SHORT, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_RED, GL_SHORT, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE); @@ -251,30 +128,30 @@ public: break; case 0x9a: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); break; case 0x9e: { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE); } break; - default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, m_format & 0x20, m_format & 0x40); break; + default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, tex.GetFormat() & 0x20, tex.GetFormat() & 0x40); break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_mipmap - 1); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, m_mipmap > 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.m_mipmap - 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.m_mipmap > 1); if(format != 0x81 && format != 0x94) { - u8 remap_a = m_remap & 0x3; - u8 remap_r = (m_remap >> 2) & 0x3; - u8 remap_g = (m_remap >> 4) & 0x3; - u8 remap_b = (m_remap >> 6) & 0x3; + u8 remap_a = tex.m_remap & 0x3; + u8 remap_r = (tex.m_remap >> 2) & 0x3; + u8 remap_g = (tex.m_remap >> 4) & 0x3; + u8 remap_b = (tex.m_remap >> 6) & 0x3; static const int gl_remap[] = { @@ -302,14 +179,14 @@ public: GL_ALWAYS, }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(m_wraps)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(m_wrapt)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(m_wrapr)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[m_zfunc]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.m_wraps)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.m_wrapt)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.m_wrapr)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.m_zfunc]); - glTexEnvi(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); + glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.m_bias); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, tex.m_minlod); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, tex.m_maxlod); static const int gl_tex_filter[] = { @@ -323,20 +200,20 @@ public: 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]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[tex.m_min_filter]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[tex.m_mag_filter]); //Unbind(); } - void Save(const wxString& name) + void Save(RSXTexture& tex, const wxString& name) { - if(!m_id || !m_offset || !m_width || !m_height) return; + if(!m_id || !tex.m_offset || !tex.m_width || !tex.m_height) return; - u32* alldata = new u32[m_width * m_height]; + u32* alldata = new u32[tex.m_width * tex.m_height]; Bind(); - switch(m_format & ~(0x20 | 0x40)) + switch(tex.m_format & ~(0x20 | 0x40)) { case 0x81: glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); @@ -353,15 +230,15 @@ public: { wxFile f(name + ".raw", wxFile::write); - f.Write(alldata, m_width * m_height * 4); + f.Write(alldata, tex.m_width * tex.m_height * 4); } - u8* data = new u8[m_width * m_height * 3]; - u8* alpha = new u8[m_width * m_height]; + u8* data = new u8[tex.m_width * tex.m_height * 3]; + u8* alpha = new u8[tex.m_width * tex.m_height]; u8* src = (u8*)alldata; u8* dst_d = data; u8* dst_a = alpha; - for(u32 i=0; i m_data; - int m_type; - u32 m_first; - u32 m_count; - u32 m_addr; - u32 index_max; - u32 index_min; - - IndexArrayData() - { - Reset(); - } - - void Reset() - { - m_type = 0; - m_first = ~0; - m_count = 0; - m_addr = 0; - index_min = ~0; - index_max = 0; - m_data.Clear(); - } }; struct GLGSFrame : public GSFrame { wxGLCanvas* canvas; - GLTexture m_textures[16]; u32 m_frames; GLGSFrame(); @@ -474,7 +298,6 @@ struct GLGSFrame : public GSFrame void Flip(); wxGLCanvas* GetCanvas() const { return canvas; } - GLTexture& GetTexture(const u32 index) { return m_textures[index]; } virtual void SetViewport(int x, int y, u32 w, u32 h); @@ -482,22 +305,12 @@ private: virtual void OnSize(wxSizeEvent& event); }; -struct GLRSXThread : public ThreadBase -{ - wxWindow* m_parent; - Stack call_stack; - - GLRSXThread(wxWindow* parent); - - virtual void Task(); -}; - class PostDrawObj { protected: - ShaderProgram m_fp; - VertexProgram m_vp; - Program m_program; + GLShaderProgram m_fp; + GLVertexProgram m_vp; + GLProgram m_program; GLfbo m_fbo; GLrbo m_rbo; @@ -594,51 +407,35 @@ public: class GLGSRender : public wxWindow , public GSRender - , public ExecRSXCMDdata { -public: - static const uint m_vertex_count = 16; - static const uint m_fragment_count = 16; - static const uint m_textures_count = 16; - private: - GLRSXThread* m_rsx_thread; - - IndexArrayData m_indexed_array; - - ShaderProgram m_shader_progs[m_fragment_count]; - ShaderProgram* m_cur_shader_prog; - int m_cur_shader_prog_num; - VertexData m_vertex_data[m_vertex_count]; Array m_vdata; - VertexProgram m_vertex_progs[m_vertex_count]; - VertexProgram* m_cur_vertex_prog; - Array m_transform_constants; - Array m_fragment_constants; ArrayF m_post_draw_objs; - Program m_program; + GLProgram m_program; int m_fp_buf_num; int m_vp_buf_num; - int m_draw_array_count; - int m_draw_mode; - ProgramBuffer m_prog_buffer; + GLProgramBuffer m_prog_buffer; - u32 m_width; - u32 m_height; + GLShaderProgram m_shader_prog; + GLVertexProgram m_vertex_prog; + + GLTexture m_gl_textures[m_textures_count]; GLvao m_vao; GLvbo m_vbo; GLrbo m_rbo; GLfbo m_fbo; + wxGLContext* m_context; + public: GLGSFrame* m_frame; u32 m_draw_frames; u32 m_skip_frames; GLGSRender(); - ~GLGSRender(); + virtual ~GLGSRender(); private: void EnableVertexData(bool indexed_draw=false); @@ -648,8 +445,6 @@ private: void InitFragmentData(); void Enable(bool enable, const u32 cap); - virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); - virtual void Draw(); virtual void Close(); bool LoadProgram(); void WriteDepthBuffer(); @@ -661,11 +456,11 @@ private: void DrawObjects(); -public: - void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count); - void CloseOpenGL(); - +protected: + virtual void OnInit(); + virtual void OnInitThread(); + virtual void OnExitThread(); + virtual void OnReset(); virtual void ExecCMD(); - virtual void Reset(); - void Init(); + virtual void Flip(); }; \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/Program.cpp b/rpcs3/Emu/GS/GL/GLProgram.cpp similarity index 86% rename from rpcs3/Emu/GS/GL/Program.cpp rename to rpcs3/Emu/GS/GL/GLProgram.cpp index 4730f33805..1f0c21539b 100644 --- a/rpcs3/Emu/GS/GL/Program.cpp +++ b/rpcs3/Emu/GS/GL/GLProgram.cpp @@ -1,12 +1,12 @@ #include "stdafx.h" -#include "Program.h" +#include "GLProgram.h" #include "GLGSRender.h" -Program::Program() : id(0) +GLProgram::GLProgram() : id(0) { } -int Program::GetLocation(const wxString& name) +int GLProgram::GetLocation(const wxString& name) { for(u32 i=0; i 0; } -void Program::Create(const u32 vp, const u32 fp) +void GLProgram::Create(const u32 vp, const u32 fp) { if(IsCreated()) Delete(); id = glCreateProgram(); @@ -74,19 +74,19 @@ void Program::Create(const u32 vp, const u32 fp) } } -void Program::UnUse() +void GLProgram::UnUse() { id = 0; m_locations.Clear(); } -void Program::Use() +void GLProgram::Use() { glUseProgram(id); checkForGlError("glUseProgram"); } -void Program::SetTex(u32 index) +void GLProgram::SetTex(u32 index) { int loc = GetLocation(wxString::Format("tex%u", index)); checkForGlError(wxString::Format("GetLocation(tex%u)", index)); @@ -94,7 +94,7 @@ void Program::SetTex(u32 index) checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc)); } -void Program::Delete() +void GLProgram::Delete() { if(!IsCreated()) return; glDeleteProgram(id); diff --git a/rpcs3/Emu/GS/GL/Program.h b/rpcs3/Emu/GS/GL/GLProgram.h similarity index 77% rename from rpcs3/Emu/GS/GL/Program.h rename to rpcs3/Emu/GS/GL/GLProgram.h index 71fb597ff6..b06e216767 100644 --- a/rpcs3/Emu/GS/GL/Program.h +++ b/rpcs3/Emu/GS/GL/GLProgram.h @@ -1,8 +1,8 @@ #pragma once -#include "VertexProgram.h" -#include "FragmentProgram.h" +#include "GLVertexProgram.h" +#include "GLFragmentProgram.h" -struct Program +struct GLProgram { private: struct Location @@ -16,7 +16,7 @@ private: public: u32 id; - Program(); + GLProgram(); int GetLocation(const wxString& name); bool IsCreated() const; diff --git a/rpcs3/Emu/GS/GL/ProgramBuffer.cpp b/rpcs3/Emu/GS/GL/GLProgramBuffer.cpp similarity index 54% rename from rpcs3/Emu/GS/GL/ProgramBuffer.cpp rename to rpcs3/Emu/GS/GL/GLProgramBuffer.cpp index 859bad2bce..76b6e0f602 100644 --- a/rpcs3/Emu/GS/GL/ProgramBuffer.cpp +++ b/rpcs3/Emu/GS/GL/GLProgramBuffer.cpp @@ -1,14 +1,14 @@ #include "stdafx.h" -#include "ProgramBuffer.h" +#include "GLProgramBuffer.h" -int ProgramBuffer::SearchFp(ShaderProgram& fp) +int GLProgramBuffer::SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp) { for(u32 i=0; i fp_data; + Array vp_data; + ArrayString fp_shader; + ArrayString vp_shader; +}; + +struct GLProgramBuffer +{ + Array m_buf; + + int SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp); + int SearchVp(const RSXVertexProgram& rsx_vp, GLVertexProgram& gl_vp); + + bool CmpVP(const u32 a, const u32 b) const; + bool CmpFP(const u32 a, const u32 b) const; + + u32 GetProg(u32 fp, u32 vp) const; + + void Add(GLProgram& prog, GLShaderProgram& gl_fp, RSXShaderProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp); + void Clear(); +}; \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/ShaderParam.h b/rpcs3/Emu/GS/GL/GLShaderParam.h similarity index 57% rename from rpcs3/Emu/GS/GL/ShaderParam.h rename to rpcs3/Emu/GS/GL/GLShaderParam.h index c0f91e38fb..fe1991cede 100644 --- a/rpcs3/Emu/GS/GL/ShaderParam.h +++ b/rpcs3/Emu/GS/GL/GLShaderParam.h @@ -1,7 +1,7 @@ #pragma once #include "OpenGL.h" -enum ParamFlag +enum GLParamFlag { PARAM_IN, PARAM_OUT, @@ -10,13 +10,13 @@ enum ParamFlag PARAM_NONE, }; -struct ParamItem +struct GLParamItem { ArrayString name; ArrayString location; ArrayString value; - ParamItem(const wxString& _name, int _location, const wxString& _value = wxEmptyString) + GLParamItem(const wxString& _name, int _location, const wxString& _value = wxEmptyString) : name(_name) , location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "") , value(_value) @@ -24,13 +24,13 @@ struct ParamItem } }; -struct ParamType +struct GLParamType { - const ParamFlag flag; + const GLParamFlag flag; ArrayString type; - Array items; + Array items; - ParamType(const ParamFlag _flag, const wxString& _type) + GLParamType(const GLParamFlag _flag, const wxString& _type) : type(_type) , flag(_flag) { @@ -68,11 +68,11 @@ struct ParamType } }; -struct ParamArray +struct GLParamArray { - Array params; + Array params; - ParamType* SearchParam(const wxString& type) + GLParamType* SearchParam(const wxString& type) { for(u32 i=0; iSearchName(name); } - wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, const wxString& value) + wxString AddParam(const GLParamFlag flag, wxString type, const wxString& name, const wxString& value) { type = GetParamFlag(flag) + type; - ParamType* t = SearchParam(type); + GLParamType* t = SearchParam(type); if(t) { - if(!t->SearchName(name)) t->items.Move(new ParamItem(name, -1, value)); + if(!t->SearchName(name)) t->items.Move(new GLParamItem(name, -1, value)); } else { const u32 num = params.GetCount(); - params.Move(new ParamType(flag, type)); - params[num].items.Move(new ParamItem(name, -1, value)); + params.Move(new GLParamType(flag, type)); + params[num].items.Move(new GLParamItem(name, -1, value)); } return name; } - wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, int location = -1) + wxString AddParam(const GLParamFlag flag, wxString type, const wxString& name, int location = -1) { type = GetParamFlag(flag) + type; - ParamType* t = SearchParam(type); + GLParamType* t = SearchParam(type); if(t) { - if(!t->SearchName(name)) t->items.Move(new ParamItem(name, location)); + if(!t->SearchName(name)) t->items.Move(new GLParamItem(name, location)); } else { const u32 num = params.GetCount(); - params.Move(new ParamType(flag, type)); - params[num].items.Move(new ParamItem(name, location)); + params.Move(new GLParamType(flag, type)); + params[num].items.Move(new GLParamItem(name, location)); } return name; diff --git a/rpcs3/Emu/GS/GL/VertexProgram.cpp b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp similarity index 82% rename from rpcs3/Emu/GS/GL/VertexProgram.cpp rename to rpcs3/Emu/GS/GL/GLVertexProgram.cpp index 100e88fa53..50b9fc30b7 100644 --- a/rpcs3/Emu/GS/GL/VertexProgram.cpp +++ b/rpcs3/Emu/GS/GL/GLVertexProgram.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" -#include "VertexProgram.h" +#include "GLVertexProgram.h" -wxString VertexDecompilerThread::GetMask(bool is_sca) +wxString GLVertexDecompilerThread::GetMask(bool is_sca) { wxString ret = wxEmptyString; @@ -23,17 +23,17 @@ wxString VertexDecompilerThread::GetMask(bool is_sca) return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret); } -wxString VertexDecompilerThread::GetVecMask() +wxString GLVertexDecompilerThread::GetVecMask() { return GetMask(false); } -wxString VertexDecompilerThread::GetScaMask() +wxString GLVertexDecompilerThread::GetScaMask() { return GetMask(true); } -wxString VertexDecompilerThread::GetDST(bool isSca) +wxString GLVertexDecompilerThread::GetDST(bool isSca) { static const wxString reg_table[] = { @@ -73,7 +73,7 @@ wxString VertexDecompilerThread::GetDST(bool isSca) return ret; } -wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca) +wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca) { static const wxString reg_table[] = { @@ -151,7 +151,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca) return ret; } -void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask) +void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask) { if(d0.cond == 0) return; enum @@ -215,17 +215,17 @@ void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask) main += "\t" + code + ";\n"; } -void VertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask) +void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask) { AddCode(false, code, src_mask); } -void VertexDecompilerThread::AddScaCode(const wxString& code) +void GLVertexDecompilerThread::AddScaCode(const wxString& code) { AddCode(true, code, false); } -wxString VertexDecompilerThread::BuildCode() +wxString GLVertexDecompilerThread::BuildCode() { wxString p = wxEmptyString; @@ -243,7 +243,7 @@ wxString VertexDecompilerThread::BuildCode() return wxString::Format(prot, p, main); } -void VertexDecompilerThread::Task() +void GLVertexDecompilerThread::Task() { for(u32 i=0;;) { @@ -327,13 +327,13 @@ void VertexDecompilerThread::Task() main = wxEmptyString; } -VertexProgram::VertexProgram() +GLVertexProgram::GLVertexProgram() : m_decompiler_thread(nullptr) , id(0) { } -VertexProgram::~VertexProgram() +GLVertexProgram::~GLVertexProgram() { if(m_decompiler_thread) { @@ -350,10 +350,10 @@ VertexProgram::~VertexProgram() Delete(); } -void VertexProgram::Decompile() +void GLVertexProgram::Decompile(RSXVertexProgram& prog) { #if 0 - VertexDecompilerThread(data, shader, parr).Entry(); + GLVertexDecompilerThread(data, shader, parr).Entry(); #else if(m_decompiler_thread) { @@ -367,12 +367,12 @@ void VertexProgram::Decompile() m_decompiler_thread = nullptr; } - m_decompiler_thread = new VertexDecompilerThread(data, shader, parr); + m_decompiler_thread = new GLVertexDecompilerThread(prog.data, shader, parr); m_decompiler_thread->Start(); #endif } -void VertexProgram::Compile() +void GLVertexProgram::Compile() { if(id) glDeleteShader(id); @@ -407,9 +407,8 @@ void VertexProgram::Compile() } -void VertexProgram::Delete() +void GLVertexProgram::Delete() { - data.Clear(); parr.params.Clear(); shader.Clear(); @@ -419,79 +418,3 @@ void VertexProgram::Delete() id = 0; } } - -VertexData::VertexData() - : frequency(0) - , stride(0) - , size(0) - , type(0) - , addr(0) - , data() -{ -} - -void VertexData::Reset() -{ - frequency = 0; - stride = 0; - size = 0; - type = 0; - addr = 0; - data.ClearF(); -} - -void VertexData::Load(u32 start, u32 count) -{ - if(!addr) return; - - const u32 tsize = GetTypeSize(); - - data.SetCount((start + count) * tsize * size); - - for(u32 i=start; i& m_data; - ParamArray& m_parr; + GLParamArray& m_parr; - VertexDecompilerThread(Array& data, wxString& shader, ParamArray& parr) + GLVertexDecompilerThread(Array& data, wxString& shader, GLParamArray& parr) : ThreadBase(false, "Vertex Shader Decompiler Thread") , m_data(data) , m_shader(shader) @@ -152,17 +153,16 @@ struct VertexDecompilerThread : public ThreadBase virtual void Task(); }; -struct VertexProgram -{ - wxString shader; +struct GLVertexProgram +{ + GLVertexDecompilerThread* m_decompiler_thread; + + GLVertexProgram(); + ~GLVertexProgram(); + + GLParamArray parr; u32 id; - VertexDecompilerThread* m_decompiler_thread; - - VertexProgram(); - ~VertexProgram(); - - Array data; - ParamArray parr; + wxString shader; void Wait() { @@ -171,27 +171,8 @@ struct VertexProgram m_decompiler_thread->Wait(); } } - void Decompile(); + + void Decompile(RSXVertexProgram& prog); void Compile(); void Delete(); }; - -struct VertexData -{ - u32 frequency; - u32 stride; - u32 size; - u32 type; - u32 addr; - u32 constant_count; - - Array data; - - VertexData(); - - void Reset(); - bool IsEnabled() { return size > 0; } - void Load(u32 start, u32 count); - - u32 GetTypeSize(); -}; \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/ProgramBuffer.h b/rpcs3/Emu/GS/GL/ProgramBuffer.h deleted file mode 100644 index 8d66dca99b..0000000000 --- a/rpcs3/Emu/GS/GL/ProgramBuffer.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include "Program.h" - -struct BufferInfo -{ - u32 prog_id; - u32 fp_id; - u32 vp_id; - Array fp_data; - Array vp_data; - ArrayString fp_shader; - ArrayString vp_shader; -}; - -struct ProgramBuffer -{ - Array m_buf; - - int SearchFp(ShaderProgram& fp); - int SearchVp(VertexProgram& vp); - - bool CmpVP(const u32 a, const u32 b) const; - bool CmpFP(const u32 a, const u32 b) const; - - u32 GetProg(u32 fp, u32 vp) const; - - void Add(Program& prog, ShaderProgram& fp, VertexProgram& vp); - void Clear(); -}; \ No newline at end of file diff --git a/rpcs3/Emu/GS/GSManager.cpp b/rpcs3/Emu/GS/GSManager.cpp index 456aa9125e..ad6ac2bedf 100644 --- a/rpcs3/Emu/GS/GSManager.cpp +++ b/rpcs3/Emu/GS/GSManager.cpp @@ -32,6 +32,7 @@ void GSManager::Close() if(m_render) { m_render->Close(); + delete m_render; m_render = nullptr; } } diff --git a/rpcs3/Emu/GS/GSRender.cpp b/rpcs3/Emu/GS/GSRender.cpp index 75664a9a1a..5a1fc4bceb 100644 --- a/rpcs3/Emu/GS/GSRender.cpp +++ b/rpcs3/Emu/GS/GSRender.cpp @@ -76,28 +76,6 @@ void GSFrame::SetSize(int width, int height) } */ - -GSRender::GSRender() - : m_ctrl(nullptr) - , m_flip_status(0) - , m_flip_mode(CELL_GCM_DISPLAY_VSYNC) - , m_main_mem_addr(0) -{ -} - -u32 GSRender::GetAddress(u32 offset, u8 location) -{ - switch(location) - { - case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset; - case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset; - } - - ConLog.Error("GetAddress(offset=0x%x, location=0x%x", location); - assert(0); - return 0; -} - GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type) { } \ No newline at end of file diff --git a/rpcs3/Emu/GS/GSRender.h b/rpcs3/Emu/GS/GSRender.h index 8c79740f2e..3ae017cb39 100644 --- a/rpcs3/Emu/GS/GSRender.h +++ b/rpcs3/Emu/GS/GSRender.h @@ -1,16 +1,6 @@ #pragma once #include "Emu/GS/GCM.h" -#include "Emu/SysCalls/Callback.h" -#include "rpcs3.h" - -enum Method -{ - CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, - CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, - CELL_GCM_METHOD_FLAG_CALL = 0x00000002, - CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, -}; - +#include "Emu/GS/RSXThread.h" wxSize AspectRatio(wxSize rs, const wxSize as); @@ -40,138 +30,13 @@ private: DECLARE_EVENT_TABLE(); }; -struct CellGcmSurface +struct GSRender : public RSXThread { - u8 type; - u8 antialias; - - u8 color_format; - u8 color_target; - u8 color_location[4]; - u32 color_offset[4]; - u32 color_pitch[4]; - - u8 depth_format; - u8 depth_location; - u16 pad; - u32 depth_offset; - u32 depth_pitch; - - u16 width; - u16 height; - u16 x; - u16 y; -}; - -struct CellGcmReportData -{ - u64 timer; - u32 value; - u32 pad; -}; - -struct CellGcmZcullInfo -{ - u32 region; - u32 size; - u32 start; - u32 offset; - u32 status0; - u32 status1; -}; - -struct CellGcmTileInfo -{ - u32 tile; - u32 limit; - u32 pitch; - u32 format; -}; - -struct GcmZcullInfo -{ - u32 m_offset; - u32 m_width; - u32 m_height; - u32 m_cullStart; - u32 m_zFormat; - u32 m_aaFormat; - u32 m_zCullDir; - u32 m_zCullFormat; - u32 m_sFunc; - u32 m_sRef; - u32 m_sMask; - bool m_binded; - - GcmZcullInfo() + virtual ~GSRender() { - memset(this, 0, sizeof(*this)); - } -}; - -struct GcmTileInfo -{ - u8 m_location; - u32 m_offset; - u32 m_size; - u32 m_pitch; - u8 m_comp; - u16 m_base; - u8 m_bank; - bool m_binded; - - GcmTileInfo() - { - memset(this, 0, sizeof(*this)); } - CellGcmTileInfo Pack() - { - CellGcmTileInfo ret; - - re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31)); - re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31)); - re(ret.pitch, (m_pitch / 0x100) << 8); - re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30)); - - return ret; - } -}; - -static const int g_tiles_count = 15; - -struct GSRender -{ - u32 m_ioAddress, m_ioSize, m_ctrlAddress; - CellGcmControl* m_ctrl; - wxCriticalSection m_cs_main; - wxSemaphore m_sem_flush; - wxSemaphore m_sem_flip; - int m_flip_status; - int m_flip_mode; - volatile bool m_draw; - Callback m_flip_handler; - - GcmTileInfo m_tiles[g_tiles_count]; - - u32 m_tiles_addr; - u32 m_zculls_addr; - u32 m_gcm_buffers_addr; - u32 m_gcm_buffers_count; - u32 m_gcm_current_buffer; - u32 m_ctxt_addr; - u32 m_report_main_addr; - - u32 m_local_mem_addr, m_main_mem_addr; - Array m_main_mem_info; - - GSRender(); - - virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress)=0; - virtual void Draw()=0; virtual void Close()=0; - - u32 GetAddress(u32 offset, u8 location); }; enum GSLockType diff --git a/rpcs3/Emu/GS/Null/NullGSRender.h b/rpcs3/Emu/GS/Null/NullGSRender.h index 8b911eece4..032d34fc5c 100644 --- a/rpcs3/Emu/GS/Null/NullGSRender.h +++ b/rpcs3/Emu/GS/Null/NullGSRender.h @@ -24,168 +24,53 @@ private: } }; -struct NullRSXThread : public wxThread -{ - wxWindow* m_parent; - Stack call_stack; - - NullRSXThread(wxWindow* parent); - - virtual void OnExit(); - void Start(); - ExitCode Entry(); -}; - class NullGSRender : public wxWindow , public GSRender { -private: - NullRSXThread* m_rsx_thread; - public: NullGSFrame* m_frame; - NullGSRender() - : m_frame(nullptr) - , m_rsx_thread(nullptr) + NullGSRender() : m_frame(nullptr) { - m_draw = false; m_frame = new NullGSFrame(); } - ~NullGSRender() + virtual ~NullGSRender() { - Close(); m_frame->Close(); } private: - virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) + virtual void OnInit() { - if(m_frame->IsShown()) return; - - m_frame->SetSize(740, 480); m_frame->Show(); - - m_ioAddress = ioAddress; - m_ctrlAddress = ctrlAddress; - m_ioSize = ioSize; - m_local_mem_addr = localAddress; - m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress); - - (m_rsx_thread = new NullRSXThread(this))->Start(); } -public: - void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count) + virtual void OnInitThread() { - switch(cmd) - { - case NV406E_SET_REFERENCE: - m_ctrl->ref = re32(args[0]); - break; - } } - virtual void Draw() + virtual void OnExitThread() + { + } + + virtual void OnReset() + { + } + + virtual void ExecCMD() + { + } + + virtual void Flip() { - //if(m_frame && !m_frame->IsBeingDeleted()) m_frame->Draw(); - m_draw = true; } virtual void Close() { - if(m_rsx_thread) m_rsx_thread->Delete(); + if(IsAlive()) Stop(); + if(m_frame->IsShown()) m_frame->Hide(); - m_ctrl = NULL; } }; - -NullRSXThread::NullRSXThread(wxWindow* parent) - : wxThread(wxTHREAD_DETACHED) - , m_parent(parent) -{ -} - -void NullRSXThread::OnExit() -{ - call_stack.Clear(); -} - -void NullRSXThread::Start() -{ - Create(); - Run(); -} - -wxThread::ExitCode NullRSXThread::Entry() -{ - ConLog.Write("Null RSX thread entry"); - - NullGSRender& p = *(NullGSRender*)m_parent; - - while(!TestDestroy() && p.m_frame && !p.m_frame->IsBeingDeleted()) - { - wxCriticalSectionLocker lock(p.m_cs_main); - - if(p.m_ctrl->get == p.m_ctrl->put || !Emu.IsRunning()) - { - SemaphorePostAndWait(p.m_sem_flush); - - if(p.m_draw) - { - p.m_draw = false; - p.m_flip_status = 0; - if(SemaphorePostAndWait(p.m_sem_flip)) continue; - } - - Sleep(1); - continue; - } - - const u32 get = re(p.m_ctrl->get); - const u32 cmd = Memory.Read32(p.m_ioAddress + get); - const u32 count = (cmd >> 18) & 0x7ff; - - if(cmd & CELL_GCM_METHOD_FLAG_JUMP) - { - p.m_ctrl->get = re32(cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT)); - ConLog.Warning("rsx jump!"); - continue; - } - if(cmd & CELL_GCM_METHOD_FLAG_CALL) - { - call_stack.Push(get + 4); - p.m_ctrl->get = re32(cmd & ~CELL_GCM_METHOD_FLAG_CALL); - ConLog.Warning("rsx call!"); - continue; - } - if(cmd & CELL_GCM_METHOD_FLAG_RETURN) - { - p.m_ctrl->get = re32(call_stack.Pop()); - ConLog.Warning("rsx return!"); - continue; - } - if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) - { - //ConLog.Warning("non increment cmd! 0x%x", cmd); - } - - if(cmd == 0) - { - ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", p.m_ioAddress + get, re(p.m_ctrl->put), get); - Emu.Pause(); - continue; - } - - p.DoCmd(cmd, cmd & 0x3ffff, mem32_ptr_t(p.m_ioAddress + get + 4), count); - re(p.m_ctrl->get, get + (count + 1) * 4); - } - - ConLog.Write("Null RSX thread exit..."); - - call_stack.Clear(); - - return (ExitCode)0; -} \ No newline at end of file diff --git a/rpcs3/Emu/GS/RSXFragmentProgram.h b/rpcs3/Emu/GS/RSXFragmentProgram.h new file mode 100644 index 0000000000..ef627a07b8 --- /dev/null +++ b/rpcs3/Emu/GS/RSXFragmentProgram.h @@ -0,0 +1,15 @@ +#pragma once + +struct RSXShaderProgram +{ + u32 size; + u32 addr; + u32 offset; + + RSXShaderProgram() + : size(0) + , addr(0) + , offset(0) + { + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 910a7ed0e4..1ccdf4750d 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -1,17 +1,1399 @@ #include "stdafx.h" #include "RSXThread.h" -RSXThread::RSXThread(CellGcmControl* ctrl, u32 ioAddress) - : m_ctrl(*ctrl) - , m_ioAddress(ioAddress) +RSXVertexData::RSXVertexData() + : frequency(0) + , stride(0) + , size(0) + , type(0) + , addr(0) + , data() { } +void RSXVertexData::Reset() +{ + frequency = 0; + stride = 0; + size = 0; + type = 0; + addr = 0; + data.ClearF(); +} + +void RSXVertexData::Load(u32 start, u32 count) +{ + if(!addr) return; + + const u32 tsize = GetTypeSize(); + + data.SetCount((start + count) * tsize * size); + + for(u32 i=start; iref = re32(args[0]); + break; + + case_16(NV4097_SET_TEXTURE_OFFSET, 0x20): + { + RSXTexture& tex = m_textures[index]; + const u32 offset = args[0]; + u32 a1 = args[1]; + u8 location = (a1 & 0x3) - 1; + const bool cubemap = (a1 >> 2) & 0x1; + const u8 dimension = (a1 >> 4) & 0xf; + const u8 format = (a1 >> 8) & 0xff; + const u16 mipmap = (a1 >> 16) & 0xffff; + CMD_LOG("index = %d, offset=0x%x, location=0x%x, cubemap=0x%x, dimension=0x%x, format=0x%x, mipmap=0x%x", + index, offset, location, cubemap, dimension, format, mipmap); + + if(location == 2) + { + ConLog.Error("Bad texture location."); + location = 1; + } + u32 tex_addr = GetAddress(offset, location); + //ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location); + tex.SetOffset(tex_addr); + tex.SetFormat(cubemap, dimension, format, mipmap); + } + break; + + case_16(NV4097_SET_TEXTURE_CONTROL0, 0x20): + { + RSXTexture& tex = m_textures[index]; + u32 a0 = args[0]; + bool enable = a0 >> 31 ? true : false; + u16 minlod = (a0 >> 19) & 0xfff; + u16 maxlod = (a0 >> 7) & 0xfff; + u8 maxaniso = (a0 >> 2) & 0x7; + tex.SetControl0(enable, minlod, maxlod, maxaniso); + } + break; + + case_16(NV4097_SET_VERTEX_DATA4UB_M, 4): + { + u32 v = args[0]; + u8 v0 = v; + u8 v1 = v >> 8; + u8 v2 = v >> 16; + u8 v3 = v >> 24; + + m_vertex_data[index].size = 4; + m_vertex_data[index].type = 4; + m_vertex_data[index].data.AddCpy(v0); + m_vertex_data[index].data.AddCpy(v1); + m_vertex_data[index].data.AddCpy(v2); + m_vertex_data[index].data.AddCpy(v3); + //ConLog.Warning("index = %d, v0 = 0x%x, v1 = 0x%x, v2 = 0x%x, v3 = 0x%x", index, v0, v1, v2, v3); + } + break; + + case_16(NV4097_SET_VERTEX_DATA2F_M, 8): + { + u32 a0 = args[0]; + u32 a1 = args[1]; + + float v0 = (float&)a0; + float v1 = (float&)a1; + + m_vertex_data[index].type = 2; + m_vertex_data[index].size = 2; + m_vertex_data[index].data.SetCount(sizeof(float) * 2); + (float&)m_vertex_data[index].data[sizeof(float)*0] = v0; + (float&)m_vertex_data[index].data[sizeof(float)*1] = v1; + + //ConLog.Warning("index = %d, v0 = %f, v1 = %f", index, v0, v1); + } + break; + + case_16(NV4097_SET_VERTEX_DATA4F_M, 16): + { + u32 a0 = args[0]; + u32 a1 = args[1]; + u32 a2 = args[2]; + u32 a3 = args[3]; + + float v0 = (float&)a0; + float v1 = (float&)a1; + float v2 = (float&)a2; + float v3 = (float&)a3; + + m_vertex_data[index].type = 2; + m_vertex_data[index].size = 4; + m_vertex_data[index].data.SetCount(sizeof(float) * 4); + (float&)m_vertex_data[index].data[sizeof(float)*0] = v0; + (float&)m_vertex_data[index].data[sizeof(float)*1] = v1; + (float&)m_vertex_data[index].data[sizeof(float)*2] = v2; + (float&)m_vertex_data[index].data[sizeof(float)*3] = v3; + + //ConLog.Warning("index = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", index, v0, v1, v2, v3); + } + break; + + case_16(NV4097_SET_TEXTURE_CONTROL1, 0x20): + { + RSXTexture& tex = m_textures[index]; + tex.SetControl1(args[0]); + } + break; + + case_16(NV4097_SET_TEXTURE_CONTROL3, 4): + { + RSXTexture& tex = m_textures[index]; + u32 a0 = args[0]; + u32 pitch = a0 & 0xFFFFF; + u16 depth = a0 >> 20; + tex.SetControl3(pitch, depth); + } + break; + + case_16(NV4097_SET_TEXTURE_FILTER, 0x20): + { + RSXTexture& tex = m_textures[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): + { + RSXTexture& tex = m_textures[index]; + + u32 a0 = args[0]; + u8 wraps = a0 & 0xf; + u8 aniso_bias = (a0 >> 4) & 0xf; + u8 wrapt = (a0 >> 8) & 0xf; + u8 unsigned_remap = (a0 >> 12) & 0xf; + u8 wrapr = (a0 >> 16) & 0xf; + u8 gamma = (a0 >> 20) & 0xf; + u8 signed_remap = (a0 >> 24) & 0xf; + u8 zfunc = a0 >> 28; + + tex.SetAddress(wraps, wrapt, wrapr, unsigned_remap, zfunc, gamma, aniso_bias, signed_remap); + } + break; + + case_16(NV4097_SET_TEX_COORD_CONTROL, 4): + //TODO + break; + + case_16(NV4097_SET_TEXTURE_IMAGE_RECT, 32): + { + RSXTexture& tex = m_textures[index]; + + const u16 height = args[0] & 0xffff; + const u16 width = args[0] >> 16; + CMD_LOG("width=%d, height=%d", width, height); + tex.SetRect(width, height); + } + break; + + case NV4097_SET_SURFACE_FORMAT: + { + u32 a0 = args[0]; + m_set_surface_format = true; + m_surface_color_format = a0 & 0x1f; + m_surface_depth_format = (a0 >> 5) & 0x7; + m_surface_type = (a0 >> 8) & 0xf; + m_surface_antialias = (a0 >> 12) & 0xf; + m_surface_width = (a0 >> 16) & 0xff; + m_surface_height = (a0 >> 24) & 0xff; + m_surface_pitch_a = args[1]; + m_surface_offset_a = args[2]; + m_surface_offset_z = args[3]; + m_surface_offset_b = args[4]; + m_surface_pitch_b = args[5]; + + 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); + } + break; + + case NV4097_SET_COLOR_MASK_MRT: + { + } + break; + + case NV4097_SET_COLOR_MASK: + { + const u32 flags = args[0]; + + m_set_color_mask = true; + m_color_mask_a = flags & 0x1000000 ? true : false; + m_color_mask_r = flags & 0x0010000 ? true : false; + m_color_mask_g = flags & 0x0000100 ? true : false; + m_color_mask_b = flags & 0x0000001 ? true : false; + } + break; + + case NV4097_SET_ALPHA_TEST_ENABLE: + m_set_alpha_test = args[0] ? true : false; + break; + + case NV4097_SET_BLEND_ENABLE: + m_set_blend = args[0] ? true : false; + break; + + case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: + m_set_depth_bounds_test = args[0] ? true : false; + break; + + case NV4097_SET_ALPHA_FUNC: + 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: + m_set_cull_face = true; + m_cull_face = args[0]; + break; + + case NV4097_SET_VIEWPORT_VERTICAL: + { + m_set_viewport_vertical = true; + m_viewport_y = args[0] & 0xffff; + m_viewport_h = args[0] >> 16; + } + break; + + case NV4097_SET_VIEWPORT_HORIZONTAL: + { + m_set_viewport_horizontal = true; + m_viewport_x = args[0] & 0xffff; + m_viewport_w = args[0] >> 16; + + if(count == 2) + { + m_set_viewport_vertical = true; + m_viewport_y = args[1] & 0xffff; + m_viewport_h = args[1] >> 16; + } + + CMD_LOG("x=%d, y=%d, w=%d, h=%d", m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); + } + break; + + case NV4097_SET_CLIP_MIN: + { + const u32 clip_min = args[0]; + const u32 clip_max = args[1]; + + m_set_clip = true; + m_clip_min = (float&)clip_min; + m_clip_max = (float&)clip_max; + + CMD_LOG("clip_min=%.01f, clip_max=%.01f", m_clip_min, m_clip_max); + } + break; + + case NV4097_SET_DEPTH_FUNC: + m_set_depth_func = true; + m_depth_func = args[0]; + break; + + case NV4097_SET_DEPTH_TEST_ENABLE: + m_depth_test_enable = args[0] ? true : false; + break; + + case NV4097_SET_FRONT_POLYGON_MODE: + m_set_front_polygon_mode = true; + m_front_polygon_mode = args[0]; + break; + + case NV4097_CLEAR_SURFACE: + { + u32 a0 = args[0]; + + if(a0 & 0x01) m_clear_surface_z = m_clear_z; + if(a0 & 0x02) m_clear_surface_s = m_clear_s; + if(a0 & 0x10) m_clear_surface_color_r = m_clear_color_r; + if(a0 & 0x20) m_clear_surface_color_g = m_clear_color_g; + if(a0 & 0x40) m_clear_surface_color_b = m_clear_color_b; + if(a0 & 0x80) m_clear_surface_color_a = m_clear_color_a; + + m_clear_surface_mask |= a0; + } + break; + + case NV4097_SET_BLEND_FUNC_SFACTOR: + { + m_set_blend_sfactor = true; + m_blend_sfactor_rgb = args[0] & 0xffff; + m_blend_sfactor_alpha = args[0] >> 16; + + if(count >= 2) + { + m_set_blend_dfactor = true; + m_blend_dfactor_rgb = args[1] & 0xffff; + m_blend_dfactor_alpha = args[1] >> 16; + } + } + break; + + case NV4097_SET_BLEND_FUNC_DFACTOR: + { + m_set_blend_dfactor = true; + m_blend_dfactor_rgb = args[0] & 0xffff; + m_blend_dfactor_alpha = args[0] >> 16; + } + break; + + case_16(NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4): + { + const u32 addr = GetAddress(args[0] & 0x7fffffff, args[0] >> 31); + CMD_LOG("num=%d, addr=0x%x", index, addr); + m_vertex_data[index].addr = addr; + } + break; + + case_16(NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4): + { + u32 a0 = args[0]; + const u16 frequency = a0 >> 16; + const u8 stride = (a0 >> 8) & 0xff; + const u8 size = (a0 >> 4) & 0xf; + const u8 type = a0 & 0xf; + + CMD_LOG("index=%d, frequency=%d, stride=%d, size=%d, type=%d", + index, frequency, stride, size, type); + + RSXVertexData& cv = m_vertex_data[index]; + cv.frequency = frequency; + cv.stride = stride; + cv.size = size; + cv.type = type; + } + break; + + case NV4097_DRAW_ARRAYS: + { + for(u32 c=0; c> 24) + 1; + + LoadVertexData(first, _count); + + m_draw_array_count += _count; + } + } + break; + + case NV4097_SET_INDEX_ARRAY_ADDRESS: + { + m_indexed_array.m_addr = GetAddress(args[0], args[1] & 0xf); + m_indexed_array.m_type = args[1] >> 4; + } + break; + + case NV4097_DRAW_INDEX_ARRAY: + { + for(u32 c=0; c> 24) + 1; + + if(first < m_indexed_array.m_first) m_indexed_array.m_first = first; + + for(u32 i=first; i<_count; ++i) + { + u32 index; + switch(m_indexed_array.m_type) + { + case 0: + { + int pos = m_indexed_array.m_data.GetCount(); + m_indexed_array.m_data.InsertRoomEnd(4); + index = Memory.Read32(m_indexed_array.m_addr + i * 4); + *(u32*)&m_indexed_array.m_data[pos] = index; + //ConLog.Warning("index 4: %d", *(u32*)&m_indexed_array.m_data[pos]); + } + break; + + case 1: + { + int pos = m_indexed_array.m_data.GetCount(); + m_indexed_array.m_data.InsertRoomEnd(2); + index = Memory.Read16(m_indexed_array.m_addr + i * 2); + //ConLog.Warning("index 2: %d", index); + *(u16*)&m_indexed_array.m_data[pos] = index; + } + break; + } + + if(index < m_indexed_array.index_min) m_indexed_array.index_min = index; + if(index > m_indexed_array.index_max) m_indexed_array.index_max = index; + } + + m_indexed_array.m_count += _count; + } + } + break; + + case NV4097_SET_BEGIN_END: + { + u32 a0 = args[0]; + + if(a0) + { + Begin(a0); + } + else + { + End(); + } + } + break; + + case NV4097_SET_COLOR_CLEAR_VALUE: + { + const u32 color = args[0]; + m_clear_color_a = (color >> 24) & 0xff; + m_clear_color_r = (color >> 16) & 0xff; + m_clear_color_g = (color >> 8) & 0xff; + m_clear_color_b = color & 0xff; + } + break; + + case NV4097_SET_SHADER_PROGRAM: + { + m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num++]; + u32 a0 = args[0]; + m_cur_shader_prog->offset = a0 & ~0x3; + m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); + } + break; + + case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: + { + //VertexData[0].prog.attributeOutputMask = args[0]; + //FragmentData.prog.attributeInputMask = args[0]/* & ~0x20*/; + } + break; + + case NV4097_SET_SHADER_CONTROL: + { + const u32 arg0 = args[0]; + + //const u8 controlTxp = (arg0 >> 15) & 0x1; + //FragmentData.prog.registerCount = arg0 >> 24; + //FragmentData.prog. + } + break; + + case NV4097_SET_TRANSFORM_PROGRAM_LOAD: + { + m_cur_vertex_prog = &m_vertex_progs[args[0]]; + m_cur_vertex_prog->data.Clear(); + + if(count == 2) + { + const u32 start = args[1]; + if(start) + ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start); + } + } + break; + + case NV4097_SET_TRANSFORM_PROGRAM: + { + if(!m_cur_vertex_prog) + { + ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL"); + break; + } + + for(u32 i=0; idata.AddCpy(args[i]); + } + break; + + case NV4097_SET_TRANSFORM_TIMEOUT: + + if(!m_cur_vertex_prog) + { + ConLog.Warning("NV4097_SET_TRANSFORM_TIMEOUT: m_cur_vertex_prog == NULL"); + break; + } + + //m_cur_vertex_prog->Decompile(); + break; + + case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: + //VertexData[0].prog.attributeInputMask = args[0]; + break; + + case NV4097_INVALIDATE_VERTEX_CACHE_FILE: + break; + + case NV4097_SET_TRANSFORM_CONSTANT_LOAD: + { + if((count - 1) % 4) + { + CMD_LOG("NV4097_SET_TRANSFORM_CONSTANT_LOAD [%d]", count); + break; + } + + for(u32 id = args[0], i = 1; i= 2) + { + m_set_stencil_func_ref = true; + m_stencil_func_ref = args[1]; + + if(count >= 3) + { + m_set_stencil_func_mask = true; + m_stencil_func_mask = args[2]; + } + } + break; + + case NV4097_SET_STENCIL_FUNC_REF: + m_set_stencil_func_ref = true; + m_stencil_func_ref = args[0]; + break; + + case NV4097_SET_STENCIL_FUNC_MASK: + m_set_stencil_func_mask = true; + m_stencil_func_mask = args[0]; + break; + + case NV4097_SET_STENCIL_OP_FAIL: + m_set_stencil_fail = true; + m_stencil_fail = args[0]; + if(count >= 2) + { + m_set_stencil_zfail = true; + m_stencil_zfail = args[1]; + + if(count >= 3) + { + m_set_stencil_zpass = true; + m_stencil_zpass = args[2]; + } + } + break; + + case NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE: + m_set_two_sided_stencil_test_enable = args[0] ? true : false; + break; + + case NV4097_SET_BACK_STENCIL_MASK: + m_set_back_stencil_mask = true; + m_back_stencil_mask = args[0]; + break; + + case NV4097_SET_BACK_STENCIL_FUNC: + m_set_back_stencil_func = true; + m_back_stencil_func = args[0]; + if(count >= 2) + { + m_set_back_stencil_func_ref = true; + m_back_stencil_func_ref = args[1]; + + if(count >= 3) + { + m_set_back_stencil_func_mask = true; + m_back_stencil_func_mask = args[2]; + } + } + break; + + case NV4097_SET_BACK_STENCIL_FUNC_REF: + m_set_back_stencil_func_ref = true; + m_back_stencil_func_ref = args[0]; + break; + + case NV4097_SET_BACK_STENCIL_FUNC_MASK: + m_set_back_stencil_func_mask = true; + m_back_stencil_func_mask = args[0]; + break; + + case NV4097_SET_BACK_STENCIL_OP_FAIL: + m_set_stencil_fail = true; + m_stencil_fail = args[0]; + if(count >= 2) + { + m_set_back_stencil_zfail = true; + m_back_stencil_zfail = args[1]; + + if(count >= 3) + { + m_set_back_stencil_zpass = true; + m_back_stencil_zpass = args[2]; + } + } + break; + + case NV4097_SET_POLY_OFFSET_FILL_ENABLE: + if(args[0]) ConLog.Error("NV4097_SET_POLY_OFFSET_FILL_ENABLE"); + break; + + case NV4097_SET_RESTART_INDEX_ENABLE: + if(args[0]) ConLog.Error("NV4097_SET_RESTART_INDEX_ENABLE"); + break; + + case NV4097_SET_POINT_PARAMS_ENABLE: + if(args[0]) ConLog.Error("NV4097_SET_POINT_PARAMS_ENABLE"); + break; + + case NV4097_SET_POINT_SPRITE_CONTROL: + if(args[0] & 0x1) + { + ConLog.Error("NV4097_SET_POINT_SPRITE_CONTROL enable"); + } + break; + + case NV4097_SET_POLY_SMOOTH_ENABLE: + m_set_poly_smooth = args[0] ? true : false; + break; + + case NV4097_SET_BLEND_COLOR: + m_set_blend_color = true; + m_blend_color_r = args[0] & 0xff; + m_blend_color_g = (args[0] >> 8) & 0xff; + m_blend_color_b = (args[0] >> 16) & 0xff; + m_blend_color_a = (args[0] >> 24) & 0xff; + break; + + case NV4097_SET_BLEND_COLOR2: + if(args[0]) ConLog.Error("NV4097_SET_BLEND_COLOR2"); + break; + + case NV4097_SET_BLEND_EQUATION: + m_set_blend_equation = true; + m_blend_equation_rgb = args[0] & 0xffff; + m_blend_equation_alpha = args[0] >> 16; + break; + + case NV4097_SET_REDUCE_DST_COLOR: + if(args[0]) ConLog.Error("NV4097_SET_REDUCE_DST_COLOR"); + break; + + case NV4097_SET_DEPTH_MASK: + m_set_depth_mask = true; + m_depth_mask = args[0]; + break; + + case NV4097_SET_SCISSOR_VERTICAL: + { + m_set_scissor_vertical = true; + m_scissor_y = args[0] & 0xffff; + m_scissor_h = args[0] >> 16; + } + break; + + case NV4097_SET_SCISSOR_HORIZONTAL: + { + m_set_scissor_horizontal = true; + m_scissor_x = args[0] & 0xffff; + m_scissor_w = args[0] >> 16; + + if(count == 2) + { + m_set_scissor_vertical = true; + m_scissor_y = args[1] & 0xffff; + m_scissor_h = args[1] >> 16; + } + } + break; + + case NV4097_INVALIDATE_VERTEX_FILE: break; + + case NV4097_SET_VIEWPORT_OFFSET: + { + //TODO + } + break; + + case NV4097_SET_SEMAPHORE_OFFSET: + case NV406E_SEMAPHORE_OFFSET: + { + m_set_semaphore_offset = true; + m_semaphore_offset = args[0]; + } + break; + + case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: + { + if(m_set_semaphore_offset) + { + m_set_semaphore_offset = false; + u32 value = args[0]; + value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); + + Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, value); + } + } + break; + + case NV406E_SEMAPHORE_RELEASE: + case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: + if(m_set_semaphore_offset) + { + m_set_semaphore_offset = false; + Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, args[0]); + } + break; + + case NV406E_SEMAPHORE_ACQUIRE: + { + //TODO + } + break; + + case NV4097_SET_RESTART_INDEX: + { + //TODO + } + break; + + case NV4097_INVALIDATE_L2: + { + //TODO + } + break; + + case NV4097_SET_CONTEXT_DMA_COLOR_A: + { + m_set_context_dma_color_a = true; + m_context_dma_color_a = args[0]; + } + break; + + case NV4097_SET_CONTEXT_DMA_COLOR_B: + { + m_set_context_dma_color_b = true; + m_context_dma_color_b = args[0]; + } + break; + + case NV4097_SET_CONTEXT_DMA_COLOR_C: + { + m_set_context_dma_color_c = true; + m_context_dma_color_c = args[0]; + + if(count > 1) + { + m_set_context_dma_color_d = true; + m_context_dma_color_d = args[1]; + } + } + break; + + case NV4097_SET_CONTEXT_DMA_ZETA: + { + m_set_context_dma_z = true; + m_context_dma_z = args[0]; + } + break; + /* + case NV4097_SET_SURFACE_PITCH_A: + { + //TODO + } + break; + + case NV4097_SET_SURFACE_PITCH_B: + { + //TODO + } + break; + */ + case NV4097_SET_SURFACE_PITCH_C: + { + if(count != 4) + { + ConLog.Error("NV4097_SET_SURFACE_PITCH_C: Bad count (%d)", count); + break; + } + + m_surface_pitch_c = args[0]; + m_surface_pitch_d = args[1]; + m_surface_offset_c = args[2]; + m_surface_offset_d = args[3]; + } + break; + + case NV4097_SET_SURFACE_PITCH_Z: + { + m_surface_pitch_z = args[0]; + } + break; + + case NV4097_SET_SHADER_WINDOW: + { + u32 a0 = args[0]; + m_shader_window_height = a0 & 0xfff; + m_shader_window_origin = (a0 >> 12) & 0xf; + m_shader_window_pixel_centers = a0 >> 16; + } + break; + + case NV4097_SET_SURFACE_CLIP_VERTICAL: + { + u32 a0 = args[0]; + m_set_surface_clip_vertical = true; + m_surface_clip_y = a0; + m_surface_clip_h = a0 >> 16; + } + break; + + case NV4097_SET_SURFACE_CLIP_HORIZONTAL: + { + u32 a0 = args[0]; + + m_set_surface_clip_horizontal = true; + m_surface_clip_x = a0; + m_surface_clip_w = a0 >> 16; + + if(count >= 2) + { + u32 a1 = args[1]; + m_set_surface_clip_vertical = true; + m_surface_clip_y = a1; + m_surface_clip_h = a1 >> 16; + } + } + break; + + case NV4097_SET_WINDOW_OFFSET: + { + //TODO + } + break; + + case NV4097_SET_SURFACE_COLOR_TARGET: + { + m_surface_colour_target = args[0]; + } + break; + + case NV4097_SET_ANTI_ALIASING_CONTROL: + { + //TODO + } + break; + + case NV4097_SET_LINE_SMOOTH_ENABLE: + m_set_line_smooth = args[0] ? true : false; + break; + + case NV4097_SET_LINE_WIDTH: + m_set_line_width = true; + m_line_width = args[0]; + break; + + case NV4097_SET_SHADE_MODE: + m_set_shade_mode = true; + m_shade_mode = args[0]; + break; + + case NV4097_SET_ZSTENCIL_CLEAR_VALUE: + { + u32 a0 = args[0]; + m_clear_s = a0 & 0xff; + m_clear_z = a0 >> 8; + } + 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: + { + u32 a0 = args[0]; + u8 type = a0 >> 24; + u32 offset = a0 & 0xffffff; + + u64 data; + switch(type) + { + case 1: + data = std::chrono::steady_clock::now().time_since_epoch().count(); + data *= 1000000; + break; + + default: + data = 0; + ConLog.Error("NV4097_GET_REPORT: bad type %d", type); + break; + } + + Memory.Write64(m_local_mem_addr + offset, data); + } + break; + + case NV3062_SET_OFFSET_DESTIN: + m_dst_offset = args[0]; + break; + + case NV308A_COLOR: + { + RSXTransformConstant c; + c.id = m_dst_offset; + + if(count >= 1) + { + u32 a = args[0]; + a = a << 16 | a >> 16; + c.x = (float&)a; + } + + if(count >= 2) + { + u32 a = args[1]; + a = a << 16 | a >> 16; + c.y = (float&)a; + } + + if(count >= 3) + { + u32 a = args[2]; + a = a << 16 | a >> 16; + c.z = (float&)a; + } + + if(count >= 4) + { + u32 a = args[3]; + a = a << 16 | a >> 16; + c.w = (float&)a; + } + + if(count >= 5) + { + ConLog.Warning("NV308A_COLOR: count = %d", count); + } + + //ConLog.Warning("NV308A_COLOR: [%d]: %f, %f, %f, %f", c.id, c.x, c.y, c.z, c.w); + m_fragment_constants.AddCpy(c); + } + break; + + case NV308A_POINT: + //TODO + 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; + } + break; + + case NV3089_SET_COLOR_CONVERSION: + { + m_color_conv = args[0]; + m_color_conv_fmt = args[1]; + 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; + 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; + m_color_conv_dsdx = args[7]; + m_color_conv_dtdy = args[8]; + } + break; + + case NV3089_IMAGE_IN_SIZE: + { + u16 w = args[0]; + u16 h = args[0] >> 16; + u16 pitch = args[1]; + u8 origin = args[1] >> 16; + u8 inter = args[1] >> 24; + u32 offset = args[2]; + u16 u = args[3]; + u16 v = args[3] >> 16; + + u8* pixels_src = &Memory[GetAddress(offset, m_context_dma_img_src - 0xfeed0000)]; + u8* pixels_dst = &Memory[GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)]; + + for(u16 y=0; y> 4) & 0xf; + m_clip_plane_2 = (a0 >> 8) & 0xf; + m_clip_plane_3 = (a0 >> 12) & 0xf; + m_clip_plane_4 = (a0 >> 16) & 0xf; + m_clip_plane_5 = a0 >> 20; + } + break; + + case NV4097_SET_FOG_PARAMS: + { + m_set_fog_params = true; + u32 a0 = args[0]; + u32 a1 = args[1]; + m_fog_param0 = (float&)a0; + m_fog_param1 = (float&)a1; + } + break; + + default: + { + wxString log = GetMethodName(cmd); + log += "("; + for(u32 i=0; iget); + const u32 put = re(m_ctrl->put); + if(put == get || !Emu.IsRunning()) + { + if(put == get) + SemaphorePostAndWait(m_sem_flush); + + Sleep(1); + continue; + } + + //ConLog.Write("addr = 0x%x", m_ioAddress + get); + const u32 cmd = Memory.Read32(m_ioAddress + get); + const u32 count = (cmd >> 18) & 0x7ff; + //if(cmd == 0) continue; + + if(cmd & CELL_GCM_METHOD_FLAG_JUMP) + { + u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT); + //ConLog.Warning("rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", addr, m_ioAddress + get, cmd, get, put); + re(m_ctrl->get, addr); + continue; + } + if(cmd & CELL_GCM_METHOD_FLAG_CALL) + { + m_call_stack.Push(get + 4); + u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; + u32 addr = m_ioAddress + offs; + //ConLog.Warning("rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); + m_ctrl->get = re32(offs); + continue; + } + if(cmd == CELL_GCM_METHOD_FLAG_RETURN) + { + //ConLog.Warning("rsx return!"); + u32 get = m_call_stack.Pop(); + //ConLog.Warning("rsx return(0x%x)", get); + m_ctrl->get = re32(get); + continue; + } + if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) + { + //ConLog.Warning("non increment cmd! 0x%x", cmd); + } + + if(cmd == 0) + { + ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", m_ioAddress + get, re(m_ctrl->put), get); + Emu.Pause(); + continue; + } + + mem32_ptr_t args(m_ioAddress + get + 4); + DoCmd(cmd, cmd & 0x3ffff, args, count); + + re(m_ctrl->get, get + (count + 1) * 4); + //memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4); + } + + ConLog.Write("RSX thread exit..."); + + OnExitThread(); +} diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 1333d31a5c..d76ab88ec1 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -1,8 +1,281 @@ #pragma once #include "GCM.h" +#include "RSXVertexProgram.h" +#include "RSXFragmentProgram.h" +#include "Emu/SysCalls/Callback.h" -class ExecRSXCMDdata +enum Method { + CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, + CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, + CELL_GCM_METHOD_FLAG_CALL = 0x00000002, + CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, +}; + + +class RSXTexture +{ +public: + bool m_enabled; + + u32 m_width, m_height; + u32 m_offset; + + bool m_cubemap; + u8 m_dimension; + u32 m_format; + u16 m_mipmap; + + u32 m_pitch; + u16 m_depth; + + u16 m_minlod; + u16 m_maxlod; + u8 m_maxaniso; + + u8 m_wraps; + u8 m_wrapt; + u8 m_wrapr; + u8 m_unsigned_remap; + u8 m_zfunc; + u8 m_gamma; + 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: + RSXTexture() + : m_width(0), m_height(0) + , m_offset(0) + , m_enabled(false) + + , m_cubemap(false) + , m_dimension(0) + , m_format(0) + , m_mipmap(0) + , m_minlod(0) + , m_maxlod(1000) + , m_maxaniso(0) + { + } + + void SetRect(const u32 width, const u32 height) + { + m_width = width; + m_height = height; + } + + void SetFormat(const bool cubemap, const u8 dimension, const u32 format, const u16 mipmap) + { + m_cubemap = cubemap; + m_dimension = dimension; + m_format = format; + m_mipmap = mipmap; + } + + void SetAddress(u8 wraps, u8 wrapt, u8 wrapr, u8 unsigned_remap, u8 zfunc, u8 gamma, u8 aniso_bias, u8 signed_remap) + { + m_wraps = wraps; + m_wrapt = wrapt; + m_wrapr = wrapr; + m_unsigned_remap = unsigned_remap; + m_zfunc = zfunc; + m_gamma = gamma; + m_aniso_bias = aniso_bias; + m_signed_remap = signed_remap; + } + + void SetControl0(const bool enable, const u16 minlod, const u16 maxlod, const u8 maxaniso) + { + m_enabled = enable; + m_minlod = minlod; + m_maxlod = maxlod; + m_maxaniso = maxaniso; + } + + void SetControl1(u32 remap) + { + m_remap = remap; + } + + void SetControl3(u16 depth, u32 pitch) + { + m_depth = depth; + 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) + { + m_offset = offset; + } + + wxSize GetRect() const + { + return wxSize(m_width, m_height); + } + + bool IsEnabled() const + { + return m_enabled; + } + + u32 GetOffset() const + { + return m_offset; + } +}; + +struct RSXVertexData +{ + u32 frequency; + u32 stride; + u32 size; + u32 type; + u32 addr; + u32 constant_count; + + Array data; + + RSXVertexData(); + + void Reset(); + bool IsEnabled() { return size > 0; } + void Load(u32 start, u32 count); + + u32 GetTypeSize(); +}; + +struct RSXIndexArrayData +{ + Array m_data; + int m_type; + u32 m_first; + u32 m_count; + u32 m_addr; + u32 index_max; + u32 index_min; + + RSXIndexArrayData() + { + Reset(); + } + + void Reset() + { + m_type = 0; + m_first = ~0; + m_count = 0; + m_addr = 0; + index_min = ~0; + index_max = 0; + m_data.Clear(); + } +}; + +struct RSXTransformConstant +{ + u32 id; + float x, y, z, w; + + RSXTransformConstant() + : x(0.0f) + , y(0.0f) + , z(0.0f) + , w(0.0f) + { + } + + RSXTransformConstant(u32 id, float x, float y, float z, float w) + : id(id) + , x(x) + , y(y) + , z(z) + , w(w) + { + } +}; + +class RSXThread : public ThreadBase +{ +public: + static const uint m_textures_count = 16; + static const uint m_vertex_count = 16; + static const uint m_fragment_count = 16; + static const uint m_tiles_count = 15; + +protected: + Stack m_call_stack; + CellGcmControl* m_ctrl; + +public: + GcmTileInfo m_tiles[m_tiles_count]; + RSXTexture m_textures[m_textures_count]; + RSXVertexData m_vertex_data[m_vertex_count]; + RSXIndexArrayData m_indexed_array; + Array m_fragment_constants; + Array m_transform_constants; + + u32 m_cur_shader_prog_num; + RSXShaderProgram m_shader_progs[m_fragment_count]; + RSXShaderProgram* m_cur_shader_prog; + RSXVertexProgram m_vertex_progs[m_vertex_count]; + RSXVertexProgram* m_cur_vertex_prog; + +public: + u32 m_ioAddress, m_ioSize, m_ctrlAddress; + int m_flip_status; + int m_flip_mode; + + u32 m_tiles_addr; + u32 m_zculls_addr; + u32 m_gcm_buffers_addr; + u32 m_gcm_buffers_count; + u32 m_gcm_current_buffer; + u32 m_ctxt_addr; + u32 m_report_main_addr; + + u32 m_local_mem_addr, m_main_mem_addr; + Array m_main_mem_info; + +protected: + uint m_draw_mode; + + u32 m_width, m_height; + u32 m_draw_array_count; + +public: + wxCriticalSection m_cs_main; + wxSemaphore m_sem_flush; + wxSemaphore m_sem_flip; + Callback m_flip_handler; + public: bool m_set_color_mask; bool m_color_mask_r; @@ -229,8 +502,16 @@ public: u8 m_begin_end; -public: - ExecRSXCMDdata() +protected: + RSXThread() + : ThreadBase(false, "RSXThread") + , m_ctrl(nullptr) + , m_flip_status(0) + , m_flip_mode(CELL_GCM_DISPLAY_VSYNC) + , m_main_mem_addr(0) + , m_local_mem_addr(0) + , m_draw_mode(0) + , m_draw_array_count(0) { m_set_alpha_test = false; m_set_blend = false; @@ -246,15 +527,18 @@ public: m_set_surface_clip_horizontal = false; m_set_surface_clip_vertical = false; + m_clear_surface_mask = 0; m_clear_color_r = 0; m_clear_color_g = 0; m_clear_color_b = 0; m_clear_color_a = 0; + m_clear_z = 0xffffff; + m_clear_s = 0; Reset(); } - virtual void Reset() + void Reset() { m_set_color_mask = false; m_set_clip = false; @@ -302,19 +586,57 @@ public: m_begin_end = 0; } - virtual void ExecCMD()=0; -}; + void Begin(u32 draw_mode); + void End(); -class RSXThread : public ThreadBase -{ - Array call_stack; - CellGcmControl& m_ctrl; - u32 m_ioAddress; + void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count); -protected: - RSXThread(CellGcmControl* ctrl, u32 ioAddress); + virtual void OnInit() = 0; + virtual void OnInitThread() = 0; + virtual void OnExitThread() = 0; + virtual void OnReset() = 0; + virtual void ExecCMD() = 0; + virtual void Flip() = 0; + + u32 GetAddress(u32 offset, u8 location) + { + switch(location) + { + case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset; + case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset; + } + + ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location); + assert(0); + return 0; + } + + void LoadVertexData(u32 first, u32 count) + { + for(u32 i=0; i data; +}; \ No newline at end of file diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 674b8d1ccc..453a0573a6 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -219,7 +219,7 @@ public: MemoryBlocks[i].Delete(); } - MemoryBlocks.Clear(); + MemoryBlocks.ClearF(); } void Write8(const u64 addr, const u8 data); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index fa8b4a5695..9ca022ad41 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -433,7 +433,7 @@ int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); - if(index >= g_tiles_count || base >= 800 || bank >= 4) + if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) { return CELL_GCM_ERROR_INVALID_VALUE; } @@ -470,7 +470,7 @@ int cellGcmBindTile(u8 index) { cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); - if(index >= g_tiles_count) + if(index >= RSXThread::m_tiles_count) { return CELL_GCM_ERROR_INVALID_VALUE; } @@ -485,7 +485,7 @@ int cellGcmUnbindTile(u8 index) { cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); - if(index >= g_tiles_count) + if(index >= RSXThread::m_tiles_count) { return CELL_GCM_ERROR_INVALID_VALUE; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index beaa904bad..5ffa755bfe 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -9,7 +9,6 @@ Module cellRecs(0x001f, cellRecs_init); int cellRescSetConvertAndFlip(s32 indx) { cellRecs.Log("cellRescSetConvertAndFlip(indx=0x%x)", indx); - Emu.GetGSManager().GetRender().Draw(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index eff6342761..703181c264 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -312,13 +312,6 @@ void default_syscall() case 23: RESULT(lv2ProcessWaitForChild2(CPU)); return; case 25: RESULT(lv2ProcessGetSdkVersion(CPU)); return; */ - //timer - case 141: - case 142: - std::this_thread::sleep_for(std::chrono::nanoseconds(SC_ARGS_1)); - RESULT(0); - return; - //tty case 988: ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx", diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 5b2719a961..3259beaf19 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -219,13 +219,13 @@ - + + + + - - - diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 358fc77e04..8b71c94fba 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -160,30 +160,18 @@ Emu\SysCalls\lv2 - - Emu\GS\GL - Emu\GS\GL Emu\GS\GL - - Emu\GS\GL - - - Emu\GS\GL - Emu\GS\GL Emu\GS - - Emu\GS\GL - Emu\SysCalls\lv2 @@ -343,6 +331,18 @@ Emu\SysCalls\Modules + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS\GL + diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 8fd1f8d2e5..e9f954e7cf 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -198,8 +198,8 @@ enum Status #include "Ini.h" #include "Gui/FrameBase.h" #include "Gui/ConLog.h" -#include "Emu/System.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/Cell/PPUThread.h" #include "Emu/FS/vfsFileBase.h"