diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index e4df7d80fe..2f5bd2d49e 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -478,7 +478,7 @@ namespace rsx if (auto method = methods[reg]) { - method(this, value); + method(this, reg, value); } } diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index aa94783c4a..18c8ecc965 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -26,7 +26,7 @@ cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", namespace rsx { rsx_state method_registers; - using rsx_method_t = void(*)(class thread*, u32); + std::array methods{}; template struct vertex_data_type_from_element_type; @@ -37,12 +37,12 @@ namespace rsx namespace nv406e { - force_inline void set_reference(thread* rsx, u32 arg) + void set_reference(thread* rsx, u32 _reg, u32 arg) { rsx->ctrl->ref.exchange(arg); } - force_inline void semaphore_acquire(thread* rsx, u32 arg) + void semaphore_acquire(thread* rsx, u32 _reg, u32 arg) { //TODO: dma while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg) @@ -54,7 +54,7 @@ namespace rsx } } - force_inline void semaphore_release(thread* rsx, u32 arg) + void semaphore_release(thread* rsx, u32 _reg, u32 arg) { //TODO: dma vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg); @@ -63,21 +63,45 @@ namespace rsx namespace nv4097 { - force_inline void texture_read_semaphore_release(thread* rsx, u32 arg) + void clear(thread* rsx, u32 _reg, u32 arg) { + // TODO: every backend must override method table to insert its own handlers + if (!rsx->do_method(/* reg << 2 */ NV4097_CLEAR_SURFACE, arg)) + { + // + } + + if (rsx->capture_current_frame) + { + rsx->capture_frame("clear"); + } + } + + void texture_read_semaphore_release(thread* rsx, u32 _reg, u32 arg) + { + if (!rsx->do_method(/* reg << 2 */ NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, arg)) + { + // + } + //TODO: dma vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg); } - force_inline void back_end_write_semaphore_release(thread* rsx, u32 arg) + void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg) { + if (!rsx->do_method(/* reg << 2 */ NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE, arg)) + { + // + } + //TODO: dma vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); } template - force_inline void set_vertex_data_impl(thread* rsx, u32 arg) + void set_vertex_data_impl(thread* rsx, u32 arg) { static const size_t increment_per_array_index = (count * sizeof(type)) / sizeof(u32); @@ -96,7 +120,7 @@ namespace rsx template struct set_vertex_data4ub_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -105,7 +129,7 @@ namespace rsx template struct set_vertex_data1f_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -114,7 +138,7 @@ namespace rsx template struct set_vertex_data2f_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -123,7 +147,7 @@ namespace rsx template struct set_vertex_data3f_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -132,7 +156,7 @@ namespace rsx template struct set_vertex_data4f_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -141,7 +165,7 @@ namespace rsx template struct set_vertex_data2s_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -150,7 +174,7 @@ namespace rsx template struct set_vertex_data4s_m { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { set_vertex_data_impl(rsx, arg); } @@ -159,7 +183,7 @@ namespace rsx template struct set_vertex_data_array_format { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { const typename rsx::registers_decoder::decoded_type decoded_value(arg); rsx::method_registers.vertex_arrays_info[index].frequency = decoded_value.frequency(); @@ -169,7 +193,7 @@ namespace rsx } }; - force_inline void draw_arrays(thread* rsx, u32 arg) + void draw_arrays(thread* rsx, u32 _reg, u32 arg) { rsx->draw_command = rsx::draw_command::array; u32 first = arg & 0xffffff; @@ -178,7 +202,7 @@ namespace rsx rsx->first_count_commands.emplace_back(std::make_pair(first, count)); } - force_inline void draw_index_array(thread* rsx, u32 arg) + void draw_index_array(thread* rsx, u32 _reg, u32 arg) { rsx->draw_command = rsx::draw_command::indexed; u32 first = arg & 0xffffff; @@ -187,7 +211,7 @@ namespace rsx rsx->first_count_commands.emplace_back(std::make_pair(first, count)); } - force_inline void draw_inline_array(thread* rsx, u32 arg) + void draw_inline_array(thread* rsx, u32 _reg, u32 arg) { rsx->draw_command = rsx::draw_command::inlined_array; rsx->draw_inline_vertex_array = true; @@ -197,7 +221,7 @@ namespace rsx template struct set_transform_constant { - force_inline static void impl(thread* rsxthr, u32 arg) + static void impl(thread* rsxthr, u32 _reg, u32 arg) { static constexpr u32 reg = index / 4; static constexpr u8 subreg = index % 4; @@ -211,13 +235,13 @@ namespace rsx template struct set_transform_program { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { method_registers.commit_4_transform_program_instructions(index); } }; - force_inline void set_begin_end(thread* rsxthr, u32 arg) + void set_begin_end(thread* rsxthr, u32 _reg, u32 arg) { if (arg) { @@ -257,7 +281,7 @@ namespace rsx } } - force_inline void get_report(thread* rsx, u32 arg) + void get_report(thread* rsx, u32 _reg, u32 arg) { u8 type = arg >> 24; u32 offset = arg & 0xffffff; @@ -297,7 +321,7 @@ namespace rsx //result->padding = 0; } - force_inline void clear_report_value(thread* rsx, u32 arg) + void clear_report_value(thread* rsx, u32 _reg, u32 arg) { switch (arg) { @@ -313,7 +337,7 @@ namespace rsx } } - force_inline void set_surface_dirty_bit(thread* rsx, u32) + void set_surface_dirty_bit(thread* rsx, u32 _reg, u32) { rsx->m_rtts_dirty = true; } @@ -321,7 +345,7 @@ namespace rsx template struct set_texture_dirty_bit { - force_inline static void impl(thread* rsx, u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { rsx->m_textures_dirty[index] = true; } @@ -333,7 +357,7 @@ namespace rsx template struct color { - force_inline static void impl(u32 arg) + static void impl(thread* rsx, u32 _reg, u32 arg) { u16 x = method_registers.nv308a_x(); u16 y = method_registers.nv308a_y(); @@ -351,7 +375,7 @@ namespace rsx namespace nv3089 { - never_inline void image_in(thread *rsx, u32 arg) + void image_in(thread *rsx, u32 _reg, u32 arg) { rsx::blit_engine::transfer_operation operation = method_registers.blit_engine_operation(); @@ -659,7 +683,7 @@ namespace rsx namespace nv0039 { - never_inline void buffer_notify(u32 arg) + void buffer_notify(thread*, u32, u32 arg) { s32 in_pitch = method_registers.nv0039_input_pitch(); s32 out_pitch = method_registers.nv0039_output_pitch(); @@ -713,7 +737,7 @@ namespace rsx } } - void flip_command(thread* rsx, u32 arg) + void flip_command(thread* rsx, u32, u32 arg) { if (user_asked_for_frame_capture) { @@ -764,7 +788,7 @@ namespace rsx } } - void user_command(thread* rsx, u32 arg) + void user_command(thread* rsx, u32, u32 arg) { if (rsx->user_handler) { @@ -856,172 +880,117 @@ namespace rsx registers[reg] = value; } - struct __rsx_methods_t + namespace method_detail { - using rsx_impl_method_t = void(*)(u32); - - template - force_inline static void call_impl_func(thread *rsx, u32 arg) - { - impl_func(rsx, arg); - } - - template - force_inline static void call_impl_func(thread *rsx, u32 arg) - { - impl_func(arg); - } - - template - static void wrapper(thread *rsx, u32 arg) - { - // try process using gpu - if (rsx->do_method(id, arg)) - { - if (rsx->capture_current_frame && id == NV4097_CLEAR_SURFACE) - rsx->capture_frame("clear"); - return; - } - - // not handled by renderer - // try process using cpu - if (impl_func != nullptr) - call_impl_func(rsx, arg); - } - - template class T, int index = 0> + template class T, int Index = 0> struct bind_range_impl_t { - force_inline static void impl() + static inline void impl() { - bind_range_impl_t::impl(); - bind::impl>(); + methods[Id] = &T::impl; + bind_range_impl_t::impl(); } }; - template class T> - struct bind_range_impl_t + template class T> + struct bind_range_impl_t { - force_inline static void impl() + static inline void impl() { } }; - template class T, int index = 0> - force_inline static void bind_range() + template class T, int Index = 0> + static inline void bind_range() { - bind_range_impl_t::impl(); + bind_range_impl_t::impl(); } - [[noreturn]] never_inline static void bind_redefinition_error(int id) + template + static void bind() { - throw EXCEPTION("RSX method implementation redefinition (0x%04x)", id); + methods[Id] = Func; } + } - template - static void bind_impl() - { - if (methods[id]) - { - bind_redefinition_error(id); - } + // TODO: implement this as virtual function: rsx::thread::init_methods() or something + static const bool s_methods_init = []() -> bool + { + using namespace method_detail; - methods[id] = wrapper; - } + // NV406E + bind(); + bind(); + bind(); - template - static void bind_cpu_only_impl() - { - if (methods[id]) - { - bind_redefinition_error(id); - } + /* - methods[id] = call_impl_func; - } + // Store previous fbo addresses to detect RTT config changes. + std::array m_previous_color_address = {}; + u32 m_previous_address_z = 0; + u32 m_previous_target = 0; + u32 m_previous_clip_horizontal = 0; + u32 m_previous_clip_vertical = 0; + */ - template static void bind() { bind_impl(); } - template static void bind() { bind_impl(); } + // NV4097 + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); + bind_range(); - //do not try process on gpu - template static void bind_cpu_only() { bind_cpu_only_impl(); } - //do not try process on gpu - template static void bind_cpu_only() { bind_cpu_only_impl(); } + //NV308A + bind_range(); + bind_range(); - __rsx_methods_t() - { - // NV406E - bind_cpu_only(); - bind(); - bind(); + //NV3089 + bind(); - /* + //NV0039 + bind(); - // Store previous fbo addresses to detect RTT config changes. - std::array m_previous_color_address = {}; - u32 m_previous_address_z = 0; - u32 m_previous_target = 0; - u32 m_previous_clip_horizontal = 0; - u32 m_previous_clip_vertical = 0; - */ + // custom methods + bind(); + bind(); - // NV4097 - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_cpu_only(); - bind_cpu_only(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - bind_range(); - - //NV308A - bind_range(); - bind_range(); - - //NV3089 - bind(); - - //NV0039 - bind(); - - // custom methods - bind_cpu_only(); - bind_cpu_only(); - } - } __rsx_methods; + return true; + }(); } diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index a8462b718d..308bab3f54 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -14,6 +14,8 @@ namespace rsx { + using rsx_method_t = void(*)(class thread*, u32 reg, u32 arg); + //TODO union alignas(4) method_registers_t { @@ -1114,7 +1116,6 @@ namespace rsx } }; - using rsx_method_t = void(*)(class thread*, u32); extern rsx_state method_registers; extern std::array methods; }