diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 36108bc20e..4912990e0f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -295,6 +295,18 @@ void D3D12GSRender::OnReset() { } +bool D3D12GSRender::domethod(u32 cmd, u32 arg) +{ + switch (cmd) + { + case NV4097_CLEAR_SURFACE: + clear_surface(arg); + return true; + default: + return false; + } +} + void D3D12GSRender::clear_surface(u32 arg) { std::chrono::time_point startDuration = std::chrono::system_clock::now(); @@ -623,6 +635,8 @@ void D3D12GSRender::end() m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf()); getCurrentResourceStorage().setNewCommandList(); } + + thread::end(); } static bool diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 1127e8b6ae..c06ba71ee6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -508,10 +508,12 @@ private: */ void renderOverlay(); + void clear_surface(u32 arg); + protected: virtual void onexit_thread() override; virtual void OnReset() override; - virtual void clear_surface(u32 arg) override; + virtual bool domethod(u32 cmd, u32 arg) override; virtual void end() override; virtual void flip(int buffer) override; }; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index d8c1cf13d1..a1fe5ad58e 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1043,7 +1043,7 @@ void GLGSRender::InitVertexData() }*/ // Scale - scaleOffsetMat[0] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); +/* scaleOffsetMat[0] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); scaleOffsetMat[5] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale); scaleOffsetMat[10] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; @@ -1053,7 +1053,7 @@ void GLGSRender::InitVertexData() scaleOffsetMat[11] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)] - 1 / 2.0f; scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale; - scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale; + scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale;*/ l = m_program.GetLocation("scaleOffsetMat"); glUniformMatrix4fv(l, 1, false, scaleOffsetMat); @@ -1137,7 +1137,6 @@ void GLGSRender::WriteBuffers() if (Ini.GSDumpDepthBuffer.GetValue()) { glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); WriteDepthBuffer(); } @@ -1150,212 +1149,38 @@ void GLGSRender::WriteBuffers() void GLGSRender::WriteDepthBuffer() { -/* if (!m_set_context_dma_z) - { - return; - } - u32 address;// = rsx::get_address(m_surface_offset_z, m_context_dma_z - 0xfeed0000); - auto ptr = vm::get_ptr(address); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); - checkForGlError("WriteDepthBuffer(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); - checkForGlError("WriteDepthBuffer(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(ptr, packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteDepthBuffer(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - - checkForGlError("WriteDepthBuffer(): glReadPixels"); - glBindTexture(GL_TEXTURE_2D, g_depth_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RSXThread::m_width, RSXThread::m_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, ptr); - checkForGlError("WriteDepthBuffer(): glTexImage2D"); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ptr); - checkForGlError("WriteDepthBuffer(): glGetTexImage");*/ } void GLGSRender::WriteColorBufferA() { - /*if (!m_set_context_dma_color_a) - { - return; - } - u32 address;// = rsx::get_address(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT0); - checkForGlError("WriteColorBufferA(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]); - checkForGlError("WriteColorBufferA(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferA(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferA(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/ } void GLGSRender::WriteColorBufferB() { -/* if (!m_set_context_dma_color_b) - { - return; - } - u32 address;// = rsx::get_address(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT1); - checkForGlError("WriteColorBufferB(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]); - checkForGlError("WriteColorBufferB(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferB(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferB(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/ } void GLGSRender::WriteColorBufferC() { -/* if (!m_set_context_dma_color_c) - { - return; - } - u32 address;// = rsx::get_address(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT2); - checkForGlError("WriteColorBufferC(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[2]); - checkForGlError("WriteColorBufferC(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferC(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferC(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/ } void GLGSRender::WriteColorBufferD() { -/* if (!m_set_context_dma_color_d) - { - return; - } - - u32 address;// = rsx::get_address(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT3); - checkForGlError("WriteColorBufferD(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[3]); - checkForGlError("WriteColorBufferD(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferD(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferD(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/ } void GLGSRender::WriteColorBuffers() { - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 4); - - switch(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) - { - case CELL_GCM_SURFACE_TARGET_NONE: - return; - - case CELL_GCM_SURFACE_TARGET_0: - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - break; - - case CELL_GCM_SURFACE_TARGET_1: - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferB(); - break; - - case CELL_GCM_SURFACE_TARGET_MRT1: - for (int i = 0; i < 2; i++) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - break; - - case CELL_GCM_SURFACE_TARGET_MRT2: - for (int i = 0; i < 3; i++) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - WriteColorBufferC(); - break; - - case CELL_GCM_SURFACE_TARGET_MRT3: - for (int i = 0; i < 4; i++) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - WriteColorBufferC(); - WriteColorBufferD(); - break; - } } void GLGSRender::oninit() { m_draw_frames = 1; m_skip_frames = 0; - RSXThread::m_width = 720; - RSXThread::m_height = 576; - RSXThread::m_width_scale = 2.0f; - RSXThread::m_height_scale = 2.0f; - last_width = 0; last_height = 0; last_depth_format = 0; @@ -1415,9 +1240,6 @@ void GLGSRender::InitDrawBuffers() { // if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) { - LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); - last_width = RSXThread::m_width; - last_height = RSXThread::m_height; // last_depth_format = m_surface_depth_format; m_fbo.Create(); @@ -1430,7 +1252,6 @@ void GLGSRender::InitDrawBuffers() for (int i = 0; i < 4; ++i) { m_rbo.Bind(i); - m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); } @@ -1444,14 +1265,12 @@ void GLGSRender::InitDrawBuffers() // [E : RSXThread]: Bad depth format! (0) // [E : RSXThread]: glEnable: opengl error 0x0506 // [E : RSXThread]: glDrawArrays: opengl error 0x0506 - m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)"); break; } case CELL_GCM_SURFACE_Z16: { - m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); @@ -1462,7 +1281,6 @@ void GLGSRender::InitDrawBuffers() case CELL_GCM_SURFACE_Z24S8: { - m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); @@ -1574,8 +1392,9 @@ void GLGSRender::InitDrawBuffers() } } -void GLGSRender::clear_surface(u32 arg) +bool GLGSRender::domethod(u32 arg, u32) { + return false; InitDrawBuffers(); // if (m_set_color_mask) @@ -1938,10 +1757,10 @@ void GLGSRender::end() m_vao.Bind(); - if (m_indexed_array.m_count) +/* if (m_indexed_array.m_count) LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); else - LoadVertexData(draw_array_first, draw_array_count); + LoadVertexData(draw_array_first, draw_array_count);*/ if (m_indexed_array.m_count || draw_array_count) { @@ -1990,7 +1809,6 @@ void GLGSRender::flip(int buffer) // Set scissor to FBO size if (m_set_scissor_horizontal && m_set_scissor_vertical) { - glScissor(0, 0, RSXThread::m_width, RSXThread::m_height); checkForGlError("glScissor"); } @@ -2005,7 +1823,6 @@ void GLGSRender::flip(int buffer) // Fast path for non-MRT using glBlitFramebuffer. GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); // Renderbuffer is upside turn , swapped srcY0 and srcY1 - GLfbo::Blit(0, RSXThread::m_height, RSXThread::m_width, 0, 0, 0, RSXThread::m_width, RSXThread::m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } break; @@ -2030,24 +1847,18 @@ void GLGSRender::flip(int buffer) { format = GL_RGBA; static std::vector pixels; - pixels.resize(RSXThread::m_width * RSXThread::m_height * 4); m_fbo.Bind(GL_READ_FRAMEBUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)"); GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (packed) { - memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); checkForGlError("Flip(): glUnmapBuffer"); } glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); src_buffer = pixels.data(); - width = RSXThread::m_width; - height = RSXThread::m_height; } else { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 624dd652ac..3b718029ee 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -168,7 +168,7 @@ protected: virtual void oninit_thread() override; virtual void onexit_thread() override; virtual void OnReset() override; - virtual void clear_surface(u32 arg) override; + virtual bool domethod(u32, u32) override; virtual void end() override; virtual void flip(int buffer) override; diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index 886510df3d..35d3361ce6 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -37,7 +37,7 @@ enum class frame_type DX12 }; -class GSRender : public RSXThread +class GSRender : public rsx::thread { protected: GSFrameBase* m_frame; diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index ece9a54610..31e46bbe26 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -30,8 +30,9 @@ private: { } - virtual void clear_surface(u32 arg) override + virtual bool domethod(u32, u32) override { + return false; } virtual void end() override diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index c80cfbe0b3..b38885013f 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -38,7 +38,7 @@ namespace rsx { //fire only when all data passed to rsx cmd buffer template - force_inline void set_vertex_data_impl(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data_impl(thread* rsx, u32 arg) { static const size_t element_size = (count * sizeof(type)); static const size_t element_size_in_words = element_size / sizeof(u32); @@ -63,49 +63,49 @@ namespace rsx } template - force_inline void set_vertex_data4ub_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data4ub_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data1f_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data1f_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data2f_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data2f_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data3f_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data3f_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data4f_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data4f_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data2s_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data2s_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data4s_m(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data4s_m(thread* rsx, u32 arg) { set_vertex_data_impl(rsx, arg); } template - force_inline void set_vertex_data_array_format(RSXThread* rsx, u32 arg) + force_inline void set_vertex_data_array_format(thread* rsx, u32 arg) { auto& info = rsx->vertex_arrays_info[index]; info.unpack(arg); @@ -203,9 +203,9 @@ namespace rsx return 1; } } -} -u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) + +u32 thread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) { auto args = vm::ps3::ptr::make(args_addr); std::string debug = GetMethodName(cmd); @@ -236,7 +236,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons case_##n(offset, step) \ index = (cmd - offset) / step -void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count) +void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count) { auto args = vm::ps3::ptr::make(args_addr); @@ -770,7 +770,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV4097_CLEAR_SURFACE: { const u32 a0 = ARGS(0); - clear_surface(a0); + domethod(NV4097_CLEAR_SURFACE, a0); break; } case NV4097_SET_ZSTENCIL_CLEAR_VALUE: @@ -921,7 +921,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } else { - End(); + end(); } break; } @@ -2075,176 +2075,232 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } } -void RSXThread::begin(u32 drawMode) -{ - m_begin_end = 1; - draw_mode = drawMode; - draw_array_count = 0; - draw_array_first = ~0; -} - -void RSXThread::End() -{ - end(); - - for (auto &vdata : vertex_arrays) + void thread::begin(u32 drawMode) { - vdata.clear(); + m_begin_end = 1; + draw_mode = drawMode; + draw_array_count = 0; + draw_array_first = ~0; } - m_indexed_array.Reset(); - fragment_constants.clear(); - - m_clear_surface_mask = 0; - m_begin_end = 0; - - OnReset(); -} - -void RSXThread::Task() -{ - u8 inc; - LOG_NOTICE(RSX, "RSX thread started"); - - oninit_thread(); - - last_flip_time = get_system_time() - 1000000; - - autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() + void thread::end() { - const u64 start_time = get_system_time(); - - vblank_count = 0; - - while (joinable()) + for (auto &vdata : vertex_arrays) { - CHECK_EMU_STATUS; + vdata.clear(); + } - if (get_system_time() - start_time > vblank_count * 1000000 / 60) + m_indexed_array.Reset(); + fragment_constants.clear(); + + m_clear_surface_mask = 0; + m_begin_end = 0; + + OnReset(); + } + + void thread::task() + { + u8 inc; + LOG_NOTICE(RSX, "RSX thread started"); + + oninit_thread(); + + last_flip_time = get_system_time() - 1000000; + + autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() + { + const u64 start_time = get_system_time(); + + vblank_count = 0; + + while (joinable()) { - vblank_count++; + CHECK_EMU_STATUS; - if (auto cb = vblank_handler) + if (get_system_time() - start_time > vblank_count * 1000000 / 60) { - Emu.GetCallbackManager().Async([=](CPUThread& cpu) + vblank_count++; + + if (auto cb = vblank_handler) { - cb(static_cast(cpu), 1); - }); + Emu.GetCallbackManager().Async([=](CPUThread& cpu) + { + cb(static_cast(cpu), 1); + }); + } + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } } - else + }); + + while (joinable() && !Emu.IsStopped()) + { + std::lock_guard lock(cs_main); + + inc = 1; + + const be_t put = ctrl->put; + const be_t get = ctrl->get; + + if (put == get || !Emu.IsRunning()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; } - } - }); - while (joinable() && !Emu.IsStopped()) - { - std::lock_guard lock(cs_main); + const u32 cmd = ReadIO32(get); + const u32 count = (cmd >> 18) & 0x7ff; - inc = 1; - - const be_t put = ctrl->put; - const be_t get = ctrl->get; - - 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 (Ini.RSXLogging.GetValue()) - { - LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); - } + if (Ini.RSXLogging.GetValue()) + { + LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); + } - 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 & 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 += 4; + continue; + } + + auto args = vm::ps3::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); + + for (u32 i = 0; i < count; i++) + { + rsx::method_registers[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i); + } + + DoCmd(cmd, cmd & 0x3ffff, args.addr(), count); + + ctrl->get += (count + 1) * 4; } - if (cmd == 0) //nop - { - ctrl->get += 4; - continue; - } - - auto args = vm::ps3::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); - - for (u32 i = 0; i < count; i++) - { - rsx::method_registers[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i); - } - - DoCmd(cmd, cmd & 0x3ffff, args.addr(), count); - - ctrl->get += (count + 1) * 4; + onexit_thread(); } - onexit_thread(); -} - -void RSXThread::Init(const u32 ioAddress, const u32 io_size, const u32 ctrlAddress, const u32 localAddress) -{ - ctrl = vm::get_ptr(ctrlAddress); - this->ioAddress = ioAddress; - this->ioSize = io_size; - m_ctrlAddress = ctrlAddress; - local_mem_addr = localAddress; - - m_cur_vertex_prog = nullptr; - - m_used_gcm_commands.clear(); - - oninit(); - - start(WRAP_EXPR("RSXThread"), WRAP_EXPR(Task())); -} - -u32 RSXThread::ReadIO32(u32 addr) -{ - u32 value; - - if (!RSXIOMem.Read32(addr, &value)) + u64 thread::timestamp() const { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + // Get timestamp, and convert it from microseconds to nanoseconds + return get_system_time() * 1000; } - return value; -} - -void RSXThread::WriteIO32(u32 addr, u32 value) -{ - if (!RSXIOMem.Write32(addr, value)) + void thread::reset() { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; + rsx::method_registers[NV4097_SET_DEPTH_MASK] = 1; + rsx::method_registers[NV4097_SET_DEPTH_FUNC] = 0x0201; + + m_set_dither = false; + rsx::method_registers[NV4097_SET_COLOR_MASK] = -1; + m_set_clip = false; + m_set_depth_bounds_test = false; + m_set_depth_bounds = false; + m_set_scissor_horizontal = false; + m_set_scissor_vertical = false; + m_set_front_polygon_mode = false; + m_set_back_polygon_mode = false; + rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; + rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; + m_set_two_side_light_enable = false; + m_set_point_sprite_control = false; + m_set_point_size = false; + m_set_line_width = false; + m_set_line_smooth = false; + m_set_shade_mode = false; + m_set_fog_mode = false; + m_set_fog_params = false; + m_set_clip_plane = false; + rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; + rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; + rsx::method_registers[NV4097_SET_ALPHA_FUNC] = false; + rsx::method_registers[NV4097_SET_ALPHA_REF] = false; + m_set_poly_smooth = false; + m_set_poly_offset_fill = false; + m_set_poly_offset_line = false; + m_set_poly_offset_point = false; + m_set_poly_offset_mode = false; + m_set_restart_index = false; + m_set_specular = false; + m_set_line_stipple = false; + m_set_polygon_stipple = false; + m_set_surface_clip_horizontal = false; + m_set_surface_clip_vertical = false; + + m_clear_surface_mask = 0; + m_begin_end = 0; + + for (uint i = 0; i < rsx::limits::textures_count; ++i) + { + textures[i].init(i); + } + } + + void thread::init(const u32 ioAddress, const u32 io_size, const u32 ctrlAddress, const u32 localAddress) + { + ctrl = vm::get_ptr(ctrlAddress); + this->ioAddress = ioAddress; + this->ioSize = io_size; + m_ctrlAddress = ctrlAddress; + local_mem_addr = localAddress; + + m_cur_vertex_prog = nullptr; + + m_used_gcm_commands.clear(); + + oninit(); + + start(WRAP_EXPR("RSXThread"), WRAP_EXPR(task())); + } + + u32 thread::ReadIO32(u32 addr) + { + u32 value; + + if (!RSXIOMem.Read32(addr, &value)) + { + throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + } + + return value; + } + + void thread::WriteIO32(u32 addr, u32 value) + { + if (!RSXIOMem.Write32(addr, value)) + { + throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + } } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index f7edaa9243..0e12249c5d 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -10,6 +10,42 @@ #include "Utilities/Timer.h" #include "Utilities/types.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, +}; + +struct RSXIndexArrayData +{ + std::vector 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(); + } +}; + + namespace rsx { namespace limits @@ -76,489 +112,381 @@ namespace rsx type = data_array_format & 0xf; } }; + + class thread : protected named_thread_t + { + protected: + std::stack m_call_stack; + + public: + CellGcmControl* ctrl = nullptr; + Timer timer_sync; + + GcmTileInfo tiles[limits::tiles_count]; + GcmZcullInfo zculls[limits::zculls_count]; + texture textures[limits::textures_count]; + vertex_texture m_vertex_textures[limits::vertex_textures_count]; + + data_array_format_info vertex_arrays_info[limits::vertex_count]; + std::vector vertex_arrays[limits::vertex_count]; + RSXIndexArrayData m_indexed_array; + + std::unordered_map> transform_constants; + std::unordered_map> fragment_constants; + + u32 m_shader_ctrl; + RSXVertexProgram m_vertex_progs[limits::vertex_count]; + RSXVertexProgram* m_cur_vertex_prog; + + public: + u32 ioAddress, ioSize; + int flip_status; + int flip_mode; + int debug_level; + int frequency_mode; + + u32 tiles_addr; + u32 zculls_addr; + u32 m_gcm_buffers_addr; + u32 gcm_buffers_count; + u32 gcm_current_buffer; + u32 ctxt_addr; + u32 report_main_addr; + u32 label_addr; + u32 draw_mode; + + // DMA + u32 dma_report; + + u32 local_mem_addr, main_mem_addr; + bool strict_ordering[0x1000]; + + public: + u32 draw_array_count; + u32 draw_array_first; + double m_fps_limit = 59.94; + + public: + std::mutex cs_main; + semaphore_t sem_flip; + u64 last_flip_time; + vm::ps3::ptr flip_handler = { 0 }; + vm::ps3::ptr user_handler = { 0 }; + vm::ps3::ptr vblank_handler = { 0 }; + u64 vblank_count; + + public: + std::set m_used_gcm_commands; + + protected: + virtual ~thread() {} + + public: + virtual void begin(u32 draw_mode); + virtual void end(); + + virtual void oninit() = 0; + virtual void oninit_thread() = 0; + virtual void onexit_thread() = 0; + virtual bool domethod(u32 cmd, u32 value) { return false; } + virtual void flip(int buffer) = 0; + virtual u64 timestamp() const; + + void task(); + + public: + void reset(); + void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); + + u32 ReadIO32(u32 addr); + void WriteIO32(u32 addr, u32 value); + + public: + u32 m_ctrlAddress; + u32 m_width; + u32 m_height; + float m_width_scale; + float m_height_scale; + // Dither + bool m_set_dither; + + // Clip + bool m_set_clip; + float m_clip_min; + float m_clip_max; + + // Depth bound test + bool m_set_depth_bounds_test; + bool m_set_depth_bounds; + float m_depth_bounds_min; + float m_depth_bounds_max; + + // Primitive restart + bool m_set_restart_index; + u32 m_restart_index; + + // Point + bool m_set_point_size; + bool m_set_point_sprite_control; + float m_point_size; + u16 m_point_x; + u16 m_point_y; + + // Line smooth + bool m_set_line_smooth; + + // Viewport & scissor + bool m_set_scissor_horizontal; + bool m_set_scissor_vertical; + u16 m_scissor_x; + u16 m_scissor_y; + u16 m_scissor_w; + u16 m_scissor_h; + + // Polygon mode/offset + bool m_set_poly_smooth; + bool m_set_poly_offset_fill; + bool m_set_poly_offset_line; + bool m_set_poly_offset_point; + bool m_set_front_polygon_mode; + u32 m_front_polygon_mode; + bool m_set_back_polygon_mode; + u32 m_back_polygon_mode; + bool m_set_poly_offset_mode; + float m_poly_offset_scale_factor; + float m_poly_offset_bias; + + // Line/Polygon stipple + bool m_set_line_stipple; + u16 m_line_stipple_pattern; + u16 m_line_stipple_factor; + bool m_set_polygon_stipple; + u32 m_polygon_stipple_pattern[32]; + + + // Clearing + u32 m_clear_surface_mask; + + // Stencil Test + bool m_set_two_side_light_enable; + + // Line width + bool m_set_line_width; + float m_line_width; + + // Shader mode + bool m_set_shade_mode; + u32 m_shade_mode; + + // Lighting + bool m_set_specular; + + // Color + u32 m_color_format; + u16 m_color_format_src_pitch; + u16 m_color_format_dst_pitch; + u32 m_color_conv; + u32 m_color_conv_fmt; + u32 m_color_conv_op; + s16 m_color_conv_clip_x; + s16 m_color_conv_clip_y; + u16 m_color_conv_clip_w; + u16 m_color_conv_clip_h; + s16 m_color_conv_out_x; + s16 m_color_conv_out_y; + u16 m_color_conv_out_w; + u16 m_color_conv_out_h; + s32 m_color_conv_dsdx; + s32 m_color_conv_dtdy; + + // Semaphore + // PGRAPH + u32 m_PGRAPH_semaphore_offset; + //PFIFO + u32 m_PFIFO_semaphore_offset; + u32 m_PFIFO_semaphore_release_value; + + // Fog + bool m_set_fog_mode; + u32 m_fog_mode; + bool m_set_fog_params; + float m_fog_param0; + float m_fog_param1; + + // Clip plane + bool m_set_clip_plane; + bool m_clip_plane_0; + bool m_clip_plane_1; + bool m_clip_plane_2; + bool m_clip_plane_3; + bool m_clip_plane_4; + bool m_clip_plane_5; + + // Surface + rsx::surface_info m_surface; + bool m_set_surface_clip_horizontal; + bool m_set_surface_clip_vertical; + + // DMA context + u32 m_context_surface; + u32 m_context_dma_img_src; + u32 m_context_dma_img_dst; + u32 m_context_dma_buffer_in_src; + u32 m_context_dma_buffer_in_dst; + u32 m_dst_offset; + + // Swizzle2D? + u16 m_swizzle_format; + u8 m_swizzle_width; + u8 m_swizzle_height; + u32 m_swizzle_offset; + + // Shader + u16 m_shader_window_height; + u8 m_shader_window_origin; + u16 m_shader_window_pixel_centers; + + // Vertex Data + u32 m_vertex_data_base_index; + + // Frequency divider + u32 m_set_frequency_divider_operation; + + u8 m_begin_end; + bool m_read_buffer; + + protected: + thread() + : m_shader_ctrl(0x40) + , flip_status(0) + , flip_mode(CELL_GCM_DISPLAY_VSYNC) + , debug_level(CELL_GCM_DEBUG_LEVEL0) + , frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE) + , report_main_addr(0) + , main_mem_addr(0) + , local_mem_addr(0) + , draw_mode(0) + , draw_array_count(0) + , draw_array_first(~0) + , gcm_current_buffer(0) + , m_read_buffer(true) + { + flip_handler.set(0); + vblank_handler.set(0); + user_handler.set(0); + rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; + m_set_depth_bounds_test = false; + rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; + rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; + m_set_dither = false; + m_set_scissor_horizontal = false; + m_set_scissor_vertical = false; + m_set_line_smooth = false; + m_set_poly_smooth = false; + m_set_point_sprite_control = false; + m_set_specular = false; + m_set_two_side_light_enable = false; + m_set_surface_clip_horizontal = false; + m_set_surface_clip_vertical = false; + m_set_poly_offset_fill = false; + m_set_poly_offset_line = false; + m_set_poly_offset_point = false; + m_set_restart_index = false; + m_set_line_stipple = false; + m_set_polygon_stipple = false; + + // Default value + // TODO: Check against the default value on PS3 + rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE] = 0; + rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff << 8; + m_poly_offset_scale_factor = 0.0; + m_poly_offset_bias = 0.0; + m_restart_index = 0xffffffff; + m_front_polygon_mode = 0x1b02; // GL_FILL + m_back_polygon_mode = 0x1b02; // GL_FILL + rsx::method_registers[NV4097_SET_FRONT_FACE] = 0x0901; // GL_CCW + rsx::method_registers[NV4097_SET_CULL_FACE] = 0x0405; // GL_BACK + rsx::method_registers[NV4097_SET_ALPHA_FUNC] = 0x0207; // GL_ALWAYS + rsx::method_registers[NV4097_SET_ALPHA_REF] = 0.0f; + m_shade_mode = 0x1D01; // GL_SMOOTH + + m_depth_bounds_min = 0.0; + m_depth_bounds_max = 1.0; + m_clip_min = 0.0; + m_clip_max = 1.0; + rsx::method_registers[NV4097_SET_BLEND_EQUATION] = (0x8006) | (0x8006 << 16); // GL_FUNC_ADD + rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = 1 | (1 << 16); + rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = 0; + m_point_x = 0; + m_point_y = 0; + m_point_size = 1.0; + m_line_width = 1.0; + m_line_stipple_pattern = 0xffff; + m_line_stipple_factor = 1; + rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] = 0; + m_vertex_data_base_index = 0; + + // Construct Stipple Pattern + for (size_t i = 0; i < 32; i++) + { + m_polygon_stipple_pattern[i] = 0xFFFFFFFF; + } + + // Construct Textures + for (int i = 0; i < 16; i++) + { + textures[i] = rsx::texture(); + } + + reset(); + } + + u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); + void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count); + + virtual void OnReset() = 0; + + /** + * This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE + * command. + * Backend is expected to write value at offset when current draw textures aren't + * needed anymore by the GPU and can be modified. + */ + virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0; + /** + * This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE + * command. + * Backend is expected to write value at offset when current draw call has completed + * and render surface can be used. + */ + virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0; + /** + * This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command. + * Backend and associated GPU is expected to wait that memory at offset is the same + * as value. In particular buffer/texture buffers value can change while backend is + * waiting. + */ + virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0; + /** + * Called when vertex or fragment shader changes. + * Backend can reuse same program if no change has been notified. + */ + virtual void notifyProgramChange() = 0; + /** + * Called when blend state changes. + * Backend can reuse same program if no change has been notified. + */ + virtual void notifyBlendStateChange() = 0; + /** + * Called when depth stencil state changes. + * Backend can reuse same program if no change has been notified. + */ + virtual void notifyDepthStencilStateChange() = 0; + /** + * Called when rasterizer state changes. + * Rasterizer state includes culling, color masking + * Backend can reuse same program if no change has been notified. + */ + virtual void notifyRasterizerStateChange() = 0; + }; } - -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, -}; - -struct RSXIndexArrayData -{ - std::vector 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(); - } -}; - -class RSXThread : protected named_thread_t -{ -protected: - std::stack m_call_stack; - -public: - CellGcmControl* ctrl = nullptr; - Timer timer_sync; - - GcmTileInfo tiles[rsx::limits::tiles_count]; - GcmZcullInfo zculls[rsx::limits::zculls_count]; - rsx::texture textures[rsx::limits::textures_count]; - rsx::vertex_texture m_vertex_textures[rsx::limits::vertex_textures_count]; - - rsx::data_array_format_info vertex_arrays_info[rsx::limits::vertex_count]; - std::vector vertex_arrays[rsx::limits::vertex_count]; - RSXIndexArrayData m_indexed_array; - - std::unordered_map> transform_constants; - std::unordered_map> fragment_constants; - - u32 m_shader_ctrl; - RSXVertexProgram m_vertex_progs[rsx::limits::vertex_count]; - RSXVertexProgram* m_cur_vertex_prog; - -public: - u32 ioAddress, ioSize, m_ctrlAddress; - int flip_status; - int flip_mode; - int debug_level; - int frequency_mode; - - u32 tiles_addr; - u32 zculls_addr; - u32 m_gcm_buffers_addr; - u32 gcm_buffers_count; - u32 gcm_current_buffer; - u32 ctxt_addr; - u32 report_main_addr; - u32 label_addr; - u32 draw_mode; - - // DMA - u32 dma_report; - - u32 local_mem_addr, main_mem_addr; - bool strict_ordering[0x1000]; - -public: - u32 draw_array_count; - u32 draw_array_first; - - u32 m_width; - u32 m_height; - float m_width_scale; - float m_height_scale; - double m_fps_limit = 59.94; - -public: - std::mutex cs_main; - semaphore_t sem_flip; - u64 last_flip_time; - vm::ps3::ptr flip_handler = { 0 }; - vm::ps3::ptr user_handler = { 0 }; - vm::ps3::ptr vblank_handler = { 0 }; - u64 vblank_count; - -public: - // Dither - bool m_set_dither; - - // Clip - bool m_set_clip; - float m_clip_min; - float m_clip_max; - - // Depth bound test - bool m_set_depth_bounds_test; - bool m_set_depth_bounds; - float m_depth_bounds_min; - float m_depth_bounds_max; - - // Primitive restart - bool m_set_restart_index; - u32 m_restart_index; - - // Point - bool m_set_point_size; - bool m_set_point_sprite_control; - float m_point_size; - u16 m_point_x; - u16 m_point_y; - - // Line smooth - bool m_set_line_smooth; - - // Viewport & scissor - bool m_set_scissor_horizontal; - bool m_set_scissor_vertical; - u16 m_scissor_x; - u16 m_scissor_y; - u16 m_scissor_w; - u16 m_scissor_h; - - // Polygon mode/offset - bool m_set_poly_smooth; - bool m_set_poly_offset_fill; - bool m_set_poly_offset_line; - bool m_set_poly_offset_point; - bool m_set_front_polygon_mode; - u32 m_front_polygon_mode; - bool m_set_back_polygon_mode; - u32 m_back_polygon_mode; - bool m_set_poly_offset_mode; - float m_poly_offset_scale_factor; - float m_poly_offset_bias; - - // Line/Polygon stipple - bool m_set_line_stipple; - u16 m_line_stipple_pattern; - u16 m_line_stipple_factor; - bool m_set_polygon_stipple; - u32 m_polygon_stipple_pattern[32]; - - - // Clearing - u32 m_clear_surface_mask; - - // Stencil Test - bool m_set_two_side_light_enable; - - // Line width - bool m_set_line_width; - float m_line_width; - - // Shader mode - bool m_set_shade_mode; - u32 m_shade_mode; - - // Lighting - bool m_set_specular; - - // Color - u32 m_color_format; - u16 m_color_format_src_pitch; - u16 m_color_format_dst_pitch; - u32 m_color_conv; - u32 m_color_conv_fmt; - u32 m_color_conv_op; - s16 m_color_conv_clip_x; - s16 m_color_conv_clip_y; - u16 m_color_conv_clip_w; - u16 m_color_conv_clip_h; - s16 m_color_conv_out_x; - s16 m_color_conv_out_y; - u16 m_color_conv_out_w; - u16 m_color_conv_out_h; - s32 m_color_conv_dsdx; - s32 m_color_conv_dtdy; - - // Semaphore - // PGRAPH - u32 m_PGRAPH_semaphore_offset; - //PFIFO - u32 m_PFIFO_semaphore_offset; - u32 m_PFIFO_semaphore_release_value; - - // Fog - bool m_set_fog_mode; - u32 m_fog_mode; - bool m_set_fog_params; - float m_fog_param0; - float m_fog_param1; - - // Clip plane - bool m_set_clip_plane; - bool m_clip_plane_0; - bool m_clip_plane_1; - bool m_clip_plane_2; - bool m_clip_plane_3; - bool m_clip_plane_4; - bool m_clip_plane_5; - - // Surface - rsx::surface_info m_surface; - bool m_set_surface_clip_horizontal; - bool m_set_surface_clip_vertical; - - // DMA context - u32 m_context_surface; - u32 m_context_dma_img_src; - u32 m_context_dma_img_dst; - u32 m_context_dma_buffer_in_src; - u32 m_context_dma_buffer_in_dst; - u32 m_dst_offset; - - // Swizzle2D? - u16 m_swizzle_format; - u8 m_swizzle_width; - u8 m_swizzle_height; - u32 m_swizzle_offset; - - // Shader - u16 m_shader_window_height; - u8 m_shader_window_origin; - u16 m_shader_window_pixel_centers; - - // Vertex Data - u32 m_vertex_data_base_index; - - // Frequency divider - u32 m_set_frequency_divider_operation; - - u8 m_begin_end; - bool m_read_buffer; - - std::set m_used_gcm_commands; - -protected: - RSXThread() - : m_shader_ctrl(0x40) - , flip_status(0) - , flip_mode(CELL_GCM_DISPLAY_VSYNC) - , debug_level(CELL_GCM_DEBUG_LEVEL0) - , frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE) - , report_main_addr(0) - , main_mem_addr(0) - , local_mem_addr(0) - , draw_mode(0) - , draw_array_count(0) - , draw_array_first(~0) - , gcm_current_buffer(0) - , m_read_buffer(true) - { - flip_handler.set(0); - vblank_handler.set(0); - user_handler.set(0); - rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; - m_set_depth_bounds_test = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; - rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; - m_set_dither = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_line_smooth = false; - m_set_poly_smooth = false; - m_set_point_sprite_control = false; - m_set_specular = false; - m_set_two_side_light_enable = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_restart_index = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - - // Default value - // TODO: Check against the default value on PS3 - rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE] = 0; - rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff << 8; - m_poly_offset_scale_factor = 0.0; - m_poly_offset_bias = 0.0; - m_restart_index = 0xffffffff; - m_front_polygon_mode = 0x1b02; // GL_FILL - m_back_polygon_mode = 0x1b02; // GL_FILL - rsx::method_registers[NV4097_SET_FRONT_FACE] = 0x0901; // GL_CCW - rsx::method_registers[NV4097_SET_CULL_FACE] = 0x0405; // GL_BACK - rsx::method_registers[NV4097_SET_ALPHA_FUNC] = 0x0207; // GL_ALWAYS - rsx::method_registers[NV4097_SET_ALPHA_REF] = 0.0f; - m_shade_mode = 0x1D01; // GL_SMOOTH - - m_depth_bounds_min = 0.0; - m_depth_bounds_max = 1.0; - m_clip_min = 0.0; - m_clip_max = 1.0; - rsx::method_registers[NV4097_SET_BLEND_EQUATION] = (0x8006) | (0x8006 << 16); // GL_FUNC_ADD - rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = 1 | (1 << 16); - rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = 0; - m_point_x = 0; - m_point_y = 0; - m_point_size = 1.0; - m_line_width = 1.0; - m_line_stipple_pattern = 0xffff; - m_line_stipple_factor = 1; - rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] = 0; - m_vertex_data_base_index = 0; - - // Construct Stipple Pattern - for (size_t i = 0; i < 32; i++) - { - m_polygon_stipple_pattern[i] = 0xFFFFFFFF; - } - - // Construct Textures - for (int i = 0; i < 16; i++) - { - textures[i] = rsx::texture(); - } - - Reset(); - } - - virtual ~RSXThread() override - { - } - - void Reset() - { - rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; - rsx::method_registers[NV4097_SET_DEPTH_MASK] = 1; - rsx::method_registers[NV4097_SET_DEPTH_FUNC] = 0x0201; - - m_set_dither = false; - rsx::method_registers[NV4097_SET_COLOR_MASK] = -1; - m_set_clip = false; - m_set_depth_bounds_test = false; - m_set_depth_bounds = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_front_polygon_mode = false; - m_set_back_polygon_mode = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; - rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; - m_set_two_side_light_enable = false; - m_set_point_sprite_control = false; - m_set_point_size = false; - m_set_line_width = false; - m_set_line_smooth = false; - m_set_shade_mode = false; - m_set_fog_mode = false; - m_set_fog_params = false; - m_set_clip_plane = false; - rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; - rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; - rsx::method_registers[NV4097_SET_ALPHA_FUNC] = false; - rsx::method_registers[NV4097_SET_ALPHA_REF] = false; - m_set_poly_smooth = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_poly_offset_mode = false; - m_set_restart_index = false; - m_set_specular = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; - - m_clear_surface_mask = 0; - m_begin_end = 0; - - for (uint i = 0; i < rsx::limits::textures_count; ++i) - { - textures[i].init(i); - } - } - - void begin(u32 draw_mode); - void End(); - - u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); - void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count); - - virtual void oninit() = 0; - virtual void oninit_thread() = 0; - virtual void onexit_thread() = 0; - virtual void OnReset() = 0; - - /** - * This member is called when the backend is expected to render a draw call, either - * indexed or not. - */ - virtual void end() = 0; - - /** - * This member is called when the backend is expected to clear a target surface. - */ - virtual void clear_surface(u32 arg) = 0; - - /** - * This member is called when the backend is expected to present a target surface in - * either local or main memory. - */ - virtual void flip(int buffer) = 0; - - /** - * This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw textures aren't - * needed anymore by the GPU and can be modified. - */ - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw call has completed - * and render surface can be used. - */ - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command. - * Backend and associated GPU is expected to wait that memory at offset is the same - * as value. In particular buffer/texture buffers value can change while backend is - * waiting. - */ - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0; - /** - * Called when vertex or fragment shader changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyProgramChange() = 0; - /** - * Called when blend state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyBlendStateChange() = 0; - /** - * Called when depth stencil state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyDepthStencilStateChange() = 0; - /** - * Called when rasterizer state changes. - * Rasterizer state includes culling, color masking - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyRasterizerStateChange() = 0; - - void LoadVertexData(u32 first, u32 count) - { - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) - { -// if (!m_vertex_data[i].IsEnabled()) continue; - -// m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index); - } - } - - virtual void Task(); - -public: - void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); - - u32 ReadIO32(u32 addr); - - void WriteIO32(u32 addr, u32 value); -}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index a3dcaae8f8..a31eb7ab4c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -396,7 +396,7 @@ s32 _cellGcmInitBody(vm::pptr context, u32 cmdSize, u32 ioSi render.gcm_current_buffer = 0; render.main_mem_addr = 0; render.label_addr = gcm_info.label_addr; - render.Init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr); + render.init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr); return CELL_OK; }