diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 1b532f7366..dcbf259e4e 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -179,14 +179,14 @@ ComPtr uploadSingleTexture( */ static void updateExistingTexture( - const RSXTexture &texture, + const rsx::texture &texture, ID3D12GraphicsCommandList *commandList, DataHeap &textureBuffersHeap, ID3D12Resource *existingTexture) { - size_t w = texture.GetWidth(), h = texture.GetHeight(); + size_t w = texture.width(), h = texture.height(); - int format = texture.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); + int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); size_t textureSize = getPlacedTextureStorageSpace(texture, 256); @@ -309,12 +309,12 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist) vramTexture = ItRTT->second; isRenderTarget = true; } - else if (cachedTex != nullptr && (cachedTex->first == TextureEntry(format, w, h, m_textures[i].GetMipmap()))) + else if (cachedTex != nullptr && (cachedTex->first == TextureEntry(format, w, h, textures[i].mipmap()))) { if (cachedTex->first.m_isDirty) { - updateExistingTexture(m_textures[i], cmdlist, m_textureUploadData, cachedTex->second.Get()); - m_textureCache.protectData(texaddr, texaddr, getTextureSize(m_textures[i])); + updateExistingTexture(textures[i], cmdlist, m_textureUploadData, cachedTex->second.Get()); + m_textureCache.protectData(texaddr, texaddr, getTextureSize(textures[i])); } vramTexture = cachedTex->second.Get(); } @@ -322,9 +322,9 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist) { if (cachedTex != nullptr) getCurrentResourceStorage().m_dirtyTextures.push_back(m_textureCache.removeFromCache(texaddr)); - ComPtr tex = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData); + ComPtr tex = uploadSingleTexture(textures[i], m_device.Get(), cmdlist, m_textureUploadData); vramTexture = tex.Get(); - m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(m_textures[i]), format, w, h, m_textures[i].mipmap(), tex); + m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(textures[i]), format, w, h, textures[i].mipmap(), tex); } D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 5f6696c76e..861e82e7a1 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -28,7 +28,7 @@ std::string GLFragmentDecompilerThread::compareFunction(COMPARE f, const std::st void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS) { - OS << "#version 420" << std::endl; + OS << "#version 140" << std::endl; } void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS) @@ -110,7 +110,7 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << " " << table[i].first << " = " << table[i].second << ";" << std::endl; } - OS << "};" << std::endl; + OS << "}" << std::endl; } void GLFragmentDecompilerThread::Task() diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 3586bc7cf1..64d177de49 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -605,28 +605,27 @@ void GLGSRender::begin() __glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h); - if (enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) { __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); } - if (enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT)) + if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))) { __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); } __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); - __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + __glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); - enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); - if (enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST)) { //TODO: NV4097_SET_ALPHA_REF must be converted to f32 //glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF])); } - if (enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) { u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; @@ -667,14 +666,14 @@ void GLGSRender::begin() __glcheck glBlendEquationSeparate(equation_rgb, equation_a); } - if (enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST)) { __glcheck glStencilFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC], rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF], rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]); __glcheck glStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - if (enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT)) { __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_MASK]); __glcheck glStencilFuncSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC], @@ -693,14 +692,14 @@ void GLGSRender::begin() __glcheck enable(blend_mrt & 8, GL_BLEND, GL_COLOR_ATTACHMENT3); } - if (enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP)) { __glcheck glLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]); } u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH]; __glcheck glLineWidth((line_width >> 3) + (line_width & 7) / 8.f); - enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH); + __glcheck enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH); //TODO //NV4097_SET_ANISO_SPREAD @@ -740,16 +739,16 @@ void GLGSRender::begin() u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf; //TODO - if (enable(clip_plane_0, GL_CLIP_DISTANCE0)) {} - if (enable(clip_plane_1, GL_CLIP_DISTANCE1)) {} - if (enable(clip_plane_2, GL_CLIP_DISTANCE2)) {} - if (enable(clip_plane_3, GL_CLIP_DISTANCE3)) {} - if (enable(clip_plane_4, GL_CLIP_DISTANCE4)) {} - if (enable(clip_plane_5, GL_CLIP_DISTANCE5)) {} + if (__glcheck enable(clip_plane_0, GL_CLIP_DISTANCE0)) {} + if (__glcheck enable(clip_plane_1, GL_CLIP_DISTANCE1)) {} + if (__glcheck enable(clip_plane_2, GL_CLIP_DISTANCE2)) {} + if (__glcheck enable(clip_plane_3, GL_CLIP_DISTANCE3)) {} + if (__glcheck enable(clip_plane_4, GL_CLIP_DISTANCE4)) {} + if (__glcheck enable(clip_plane_5, GL_CLIP_DISTANCE5)) {} - __glcheck (enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL)); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL); - if (enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE)) { __glcheck glPolygonStipple((GLubyte*)(rsx::method_registers + NV4097_SET_POLYGON_STIPPLE_PATTERN)); } @@ -757,13 +756,13 @@ void GLGSRender::begin() __glcheck glPolygonMode(GL_FRONT, rsx::method_registers[NV4097_SET_FRONT_POLYGON_MODE]); __glcheck glPolygonMode(GL_BACK, rsx::method_registers[NV4097_SET_BACK_POLYGON_MODE]); - if (enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE)) { __glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]); __glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE]); } - enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH); //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL @@ -771,12 +770,12 @@ void GLGSRender::begin() //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE - if (enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART)) { __glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]); } - if (enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE)) + if (__glcheck enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE)) { u32 line_stipple_pattern = rsx::method_registers[NV4097_SET_LINE_STIPPLE_PATTERN]; u16 factor = line_stipple_pattern; @@ -791,45 +790,45 @@ struct apply_attrib_t; template struct apply_attrib_t { - static void func(gl::glsl::program& program, int index, const T* data) + static void func(gl::glsl::program& program, int location, const T* data) { - program.attribs[index] = data[0]; + program.attribs[location] = data[0]; } }; template struct apply_attrib_t { - static void func(gl::glsl::program& program, int index, const T* data) + static void func(gl::glsl::program& program, int location, const T* data) { - program.attribs[index] = color2_base{ data[0], data[1] }; + program.attribs[location] = color2_base{ data[0], data[1] }; } }; template struct apply_attrib_t { - static void func(gl::glsl::program& program, int index, const T* data) + static void func(gl::glsl::program& program, int location, const T* data) { - program.attribs[index] = color3_base{ data[0], data[1], data[2] }; + program.attribs[location] = color3_base{ data[0], data[1], data[2] }; } }; template struct apply_attrib_t { - static void func(gl::glsl::program& program, int index, const T* data) + static void func(gl::glsl::program& program, int location, const T* data) { - program.attribs[index] = color4_base{ data[0], data[1], data[2], data[3] }; + program.attribs[location] = color4_base{ data[0], data[1], data[2], data[3] }; } }; template -void apply_attrib_array(gl::glsl::program& program, int index, const std::vector& data) +void apply_attrib_array(gl::glsl::program& program, int location, const std::vector& data) { for (size_t offset = 0; offset < data.size(); offset += count * sizeof(T)) { - apply_attrib_t::func(program, index, (T*)(data.data() + offset)); + apply_attrib_t::func(program, location, (T*)(data.data() + offset)); } } @@ -992,9 +991,21 @@ void GLGSRender::end() continue; } - if (0 || vertex_info.array) + static const std::string reg_table[] = { - __glcheck m_program.attribs[index] = + "in_pos", "in_weight", "in_normal", + "in_diff_color", "in_spec_color", + "in_fog", + "in_point_size", "in_7", + "in_tc0", "in_tc1", "in_tc2", "in_tc3", + "in_tc4", "in_tc5", "in_tc6", "in_tc7" + }; + + int location = m_program.attribs.location(reg_table[index]); + + if (vertex_info.array) + { + __glcheck m_program.attribs[location] = (vao + vertex_arrays_offsets[index]) .config(gl_types[vertex_info.type], vertex_info.size, gl_normalized[vertex_info.type]); } @@ -1007,10 +1018,10 @@ void GLGSRender::end() case CELL_GCM_VERTEX_F: switch (vertex_info.size) { - case 1: apply_attrib_array(m_program, index, vertex_data); break; - case 2: apply_attrib_array(m_program, index, vertex_data); break; - case 3: apply_attrib_array(m_program, index, vertex_data); break; - case 4: apply_attrib_array(m_program, index, vertex_data); break; + case 1: apply_attrib_array(m_program, location, vertex_data); break; + case 2: apply_attrib_array(m_program, location, vertex_data); break; + case 3: apply_attrib_array(m_program, location, vertex_data); break; + case 4: apply_attrib_array(m_program, location, vertex_data); break; } break; @@ -1042,23 +1053,14 @@ void GLGSRender::end() rsx::thread::end(); } -void GLGSRender::oninit() -{ - GSRender::oninit(); - - m_draw_frames = 1; - m_skip_frames = 0; -} - void GLGSRender::oninit_thread() { GSRender::oninit_thread(); gl::init(); - LOG_NOTICE(Log::RSX, "%s", glGetString(GL_VERSION)); - LOG_NOTICE(Log::RSX, "%s", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel"); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VERSION)); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VENDOR)); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 799a0afbf0..be2c0d4ea2 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -57,8 +57,6 @@ private: GLTexture m_gl_textures[rsx::limits::textures_count]; GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count]; - draw_context_t m_context = nullptr; - //TODO: program cache gl::glsl::program m_program; @@ -78,11 +76,6 @@ private: gl::texture m_flip_tex_color; public: - GSFrameBase* m_frame = nullptr; - u32 m_draw_frames; - u32 m_skip_frames; - bool is_intel_vendor; - GLGSRender(); private: @@ -99,7 +92,6 @@ protected: void begin() override; void end() override; - void oninit() override; void oninit_thread() override; void onexit_thread() override; bool domethod(u32 id, u32 arg) override; diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 472af37a27..a82547aeb7 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -40,6 +40,10 @@ struct GLTraits __glcheck result->create() .attach(gl::glsl::shader_view(vertexProgramData.id)) .attach(gl::glsl::shader_view(fragmentProgramData.id)) + .bind_fragment_data_location("ocol0", 0) + .bind_fragment_data_location("ocol1", 1) + .bind_fragment_data_location("ocol2", 2) + .bind_fragment_data_location("ocol3", 3) .make(); __glcheck result->use(); diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 10af89a112..ea69a65c3d 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -22,7 +22,7 @@ std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::stri void GLVertexDecompilerThread::insertHeader(std::stringstream &OS) { - OS << "#version 420" << std::endl << std::endl; + OS << "#version 140" << std::endl << std::endl; OS << "uniform mat4 scaleOffsetMat = mat4(1.0);" << std::endl; } @@ -31,7 +31,7 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v for (const ParamType PT : inputs) { for (const ParamItem &PI : PT.items) - OS << "layout(location = " << PI.location << ") in " << PT.type << " " << PI.name << ";" << std::endl; + OS << /*"layout(location = " << PI.location << ") "*/ "in " << PT.type << " " << PI.name << ";" << std::endl; } } diff --git a/rpcs3/Emu/RSX/GSRender.cpp b/rpcs3/Emu/RSX/GSRender.cpp index 19408a4010..58e2248c6b 100644 --- a/rpcs3/Emu/RSX/GSRender.cpp +++ b/rpcs3/Emu/RSX/GSRender.cpp @@ -8,7 +8,12 @@ draw_context_t GSFrameBase::new_context() { - return std::shared_ptr(make_context(), [this](void* ctxt) { delete_context(ctxt); }); + if (void* context = make_context()) + { + return std::shared_ptr(context, [this](void* ctxt) { delete_context(ctxt); }); + } + + return nullptr; } void GSFrameBase::title_message(const std::wstring& msg) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index ac3a92f96e..48a9f5d0d4 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -960,98 +960,107 @@ namespace rsx reset(); - while (joinable()) + try { - //TODO: async mode - if (Emu.IsStopped()) + while (joinable()) { - LOG_WARNING(RSX, "RSX thread aborted"); - break; - } - std::lock_guard lock(cs_main); - - inc = 1; - - be_t get = ctrl->get; - be_t put = ctrl->put; - - if (put == get || !Emu.IsRunning()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - continue; - } - - const u32 cmd = ReadIO32(get); - const u32 count = (cmd >> 18) & 0x7ff; - - if (cmd & CELL_GCM_METHOD_FLAG_JUMP) - { - u32 offs = cmd & 0x1fffffff; - //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - ctrl->get.exchange(offs); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_CALL) - { - m_call_stack.push(get + 4); - u32 offs = cmd & ~3; - //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); - ctrl->get.exchange(offs); - continue; - } - if (cmd == CELL_GCM_METHOD_FLAG_RETURN) - { - u32 get = m_call_stack.top(); - m_call_stack.pop(); - //LOG_WARNING(RSX, "rsx return(0x%x)", get); - ctrl->get.exchange(get); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) - { - //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); - inc = 0; - } - - if (cmd == 0) //nop - { - ctrl->get.atomic_op([](be_t& value) + //TODO: async mode + if (Emu.IsStopped()) { - value += 4; - }); + LOG_WARNING(RSX, "RSX thread aborted"); + break; + } + std::lock_guard lock(cs_main); - continue; - } + inc = 1; - auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); + be_t get = ctrl->get; + be_t put = ctrl->put; - u32 first_cmd = (cmd & 0xffff) >> 2; - - if (cmd & 0x3) - { - LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff); - } - - for (u32 i = 0; i < count; i++) - { - u32 reg = first_cmd + (i * inc); - u32 value = args[i]; - - if (Ini.RSXLogging.GetValue()) + if (put == get || !Emu.IsRunning()) { - LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; } - method_registers[reg] = value; + const u32 cmd = ReadIO32(get); + const u32 count = (cmd >> 18) & 0x7ff; - if (auto method = methods[reg]) - method(this, value); + if (cmd & CELL_GCM_METHOD_FLAG_JUMP) + { + u32 offs = cmd & 0x1fffffff; + //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); + ctrl->get.exchange(offs); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_CALL) + { + m_call_stack.push(get + 4); + u32 offs = cmd & ~3; + //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); + ctrl->get.exchange(offs); + continue; + } + if (cmd == CELL_GCM_METHOD_FLAG_RETURN) + { + u32 get = m_call_stack.top(); + m_call_stack.pop(); + //LOG_WARNING(RSX, "rsx return(0x%x)", get); + ctrl->get.exchange(get); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) + { + //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); + inc = 0; + } + + if (cmd == 0) //nop + { + ctrl->get.atomic_op([](be_t& value) + { + value += 4; + }); + + continue; + } + + auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); + + u32 first_cmd = (cmd & 0xffff) >> 2; + + if (cmd & 0x3) + { + LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff); + } + + for (u32 i = 0; i < count; i++) + { + u32 reg = first_cmd + (i * inc); + u32 value = args[i]; + + if (Ini.RSXLogging.GetValue()) + { + LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); + } + + method_registers[reg] = value; + + if (auto method = methods[reg]) + method(this, value); + } + + ctrl->get.atomic_op([count](be_t& value) + { + value += (count + 1) * 4; + }); } + } + catch (const std::exception& ex) + { + LOG_ERROR(Log::RSX, ex.what()); - ctrl->get.atomic_op([count](be_t& value) - { - value += (count + 1) * 4; - }); + std::rethrow_exception(std::current_exception()); } LOG_NOTICE(RSX, "RSX thread ended");